找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8243|回复: 13
收起左侧

从51上修改而来,基于stm32f103,带字库LCD12864液晶的驱动程序,串行和并行都有

  [复制链接]
ID:232078 发表于 2017-9-9 15:36 | 显示全部楼层 |阅读模式
从51单片机平台上修改而来的带字库LCD12864液晶的驱动程序,串行和并行都有,各个函数均带有注释。亲测可用,使用时注意修改宏定义里对管脚的定义以及引脚初始化程序

单片机源程序如下:
  1. #include <stm32f10x.h>           
  2. #include "12864.h"        
  3. #include "delay.h"        

  4. void LCD12864_Init(void)
  5. {
  6.         GPIO_InitTypeDef  GPIO_InitStructure;
  7.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  8.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
  9.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  10.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  12.         
  13.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  14.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  15.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  16.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  17.         delay_init();        
  18. /*--------------------LCD基本指令-----------------------*/
  19.     delay_ms(2);
  20.     Write_LCD_Command(0x30);  //30--基本指令动作
  21.     delay_ms(2);
  22.     Write_LCD_Command(0x0c);  //光标右移画面不动
  23.     delay_ms(2);
  24.     Write_LCD_Command(0x01);  //清屏
  25.     delay_ms(5);              //清屏时间较长
  26.     Write_LCD_Command(0x06);  //显示打开,光标开,反白关
  27.     delay_ms(2);

  28.         Draw_Clear();                                        // 清屏

  29. }
  30. /*********************************************************
  31. 函数名:Send_Byte()
  32. 返回值:无
  33. 功  能:        写数据到LCD
  34. *********************************************************/
  35. void Send_Byte(u8 zdata)
  36. {
  37.   u16 i;
  38.   for(i=0; i<8; i++)
  39.     {
  40.           if((zdata << i) & 0x80)
  41.                         SID_H;
  42.           else   
  43.                         SID_L;
  44.           SCLK_H;
  45.                 SCLK_L;
  46.           }
  47.         }
  48. /*********************************************************
  49. 函数名:Receive_Byte()
  50. 返回值:temp1+temp2
  51. 功  能:        读LCD数据
  52. *********************************************************/
  53. u8 Receive_Byte(void)
  54.         {
  55.            u8 i,temp1,temp2,value;
  56.            temp1=0;
  57.            temp2=0;
  58.            for(i=0;i<8;i++)
  59.               {
  60.                            temp1=temp1<<1;
  61.                            SCLK_L;
  62.                          SCLK_H;
  63.                            SCLK_L;
  64.                          if(PAout(7)==1)
  65.                            {
  66.                              temp1++;
  67.                                 }
  68.                   }
  69.            for(i=0;i<8;i++)
  70.               {
  71.                            temp2=temp2<<1;
  72.                            SCLK_L;
  73.                          SCLK_H;
  74.                            SCLK_L;
  75.                          if(PAout(7)==1)
  76.                            {
  77.                               temp2++;
  78.                            }
  79.                   }
  80.               temp1=0xf0&temp1;
  81.                   temp2=0x0f&temp2;
  82.                   value=temp1+temp2;
  83.        return   value ;
  84.         }
  85. /*********************************************************
  86. 函数名:Check_Busy()
  87. 返回值:无
  88. 功  能:        LCD忙检查
  89. *********************************************************/
  90. void Check_Busy(void)
  91. {
  92.         do
  93.                 Send_Byte(0xfc);                  //11111,RW(1),RS(0),0
  94.         while(0x80&Receive_Byte());
  95. }
  96. /*********************************************************
  97. 函数名: Write_LCD_Command()
  98. 返回值:无
  99. 功  能:        写命令到LCD
  100. *********************************************************/
  101. void Write_LCD_Command(u8 cmdcode)
  102. {

  103.    CS_H;
  104.    Check_Busy();
  105.    Send_Byte(0xf8);
  106.    Send_Byte(cmdcode & 0xf0);
  107.    Send_Byte((cmdcode << 4) & 0xf0);
  108.    delay_ms(2);
  109.    CS_L;
  110. }
  111. /*********************************************************
  112. 函数名: Write_LCD_Data()
  113. 返回值:无
  114. 功  能:        写显示内容到LCD
  115. *********************************************************/
  116. void Write_LCD_Data(u8 Dispdata)
  117. {  
  118.   CS_H;
  119.   Check_Busy();
  120.   Send_Byte(0xfa);          //11111,RW(0),RS(1),0
  121.   Send_Byte(Dispdata & 0xf0);
  122.   Send_Byte((Dispdata << 4) & 0xf0);
  123.   delay_ms(2);
  124.   CS_L;
  125. }
  126. /*********************************************************
  127. 函数名: Read_LCD_Data()
  128. 返回值:LCD收到的数据
  129. 功  能:        读取LCD显示内容
  130. *********************************************************/
  131. u8 Read_Data(void)
  132.         {
  133.           Check_Busy();
  134.           Send_Byte(0xfe);    //11111,RW(1),RS(1),0 LCD->MCU
  135.           return  Receive_Byte();
  136.         
  137.         }
  138. /*********************************************************
  139. 函数名: LCD_Clear_Txt
  140. 返回值:无
  141. 功  能:        文本区清除
  142. *********************************************************/
  143. void LCD_Clear_TXT( void )
  144. {
  145.      u8 i;
  146.      Write_LCD_Command(0x30);      //8BitMCU,基本指令集合
  147.      Write_LCD_Command(0x80);      //AC归起始位
  148.      for(i=0;i<64;i++)
  149.           {
  150.        Write_LCD_Data(0x20);
  151.           }
  152. }
  153. /*********************************************************
  154. 函数名: LCD_Clear_BMP
  155. 返回值:无
  156. 功  能:        图片区清除
  157. *********************************************************/
  158. void LCD_Clear_BMP( void )
  159. {
  160.      u8 i,j;
  161.      Write_LCD_Command(0x34);      //8Bit扩充指令集,即使是36H也要写两次
  162.      Write_LCD_Command(0x36);      //绘图ON,基本指令集里面36H不能开绘图
  163.      for(i=0;i<32;i++)            //12864实际为256x32
  164.      {
  165.            Write_LCD_Command(0x80|i);      //行位置
  166.            Write_LCD_Command(0x80);      //列位置
  167.            for(j=0;j<32;j++)            //256/8=32 byte
  168.                 Write_LCD_Data(0);
  169.      }
  170. }
  171. /*********************************************************
  172. 函数名: Display_LCD_Pos
  173. 返回值:无
  174. 功  能:设置显示位置
  175. *********************************************************/
  176. void Display_LCD_Pos(u8 x,u8 y)
  177.         {
  178.            u8 pos;
  179.            switch(x)
  180.                {
  181.                              case 0: x=0x80;break;
  182.                           case 1: x=0x90;break;
  183.                              case 2: x=0x88;break;
  184.                           case 3: x=0x98;break;
  185.                    }
  186.            pos=x+y;
  187.            Write_LCD_Command(pos);
  188.     }

  189. /*********************************************************
  190. 函数名:Display_LCD_String()
  191. 返回值:无
  192. 功  能:显示字符串
  193. *********************************************************/

  194. void Display_LCD_String(u8 *s)
  195. {
  196.     while(*s != '\0')
  197.     {
  198.         Write_LCD_Data(*s);
  199.         s++;
  200.         delay_ms(2);                                    //控制每一个字符之间显示的时间 间隔
  201.     }
  202. }
  203. /*************************************************************
  204. * 函数名称    :PutBMP
  205. **************************************************************/
  206. void PutBMP(const u8 *puts)
  207. {
  208.      u16 x=0;
  209.      u8 i,j;
  210.      Write_LCD_Command(0x34);      //8Bit扩充指令集,即使是36H也要写两次
  211.      Write_LCD_Command(0x36);      //绘图ON,基本指令集里面36H不能开绘图
  212.      for(i=0;i<32;i++)            //12864实际为256x32
  213.      {
  214.            Write_LCD_Command(0x80|i);      //行位置
  215.            Write_LCD_Command(0x80);      //列位置
  216.            for(j=0;j<16;j++)      //256/8=32 byte
  217.            {            //列位置每行自动增加
  218.                  Write_LCD_Data(puts[x]);
  219.                  x++;
  220.            }
  221.      }
  222.      for(i=0;i<32;i++)            //12864实际为256x32
  223.      {
  224.            Write_LCD_Command(0x80|i);      //行位置
  225.            Write_LCD_Command(0x88);      //列位置
  226.            for(j=0;j<16;j++)      //256/8=32 byte
  227.            {            //列位置每行自动增加
  228.                  Write_LCD_Data(puts[x]);
  229.                  x++;
  230.            }
  231.      }
  232. }
  233. void PHO_Display(const u8 *s)
  234. {
  235.         u8 COUNT3 = 0X02,COUNT1,COUNT2,LCD_X = 0X80,LCD_Y;
  236.                  
  237.         for (;COUNT3 != 0;COUNT3 --)
  238.         {
  239.                 LCD_Y = 0X80;
  240.                 COUNT2 = 0X20;
  241.                 for(;COUNT2 != 0;COUNT2 --)
  242.                 {
  243.                         //COUNT1 = 0X10;//全屏
  244.                         COUNT1 = 0X08;//半屏
  245.                         Write_LCD_Command(0x34);
  246.                         Write_LCD_Command(LCD_Y);
  247.                         Write_LCD_Command(LCD_X);
  248.                         Write_LCD_Command(0x30);
  249.                         for (;COUNT1 != 0;COUNT1 --)
  250.                         {
  251.                                 Write_LCD_Data(*s ++);                 
  252.                         }
  253.                         LCD_Y += 1;
  254.                 }
  255.                 LCD_X = 0X88;
  256.         }
  257.         Write_LCD_Command(0x36);
  258.         Write_LCD_Command(0x30);
  259. }
  260. /*-------------------------------------------------
  261. LCD显示缓存
  262. --------------------------------------------------*/
  263. u16 LCD12864_Buffer[64][16] = {0};

  264. const u8 m_ch4x5[][6] =
  265. {
  266.         {0x06,0x09,0x09,0x09,0x06,5},                // 0,字符宽度5点阵
  267.         {0x02,0x06,0x02,0x02,0x07,5},                // 1
  268.         {0x06,0x09,0x02,0x04,0x0F,5},                // 2
  269.         {0x06,0x09,0x02,0x09,0x06,5},                // 3
  270.         {0x02,0x06,0x0A,0x0F,0x02,5},                // 4
  271.         {0x0E,0x08,0x0E,0x01,0x0E,5},                // 5
  272.         {0x06,0x08,0x0E,0x09,0x06,5},                // 6
  273.         {0x0F,0x01,0x02,0x04,0x04,5},                // 7
  274.         {0x06,0x09,0x06,0x09,0x06,5},                // 8
  275.         {0x06,0x09,0x07,0x01,0x06,5},                // 9
  276.         {0x00,0x00,0x00,0x00,0x01,2},                // .
  277.         {0x00,0x01,0x00,0x01,0x00,2},                // :
  278.         {0x00,0x00,0x00,0x00,0x00,5},                 // 空格

  279. };
  280. /*------------------------------------------------------------------------------
  281. 功能:画点
  282. 参数:
  283.         x:横坐标
  284.         y:纵坐标
  285.         color:颜色,0不显示,1显示
  286. ------------------------------------------------------------------------------*/
  287. const u16 DrawDotsTable[] = {0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100, 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001};
  288. void Draw_Dots(u8 x, u8 y, u8 color)
  289. {
  290.         u8 i0, y0;
  291.         u16 value;

  292.         // 获得坐标
  293.         if ( y >= 32 )
  294.         {
  295.                 y0 = y-32;
  296.                 i0 = x/16+8;
  297.         }
  298.         else
  299.         {
  300.                 y0 = y;
  301.                 i0 = x/16;
  302.         }
  303.         value = DrawDotsTable[x%16];
  304.         if (color == 0)
  305.         {
  306.                 LCD12864_Buffer[y0][i0] &= ~value;
  307.         }
  308.         else
  309.         {
  310.                 LCD12864_Buffer[y0][i0] |= value;
  311.         }
  312. }

  313. /*------------------------------------------------------------------------------
  314. 功能:刷新显示
  315. ------------------------------------------------------------------------------*/
  316. void Draw_Update(void)
  317. {
  318.         u8 x, y;

  319.         for (y=0; y<64; y++)
  320.         {
  321.                 Write_LCD_Command(0x80|y);
  322.                 Write_LCD_Command(0x80);
  323.                 for (x=0; x<16; x++)
  324.                 {
  325.                         Write_LCD_Data(LCD12864_Buffer[y][x]>>8);
  326.                         Write_LCD_Data(LCD12864_Buffer[y][x]);
  327.                 }
  328.         }
  329. }

  330. /*------------------------------------------------------------------------------
  331. 功能:显示清屏
  332. ------------------------------------------------------------------------------*/
  333. void Draw_Clear(void)
  334. {
  335.         u8 x, y;

  336.         for (y=0; y<64; y++)
  337.         {
  338.                 for (x=0; x<16; x++)
  339.                 {
  340.                         LCD12864_Buffer[y][x] = 0;
  341.                 }
  342.         }
  343. }

  344. /*------------------------------------------------------------------------------
  345. 功能:显示4*5字符
  346. 参数:
  347.         x:写出横坐标
  348.         y:写出纵坐标
  349.         value:字符
  350. ------------------------------------------------------------------------------*/
  351. void Draw_Char4x5(u8 x, u8 y, u8 value)
  352. {
  353.         u8 i, j, p, z, a;
  354.         
  355.         a = m_ch4x5[value][5];        
  356.         for (i=0; i<5; i++)
  357.         {
  358.                 p = 0x10>>(5-a);
  359.                 for (j=0; j<a; j ++)
  360.                 {
  361.                         z = m_ch4x5[value][i];
  362.                         if ( z & p )
  363.                         {
  364.                                 Draw_Dots(j+x, i+y, 1);
  365.                         }
  366.                         p >>= 1;
  367.                 }
  368.         }
  369. }

  370. /*--------------------------------------------------------
  371. 功能:显示一行4*5字符
  372. 参数:
  373.         x:写出横坐标
  374.         y:写出纵坐标
  375.         value:字符串
  376.         len:长度
  377. ---------------------------------------------------------*/
  378. ……………………

  379. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
