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 

你可能感兴趣的:(程序)