分享:基于launchpad的串行12864驱动显示程序(整理、总结和扩展)

shan_99   2012-8-1 19:47 楼主
/*************************************************************************
                      12864液晶串行显示测试程序
LCD型号:FYD12864-0402C
P2.4模拟SID(接第5脚),P2.5模拟SCLK(接第6脚)
4脚(CS信号)接高电平选通,15脚(PSB信号)接地选择串行方式->和GND焊盘相接
17脚(RST信号)根据注释提示悬空
*************************************************************************/
#include
#define  uchar  unsigned char
#define  uint  unsigned int

void int_port(void)                    //管脚初始化                       
{
  P2SEL&=~BIT4;                        //P1.4模拟SID,设置为i/o口输出方向                        
  P2DIR|=BIT4;                          
  P2OUT&=~BIT4;                           
  P2SEL&=~BIT5;                        //P1.5模拟SCLK,设置为i/o口输出方向                           
  P2DIR|=BIT5;                           
  P2OUT&=~BIT5;                           
}
/********************************************************************
* 名称 : delay()
*
* 输入 : t
* 输出 : 无
***********************************************************************/
void delay(uint t)             //延时函数
{                                      //粗略延时,满足时序要求
uint i,j;
for(i=0; i    for(j=0; j<10; j++);
}
/********************************************************************
* 名称 : sendbyte()
* 功能 : 按照液晶的串口通信协议,发送数据
* 输入 : zdata
* 输出 : 无
***********************************************************************/
void sendbyte(uchar zdata)     //数据传送函数
{
  uchar code_seg7;            
  uchar serial_clk;              
  uchar serial_shift;               
  code_seg7=zdata;                              
  serial_shift=0x80;                       
  for(serial_clk=0; serial_clk<8; serial_clk++)
  {                                   
    if(code_seg7&serial_shift)            
    {
      P2OUT|=BIT4;                     //SID为1
    }
    else
    {
      P2OUT&=~BIT4;                    //SID为0                       
    }
    P2OUT&=~BIT5;                      //产生时钟信号下沿
    P2OUT|=BIT5;                       //产生时钟信号上沿                             
    serial_shift=serial_shift>>1;      //准备发送下一位数据           
  }   
}
/********************************************************************
* 名称 : write_com()
* 功能 : 写串口指令
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void write_com(unsigned char cmdcode)  //写命令函数
{
                                 //串口控制格式(11111AB0)
                                //A数据方向控制,A=H时读,A=L时写
                                       //B数据类型选择,B=H时为显示数据,B=L时为命令
sendbyte(0xf8);                //MCU向LCD发命令
sendbyte(cmdcode & 0xf0);      //发高四位数据(数据格式D7D6D5D4_0000)
sendbyte((cmdcode << 4) & 0xf0);//发低四位数据(数据格式D3D2D1D0_0000)
delay(2);                      //延时等待
}

/********************************************************************
* 名称 : write_data()
* 功能 : 写串口数据
* 输入 : Dispdata
* 输出 : 无
***********************************************************************/
void write_data(uchar Dispdata)//写数据函数
{
  sendbyte(0xfa);                //MCU向LCD发数据
  sendbyte(Dispdata & 0xf0);     //发高四位数据
  sendbyte((Dispdata << 4) & 0xf0);//发低四位数据
  delay(2);
}
/********************************************************************
* 名称 : lcdinit()
* 功能 : 初始化函数
* 输入 : cmdcode
* 输出 : 无
***********************************************************************/
void lcdinit()                         //LCD初始化
{  
  delay(20000);                  //复位等待(内部自带上电复位电路),时间较长
  write_com(0x30);               //功能设定:基本指令集操作               
  delay(50);                     //延时等待
  write_com(0x0c);               //整体显示,关游标            
  delay(50);
  write_com(0x01);               //清屏            
  delay(50);
  write_com(0x06);               //入口设置            
  delay(50);
}
/********************************************************************
* 名称 : print_string()
* 功能 : 显示字符串
* 输入 : *s
* 输出 : 无
***********************************************************************/
void print_string(uchar *s)          //发送字符串
{  
while(*s > 0)                  //C语言里字符串末尾自动加“\0”(ASCII码值为0)
{
   write_data(*s);        //发送字符对应的ASCII码,12864指针可设置自动指向下一个显示地址
   s++;      
   delay(50);
}
}
/********************************************************************
* 函数名称  : LCD_12864_address_set( uchar x, y )
* 函数功能  : 12864地址坐标设置
* 函数参数  : X坐标,Y坐标
* 函数返回值: 无
*********************************************************************/
void LCD_12864_address_set( uchar x,uchar y )
{
  uchar Address ;
  switch( y )
  {
  case 1  :  Address = 0x80 + (x - 1);  break;
  case 2  :  Address = 0x90 + (x - 1);  break;
  case 3  :  Address = 0x88 + (x - 1);  break;
  case 4  :  Address = 0x98 + (x - 1);  break;
  default :                             break;
  }
  write_com(Address);
}
/**********************************************************************
* 函数名称   : LCD_12864_String( uchar y, uchar x, uchar *pData )
* 函数功能   : 12864显示字符串
* 函数参数   : 行,列,需要显示的字符串或汉字
* 函数返回值 : 无
***********************************************************************/
void LCD_12864_string( uchar y, uchar x, uchar *pData )
{
  LCD_12864_address_set(  x, y );
  while( *pData != '\0' )
  {
    write_data(*pData++);
  }
}

/********************************************************************
* 函数名称  : LCD_12864_num(uchar y,uchar x,uchar num)
* 函数功能  : 12864以十进制格式显示一个两位数字
* 函数参数  : 行,列,需要输入需要显示的两位数字
* 函数返回值: 无
**********************************************************************/
void LCD_12864_2num(uchar y,uchar x,uchar num)
{
    uchar  num_1, num_2;
    LCD_12864_address_set(x, y);
        num_2  = (num/10) + 0x30;
        num_1  = (num%10) + 0x30;
        write_data(num_2);
        write_data(num_1);
}

/********************************************************************
* 函数名称  : LCD_12864_num(uchar y,uchar x,uint num)
* 函数功能  : 12864以十进制格式显示一个四位数字
* 函数参数  : 行,列,需要输入需要显示的四位数字
* 函数返回值: 无
**********************************************************************/

void LCD_12864_4num(uchar y,uchar x,uint num)
{
    uchar  num_1, num_2, num_3, num_4  ;
    LCD_12864_address_set(x, y);
        num_4  =   (num/1000)          + 0x30;
        num_3  =  ((num%1000)/100)     + 0x30;
        num_2  = (((num%1000)%100)/10) + 0x30;
        num_1  = (((num%1000)%100)%10) + 0x30;
        write_data(num_4);
        write_data(num_3);
        write_data(num_2);
        write_data(num_1);
}

/********************************************************************
* 函数名称  : LCD_12864_numx(uchar y,uchar x,char numx)
* 函数功能  : 12864以十六进制格式显示一个数字
* 函数参数  : 行,列,需要输入需要显示的数字(最高255 ==> 0xFF)
* 函数返回值: 无
**********************************************************************/

void LCD_12864_numx(uchar y,uchar x,uchar numx)
{
   uchar  num_l, num_h;
   LCD_12864_address_set(x, y);
   num_l = numx & 0x0F;     //取键码的低四位
   num_h = numx >> 4;       //右移4次,高四位变为低四位
   if(num_l > 9)  num_l = num_l + 0x37;
   else                          num_l = num_l + 0x30;

   if(num_h > 9)  num_h = num_h + 0x37;
   else                          num_h = num_h + 0x30;
        write_data(num_h);
        write_data(num_l);
}

/********************************************************************
* 函数名称  : LCD_12864_draw_clear(void)
* 函数功能  : 12864绘图清屏
* 函数参数  : 无
* 函数返回值: 无
**********************************************************************/

void LCD_12864_draw_clear(void)           
{
        uchar i, j, k;
        write_com(0x34);            //扩展指令               
        for(i=0;i<2;i++)
        {
                for(j=0;j<32;j++)
                {
                        write_com(0x80+j);  //垂直地址+1
                        if(i==0)
                           {
                                write_com(0x80);//复位上半屏水平地址
                           }
                        else
                           {
                                write_com(0x88);//复位下半屏水平地址
                           }
                        write_com(0x36);    //打开绘图
                        for(k=0;k<16;k++)                        //写两个字节数据水平地址加一,写完一行水平地址加到0x87
                           {
                                write_data(0x00);
                           }
                }               
        }
        write_com(0x30);                        //关闭扩展指令
}

/********************************************************************
* 函数名称  : LCD_12864_draw(*p)
* 函数功能  : 12864绘图
* 函数参数  : 图片数据数组首地址 (数组名)
* 函数返回值: 无
**********************************************************************/

void LCD_12864_draw(uchar *p)
{
        uchar i, j, k;
        LCD_12864_draw_clear();                                   //绘图清屏
        write_com(0x34);                           //打开扩展指令
        for(i=0; i<2; i++)
          {
                for(j=0; j<32; j++)
                  {
                        write_com(0x80+j);           //垂直地址+1
                        if(i==0)
                            {
                                  write_com(0x80); //复位上半屏水平地址
                            }
                        else
                            {
                                 write_com(0x88); //复位下半屏水平地址
                                }
                    write_com(0x36);            //打开绘图
                    for(k=0; k<16; k++)                                //写两个字节数据水平地址加一,写完一行水平地址加到0x87
                    {
                                  write_data(*p++);
                             }  
                  }               
      }
        write_com(0x30);                                //关闭扩展指令
}

/********************************************************************
* 名称 : Test()
* 功能 : 显示子函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Test()
{       uchar dat1,dat2,dat3,dat4;
dat1=6;dat2=8;dat3=8;dat4=8;
        write_com(0x03);              //发指令,地址归位
delay(50);                     //延时   
write_com(0x80);               //第一行首地址0x80
print_string("2012年电子竞赛 "); //第一行显示(必须加一个空格否则不能下载)
        write_com(0x94);               //第二行首地址0x90,从第四个开始显示
        write_data(dat1+0x30);         //发送dat1的ASCII码,显示dat1的值
        write_data(dat2+0x30);         //发送dat1的ASCII码,显示dat2的值
        write_data(dat3+0x30);         //发送dat1的ASCII码,显示dat3的值
        write_data(dat4+0x30);         //发送dat1的ASCII码,显示dat4的值
        write_data('H');               //发送H的ASCII码,显示H
        write_data('z');               //发送z的ASCII码,显示z
        write_com(0x90);
        print_string("频率: ");
        delay(500);                    //较长时间延时,保证下次操作前LCD完成上述功能处于非忙状态
}

void main()
{
  WDTCTL=WDTPW+WDTHOLD;          //关闭看门狗
  int_port();                    //端口初始化
  lcdinit();                     //LCD初始化
  //Test();                        //测试
  LCD_12864_string(1,1,"2012年TI杯");
  LCD_12864_string(2,1,"倒计时:");
  LCD_12864_4num(3,1,0004);
   LCD_12864_string(4,1,"天 ");
  while(1);                      //CPU空转
}

回复评论 (7)

先收藏了。。谢谢了!
点赞  2012-8-1 21:47

回复 沙发 wangyuzhang1 的帖子

呵呵、不用的  来到这个论坛都是大家互相探讨,互相帮助的!这程序是在lauchpad上调试通过了的,你可以根据你的实际要求再改改哈
点赞  2012-8-1 21:57
我苦苦寻求的动画你在哪啊,找了这么久还是不见啊
点赞  2012-8-22 21:03
搞得不错嘛
点赞  2012-8-24 13:12
   谢谢楼主 顶起
点赞  2013-7-16 20:25
多谢楼主分享~
支持
点赞  2013-7-17 08:31

回复 楼主shan_99 的帖子

:carnation: 能否将 这个具体的接线,详细说下,我跑了下,没反应,也不知道是不是跟LZ接的不一样导致的。
LCD模块是:LCM12864R
点赞  2013-7-26 22:34
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复