12864.rar (6.83 KB, 下载次数: 368)

评分

参与人数 1黑币 +5 收起 理由
19931124 + 5 很给力!

查看全部评分

回复

使用道具 举报

ID:335078 发表于 2018-6-4 22:15 | 显示全部楼层
这程序写得有点奇怪,注释不太完整
回复

使用道具 举报

ID:123956 发表于 2018-6-5 16:46 | 显示全部楼层
感謝分享
回复

使用道具 举报

ID:267330 发表于 2018-6-17 17:10 | 显示全部楼层
下载看看
回复

使用道具 举报

ID:73168 发表于 2018-7-14 08:58 | 显示全部楼层
来看看
回复

使用道具 举报

ID:375092 发表于 2018-9-13 20:41 | 显示全部楼层
就是请问一下,你的那个PAout(7)这是什么管脚哦,是它等于1的作用是什么,还要就是我在写串行的时候,我去掉忙函数之后没什么影响,但是stm32在写并行的时候没写忙函数出现了一些问题

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:203214 发表于 2019-4-23 20:03 | 显示全部楼层
下来试试,好用回来追评
回复

使用道具 举报

ID:477134 发表于 2019-7-20 20:41 | 显示全部楼层
感觉挺怪的
回复

使用道具 举报

ID:479945 发表于 2019-7-21 12:39 | 显示全部楼层
感謝分享!
回复

使用道具 举报

ID:86901 发表于 2019-12-31 12:00 | 显示全部楼层
谢谢!!!!参考一下!
回复

使用道具 举报

ID:58110 发表于 2020-2-6 10:23 | 显示全部楼层
学习分享!!!
回复

使用道具 举报

ID:142383 发表于 2020-2-19 21:23 | 显示全部楼层
谢谢分享,学习学习!
回复

使用道具 举报

ID:834436 发表于 2021-7-11 19:14 | 显示全部楼层
怎么没看到主函数
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表