你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

贡献一个LCD12864驱动(ST7920,3.3V)包括字符(串)汉字(串)绘图  

[复制链接]
caizhiwei 发布时间:2015-1-7 09:16
本帖最后由 caizhiwei 于 2015-11-5 11:04 编辑

      虽然很久之前(51时代)就开始接触lcd12864,如今在工控机里面,LCD12864还是应用比较普遍的!
我用的lcd12864类型为串行接口,3.3V st7920
代码优化说明:
1.修复了字符串,汉字串不能自动换行的bug
注意:
1.在使用带jtag接口的I/O时要特别注意
  PA13:SWDIO/JTAG_TMS
  PA14:SWCLK/JTAG_TCK
  PA15:JTAG_TDI
  PB3:JTAG_TDO
  PB4:JTAG_RST
硬件设计缺陷:
1.没有引出LCM的复位引脚,导致偶尔显示不正常之后,mcu复位(LCM并没有复位)
也无法解决,只能强行断电重启。
2.BLK液晶背光引脚的输入电流至少在20mA以上,没有用三极管驱动,而是直接用IO驱动,
  需要较大的驱动电流。
3.
编译器缺陷:
1.由于使用的是iar6.70版本,编译器在编译汉字串数组的时候可能会使带字库液晶产生乱码。
  所以在有汉字数组的C文件中统一使用简体中文(GB2312)(全选--右键--Charracter Encoding)

部分硬件结构说明:
1.按键按下,(上连接VCC)连接电阻下拉到地,检测IO连接上端,检测到高电平。
2.lcd12864底板反面接线图:

从反面看:
5V  RW GND GND LED K2 K4 GND
GND RS  E  BLK GND K1 K3 5V

