LCD12864的MSP430驱动程序(草稿)
为解决原有指令集只能使全码反白,不能使单个字符的半码反白问题,写了单个字符反白和恢复函数。原理是:在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');
}
.h文件
//=================================版本信息==================================// //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
/***万好好-科研论文培训,微信号:wanhaohao258。如转载本博客内容请注明,如果存在知识产权问题请主动联系。***/
浙公网安备 33010602011771号