1602是液晶显示内容,汉字显示对于初学者来说,有较大难度,我在学习过程中对前人的程序做了详细注释。希望可以帮助到列位黑友。
需要等1分钟左右才显示
单片机源程序如下:
- /*************************************************************************
- 程序功能:在LCD上显示2013年08月21日
- I Love Mcu
- Author
- x x x
- ******************头文件声明**********************************************/
- #include <reg51.h>
- #include <intrins.h>
- /*********************************端口定义**********************************/
- sbit rs= P3^0;
- sbit rw = P3^1;
- sbit en = P3^2;
- sbit busy=P0^7;
- /********************************显示数据表*********************************/
- unsigned char day[] = {0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00}; //日的字符表
- unsigned char month[]={0x1f,0x11,0x1d,0x11,0x1d,0x11,0x11,0x00}; //月的字符表 //月的字符表
- unsigned char year[] ={0x40,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02}; //年的字符表
- unsigned char time[] ={"20130821"};
- unsigned char code1[]={"I Love Mcu"};
- unsigned char author[]={"Author"};
- unsigned char name[]={"X X X"};
- /*****************************************************************************
- 函数功能:LCD延时子程序
- *****************************************************************************/
- void Delay(unsigned char x)
- {
- int i,j;
- for(i=x;i>0;i--)
- for(j=110;j>0;j--);
- }
- /*****************************************************************************
- 函数功能:测试LCD状态是否忙碌
- 检测原因:单片机处理速度较快,而LCD的处理速度较慢
- *****************************************************************************/
- bit lcd_check_busy()
- {
- P0=0Xff;
- rs = 0;//只要设置了rs=0,rw=1,就是要读BF位
- rw = 1;
- en = 0;
- _nop_(); //这三行的作用是进行一个空操作,读BF数值,然后使能输出BF值
- en=1;
- return busy; //如果LCD忙,就返回忙(BF=1)
- }
- /*****************************************************************************
- 函数功能:写指令到LCD子程序
- *****************************************************************************/
- void lcd_wcmd(unsigned char cmd)
- {
- while(lcd_check_busy()); //判断LCD是否忙碌,忙才写。我曾经改成!lcd_check_busy(),无法正常显示
- rs = 0; //写指令(只要rs = 0,rw = 0就是写指令)
- rw = 0;
- en = 1;
- P0 = cmd;
- _nop_();
- en = 0;
- }
- /*****************************************************************************
- 函数功能:写数据到LCD子程序
- *****************************************************************************/
- void lcd_wdat(unsigned char dat)
- {
- while(lcd_check_busy()); //判断LCD是否忙碌,忙才写
- rs = 1; //写数据(只要rs = 1,rw = 0就是写指令)
- rw = 0;
- en = 1;
- P0 = dat;//先使能,才能读dat数据
- _nop_();
- en = 0;
- }
- /*****************************************************************************
- 函数功能:设定显示位置子程序
- *****************************************************************************/
- void lcd_pos(unsigned char pos)
- {
- lcd_wcmd(pos | 0x80);//DDRAM地址设置,0x80=1000 0000,N = 1,分两行显示,
- } //首行A6-A0=00H-2FH|pos值,次行A6-A0 = 40H-67H|pos值
- /*****************************************************************************
- 函数功能:LCD初始化子程序(有个疑问,初始化程序,为什么显示开关不直接设为0x0c?
- 是不是因为要先全部关闭,才能清屏?)
- *****************************************************************************/
- void lcd_init() // 以下指令名lcd_wcmd只是有个名字而已,0x38等才是关键
- {
- lcd_wcmd(0x38); //功能设置:8位数据,双行显示,5*7点阵
- lcd_wcmd(0x08); //显示开关设置:显示关闭,无光标,不闪烁--先关闭
- lcd_wcmd(0x01); //清屏
- lcd_wcmd(0x06); //输入方式设置:光标自动增一
- Delay(100);
- lcd_wcmd(0x0c); //显示开关设置:显示开启,无光标,不闪烁--再开启
- }
- /****************************************************************************
- 函数功能:建立年月日字符
- *****************************************************************************/
- void lcd_setup() //先建立年月日字符
- {
- unsigned int i;
- lcd_wcmd(0x40); //功能设置P0=0x40=0010 0000,4位,一行显示,5*7点阵显示
- for(i=0;i<8;i++)
- {
- lcd_wdat(year[i]);
- }
- Delay(1000);
- lcd_wcmd(0x48);
- for(i=0;i<8;i++)
- {
- lcd_wdat(month[i]);
- }
- Delay(1000);
- lcd_wcmd(0x56);
- for(i=0;i<8;i++)
- {
- lcd_wdat(day[i]);
- }
- Delay(1000);
- }
- /*****************************************************************************
- 函数功能:主程序
- *****************************************************************************/
- void main(void)
- {
- unsigned char i;
- lcd_init(); //初始化LCD
- lcd_setup(); //建立字符
- while(1)
- {
- lcd_pos(0x00);
- for(i=0;i<4;i++)
- {
- lcd_wdat(time[i]); //显示2013
- }
- lcd_pos(0x05); //设置起始地址是0x05,0x05|0x80=0x85
- lcd_wdat(0x00); //写指令,P0=0x00
-
- lcd_pos(0x07); //设置起始地址是0x07,0x05|0x80=0x87
- for(i=4;i<6;i++)
- {
- lcd_wdat(time[i]); //显示08
- Delay(1000);
- }
-
- lcd_pos(0x0a); //设置起始地址是0x0a,0x0a|0x80=0x8a
- lcd_wdat(0x01); //写数据,P0=0x01
-
- lcd_pos(0x0c); //设置起始地址是0x0c,0x0c|0x80=0x8c
- for(i=6;i<8;i++)
- {
- lcd_wdat(time[i]); //显示21
- Delay(1000);
- }
- lcd_pos(0x0f); //设置起始地址是0x0f,0x0f|0x80=0x8f
- lcd_wdat(0x02); //写数据,P0=0x02
-
- lcd_pos(0x43); //设置起始地址是0x43,0x43|0x80=0xc3
- for(i=0;i<10;i++)
- {
- lcd_wdat(code1[i]); //显示I Love Mcu
- Delay(1000);
- }
- for(i=0;i<17;i++)
- {
- lcd_wcmd(0x18); //0001 1000显示字符平移一个字符位(0001),
- Delay(1000); //显示字符整体左移1位(1000)
- }
- lcd_wcmd(0x01); //清屏
-
- lcd_pos(0x05);
- for(i=0;i<6;i++)
- {
- Delay(10);
- lcd_wdat(author[i]);
- }
- lcd_pos(0x41);
- for(i=0;i<13;i++)
- {
- Delay(10);
- lcd_wdat(name[i]);
- }
- Delay(10);
- lcd_wcmd(0x01);
- }
- }
复制代码
所有资料51hei提供下载(有问题的问题):
1602LCD显示详细注释.zip
(864.6 KB, 下载次数: 116)
|