2015-6-10 原工程代码在23楼!|r
2015-7-12 程序更新了,,代码在35楼!
更新记录:
1.增加了24*32大字体显示功能;
2.增加了16*32大字体显示功能;
3.优化了读LCD忙的代码;
4.新增了是sprintf的任意位数数字直接显示;
5.新增了CGRAM的写入,读出操作函数;
6.优化了绘图GDRAM函数的操作,绘图速度提高;
2015.11.04 ,看到很多评论说链接失效,现在重新找了一份完整的工程代码,整理之后传到网盘:
这个代码优化了.h文件中的宏定义,方便用户移植,C文件和gui.c文件均不用修改。
https://pan.baidu.com/s/1pJw3wHd


  1. #include "gui.h"

  2. /*******************************************************************************
  3. DDRAM地址
  4. 0x80  0x81  0x82  0x83  0x84  0x85  0x86  0x87    //第一行汉字位置
  5. 0x90  0x91  0x92  0x93  0x94  0x95  0x96  0x97    //第二行汉字位置
  6. 0x88  0x89  0x8a  0x8b  0x8c  0x8d  0x8e  0x8f     //第三行汉字位置
  7. 0x98  0x99  0x9a  0x9b  0x9c  0x9d  0x9e  0x9f     //第四行汉字位置

  8. *******************************************************************************/  

  9. /*******************************************************************************
  10. * 名称 :  LCD_SetPos
  11. * 功能 : 设定显示位置
  12. * 输入 :  x (0~3)行
  13.           y (0~7)列
  14. * 输出 : 无
  15. *******************************************************************************/  
  16. void LCD_SetPos(u8 row, u8 col)  
  17. {  
  18.     u8 pos;  
  19.     if( row == 0)  
  20.             row = 0x80;  
  21.     else if(row == 1)  
  22.             row = 0x90;  
  23.     else if(row == 2)  
  24.             row = 0x88;  
  25.     else if(row == 3)  
  26.             row = 0x98;     
  27.     pos = row + col;  
  28.     LCD_WriteCMD(pos);//在写入数据前先指定显示地址   
  29.     delay_us(10);
  30. }  


  31. /********************************************************************
  32. * 名称 : ShowASCII
  33. * 功能 : 在当前坐标位置显示单个字符
  34. * 输入 : *s
  35. * 输出 : 无
  36. ***********************************************************************/
  37. void ShowASCII(u8 i)
  38. {
  39.     LCD_WriteDATA(i);
  40. }

  41. void ShowCharPos(u8 row, u8 col,u8 dat)
  42. {   
  43.   LCD_SetPos(row, col);
  44.   ShowASCII(dat);
  45. }

  46. /*******************************************************************************
  47. * 名称 : ShowEnString(u8 *s)  
  48. * 功能 : 显示英文字符串
  49. * 输入 : *s
  50. * 输出 : 无
  51. *******************************************************************************/  
  52. void ShowString(u8 *s)  
  53. {   
  54.     u8  i = 0;  
  55.     while(s[i] != '\0')  
  56.     {   
  57.       ShowASCII(s[i++]);      
  58.     }  
  59. }  

  60. void ShowStringPos(u8 row, u8 col,u8 *s)     //col is full char wide
  61. {  
  62.      u8  i = 0;  
  63.      LCD_SetPos(row, col);   
  64.     while(s[i] != '\0')  
  65.     {      
  66.       ShowASCII(s[i++]);        
  67.       if((2*col+i)%(16)==0)     //must 16, is OK
  68.       {         
  69.         LCD_SetPos(++row,0);     //display start at next row.
  70.       }
  71.    
  72.     }  
  73. }  



  74. /*******************************************************************************
  75. * 名称 : ShowGB
  76. * 功能 : 显示单个汉字
  77. * 输入 : i
  78. * 输出 : 无
  79. ********************************************************************************/  
  80. void ShowGB( unsigned char *HZ)
  81. {
  82.    LCD_WriteDATA(HZ[0]);                //写入汉字的高八位数据
  83.   
  84.    LCD_WriteDATA(HZ[1]);                //写入汉字的低八位数据
  85.   
  86. }

  87. void ShowGBPos(u8 row, u8 col, u8 *HZ)
  88. {
  89.    LCD_SetPos(row, col);
  90.    ShowGB(HZ);
  91. }

  92. /********************************************************************
  93. * 名称 : ShowGBStringPos
  94. * 功能 : 显示多个汉字
  95. * 输入 : u8 row, u8 col :汉字串的起始地址
  96. * 输出 : 无
  97. * 说明 : 自动换行:lcm默认换行顺序是乱的,0--2--1--3--0
  98. ***********************************************************************/  
  99. void ShowGBStringPos(u8 row, u8 col, u8 *s)
  100. {
  101.   u8 i = 0;
  102.   LCD_SetPos(row, col);
  103.   while (s[i] != '\0')
  104.   {
  105.     ShowGB(s+i);
  106.     i+=2;   
  107.     if((2*col+i)%(16)==0)                 //如果满一行
  108.     {            
  109.        LCD_SetPos(++row,0);            //重新设置显示的起始地址
  110.     }
  111.       
  112.   }
  113. }

  114. /*******************************************************************************
  115. 测试函数
  116. Function: 用户移植程序之后,用该函数测试液晶是否初始化成功!
  117. ********************************************************************************/
  118. void LCD_Test(void)
  119. {
  120.   ShowCharPos(0,0,0x10); //右箭头
  121.   ShowCharPos(1,0,0x10); //右箭头  
  122.   ShowString("Hello,world!") ;
  123.   ShowCharPos(2,0,0x10); //右箭头
  124.   ShowASCII(0x11);//左箭头
  125. }  
  126.   




  127. //自定义字符写入CGRAM
  128. void Write_USR_CGRAM(u8 data1,u8 data2,u8 addr)
  129. {     
  130.   u8 i;
  131.   for(i=0;i<16;)
  132.   {
  133.     LCD_WriteCMD(addr+i);          //设定CGRAM地址
  134.     LCD_WriteDATA(data1);
  135.     LCD_WriteDATA(data1);
  136.     i++;
  137.     LCD_WriteCMD(addr+i);          //设定CGRAM地址
  138.     LCD_WriteDATA(data2);
  139.     LCD_WriteDATA(data2);
  140.     i++;
  141.   }  
  142. }

  143. //显示自定义的字符,并把这个字符填满全屏16*16
  144. void Show_USR_CGRAM_Char(u8 addr,u8 i)
  145. {
  146.   u8 j;
  147.   for(j=0;j<0x20;)
  148.   {        
  149.     LCD_WriteCMD(addr+j);        //设定DDRAM地址
  150.     LCD_WriteDATA(0x00);
  151.     LCD_WriteDATA(i);
  152.     j++;
  153.   }               
  154. }

  155. //写入GDRAM 绘图,Y是Y绘图坐标,2个字节一行,X是图形起始坐标,CLONG是图形长度,以字节
  156. //为单位;HIGHT是图形高度,TAB是图形数据表.12864M的图形显示范围是256*32点阵.
  157. //要在12864M里显示全屏,取模时一幅图横切成两半

  158. /*
  159. ST7920提供64×32 个字节的空间(由扩充指令设定绘图RAM 地址),最多可以控制256×64
  160. 点阵的二维绘图缓冲空间,在更改绘图RAM时,由扩充指令设置GDRAM地址先垂直地址后水平
  161. 地址(连续2个字节的数据来定义垂直和水平地址),再2个字节的数据给绘图RAM(先高8位
  162. 后低8 位)
  163. */
  164. void WRGDRAM(u8 Y,u8 clong,u8 hight,u8 *TAB1)
  165. {   
  166.   u16 k=0;
  167.   u8 j;
  168.   u8 i;
  169.   LCD_WriteCMD(0x34);
  170.   LCD_WriteCMD(0x36);
  171.   for(j=0;j<hight;)
  172.   {
  173.     LCD_WriteCMD(Y+j);
  174.     LCD_WriteCMD(0x80);//X坐标
  175.     for(i=0;i<clong;i++)//
  176.     {
  177.       LCD_WriteDATA(TAB1[k]);
  178.       k++;
  179.     }
  180.     j++;
  181.   }
  182. }

  183. /********************************************************************
  184. * 名称 : ShowBlankPos
  185. * 功能 : 在当前坐标位置显示单个字符
  186. * 输入 : num 半宽字符的个数
  187. * 功能 : 黑板擦功能,擦除不显示的内容
  188. ***********************************************************************/
  189. void ShowBlankPos(u8 row, u8 col, u8 num)
  190. {
  191.   u8 i ;
  192.   LCD_SetPos(row,col);   
  193.   for (i = 0; i < num;i++)
  194.     LCD_WriteDATA(0x20); //写空格
  195. }

















