本帖最后由 SYDZ__顺 于 2012-4-28 17:58 编辑
arduino学习笔记23 1602液晶实验 本次试验使用arduino直接驱动1602液晶显示文字
1602液晶在应用中非常广泛,最初的1602液晶使用的是HD44780控制器,现在各个厂家的1602模块基本上都是采用了与之兼容的IC,所以特性上基本都是一致的。
1602LCD主要技术参数
显示容量为16×2个字符;
芯片工作电压为4.5~5.5V;
工作电流为2.0mA(5.0V);
模块最佳工作电压为5.0V;
字符尺寸为2.95×4.35(W×H)mm。
1602液晶接口引脚定义
接口说明:
1、两组电源 一组是模块的电源 一组是背光板的电源 一般均使用5V供电。本次试验背光使用3.3V供电也可以工作。
2、VL是调节对比度的引脚,串联不大于5KΩ的电位器进行调节。本次实验使用1KΩ的电阻来设定对比度。其连接分高电位与低电位接法,本次使用低电位接法,串联1KΩ电阻后接GND。
3、RS 是很多液晶上都有的引脚 是命令/数据选择引脚该脚电平为高时表示将进行数据操作;为低时表示进行命令操作。
4、RW 也是很多液晶上都有的引脚 是读写选择端 该脚电平为高是表示要对液晶进行读操作;为低时表示要进行写操作。
5、E 同样很多液晶模块有此引脚 通常在总线上信号稳定后给一正脉冲通知把数据读走,在此脚为高电平的时候总线不允许变化。
6、D0—D7 8 位双向并行总线,用来传送命令和数据。
7、BLA是背光源正极,BLK是背光源负极。
1602液晶的基本操作分以下四种:
下图就是1602液晶实物图
1602直接与arduino通信,根据产品手册描述,分8位连接法与4位连接法,咱们先使用8位连接法进行实验。硬件连接方式如下图
代码如下 1. int DI = 12; 2. int RW = 11; 3. int DB[] = {3, 4, 5, 6, 7, 8, 9, 10};//使用数组来定义总线需要的管脚 4. int Enable = 2; 5. 6. void LcdCommandWrite(int value) { 7. // 定义所有引脚 8. int i = 0; 9. for (i=DB[0]; i <= DI; i++) //总线赋值 10. { 11. digitalWrite(i,value & 01);//因为1602液晶信号识别是D7-D0(不是D0-D7),这里是用来反转信号。 12. value >>= 1; 13. } 14. digitalWrite(Enable,LOW); 15. delayMicroseconds(1); 16. digitalWrite(Enable,HIGH); 17. delayMicroseconds(1); // 延时1ms 18. digitalWrite(Enable,LOW); 19. delayMicroseconds(1); // 延时1ms 20. } 21. 22. void LcdDataWrite(int value) { 23. // 定义所有引脚 24. int i = 0; 25. digitalWrite(DI, HIGH); 26. digitalWrite(RW, LOW); 27. for (i=DB[0]; i <= DB[7]; i++) { 28. digitalWrite(i,value & 01); 29. value >>= 1; 30. } 31. digitalWrite(Enable,LOW); 32. delayMicroseconds(1); 33. digitalWrite(Enable,HIGH); 34. delayMicroseconds(1); 35. digitalWrite(Enable,LOW); 36. delayMicroseconds(1); // 延时1ms 37. } 38. 39. void setup (void) { 40. int i = 0; 41. for (i=Enable; i <= DI; i++) { 42. pinMode(i,OUTPUT); 43. } 44. delay(100); 45. // 短暂的停顿后初始化LCD 46. // 用于LCD控制需要 47. LcdCommandWrite(0x38); // 设置为8-bit接口,2行显示,5x7文字大小 48. delay(64); 49. LcdCommandWrite(0x38); // 设置为8-bit接口,2行显示,5x7文字大小 50. delay(50); 51. LcdCommandWrite(0x38); // 设置为8-bit接口,2行显示,5x7文字大小 52. delay(20); 53. LcdCommandWrite(0x06); // 输入方式设定 54. // 自动增量,没有显示移位 55. delay(20); 56. LcdCommandWrite(0x0E); // 显示设置 57. // 开启显示屏,光标显示,无闪烁 58. delay(20); 59. LcdCommandWrite(0x01); // 屏幕清空,光标位置归零 60. delay(100); 61. LcdCommandWrite(0x80); // 显示设置 62. // 开启显示屏,光标显示,无闪烁 63. delay(20); 64. } 65. 66. void loop (void) { 67. LcdCommandWrite(0x01); // 屏幕清空,光标位置归零 68. delay(10); 69. LcdCommandWrite(0x80+3); 70. delay(10); 71. // 写入欢迎信息 72. LcdDataWrite('W'); 73. LcdDataWrite('e'); 74. LcdDataWrite('l'); 75. LcdDataWrite('c'); 76. LcdDataWrite('o'); 77. LcdDataWrite('m'); 78. LcdDataWrite('e'); 79. LcdDataWrite(' '); 80. LcdDataWrite('t'); 81. LcdDataWrite('o'); 82. delay(10); 83. LcdCommandWrite(0xc0+1); // 定义光标位置为第二行第二个位置 84. delay(10); 85. LcdDataWrite('g'); 86. LcdDataWrite('e'); 87. LcdDataWrite('e'); 88. LcdDataWrite('k'); 89. LcdDataWrite('-'); 90. LcdDataWrite('w'); 91. LcdDataWrite('o'); 92. LcdDataWrite('r'); 93. LcdDataWrite('k'); 94. LcdDataWrite('s'); 95. LcdDataWrite('h'); 96. LcdDataWrite('o'); 97. LcdDataWrite('p'); 98. delay(5000); 99. LcdCommandWrite(0x01); // 屏幕清空,光标位置归零 100. delay(10); 101. LcdDataWrite('I'); 102. LcdDataWrite(' '); 103. LcdDataWrite('a'); 104. LcdDataWrite('m'); 105. LcdDataWrite(' '); 106. LcdDataWrite('h'); 107. LcdDataWrite('o'); 108. LcdDataWrite('n'); 109. LcdDataWrite('g'); 110. LcdDataWrite('y'); 111. LcdDataWrite('i'); 112. delay(3000); 113. LcdCommandWrite(0x02); //设置模式为新文字替换老文字,无新文字的地方显示不变。 114. delay(10); 115. LcdCommandWrite(0x80+5); //定义光标位置为第一行第六个位置 116. delay(10); 117. LcdDataWrite('t'); 118. LcdDataWrite('h'); 119. LcdDataWrite('e'); 120. LcdDataWrite(' '); 121. LcdDataWrite('a'); 122. LcdDataWrite('d'); 123. LcdDataWrite('m'); 124. LcdDataWrite('i'); 125. LcdDataWrite('n'); 126. delay(5000); 127. } 复制代码 1. int LCD1602_RS=12; 2. int LCD1602_RW=11; 3. int LCD1602_EN=10; 4. int DB[] = { 6, 7, 8, 9}; 5. char str1[]="Welcome to"; 6. char str2[]="geek-workshop"; 7. char str3[]="this is the"; 8. char str4[]="4-bit interface"; 9. 10. void LCD_Command_Write(int command) 11. { 12. int i,temp; 13. digitalWrite( LCD1602_RS,LOW); 14. digitalWrite( LCD1602_RW,LOW); 15. digitalWrite( LCD1602_EN,LOW); 16. 17. temp=command & 0xf0; 18. for (i=DB[0]; i <= 9; i++) 19. { 20. digitalWrite(i,temp & 0x80); 21. temp <<= 1; 22. } 23. 24. digitalWrite( LCD1602_EN,HIGH); 25. delayMicroseconds(1); 26. digitalWrite( LCD1602_EN,LOW); 27. 28. temp=(command & 0x0f)<<4; 29. for (i=DB[0]; i <= 10; i++) 30. { 31. digitalWrite(i,temp & 0x80); 32. temp <<= 1; 33. } 34. 35. digitalWrite( LCD1602_EN,HIGH); 36. delayMicroseconds(1); 37. digitalWrite( LCD1602_EN,LOW); 38. } 39. 40. void LCD_Data_Write(int dat) 41. { 42. int i=0,temp; 43. digitalWrite( LCD1602_RS,HIGH); 44. digitalWrite( LCD1602_RW,LOW); 45. digitalWrite( LCD1602_EN,LOW); 46. 47. temp=dat & 0xf0; 48. for (i=DB[0]; i <= 9; i++) 49. { 50. digitalWrite(i,temp & 0x80); 51. temp <<= 1; 52. } 53. 54. digitalWrite( LCD1602_EN,HIGH); 55. delayMicroseconds(1); 56. digitalWrite( LCD1602_EN,LOW); 57. 58. temp=(dat & 0x0f)<<4; 59. for (i=DB[0]; i <= 10; i++) 60. { 61. digitalWrite(i,temp & 0x80); 62. temp <<= 1; 63. } 64. 65. digitalWrite( LCD1602_EN,HIGH); 66. delayMicroseconds(1); 67. digitalWrite( LCD1602_EN,LOW); 68. } 69. 70. void LCD_SET_XY( int x, int y ) 71. { 72. int address; 73. if (y ==0) address = 0x80 + x; 74. else address = 0xC0 + x; 75. LCD_Command_Write(address); 76. } 77. 78. void LCD_Write_Char( int x,int y,int dat) 79. { 80. LCD_SET_XY( x, y ); 81. LCD_Data_Write(dat); 82. } 83. 84. void LCD_Write_String(int X,int Y,char *s) 85. { 86. LCD_SET_XY( X, Y ); //设置地址 87. while (*s) //写字符串 88. { 89. LCD_Data_Write(*s); 90. s ++; 91. } 92. } 93. 94. void setup (void) 95. { 96. int i = 0; 97. for (i=6; i <= 12; i++) 98. { 99. pinMode(i,OUTPUT); 100. } 101. delay(100); 102. LCD_Command_Write(0x28);//4线 2行 5x7 103. delay(50); 104. LCD_Command_Write(0x06); 105. delay(50); 106. LCD_Command_Write(0x0c); 107. delay(50); 108. LCD_Command_Write(0x80); 109. delay(50); 110. LCD_Command_Write(0x01); 111. delay(50); 112. 113. } 114. 115. void loop (void) 116. { 117. LCD_Command_Write(0x01); 118. delay(50); 119. LCD_Write_String(3,0,str1);//第1行,第4个地址起 120. delay(50); 121. LCD_Write_String(1,1,str2);//第2行,第2个地址起 122. delay(5000); 123. LCD_Command_Write(0x01); 124. delay(50); 125. LCD_Write_String(0,0,str3); 126. delay(50); 127. LCD_Write_String(0,1,str4); 128. delay(5000); 129. 130. } 复制代码
4位接法实验效果如下
http://player.youku.com/player.php/sid/XMjg3MDE5MDIw/v.swf
这里我们讲解一下最关键的部分,就是LCD的控制命令。
在上面两段代码中,我们常常可以遇到0x01,0x38这种参数。这些参数代表什么呢?
在C/C++语言中,0x38代表的是十六进制的数值"38","0x"的意思就是十六进制。
先打开win7下的计算器,选择“程序员”“基本”,
然后咱们选择“十六进制”,输入“38”,
然后再点击“二进制”。这时十六进制的“38”就会转换为二进制下的数值“111000”。
以8位控制法接LCD是,对应的控制信息就是“00111000”
同理,也可以把二进制的控制信息,逆运算为十六进制的。
有的产品说明书写的控制命令是"38H"
这里说明一下,一般情况下
十六进制 前缀0x 后缀h
十进制 后缀D
八进制 后缀Q
二进制 后缀B
但是不同的程序语言,对于十六进制的表达方式不完全相同,在arduino下,表达十六进制数值“38”只能使用“0x38”而不能用“38H”
最后放三个附件,是三个不同厂家的1602 LCD手册,供大家深入研究。
1602手册.pdf (634.17 KB, 下载次数: 3)
1602.pdf (233 KB, 下载次数: 1)
SMC1602A.pdf (255.88 KB, 下载次数: 1) |