写出编程LCD1602液晶的初始化程序
#include
lcd1602转接板程序 lcd转接板怎么用
#define uchar unsigned char
#define uint unsigned int
#define lcd_ports P1
sbit lcdrs=P3^5;
sbit lcdrw=P3^3;
sbit lcde=P3^4;
void delay(uint z) //延迟子程序
{uchar i,j;
for(i=z;i>0;i--)
for(j=256;j>0;j--);
}void write_com(uchar com) //1602写指令
{lcdrs=0;
P1=com;
delay(5);
lcde=1;
delay(5);
lcde=0;
}void write_data(uchar date) //1602写数据,写的是你要显示数据的ASCLL码值
{lcdrs=1;
P1=date;
delay(5);
lcde=1;
delay(5);
lcde=0;
}void init() //初始化
{lcdrw=0;
lcde=0;
write_com(0x38); //使液晶显示点阵
write_com(0x0e); //初始设置
write_com(0x06); //初始设置
write_com(0x01); //清零
write_com(0x80+0x00); //使指针指向第一行第一列
}void main()
{init();
while(1){
write_com(0x80);//从第一行第一列开始写数据。
write_data(0x73); //显示s字符
write_data(0x69);//第一行第二列显示字符i
write_data(0x6e);//第一行第三列显示字符n
write_data(0x65);//第一行第四列显示字符e;}
}
可以给你写一份
; LCD Display Driver Demo.
; Timing code assumes 1.2MHz Clock
;LCD Registers addresses
LCD_CMD_WR equ 0 ;宏定义
LCD_DATA_WR equ 1
LCD_BUSY_RD equ 2
LCD_DATA_RD equ 3
;LCD Commands
LCD_CLS equ 1
LCD_HOME equ 2
LCD_SETMODE equ 4
LCD_SETVISIBLE equ 8
LCD_SHIFT equ 16
LCD_SETFUNCTION equ 32
LCD_SETCGADDR equ 64
LCD_SETDDADDR equ 128
;Reset vector
org 0000h;程序开始入口地址0x00
jmp start;跳转到start处
;Start of the program
org 0100h
string1a:db ' !! A M A Z I N G !! ' ;表格,要显示的内容。
db 0
string1b:db '!! A M A Z I N G !! '
db 0
string2:db ' A virtual LM032L... '
db 0
string3:db ' driven by a virtual '
db 0
string4:db ' 8051 processor!'
db 0
start: mov A,#038h ;为什么是38h:查1602数据手册,38h的命令
call wrcmd
loop: mov A,#LCD_SETVISIBLE+6 ;Make the display & blink visible:
call wrcmd
mov R7,#2
loop2:
mov DPTR,#string1a
call wrstr
mov DPTR,#200
call wtms
mov A,#LCD_CLS ;Clear screen
call wrcmd
mov DPTR,#string1b
call wrstr
mov DPTR,#200
call wtms
mov A,#LCD_CLS ;Clear screen
call wrcmd
djnz R7,loop2
mov DPTR,#string1a
call wrstr
mov DPTR,#400
call wtms
mov A,#LCD_SETDDADDR+64
call wrcmd
mov DPTR,#string2
call wrslow
mov DPTR,#200
call wtms
mov A,#LCD_CLS ;Clear screen
call wrcmd
mov DPTR,#string3
call wrslow
mov A,#LCD_SETDDADDR+64
call wrcmd
mov DPTR,#string4
call wrslow
mov A,#LCD_SETVISIBLE+7 ;Show the blink cursor as well.
call wrcmd
mov DPTR,#2000
call wtms
mov A,#LCD_CLS ;Clear screen
call wrcmd
jmp loop
;Sub routine to write null terminated string at DPTR in program ram.
wrstr: mov R0,#LCD_DATA_WR
wrstr1: clr A
movc A,@A+DPTR
jz wrstr2
movx @R0,A
call wtbusy
inc DPTR
push DPL
push DPH
pop DPH
pop DPL
jmp wrstr1
wrstr2: ret
;Sub routine to write null terminated string at DPTR in program ram. Slowly
wrslow: mov R0,#LCD_DATA_WR
wrslw1: clr A
movc A,@A+DPTR
jz wrslw2
movx @R0,A
call wtbusy
inc DPTR
push DPL
push DPH
mov DPTR,#100
call wtms
pop DPH
pop DPL
jmp wrslw1
wrslw2: ret
;Sub routine to write command:
wrcmd: mov R0,#LCD_CMD_WR
movx @R0,A
jmp wtbusy
;Sub routine to write character:
wrchar: mov R0,#LCD_DATA_WR
movx @R0,A
;Subroutine to wait for busy clear
wtbusy: mov R1,#LCD_BUSY_RD
movx A,@r1
jb ACC.7,wtbusy
ret
;Wait for number of seconds in A
wtsec: push ACC
call wtms
pop ACC
dec A
jnz wtsec
ret
;Wait for number of milliseconds in DPTR
wtms: xrl DPL,#0FFh ;Can't do DEC DPTR, so do the loop by forming 2's complement
xrl DPH,#0FFh ;and incrementing instead.
inc DPTR
wtms1: mov TL0,#09Ch ;100 ticks before overflow = 1ms at 1.2MHz Clock
mov TH0,#0FFh
mov TMOD,#1 ;Timer 0 mode 1
setb TCON.4 ;Timer 0 runs
wtms2: jnb TCON.5,wtms2
clr TCON.4 ;Timer 0 stops
clr TCON.5
inc DPTR
mov A,DPL
orl A,DPH
jnz wtms1
ret
END
呵呵。汇编的看不大懂,c语言的要么、。、
这么一大坨啊~~
如果你可以分别实现按键识别和LCD1602显示字符串,就很好实现切换屏幕了
LCD1602没有多余的显存,如果要切换屏幕,必须把两个(或多个)待显示的内容存储在MCU的内存中,如
unsigned char String_1_1[16]={"good luck"}; //第一屏 第一行
unsigned char String_1_2[16]={"good morning"}; //第一屏 第二行
unsigned char String_2_1[16]={"Welcome"}; //第二屏 第一行
unsigned char String_2_2[16]={"good morning"};
再用一个变量 char Show_Flag=1;// 记录当前显示的是第x屏
当有按键动作时,清屏然后再显示下一屏(如果字符长度一致也可以直接覆盖当前的显示内容)
#include
#define uchar unsigned char
#define uint unsigned int
sbit BLK=P1^0;
sbit DQ=P1^4;
sbit RS=P1^3;
sbit RW=P1^2;
sbit EN=P1^1;
unsigned char code str1[]={"temperature: "};
unsigned char code str2[]={" "};
uchar data disdata[5];
uint tvalue;//温度值
uchar tflag;//温度正负标志
/*************************lcd1602程序**************************/
void delay1ms(unsigned int ms)//延时1毫秒(不够精确的)
{unsigned int i,j;
for(i=0;i for(j=0;j<100;j++); }void wr_com(unsigned char com)//写指令// {delay1ms(1); RS=0; RW=0; EN=0; P0=com; delay1ms(1); EN=1; delay1ms(1); EN=0; }void wr_dat(unsigned char dat)//写数据// {delay1ms(1);; RS=1; RW=0; EN=0; P0=dat; delay1ms(1); EN=1; delay1ms(1); EN=0; }void lcd_init()//初始化设置// {BLK=0; delay1ms(15); wr_com(0x38); delay1ms(5); wr_com(0x08);delay1ms(5); wr_com(0x01);delay1ms(5); wr_com(0x06);delay1ms(5); wr_com(0x0c);delay1ms(5); }void display(unsigned char *p)//显示// {while(*p!='\0') {wr_dat(*p); p++; delay1ms(1); }} init_play()//初始化显示 {lcd_init(); wr_com(0x80); display(str1); wr_com(0xc0); display(str2); }/******************************ds1820程序***************************************/ void delay_18B20(unsigned int i)//延时1微秒 {while(i--); }void ds1820rst()/*ds1820复位*/ {unsigned char x=0; DQ = 1; //DQ复位 delay_18B20(4); //延时 DQ = 0; //DQ拉低 delay_18B20(100); //精确延时大于480us DQ = 1; //拉高 delay_18B20(40); }uchar ds1820rd()/*读数据*/ {unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) {DQ = 0; //给脉冲信号 dat>>=1; DQ = 1; //给脉冲信号 if(DQ) dat|=0x80; delay_18B20(10); }return(dat); }void ds1820wr(uchar wdata)/*写数据*/ {unsigned char i=0; for (i=8; i>0; i--) {DQ = 0; DQ = wdata&0x01; delay_18B20(10); DQ = 1; wdata>>=1; }} read_temp()/*读取温度值并转换*/ {uchar a,b; ds1820rst(); ds1820wr(0xcc);//*跳过读序列号*/ ds1820wr(0x44);//*启动温度转换*/ ds1820rst(); ds1820wr(0xcc);//*跳过读序列号*/ ds1820wr(0xbe);//*读取温度*/ a=ds1820rd(); b=ds1820rd(); tvalue=b; tvalue<<=8; tvalue=tvalue|a; if(tvalue<0x0fff) tflag=0; else {tvalue=~tvalue+1; tflag=1; }tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小? return(tvalue); }/*******************************************************************/ void ds1820disp()//温度值显示 { uchar flagdat; disdata[0]=tvalue/1000+0x30;//百位数 disdata[1]=tvalue%1000/100+0x30;//十位数 disdata[2]=tvalue%100/10+0x30;//个位数 disdata[3]=tvalue%10+0x30;//小数位 if(tflag==0) flagdat=0x20;//正温度不显示符号 else flagdat=0x2d;//负温度显示负号:- if(disdata[0]==0x30) {disdata[0]=0x20;//如果百位为0,不显示 if(disdata[1]==0x30) {disdata[1]=0x20;//如果百位为0,十位为0也不显示 }} wr_com(0xc0); wr_dat(flagdat);//显示符号? wr_com(0xc1); wr_dat(disdata[0]);//显示百位 wr_com(0xc2); wr_dat(disdata[1]);//显示十位 wr_com(0xc3); wr_dat(disdata[2]);//显示个位 wr_com(0xc4); wr_dat(0x2e);//显示小数点 wr_com(0xc5); wr_dat(disdata[3]);//显示小数位 }/********************主程序***********************************/ void main() {init_play();//初始化显示 while(1) {read_temp();//读取温度 ds1820disp();//显示 }} #include #include #define uchar unsigned char #define uint unsigned int #define LcdBus P0 sbit LED1602_RS=P2^6; //LCD端口定义 sbit LED1602_RW=P2^5 ; sbit LED1602_EN=P2^4 ; void LcdIni(void); void WrOp(uchar dat); void WrDat(uchar dat); void ChkBusy(void); void print_LCD(uchar disp[],uchar num); //延时n ms子程序 void delayms(unsigned int n) {unsigned int i,j; for(i=0;i for(j=0;j<120;j++); }main() {uchar disp1[16]={'S','u','n','J','i','e',' ','m','a','d','e',' ','a','t',' ',' '}; uchar disp2[16]={'2','0','0','8',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; while(1) {LcdIni(); WrOp(0x80); //数据指针地址第一行 print_LCD(disp1,16); WrOp(0xc0); //第二行 print_LCD(disp2,4); delayms(3000); WrOp(0x01); }} 功能特性 1,可以仿真63K程序空间,接近64K 的16位地址空间; 2,可以仿真64Kxdata 空间,全部64K 的16位地址空间; 3,可以真实仿真全部32 条IO脚; 4,完全兼容keilC51 UV2 调试环境,可以通过UV2 环境进行单步,断点, 全速等操作; 5,可以使用C51语言或者ASM汇编语言进行调试 ; 6,可以非常方便地进行所有变量观察,包括鼠标取值观察,即鼠标放在某 变量上就会立即显示出它此的值; 以上内容参考: #include #include #define uchar unsigned char #define uint unsigned int #define LcdBus P0 sbit LED1602_RS=P2^6; //LCD端口定义 sbit LED1602_RW=P2^5 ; sbit LED1602_EN=P2^4 ; void LcdIni(void); void WrOp(uchar dat); void WrDat(uchar dat); void ChkBusy(void); void print_LCD(uchar disp[],uchar num); //延时n ms子程序 void delayms(unsigned int n) {unsigned int i,j; for(i=0;i for(j=0;j<120;j++); }main() {uchar disp1[16]={'S','u','n','J','i','e',' ','m','a','d','e',' ','a','t',' ',' '}; uchar disp2[16]={'2','0','0','8',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; while(1) {LcdIni(); WrOp(0x80); //数据指针地址第一行 print_LCD(disp1,16); WrOp(0xc0); //第二行 print_LCD(disp2,4); delayms(3000); WrOp(0x01); }} /****************************************************************************************** 名称:led1602显示 程序模块 功能:驱动1602 包括数据口 P1 三个控制口 编译:keil 作者:孙杰 时间:2008-8-9 *******************************************************************************************/ void print_LCD(uchar disp[],uchar num) //显示数组disp 显示长度为num {uchar i; for(i=0;i {WrDat(disp[i]); delayms(300); }} void LcdIni() {WrOp(0x38); WrOp(0x06); //光标加1 WrOp(0x0f); //开显示 光标闪烁 // WrOp(0x0c); //开显示 光标不闪烁 }void WrOp(uchar dat) {//uchar i; ChkBusy(); LED1602_RS=0; //RS=0 LED1602_RW=0; //RW=0 LED1602_EN=0; //EN=0 LcdBus=dat; //送数据 LED1602_EN=1; //EN=1 delayms(10); //延时 LED1602_EN=0; //EN=0 }void WrDat(uchar dat) {//uchar i; ChkBusy(); LED1602_RS=1; //rs=1 LED1602_RW=0; //rw=0 LED1602_EN=0; //en=0 LcdBus=dat; //送数据 LED1602_EN=1; //en=1 delayms(10);; //延时 LED1602_EN=0; //en=0 }void ChkBusy() {LED1602_RS=0; //RS=0 LED1602_RW=1; //RW=1 LED1602_EN=1; //EN=1 while(LcdBus&0x80); //送数据 LED1602_EN=0; //en=0 } 1.硬件连接接触不良、虚焊。 2.lcd初始化函数写的不好,偶尔上电后初始化失败,就不能显示。建议上电延时一段时间,待lcd稳定后在执行初始化函数。 3.程序上要注意读写时序,加入适当的延时时间。 4.调节lcd第三脚v0的电压,调节到一个合适的值才可以显示。 先查硬件,确定没问题再在软件上找原因,只要细心,没有什么解决不了!祝你好运! 有时候是这样的,实物是要考虑外界干扰的,而仿真没有什么干扰,是理想情况,再继续调试,看好你的 空无一物?1602里就是没程序,也应该在第一行出现16个5X8点阵黑块。 版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至836084111@qq.com 举报,一经查实,本站将立刻删除。