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 

posted on 2011-08-21 00:01  万好好  阅读(3238)  评论(2编辑  收藏  举报

导航