圣源电子制作

 找回密码
 立即注册
查看: 13436|回复: 1
打印 上一主题 下一主题

arduino学习笔记23 1602液晶实验

[复制链接]
跳转到指定楼层
楼主
发表于 2012-4-27 20:24:22 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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.              }
复制代码
实验效果如下
http://player.youku.com/player.php/sid/XMjg2NTkxODY0/v.swf

4位接法

在正常使用下,8位接法基本把arduino的数字端口占满了,如果想要多接几个传感器就没有端口了,这种情况下怎么处理呢,咱们可以使用4位接法。

4位接法的硬件连接方法如下图







硬件接好后把下面的代码上传到控制板上,看看效果。
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)
回复

使用道具 举报

沙发
发表于 2013-3-24 10:22:27 | 只看该作者
手册下不了呀!!!正在学习中!
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|手机版|联系我们|闽公网安备 35012102000020号|闽ICP备11020110号-1|圣源电子

GMT+8, 2024-12-28 04:36 , Processed in 0.045581 second(s), 17 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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