LCD伪菜单程序,我觉得注释还是写的很详细滴。同时实现任意位置的反白,我查了很多资料,发现12864的字符RAM和绘图RAM之间的异或关系
单片机源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #include "Delay.h"
- #include "key.h"
- #define uint unsigned int
- #define uchar unsigned char
- #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();};
-
- uchar code DIS1[] = {" 菜单查询 "};//一行一共有16个字符,空格也占一个字符位
- uchar code DIS2[] = {" 地图导航 "};
- uchar code DIS3[] = {" 语音导航 "};
- uchar code DIS4[] = {" 商品查询 "};
- /************* 12864LCD引脚定义 *************/
- #define LCD_data P0 //数据口
- sbit LCD_RS = P2^6; //寄存器选择输入
- sbit LCD_RW = P2^5; //液晶读/写控制
- sbit LCD_EN = P2^7; //液晶使能控制
- sbit LCD_PSB = P3^2; //串/并方式控制
- //sbit LCD_RST = P3^7; //液晶复位端口
- /************* LCD12864字符 *************/
- uchar code Photo_inverse_1[] ={ //将第一行进行反白
- /*-- 调入了一幅图像:这是您新建的图像 --*/
- /*-- 宽度x高度=128x16 --*/
- 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
- ……字库请下载附件……
- 0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
- };
- /*******************************************************************/
- /* */
- /*检查LCD忙状态 */
- /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
- /* */
- /*******************************************************************/
- bit lcd_busy() //定义了一个函数返回值类型lcd_busy()该函数只会有两个值,一个是0,一个是1
- { //位定义:bit的值只有两个,分别是0和1 如果P0&0x80的值为真,通过位定义(bit定义),那么result的值就是1。如果P0&0x80的值为假,通过位定义(bit定义),那么result的值就是0。
- bit result;
- LCD_RS = 0; //时序图:
- LCD_RW = 1;
- LCD_EN = 1;
- delayNOP();
- result = (bit)(P0&0x80); //把P0口读到的数据与0x80相与(0x80是1000 0000即判断最高位P0^7的状态是0还是1) 开发板原理图上8个数据口都是连在P0口上
- //读取P0^7引脚上的状态 1&1=1 1&0=0
- /*此程序是判断液晶忙程序,rs = 0;rw = 1;ep = 1;为读状态字功能,
- 而状态字一共有8位,STA0~STA7,其中,STA0~STA6表示当前数据地址指针的数值,
- STA7是读写操作使能,1表示禁止,也就是禁止操作液晶,也就是液晶忙,此时result为1,
- 反之,0表示允许,因此只需要状态字STA0~STA7中的最高位,你的程序中是通过P0控制状态字,
- 因此,就有result = (bit)(P0 & 0x80)*/
- LCD_EN = 0; //EN信号下降沿锁存DB7~DB0
- return(result); //返回0或者1
- }
- /*******************************************************************/
- /* */
- /*写指令数据到LCD */
- /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
- /* */
- /*******************************************************************/
- void lcd_wcmd(uchar cmd) //write_cmd写命令 想要对液晶进行操作,肯定先要在它空闲的时候操作
- {
- while(lcd_busy()); //等待lcd_busy()=0;是不是检测忙标志BF,因为BF=1,表示模块内部执行命令,不接受任何外部指令;BF=0,说明随时可以接收外部指令
- LCD_RS = 0; //RS为0表示DB7~DB0为显示指令数据
- LCD_RW = 0; //RW为0表示数据被写到IR或者DR
- LCD_EN = 0; //E下降沿锁存DB7~DB0
- _nop_();
- _nop_();
- P0 = cmd;
- delayNOP();
- LCD_EN = 1; //E下降沿锁存DB7~DB0
- delayNOP();
- LCD_EN = 0;
- }
- /*******************************************************************/
- /* */
- /*写显示数据到LCD */
- /*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
- /* */
- /*******************************************************************/
- void lcd_wdat(uchar dat) //write_data写数据
- {
- while(lcd_busy());
- LCD_RS = 1; //RS = 1;表示DB7~DB0为显示数据
- LCD_RW = 0; //DB7~DB0数据被读入IR
- LCD_EN = 0;
- P0 = dat;
- delayNOP();
- LCD_EN = 1;
- delayNOP();
- LCD_EN = 0;
- }
- /*******************************************************************/
- /* */
- /* LCD初始化设定 */
- /* */
- /*******************************************************************/
- void lcd_init()
- {
- LCD_PSB = 1; //PSB为高电平--并口方式:并口快,需要8+3条io口,读写快,特别适合图形方式;数据是从并口DB0-DB7(7-14)脚传输数据的
- //PSB为低电平--串口方式:占用Io口少,最少好像是两条,cs需要特殊处理一下,控制起来比较好使,占用单片机资源多,当然也有些小技巧可以解决
- //串口方式,是从串口4(RS/CS并行的指令/数据选择信号);串行的片选信号、5(R/W/SID)并行的读写选择信号,串行的数据口,6(E/CLK)并行的使能信号
-
- // LCD_RST = 0; //液晶复位
- // delay(3);
- // LCD_RST = 1; //复位置高
- // delay(3);
-
- lcd_wcmd(0x34); //扩充指令操作
- delay(5);
- lcd_wcmd(0x30); //基本指令操作
- delay(5);
- lcd_wcmd(0x0C); //显示开,关光标,不反白
- delay(5);
- lcd_wcmd(0x01); //清除LCD的显示内容(清屏)指针归位,设置地址指针魏00H
- delay(5);
- // lcd_wcmd(0x06); //指定在资料的读取和写入时,设定游标的移动方向及指定显示的一位,光标先从右向左加1位移动
- // delay(5);
- }
- /*********************************************************/
- /* */
- /* 设定显示位置 */
- /* */
- /*********************************************************/
- void lcd_pos(uchar X,uchar Y) //汉字显示坐标函数 X代表第几行 Y代表第几列
- {
- uchar pos;
- if (X==1) //1代表第一行
- {X=0x80;}
- else if (X==2) //2代表第二行
- {X=0x90;}
- else if (X==3) //3代表第三行
- {X=0x88;}
- else if (X==4) //4代表第四行
- {X=0x98;}
- pos = X+Y ; //pos = 0x80+0 = 0x80
-
- lcd_wcmd(pos); //显示地址
- }
- /*********************************************************
- * *
- * 闪烁函数 *
- * *
- *********************************************************/
- void lcdflag() //效果:闪三下
- {
- lcd_wcmd(0x08);
- delay(400);
- lcd_wcmd(0x0c);
- delay(400);
- lcd_wcmd(0x08);
- delay(400);
- lcd_wcmd(0x0c);
- delay(400);
- lcd_wcmd(0x08);
- delay(200);
- lcd_wcmd(0x0c);
- delay(5);
- lcd_wcmd(0x01);
- delay(5);
- }
-
-
- /*********************************************************
- * *
- * 图形显示 *
- * *
- *********************************************************/
- void photodisplay(uchar *bmp)
- {
- uchar i,j;
-
- lcd_wcmd(0x34); //写数据时,关闭图形显示
-
- for(i=0;i<32;i++)
- {
- lcd_wcmd(0x80+i); //先写入水平坐标值
- lcd_wcmd(0x80); //写入垂直坐标值
- for(j=0;j<16;j++) //再写入两个8位元的数据
- lcd_wdat(*bmp++);
- delay1(1);
- }
-
- for(i=0;i<32;i++)
- {
- lcd_wcmd(0x80+i);
- lcd_wcmd(0x88);
- for(j=0;j<16;j++)
- lcd_wdat(*bmp++);
- delay1(1);
- }
- lcd_wcmd(0x36); //写完数据,开图形显示
- }
- /*********************************************************
- * *
- * 清屏函数 *
- * *
- *********************************************************/
- void clr_screen()
- {
- lcd_wcmd(0x34); //扩充指令操作
- delay(5);
- lcd_wcmd(0x30); //基本指令操作
- delay(5);
- lcd_wcmd(0x01); //清屏
- delay(5);
- }
- /**********************************************************
- ; 显示字符表代码
- **********************************************************/
- void bytecode()
- {
- uchar s;
- clr_screen(); //清屏
- lcd_wcmd(0x80); //设置显示位置为第一行
- for(s=0;s<16;s++)
- {
- lcd_wdat(0x30+s);
- }
- lcd_wcmd(0x90); //设置显示位置为第二行
- for(s=0;s<16;s++)
- {
- lcd_wdat(0x40+s);
- }
- lcd_wcmd(0x88); //设置显示位置为第三行
- for(s=0;s<16;s++)
- {
- lcd_wdat(0x50+s);
- }
- lcd_wcmd(0x98); //设置显示位置为第四行
- for(s=0;s<16;s++)
- {
- lcd_wdat(0x60+s);
- }
- }
- /*********************************************************
- * *
- * 用于检测程序能不能跑起来。。。没啥用 就是测试 *
- * *
- *********************************************************/
- void lcd_action_up()
- {
- uchar i;
- lcd_pos(1,0); //设置显示位置为第一行 输出第一个数组
- for(i=0;i<16;i++)
- {
- lcd_wdat(DIS1[i]);
- delay(1);
- }
- for(i=0;i<16;i++)
- {
- lcd_wdat(DIS2[i]);
- delay(1);
- }
- for(i=0;i<16;i++)
- {
- lcd_wdat(DIS3[i]);
- delay(1);
- }
- for(i=0;i<16;i++)
- {
- lcd_wdat(DIS4[i]);
- delay(1);
- }
- photodisplay(Photo_inverse_5); //反白设置
- delay(3000);
- }
- void lcd_action_down()
- {
- uchar i;
- lcd_pos(1,0); //设置显示位置为第一行 输出第一个数组
- for(i=0;i<16;i++)
- {
- lcd_wdat(DIS1[i]);
- delay(1);
- }
- for(i=0;i<16;i++)
- {
- lcd_wdat(DIS2[i]);
- delay(1);
- }
- for(i=0;i<16;i++)
- {
- lcd_wdat(DIS3[i]);
- delay(1);
- }
- for(i=0;i<16;i++)
- {
- lcd_wdat(DIS4[i]);
- delay(1);
- }
- photodisplay(Photo_inverse_6); //反白设置
- delay(3000);
- }
- void lcd_action_enter()
- {
- uchar i;
- lcd_pos(1,0); //设置显示位置为第一行 输出第一个数组
- for(i=0;i<16;i++)
- {
- lcd_wdat(DIS1[i]);
- delay(1);
- }
- for(i=0;i<16;i++)
- {
- lcd_wdat(DIS2[i]);
- delay(1);
- }
- for(i=0;i<16;i++)
- {
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码- /*******************************************************************************
- * 描述: *
- * 12864标准字库液晶演示 数据p0,控制p2 *
- ********************************************************************************/
- #include <reg51.h>
- #include <intrins.h>
- #include "LCD12864.h"
- #include "Delay.h"
- #include "key.h"
- #define uchar unsigned char
- #define uint unsigned int
-
- #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();};
- /*********************************************************
- * *
- * 主函数 *
- * *
- *********************************************************/
- void main()
- {
- delay(1000); //上电,等待稳定
- lcd_init(); //初始化LCD
- while(1)
- {
- Menu_temp_judge();
- }
-
- }
复制代码- #include <reg52.h>
- #include "LCD12864.h"
- #include "Delay.h"
- #define uint unsigned int
- #define uchar unsigned char
- sbit key_UP = P1^0;
- sbit key_Down = P1^1;
- sbit key_Enter = P1^2;
- sbit key_Cancel = P1^3;
- uchar fresh_keytemp; //用于保存从按键判断函数uchar keyscan()的返回值
- uchar keyscan()
- {
- uchar keytemp;
- if (key_UP == 0) //反白上移
- {
- delays(10);
- if (key_UP == 0)
- {
- delays (10);
- while(!key_UP); //按键的完整操作是:按键按下再松开,算按一次
- /*按键按下后的具体指令位置*/
- keytemp = 1; //键码值为1,对应UP键
- }
- }
- if (key_Down == 0)
- {
- delays(10);
- if (key_Down == 0)
- {
- delays (10);
- while(!key_Down); //按键的完整操作是:按键按下再松开,算按一次
- /*按键按下后的具体指令位置*/
- keytemp = 2; //键码值为2,对应Down键
- }
- }
- if (key_Enter == 0)
- {
- delays(10);
- if (key_Enter == 0)
- {
- delays (10);
- while(!key_Enter); //按键的完整操作是:按键按下再松开,算按一次
- /*按键按下后的具体指令位置*/
- keytemp = 3; //键码值为3,对应Enter键
- }
- }
- if (key_Cancel == 0)
- {
- delays(10);
- if (key_Cancel == 0)
- {
- delays (10);
- while(!key_Cancel); //按键的完整操作是:按键按下再松开,算按一次
- /*按键按下后的具体指令位置*/
- keytemp = 4; //键码值为4,对应Cancel键
- }
- }
- return keytemp;
- }
- void Menu_temp_judge()
- {
- fresh_keytemp = keyscan();
- if (fresh_keytemp == 1) //按键效果:对应菜单1
- {
- /*替换成相应的函数*/
- lcd_action_up();
- }
- else if(fresh_keytemp == 2) //按键效果:对应菜单二
- {
- lcd_action_down();
- }
- else if(fresh_keytemp == 3) //按键效果:对应菜单三
- {
- lcd_action_enter();
- }
- else if(fresh_keytemp == 4) //按键效果:对应菜单四
- {
- lcd_action_cancel();
- }
- else
- {
- //空
- }
- // delay(20);
- }
复制代码
所有资料51hei提供下载:
成功实现LCD12864任意一行中间四个汉字的反白.zip
(70.62 KB, 下载次数: 164)
|