复制代码
上图:
IMG_20150107_090730 (1).jpg
Hellokity:
QQ图片20150107091501.jpg






收藏 10 评论74 发布时间:2015-1-7 09:16

举报

74个回答
blueskyds 回答时间:2015-1-7 10:38:15
11.jpg

点评

https://www.stmcu.org.cn/module/forum/thread-598244-1-1.html https://www.stmcu.org.cn/module/forum/thread-611285-1-1.html  发表于 2020-9-28 08:46
阿烽 回答时间:2024-8-8 09:15:11
拾捌ly 发表于 2015-3-26 19:59
请教一下大神,12864如何一个字符一个字符的移动啊?就是我要用按键控制,但是每次只能以汉字的格式来移动,有 ...

需要创建一个屏幕大小的缓冲区数组,将要显示的字模数据放入数组里面,后面再使用绘图模式,统一将数组刷上去就可以实现了
拾捌ly 回答时间:2015-3-26 19:59:40
请教一下大神,12864如何一个字符一个字符的移动啊?就是我要用按键控制,但是每次只能以汉字的格式来移动,有什么办法可以一个字符的移动啊?在做毕业设计  搞不出来    求大神相助
caizhiwei 回答时间:2015-1-7 09:16:42
顶一个,嘿嘿
皇室丶情圣 回答时间:2015-1-7 09:18:29
不错,挺好看的
Eagleson 回答时间:2015-1-7 09:22:25
不错,挺好看的
Eagleson 回答时间:2015-1-7 09:23:29
Super 不是Supper吧?
caizhiwei 回答时间:2015-1-7 10:00:01
Eagleson 发表于 2015-1-7 09:23
Super 不是Supper吧?

是的,多了一个字母~~
AAAAAB-349581 回答时间:2015-1-7 10:54:48
不错 挺好的
caizhiwei 回答时间:2015-1-7 11:08:23

这个是3.3V的屏,很好驱动的撒,这个是标准屏,目前还是用的很广的
花羊羊 回答时间:2015-1-7 11:23:01
Hellokity好看
casy99 回答时间:2015-1-7 17:14:45
正好在找这个源代码呢,非常感谢,正在抑制zlg-gui
Robot@HCS 回答时间:2015-1-7 18:18:42
老羊,你家小羊羔呢!
caizhiwei 回答时间:2015-1-7 20:52:01
Robot@HCS 发表于 2015-1-7 18:18
老羊,你家小羊羔呢!

你居然认识我哟?TA在第10楼~
大器所成 回答时间:2015-1-7 21:22:20
不错!!!谢谢!!!
Robot@HCS 回答时间:2015-1-8 14:16:57

还是没有花羊羊好看吧!!!
12345下一页

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版