找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5246|回复: 2
打印 上一主题 下一主题
收起左侧

基于m128的LCD1602驱动(8线/4线)

[复制链接]
跳转到指定楼层
楼主
ID:80436 发表于 2015-5-21 23:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式



  1. //*************************************************
  2. // 文件名: 1602.h
  3. // 作用:    AVR的LCD1602 4/8线驱动
  4. // 作者:    seabisuit
  5. // 最新修改: 2011年6月22日
  6. // 说明:   使用GCC编程,1602提供4/8线驱动
  7. //     4线暂时高4位
  8. //*************************************************/
  9. #ifndef __1602_H_
  10. #define __1602_H_ 1
  11. //***头文件调用***//
  12. #include <avr/io.h>
  13. #include <util/delay.h>
  14. #include <avr/portpins.h>
  15. #include <compat/deprecated.h>

  16. //***定义uchar***//
  17. #ifndef uchar
  18. #define uchar unsigned char
  19. #endif

  20. //***本头文件增强功能设置***//
  21. #define _LCD_DEF    0 //使自定义功能实现,如不需要将其定义为0(#define _LCD_DEF 0)
  22. #define _LCD_BIT_IS_8 1 //定义4线或者8线

  23. /*控制针脚设置*/
  24. #define LCD_CZ PORTB
  25. #define LCD_CZDDR DDRB
  26. #define LCD_E 2
  27. #define LCD_RW 1
  28. #define LCD_RS 0
  29. #define LCDDATA PORTE
  30. #define LCDDDR DDRE
  31. #define LCDPIN PINE
  32. #define busy 7

  33. /*LCD命令定义*/
  34. #define E0()   cbi(LCD_CZ,LCD_E)
  35. #define E1()   sbi(LCD_CZ,LCD_E)
  36. #define RW0()    cbi(LCD_CZ,LCD_RW)
  37. #define RW1()    sbi(LCD_CZ,LCD_RW)
  38. #define RS0()    cbi(LCD_CZ,LCD_RS)
  39. #define RS1()    sbi(LCD_CZ,LCD_RS)
  40. #define nop()    asm("nop")

  41. /*基本功能函数声明。*/
  42. void lcd_busy(void);//测试LCD忙碌状态
  43. void lcd_wrcmd(uchar CMD,uchar wait);//LCD写入指令
  44. void lcd_wrdata(uchar);//LCD写入数据
  45. void lcd_xy(uchar,uchar);//lcd显示定位
  46. void lcd_char(uchar,uchar,uchar);//lcd显示字符
  47. void lcd_string(uchar,uchar,uchar *);//lcd显示字符串
  48. void lcd_cls(void);//1602清显示
  49. void lcd_init(void); //LCD初始化设定程序
  50. void lcd_def(void);//自定义字符串


  51. /********************************************************/
  52. /* 函数:void lcd_busy(void)                            */
  53. /* 功能:检查LCD忙状态                                  */
  54. /*busy为1时,忙,等待。busy为0时,闲,可写指令与数据     */
  55. /*                                                      */
  56. /********************************************************/
  57. void lcd_busy(void)
  58. {
  59.    #if (_LCD_BIT_IS_8==1) //8位数据线

  60. uchar tmp;

  61. LCDDDR&=~1<<7;//设置为输入
  62. E0();RS0();RW1();

  63. /*循环读取忙位*/
  64. do{
  65.    E1();_delay_us(1);
  66.    tmp=LCDPIN;
  67.    E0();
  68. }
  69. while(tmp&1<<busy);
  70. LCDDDR=0xff;

  71. #else    //4位数据线

  72. uchar tmp;
  73. LCDDDR=0;
  74. E0();RS0();RW1();
  75. /*循环读取忙位*/
  76. do{
  77. E1();_delay_us(1);
  78. tmp=LCDPIN;
  79. E0();_delay_us(1);
  80. E1();_delay_us(1);

  81. E0();_delay_us(6);
  82. }
  83. while(tmp&1<<busy);

  84. LCDDDR=0xff;

  85. #endif

  86. }
  87. /********************************************************/
  88. /* 函数:lcd_wrcmd(uchar CMD,uchar wait)                */
  89. /* 功能:写入命令到LCD                                  */
  90. /*RS=0,RW=0,E=高脉冲,D0-D7=指令码。                  */
  91. /*CMD为指令,wait指定是否要检测LCD忙信号                */
  92. /*                                                      */
  93. /********************************************************/
  94. void lcd_wrcmd(uchar CMD,uchar wait)
  95. {   
  96.    #if (_LCD_BIT_IS_8==1) //8位数据线

  97. if (wait) //是否读忙
  98. lcd_busy();
  99. //else
  100. //_delay_us(40);
  101.     RS0();RW0();
  102.     LCDDATA=CMD;   
  103.     E1();E0();

  104. #else    //4位数据线

  105. if (wait)
  106. lcd_busy();
  107. else
  108. _delay_us(40);
  109.     RS0();RW0();E0();     
  110.    
  111.     LCDDATA=CMD&0xf0;
  112.     E1();_delay_us(1);E0();_delay_us(6);
  113. LCDDATA=(CMD<<4)&0xf0;
  114. E1();_delay_us(1);E0();
  115. #endif
  116. }
  117. /********************************************************/
  118. /* 函数:void lcd_wrdate(uchar);                        */
  119. /* 功能:写入数据到LCD                                  */
  120. /*RS=1,RW=0,E=高脉冲,D0-D7=指令码。                  */
  121. /*dat为要写入的数据                                     */
  122. /*                                                      */
  123. /********************************************************/
  124. void lcd_wrdata(uchar dat)      //写数据
  125. {
  126.    #if (_LCD_BIT_IS_8==1) //8位数据线

  127. lcd_busy();
  128.     RW0();RS1();      
  129. LCDDATA=dat;
  130.     E1();E0();

  131. #else    //4位数据线
  132. lcd_busy();
  133.     RW0();RS1();      

  134.     LCDDATA=dat&0xf0;
  135.     E1();_delay_us(1);E0();_delay_us(6);


  136.     LCDDATA=(dat<<4)&0xf0;
  137. E1();_delay_us(1);E0();
  138. #endif
  139.    
  140. }
  141. /********************************************************/
  142. /* 函数:lcd_xy(uchar x,uchar y)                        */
  143. /* 功能:lcd显示定位                                    */
  144. /*                                                      */
  145. /********************************************************/
  146. void lcd_xy(uchar x,uchar y)
  147. {
  148. uchar add;
  149. if(y==0)
  150. add=0x80+0x00+x;
  151.     else
  152.     add=0x80+0x40+x;
  153.     lcd_wrcmd(add,1);
  154. }

  155. /********************************************************/
  156. /* 函数:void lcd_char(uchar x,uchar y,uchar dat)       */
  157. /* 功能:lcd于(x,y)处显示字符                        */
  158. /*                                                      */
  159. /********************************************************/
  160. void lcd_char(uchar x,uchar y,uchar dat)
  161. {   
  162.     lcd_xy(x,y);
  163.     lcd_wrdata(dat);
  164. }           
  165. /********************************************************/
  166. /* 函数:void lcd_string(uchar x,uchar y,uchar *s)      */
  167. /* 功能:lcd于(x,y)处开始显示字符串                  */
  168. /*                                                      */
  169. /********************************************************/
  170. void lcd_string(uchar x,uchar y,uchar *s)
  171. {
  172. lcd_xy(x,y);
  173. while(*s)
  174.     {
  175.    lcd_wrdata(*s);
  176.         s++;
  177.     }
  178. }
  179. /********************************************************/
  180. /* 函数:void lcd_cls(void)                             */
  181. /* 功能:对1602显示屏清除,并进行延时                   */
  182. /* 延时是为了使1602又时间进行清除                       */
  183. /*                                                      */
  184. /********************************************************/
  185. void lcd_cls(void)
  186. {
  187. lcd_wrcmd(0x01,1);
  188. _delay_ms(10);
  189. }
  190. /********************************************************/
  191. /* 函数:void LcdReset(void);                           */
  192. /* 功能:对1602进行复位                                 */
  193. /*                                                      */
  194. /********************************************************/
  195. void lcd_init(void)     
  196. {   
  197.    #if (_LCD_BIT_IS_8==1) //8位数据线
  198.    
  199. LCD_CZDDR=1<<LCD_E|1<<LCD_RS|1<<LCD_RW;
  200. LCDDDR=0xff;
  201. _delay_ms(15);
  202. lcd_wrcmd(0x38,0);   
  203. _delay_ms(5);
  204. lcd_wrcmd(0x38,0);   
  205. _delay_ms(5);
  206. lcd_wrcmd(0x38,0);
  207. _delay_us(1);
  208. lcd_wrcmd(0x38,1);
  209. lcd_wrcmd(0x08,1);
  210. lcd_cls();

  211.     lcd_wrcmd(0x06,1);
  212.     lcd_wrcmd(0x0e,1);

  213. #else    //4位数据线
  214. LCD_CZDDR=1<<LCD_E|1<<LCD_RS|1<<LCD_RW;
  215. LCDDDR=0xf0;
  216. _delay_ms(15);
  217. lcd_wrcmd(0x38,0);   
  218. _delay_ms(5);
  219. lcd_wrcmd(0x38,0);   
  220. _delay_ms(5);
  221. lcd_wrcmd(0x38,0);
  222. _delay_us(1);
  223. lcd_wrcmd(0x38,1);
  224. lcd_wrcmd(0x02,1);
  225. lcd_wrcmd(0x28,1);
  226. lcd_cls();
  227. lcd_wrcmd(0x06,1);
  228.     lcd_wrcmd(0x0e,1);


  229. #endif

  230.    
  231. }


  232. #if (_LCD_DEF==1)
  233. //定义CGRAM的值,在功能开启后再主文件加入如下面字符串数组定义
  234. const uchar lcd_cgram[64]=
  235. {
  236. 0x03,0x07,0x0f,0x1f,0x1f,0x1f,0x1f,0x1f,
  237. 0x18,0x1E,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
  238. 0x07,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
  239. 0x10,0x18,0x1c,0x1E,0x1E,0x1E,0x1E,0x1E,
  240. 0x0f,0x07,0x03,0x01,0x00,0x00,0x00,0x00,
  241. 0x1f,0x1f,0x1f,0x1f,0x1f,0x0f,0x07,0x01,
  242. 0x1f,0x1f,0x1f,0x1f,0x1f,0x1c,0x18,0x00,
  243. 0x1c,0x18,0x10,0x00,0x00,0x00,0x00,0x00
  244. };

  245. void lcd_def(uchar cg[64])
  246. {
  247.     uchar temp=0;
  248.     lcd_wrcmd(0x40,1);
  249.     while(temp<64)
  250.     {
  251.       lcd_wrdata(cg[temp]);
  252.       temp++;
  253.     }
  254. }
  255. #endif

  256. #endif /*__1602_H_*/
复制代码





分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:86711 发表于 2015-7-24 13:27 | 只看该作者
十分感谢你的程序,照着你的我改了一份自己的。
回复

使用道具 举报

板凳
ID:86711 发表于 2015-7-24 13:29 | 只看该作者
十分感谢你的程序,照着你的我改了一份自己的。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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