理解单片机的液晶显示器接口原理,掌握基本编程流程。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- //函数库名称:12864显示函数
- #include<reg51.h>
- #include<absacc.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define PORT P0
- sbit CS1=P2^4; //左半屏片选脚
- sbit CS2=P2^3; //右半屏片选脚
- sbit RS=P2^2; //H代表数据输入,L代表指令码输入
- sbit RW=P2^1; //H读取,L写入
- sbit E=P2^0; //使能,由H到L完成使能
- sbit bflag=P0^7; //忙标志位
- uchar code Num[]={
- 0x00,0x20,0x60,0xE0,0xE0,0xE0,0xF0,0xFC,
- 0xFF,0xFC,0xF0,0xE0,0xE0,0xE0,0x60,0x20,
- 0x00,0x00,0x40,0x30,0x3D,0x1F,0x1F,0x0F,
- 0x07,0x0F,0x1F,0x1F,0x3D,0x30,0x40,0x00, //星号
- 0x00,0xf8,0x08,0x08,0x08,0x08,0x08,0xff,
- 0x08,0x08,0x08,0x08,0x08,0xfc,0x08,0x00,
- 0x00,0x03,0x01,0x01,0x01,0x01,0x01,0xff,
- 0x01,0x01,0x01,0x01,0x01,0x03,0x00,0x00, //中
- 0x00,0xf0,0x00,0x00,0x00,0x00,0x00,0xff,
- 0x00,0x00,0x00,0x00,0x00,0xf0,0x00,0x00,
- 0x00,0x7f,0x20,0x20,0x20,0x20,0x20,0x3f,
- 0x20,0x20,0x20,0x20,0x20,0x7f,0x00,0x00, //山
- 0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x7f,
- 0xa0,0x20,0x20,0x20,0x20,0x30,0x20,0x00,
- 0x00,0x40,0x40,0x20,0x10,0x0c,0x03,0x00,
- 0x01,0x06,0x08,0x10,0x20,0x60,0x20,0x00, //大
- 0x40,0x30,0x11,0x96,0x90,0x90,0x91,0x96,
- 0x90,0x90,0x98,0x14,0x13,0x50,0x30,0x00,
- 0x04,0x04,0x04,0x04,0x04,0x44,0x84,0x7e,
- 0x06,0x05,0x04,0x04,0x04,0x06,0x04,0x00, //学
- };
- //****驱动函数****
- void Left()//选左半屏
- {
- CS1=0;
- CS2=1;
- }
- void Right()//选右半屏
- {
- CS1=1;
- CS2=0;
- }
- void Busy_12864()//判忙函数
- {
- do
- {
- E=0;
- RS=0; //读状态
- RW=1;
- PORT=0xff;
- E=1;
- E=0;
- }
- while(bflag); //若bflag=1则代表系统忙
- }
- void Wreg(uchar c)//写指令
- {
- Busy_12864();
- RS=0;
- RW=0;
- PORT=c;
- E=1; //E下降沿,液晶模块从数据总线写入指令
- E=0;
- }
- void Wdata(uchar c)//写数据
- {
- Busy_12864();
- RS=1;
- RW=0;
- PORT=c;
- E=1;
- E=0;
- }
- void Pagefirst(uchar c)//页设置
- //LCD12864一共可以画32个字,4行,每行8个字,左半屏4个,右半屏4个;
- //每个字占2页,第0页显示上半字,第1页显示下半字,画1个字是16X16个点;
- //8小行为一页,DDRAM共64小行,即8页,Page0-7,所以只能显示4行汉字
- {
- uchar i;
- i=c;
- c=i|0xb8;//实际页数和b8(即10111000B)的或运算就是要送的代码,逻辑加法
- Busy_12864();
- Wreg(c);
- }
- void Linefirst(uchar c)//列设置,Y=0-63,左右半屏各64列
- {
- uchar i;
- i=c;
- c=i|0x40;//实际列数和40(即01000000B)的或运算就是要送的代码
- Busy_12864();
- Wreg(c);
- }
- //****清屏函数****
- void Ready_12864()
- {
- uint i,j;
- Left();
- Wreg(0x3f);//左屏开显示;0x3e为关显示的控制字
- Right();
- Wreg(0x3f);//右屏开显示;0x3f为开显示的控制字
- Left();//清左屏
- for(i=0;i<8;i++)
- {
- Pagefirst(i);
- Linefirst(0x00);
- for(j=0;j<64;j++)
- {
- Wdata(0x00);
- }
- }
- Right();//清右屏
- for(i=0;i<8;i++)
- {
- Pagefirst(i);
- Linefirst(0x00);
- for(j=0;j<64;j++)
- {
- Wdata(0x00);
- }
- }
- }
- //****16×6汉字显示程序****
- void Display(uchar *s,uchar page,uchar line)
- {
- //先上半字,再下半字;由左向右逐列送值
- uchar i,j;
- Pagefirst(page);
- Linefirst(line);
- for(i=0;i<16;i++)
- {
- Wdata(*s);//指针S指向数组Num进行抽数
- s++;
- }
- Pagefirst(page+1);
- //换页,显示下半字,一个字需要2页才可以完成显示,即16小行
- Linefirst(line);
- for(j=0;j<16;j++)
- {
- Wdata(*s);
- s++;
- }
- }
- main()//主程序
- {
- //在第2行(3、4页)显示6个字;
- Ready_12864();
- Left();
- Display(Num+0,0x03,16); //第3页第16列(左屏第1个字位置)
- Display(Num+32,0x03,32); //第3页第32列(左屏第2个字位置)
- Display(Num+64,0x03,48); //第3页第48列(左屏第3个字位置)
- Right();
- Display(Num+96,0x03,0); //第3页第0列(右屏第0个字位置)
- Display(Num+128,0x03,16); //第3页第16列(右屏第1个字位置)
- Display(Num+0,0x03,32); //第3页第32列(右屏第2个字位置)
- while(1);
- }
复制代码
所有资料51hei提供下载:
LCD12864.zip
(758.39 KB, 下载次数: 86)
|