为解决原有指令集只能使全码反白,不能使单个字符的半码反白问题,写了单个字符反白和恢复函数。原理是:在DDRAM中写字符,然后在GDRAM中原字符位置写1,则该位置显示内容为GDRAM和DDRAM数据的异或,故字符显示反白;在GDRAM中原字符位置写0,清除掉GDRAM内容,则显示内容恢复。
.c文件
//=================================版本信息==================================// //Ver:2011082002 //Author:XZQ //===========================================================================// #include "LCD12864_Driver.h" /******************************************* 函数名称:Write_Cmd 功 能:向液晶中写控制命令 参 数:cmd--控制命令 返回值 :无 ********************************************/ void Write_Cmd(uchar cmd) { uchar lcdtemp = 0; //定义一个变量为输出 LCD_RS_L; //设置为命令输入/输出 LCD_RW_H; //设置为读数据/命令 LCD_DataIn; //设置P9口的方向为输入 do //判忙,直到不忙位置 { LCD_EN_H; //LCD使能 delay_us(1); //空操作 lcdtemp = LCD2MCU_Data; //将读到的数据放入lcdtemp LCD_EN_L; //不选择LCD } while(lcdtemp & 0x80); LCD_DataOut; LCD_RW_L; MCU2LCD_Data = cmd; LCD_EN_H; delay_us(1); LCD_EN_L; } /******************************************* 函数名称:Write_Data 功 能:向液晶中写显示数据 参 数:dat--显示数据 返回值 :无 ********************************************/ void Write_Data(uchar dat) { uchar lcdtemp = 0; LCD_RS_L; LCD_RW_H; LCD_DataIn; do //判忙 { LCD_EN_H; delay_us(1); lcdtemp = LCD2MCU_Data; LCD_EN_L; } while(lcdtemp & 0x80); LCD_DataOut; LCD_RS_H; LCD_RW_L; MCU2LCD_Data = dat; LCD_EN_H; delay_us(1); LCD_EN_L; } /******************************************* 函数名称:Read_Data 功 能:读取液晶中的数据 参 数:无 返回值 :temp,读取的数据值 ********************************************/ uchar Read_Data() { uchar temp; LCD_DataIn; LCD_RW_H; //读数据,高电平有效 LCD_EN_L; LCD_RS_H; //读数据,高电平有效 delay_us(15); //延时最小值1500ns LCD_EN_H; //lcden一旦拉高,数据开始读入 temp=LCD2MCU_Data;//读出数据口的值 delay_us(15); //读数据持续时间最小值1500ns LCD_EN_L; //再次置低,准备下一次拉高 LCD_DataOut; return temp; //将读到的数据返回 } /******************************************* 函数名称:Ini_Lcd 功 能:初始化液晶模块 参 数:无 返回值 :无 ********************************************/ void Ini_Lcd(void) { LCD_CMDOut; //液晶控制端口设置为输出 delay_ms(500); Write_Cmd(0x30); //基本指令集 delay_ms(1); Write_Cmd(0x02); // 地址归位 delay_ms(1); Write_Cmd(0x0c); //整体显示打开,游标关闭 delay_ms(1); Write_Cmd(0x01); //清除显示 delay_ms(1); Write_Cmd(0x06); //游标右移 delay_ms(1); Write_Cmd(0x80); //设定显示的起始地址 } /******************************************* 函数名称:DispData8Bit 功 能:将8位无符号二进制数以十进制方式显示 参 数:uchar Data8Bit要显示的数据 uchar addr 数据显示位置(0x80-0x98+7) 返回值 :无 ********************************************/ void Disp8BitData(uchar Data8Bit,uchar addr) { uchar bai=0,shi=0,ge=0; bai= Data8Bit/100; Write_Cmd(addr); Write_Data(bai+0x30); Data8Bit= Data8Bit%100; shi= Data8Bit/10; Write_Data(shi+0x30); ge= Data8Bit%10; Write_Data(ge+0x30); } /******************************************* 函数名称:DispData16Bit 功 能:将16位无符号二进制数以十进制方式显示 参 数:uchar Data16Bit要显示的数据 uchar addr 数据显示位置(0x80-0x98+7) 返回值 :无 ********************************************/ void Disp16BitData(uint Data16Bit,uchar addr) { uchar Bit5=0,Bit4=0,Bit3=0,Bit2=0,Bit1=0; Write_Cmd(addr); Bit5= Data16Bit/10000; Write_Data(Bit5+0x30); Data16Bit=Data16Bit%10000; Bit4= Data16Bit/1000; Write_Data(Bit4+0x30); Data16Bit=Data16Bit%1000; Bit3= Data16Bit/100; Write_Data(Bit3+0x30); Data16Bit=Data16Bit%100; Bit2= Data16Bit/10; Write_Data(Bit2+0x30); Bit1= Data16Bit%10; Write_Data(Bit1+0x30); } /******************************************* 函数名称:Disp_HZ 功 能:控制液晶显示汉字 参 数:x:行坐标{0,1,2,3} y:列坐标[0-7] pt--指向显示数据的指针 num--显示字符个数 返回值 :无 ********************************************/ void Disp_HZ(uchar x,uchar y,const uchar * pt,uchar num) { uchar i; if (x==0)Write_Cmd(0x80+y); else if(x==1)Write_Cmd(0x90+y); else if(x==2)Write_Cmd(0x88+y); else Write_Cmd(0x98+y); for(i = 0;i < (num*2);i++) Write_Data(*(pt++)); } /******************************************* 函数名称:Draw1Word 功 能:打点。在液晶屏幕显示一次16位数据图像 参 数:z;半屏坐标,0-上半屏,1-下半屏 y:行坐标[0-31] x:列坐标[0-7] ByteData:要显示的图像数据高位在前,地位在后 返回值 :无 说明:坐标系示意 -----0---x---7---------- |0 z=0 |y |31 |0 z=1 |y |31 ********************************************/ void Draw1Word(uchar z,uchar y,uchar x,uint WordData) { Write_Cmd(0x34); //打开扩展指令集 Write_Cmd(0x80+y);//设置行地址 if(z==0) Write_Cmd(0x80+x);//设置半屏地址和列地址 if(z==1) Write_Cmd(0x88+x);//设置半屏地址和列地址 Write_Data((uint)(WordData>>8)); Write_Data((uint)WordData); Write_Cmd(0x36); //打开绘图显示 Write_Cmd(0x30); //回到基本指令集 } /******************************************* 函数名称:Clear_DDRAM 功 能:清除液晶DDRAM中的随机数据 参 数:无 返回值 :无 ********************************************/ void Clear_DDRAM() { uchar i; Write_Cmd(0x30);//打开基本指令集 Write_Cmd(0x80); for(i=0;i<32;i++) Write_Data(' '); Write_Cmd(0x90); for(i=0;i<32;i++) Write_Data(' '); } /******************************************* 函数名称:Clear_GDRAM 功 能:清除液晶GDRAM中的随机数据 参 数:无 返回值 :无 ********************************************/ void Clear_GDRAM(void) { uchar i,j,k; Write_Cmd(0x34); //打开扩展指令集 i = 0x80; for(j = 0;j < 32;j++) { Write_Cmd(i++); Write_Cmd(0x80); for(k = 0;k < 16;k++) { Write_Data(0x00); } } i = 0x80; for(j = 0;j < 32;j++) { Write_Cmd(i++); Write_Cmd(0x88); for(k = 0;k < 16;k++) { Write_Data(0x00); } } Write_Cmd(0x30); //回到基本指令集 } /******************************************* 函数名称:Draw_PM 功 能:在整个液晶屏幕上画图 参 数:无 返回值 :无 ********************************************/ void Draw_PM(const uchar *ptr) { uchar i,j,k; Write_Cmd(0x34); //打开扩展指令集 i = 0x80; for(j = 0;j < 32;j++) { Write_Cmd(i++); Write_Cmd(0x80); for(k = 0;k < 16;k++) { Write_Data(*ptr++); } } i = 0x80; for(j = 0;j < 32;j++) { Write_Cmd(i++); Write_Cmd(0x88); for(k = 0;k < 16;k++) { Write_Data(*ptr++); } } Write_Cmd(0x36); //打开绘图显示 Write_Cmd(0x30); //回到基本指令集 } /******************************************* 函数名称: Lcd_set_dot 功 能:ST7920控制的12864任意位置打点函数 参 数:uchar x,uchar y,坐标点,范围x[0:127],y[0:63] 返回值 :无 说明:坐标系示意 -----0---x---127---------- |0 |y |63 ********************************************/ void Lcd_set_dot(uchar x,uchar y) { uchar x_byte,x_bit; //确定dot在横轴上的哪个字节内的哪个位 uchar y_byte,y_bit; //确定dot在竖轴上的哪个字节内的哪个位 uchar TempH,TempL; //用来存放读出来的原始数据的高8位和低8位, //目的是为了避免新的数据点写进去后覆盖掉前面的点 x=x&0x7f; //限制横坐标所在范围,为0-127 y=y&0x3f; //限制纵坐标所在范围,为0-31(上半屏) 32-63(下半屏) x_byte=x/16; //确定该dot在哪一个字节 x_bit=x%16; //确定该dot在哪一个点 y_byte=y/32; //确定该dot在那个半屏,0:上半屏 1:下半屏 y_bit=y%32; //确定该dot在第几行(因为到了下半屏也是从0行开始到31行) Write_Cmd(0x34); //打开扩展指令集,关闭基本功能模式,绘图显示关闭 Write_Cmd(0x80+y_bit); //先将光标纵坐标写到指定行 Write_Cmd(0x80+x_byte+8*y_byte); //再将光标横坐标写到指定位置,若y_byte为1,则说明大于了31行(从0行算起) //则需将AC指针写到0x88处即ST7920控制下的第3行 Read_Data(); //当下设定AC地址指令后,若要读取数据需要预先dummy read一次,才会读到正确数据 //第2次读取时不需要dummy read,除非又重新设定AC位置才需再次dummy read TempH=Read_Data(); //读取高8位数据 TempL=Read_Data(); //读取低8位数据 Write_Cmd(0x80+y_bit); //读操作会改变AC位置,所以需要重新写入1次 Write_Cmd(0x80+x_byte+8*y_byte); if(x_bit<8) { Write_Data(TempH|(0x01<<(7-x_bit))); //如果要写的dot在高8位,则这样写利用or运算避免新数据覆盖原先数据 Write_Data(TempL); //原先的低8位数据照常写入 } else { Write_Data(TempH); //如果要写的dot在低8位,原先的高8位数据照常写入 Write_Data(TempL|(0x01<<(15-x_bit))); //低8位则这样写利用or运算避免新数据覆盖原先数据 } Write_Cmd(0x36); //开绘图显示 Write_Cmd(0x30); //回到GDRAM显示模式 } /******************************************* 函数名称: CharHighlight 功 能:让显示的单个字符反白显示或恢复显示 参 数:uchar x,uchar y,uchar flag. 坐标点范围x[0:15],y[0:3], flag=0显示恢复,flag=1反白显示。 返回值 :无 说明:坐标系示意 -----0---x---15---------- |0 |y |3 注意:全码内的两个字符只有一个可以反白显示。恢复全码内的一个 字符,则全码内两个字符同时恢复。此函数随不完善,但已符合 数字输入提示显示。 ********************************************/ void CharHighlight(uchar x,uchar y,uchar flag) { uchar z,x1,y1,i; uint WordData; switch(y) { case 0:y1=0;break; case 1:y1=16;break; case 2:y1=0;break; case 3:y1=16;break; default:y1=0; } if(y<2)z=0; else z=1; if(flag==0)WordData=0; else { if(x%2==0) WordData=0xFF00; else WordData=0x00FF; } x1=x/2; for(i=0;i<16;i++) { Draw1Word( z,y1+i, x1, WordData); } } /************************************鉴相器频率显示****************************/ void Disp_f(uint Data16Bit,uchar addr) { uint FreValue=0; FreValue=150000/Data16Bit; Disp16BitData(FreValue,addr); } void Disp_Pha(uint Data16Bit1,uint Data16Bit2,uchar addr) { float Pha=0; uchar PhaValue=0; Pha=Data16Bit2/Data16Bit1; PhaValue=(uint)Pha*100; Disp8BitData(PhaValue,addr); } /******************************************* 函数名称:DispData16Bit 功 能:将16位无符号二进制数以十进制方式显示 参 数:uchar Data16Bit要显示的数据 uchar addr 数据显示位置(0x80-0x98+7) 返回值 :无 ********************************************/ void DispFre(long int Data16Bit,uchar addr) { uchar Bit6,Bit5=0,Bit4=0,Bit3=0,Bit2=0,Bit1=0; Write_Cmd(addr); Bit6= Data16Bit/100000; Write_Data(Bit6+0x30); Data16Bit%=100000; Bit5= Data16Bit/10000; Write_Data(Bit5+0x30); Data16Bit=Data16Bit%10000; Bit4= Data16Bit/1000; Write_Data(Bit4+0x30); Write_Data(','); Data16Bit=Data16Bit%1000; Bit3= Data16Bit/100; Write_Data(Bit3+0x30); Data16Bit=Data16Bit%100; Bit2= Data16Bit/10; Write_Data(Bit2+0x30); Bit1= Data16Bit%10; Write_Data(Bit1+0x30); Write_Data('H'); } /************************************ADC12数据显示****************************/ void DispVoltage(uint VolValue,uchar Addr) { uint Value=0,Data16Bit; uchar Bit4=0,Bit3=0,Bit2=0,Bit1=0; Value=(uint)VolValue*3.3*1000/4055; Data16Bit=Value; Write_Cmd(Addr); Data16Bit=Data16Bit%10000; Bit4= Data16Bit/1000; Write_Data(Bit4+0x30); Write_Data('.'); Data16Bit=Data16Bit%1000; Bit3= Data16Bit/100; Write_Data(Bit3+0x30); Data16Bit=Data16Bit%100; Bit2= Data16Bit/10; Write_Data(Bit2+0x30); Bit1= Data16Bit%10; Write_Data(Bit1+0x30); Write_Data('V'); }
//=================================版本信息==================================// //Ver:2011082002 //Author:XZQ //===========================================================================// #ifndef _LCD12864_DRIVER_H #define _LCD12864_DRIVER_H //=================================头文件=================================// #include <msp430f5438.h> #include "MCU_Init.h" //=================================引脚分配===============================// //数据线 #define LCD_DataIn P3DIR=0x00 //设置数据方向为输入 #define LCD_DataOut P3DIR=0xFF //设置数据传输方向为输出 #define LCD2MCU_Data P3IN //将LCD的数据放入MCU #define MCU2LCD_Data P3OUT //将MCU的输出数据放入LCD //控制线 #define LCD_CMDOut P7DIR|=BIT6+BIT5+BIT4; #define LCD_RS_H P7OUT|=BIT4 //P8.0至高, #define LCD_RS_L P7OUT&=~BIT4 //P8.0至低,进行命令传输 #define LCD_RW_H P7OUT|=BIT5 //P8.1至高 #define LCD_RW_L P7OUT&=~BIT5 //P8.1至低 #define LCD_EN_H P7OUT|=BIT6 //P8.2至高,控制使能为正 #define LCD_EN_L P7OUT&=~BIT6 //P8.2至低,控制使能为负 //=================================函数申明===============================// //底层驱动函数 extern void Write_Cmd(unsigned char cod); extern void Write_Data(unsigned char dat); extern uchar Read_Data(void); //基本功能函数 extern void Ini_Lcd(void); extern void Clear_GDRAM(void); extern void Clear_DDRAM(void); extern void Draw_PM(const unsigned char *ptr); //高级功能函数 extern void Disp8BitData(uchar Data8Bit,uchar addr); extern void Disp16BitData(uint Data16Bit,uchar addr); extern void Disp_HZ(uchar x,uchar y,const uchar * pt,uchar num); extern void Draw1Word(uchar z,uchar x,uchar y,uint WordData); extern void Lcd_set_dot(uchar x,uchar y); //单个字符反白或恢复显示函数 extern void Draw1Word(uchar z,uchar x,uchar y,uint WordData); void CharHighlight(uchar x,uchar y,uchar flag); //其他外设数据显示函数 extern void Disp_f(uint Data16Bit,uchar addr); extern void Disp_Pha(uint Data16Bit1,uint Data16Bit2,uchar addr); extern void DispFre(long int FreValue,uchar addr); extern void DispVoltage(uint VolValue,uchar Addr); #endif