【STM32】驱动LCD1602液晶8线并、4线并

简介: 【STM32】驱动LCD1602液晶8线并、4线并

LCD1602液晶

液晶模块和数码管相比,液晶模块会显得更加专业、漂亮。液晶显示器以其体积小、功耗低、超薄、轻巧、显示内容丰富、使用方便等等诸多有点,在电子设备、通讯、家用电器、仪器仪表等低功耗应用系统之中得到越来越广泛的应用了,使得这一些电子设备的人机界面变得越来越直观、越来越形象了,液晶模块现在已经广泛的应用于液晶电视机、电子表、复印机、计算器、便携式电脑、IC卡电话机、掌上型电子玩具、传真机等许多方面。1602的字符型液晶模块(带背光),是现在工控系统之中使用最为广泛的液晶屏之一了。1602采用了标准的16脚接口。

引脚定义说明

5ad30f90bf0b48dafb279bfdf37e2a20_00d43d2e0ba940c29c08187c3cdae757.png

字库概述

       1602的液晶模块内一般都是带有标准字库的,在内部的字符发生存储器(CGROM)已经是存储了192个5×7的点阵字符,32个5×10的点阵字符。另外还会有字符生成RAM(CGRAM) 512字节,供给用户来自定义字符,比如表1所示,这一些字符都有:英文字母的大小写、阿拉伯数组、常用的符号以及日文假名等,每一个字符都会有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示是模块会吧地址41H中的点阵字符图形给显示出来,我们就能看到字母“A”了。

       液晶显示模块时一个慢显示器件,所以在执行每一条指令之前都一定要确认模块得忙标志位为低电平,代表不忙,否则此指令会失效。要显示字符时需要先输入显示字符地址,也就是说告诉模块在哪里显示字符。

LCD1602原理图

d556eb86567bc015498a7c019db005e5_78917fe64f76488c8c7a26b615322cc6.png

LCD1602时序图

e0c872a5bb996cc308253f1cda58e9ed_ffb30f58673e4b5088e3a94fbd2a275d.png

RS = 0 写指令;RS = 1 写数据

LCD1602代码

LCD1602.c

1. #include "LCD1602.h"
2. 
3. void LCD1602_UserInit(void)
4. {
5.  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
6.  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
7. 
8.  //配置控制I/O口
9.  GPIO_InitTypeDef GPIO_InitStructure;
10.   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP; //推挽输出
11.   GPIO_InitStructure.GPIO_Pin   = RS | RW | EN;
12.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
13.   GPIO_Init(CMD_PROT, &GPIO_InitStructure);
14. 
15.   //配置数据I/O口
16.   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP; //推挽输出
17.   GPIO_InitStructure.GPIO_Pin   = DATA;
18.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
19.   GPIO_Init(CMD_PROT, &GPIO_InitStructure); 
20. }
21. 
22. void LCD1602_Write_Cmd_Data(uint8_t cmd, uint8_t data)
23. {
24.   if (cmd) //1 数据
25.   {        
26.     RS_HIGH;
27.     RW_LOW;
28.     EN_LOW;   
29.     GPIO_Write(DATA_PROT, data); Delay_ms(3);   
30.     EN_HIGH; Delay_ms(3);
31.     EN_LOW;   
32.   }        
33.   else   //0 指令
34.   {
35.     RS_LOW;
36.     RW_LOW;
37.     EN_LOW;   
38.     GPIO_Write(DATA_PROT, data); Delay_ms(3);   
39.     EN_HIGH; Delay_ms(3);
40.     EN_LOW;
41.   }
42. }
43. 
44. void LCD1602_Write_Init(void)
45. {
46.   LCD1602_Write_Cmd_Data(CMD, 0x38);  //基本设置 显示模式设置
47.   LCD1602_Write_Cmd_Data(CMD, 0x06);  //显示光标移动位置
48.   LCD1602_Write_Cmd_Data(CMD, 0x0C);  //开启显示 不显示光标 并且光标不闪烁
49.   LCD1602_Write_Cmd_Data(CMD, 0x01);  //清除屏幕内容
50.   LCD1602_Write_Cmd_Data(CMD, 0x80);  //设置起始地址
51. }
52. 
53. //开启显示
54. void LCD1602_Open(void)
55. {
56.   LCD1602_Write_Cmd_Data(CMD, 0x38);  //基本设置 显示模式设置
57.   LCD1602_Write_Cmd_Data(CMD, 0x0C);
58. }
59. 
60. //关闭显示
61. void LCD1602_Shut(void)
62. {
63.   LCD1602_Write_Cmd_Data(CMD, 0x38);  //基本设置 显示模式设置
64.   LCD1602_Write_Cmd_Data(CMD, 0x08);
65. }
66. 
67. /**
68.  * @brief  
69.  * @param  com  写的地址   //1602 第一行数据0x80~0x8F 第二行数据0xC0~0xCF
70.  * @param  num  写的长度
71.  * @param  *dat 写的内容
72.  * @retval 无
73.  */
74. void LCD1602_Write_Word_Display(uint8_t com, uint8_t num, uint8_t *dat)
75. {
76.   LCD1602_Write_Cmd_Data(CMD, com);
77.   for (uint8_t i = 0; i < num; i ++)
78.   {
79.     LCD1602_Write_Cmd_Data(DAT,*dat++);
80.   }
81. 
82. }
83.

LCD1602.h

1. #ifndef __LCD1602_H__
2. #define __LCD1602_H__
3. 
4. #include "stm32f10x.h"                  // Device header
5. #include "Delay.h"
6. 
7. #define RS GPIO_Pin_0  //RS = 0,指令;RS = 1,数据
8. #define RW GPIO_Pin_1  //RW = 0,写  ;RW = 1,读
9. #define EN GPIO_Pin_2
10. #define CMD_PROT  GPIOC
11. 
12. #define DATA 0x00FF //0~7引脚
13. #define DATA_PROT GPIOF
14. 
15. #define RS_HIGH GPIO_SetBits  (CMD_PROT, RS)
16. #define RS_LOW  GPIO_ResetBits(CMD_PROT, RS)
17. 
18. #define RW_HIGH GPIO_SetBits  (CMD_PROT, RW)
19. #define RW_LOW  GPIO_ResetBits(CMD_PROT, RW)
20. 
21. #define EN_HIGH GPIO_SetBits  (CMD_PROT, EN)
22. #define EN_LOW  GPIO_ResetBits(CMD_PROT, EN)
23. 
24. #define CMD 0 //代表RS = 0,指令
25. #define DAT 1 //代表RS = 1,数据
26. 
27. void LCD1602_UserInit(void);  //LCD1602初始化
28. void LCD1602_Write_Init(void);  //LCD1602写初始化
29. void LCD1602_Open(void);
30. void LCD1602_Shut(void);
31. void LCD1602_Write_Word_Display(uint8_t com, uint8_t num, uint8_t *dat);
32. 
33. #endif
34.

主函数

1. #include "stm32f10x.h"                  // Device header
2. //#include "Delay.h"
3. #include "LCD1602.h"
4. 
5. int main(void)
6. {
7.  Delay_Init (72);
8. 
9.  LCD1602_UserInit();   //LCD1602初始化
10.   LCD1602_Write_Init(); //LCD1602写初始化
11. //  LCD1602_Open();
12. //  LCD1602_Shut();
13.   LCD1602_Write_Word_Display(0x80, 16, (u8*)&"xiaoliangtongxue" );  
14. 
15.   while(1)
16.   {
17. 
18.   }
19. }
20. 
21. /***********************************END OF FILE***********************************/
22.

接线图

(参考51单片机接线图)

RS RW EN 分别是PC0、PC1、PC2,数据线依次为PF0、PF1、PF2……

28124f847a0f64c43b8f8bd79402ed6d_00defc46d7c04b0d90cc8a271e154a27.png

崩溃瞬间

插了好一会杜邦线,你竟然不亮

9b8cc9006ae7d4573f8dbd518a8781ee_0661538315d84f76b0486ed7c621d315.png

c00c5d20d7978b86f52db8b1f9d56a11_f727ba58505849b0aba5ae5542a57fc2.png

这块LCD1602好像是坏了

13ea6cfdeedff5c78cc244131c25f644_9c82ed990db64dbba2ad5112c48f81aa.jpeg

算了算了,继续敲


用结构体的方式显示字符

在LCD1602.h文件里添加结构体的声明

1. //使用结构体
2. typedef struct{
3.  uint8_t com;
4.  uint8_t num;
5.  uint8_t *data;
6. }LCD_InitTypeDef;

将LCD1602.c文件里最后一个函数的形参改成结构体,函数里对应的数据也要修改成结构体成员

1. void LCD1602_Write_Word_Display(LCD_InitTypeDef  LCD_InitStructure)
2. {
3.  LCD1602_Write_Cmd_Data(CMD, LCD_InitStructure.com);
4.  for (uint8_t i = 0; i < LCD_InitStructure.num; i ++)
5.  {
6.    LCD1602_Write_Cmd_Data(DAT,*LCD_InitStructure.data++);
7.  }
8. 
9. }

main.c

1. #include "stm32f10x.h"                  // Device header
2. //#include "Delay.h"
3. #include "LCD1602.h"
4. 
5. LCD_InitTypeDef  LCD_InitStructure;
6. 
7. int main(void)
8. {
9.  Delay_Init (72);
10. 
11.   LCD1602_UserInit();   //LCD1602初始化
12.   LCD1602_Write_Init(); //LCD1602写初始化
13. //  LCD1602_Open();
14. //  LCD1602_Shut(); 
15. 
16.   LCD_InitStructure.com = 0xC0; //第二行
17.   LCD_InitStructure.num = sizeof("xinniankuaile666")-1; //计算长度
18.   LCD_InitStructure.data = (u8*)&"xinniankuaile666";  //显示的内容
19. 
20.   LCD1602_Write_Word_Display(LCD_InitStructure);  
21.   while(1)
22.   {
23. 
24.   }
25. }

LCD1602动态显示数字

1. void LCD1602_Number_Display(u8 com, u8 num)  //数据范围0~255
2. {
3.  const u8 numcode[] = {"0123456789"};  //只读,不可修改
4. 
5.  LCD1602_Write_Cmd_Data(CMD, com);
6.  LCD1602_Write_Cmd_Data(DAT, numcode[num/100]);//数位分离
7.  LCD1602_Write_Cmd_Data(DAT, numcode[num/10%10]);
8.  LCD1602_Write_Cmd_Data(DAT, numcode[num%10]);
9. }

while(1)里的代码

1. for(u8 i = 0; i < 255; i ++)
2. {
3.     LCD1602_Number_Display(0x87, i);
4.     Delay_ms(300);
5. }

4线驱动LCD1602

a8cace8f63193674ab7f1e17a835375b_d7ab27637d264622b69d8aa690b3fde8.png

只用4567  四个数据引脚

数据以四位四位的方式发送

代码部分

1. #include "LCD1602.h"
2. 
3. void LCD1602_UserInit(void)
4. {
5.  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
6.  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
7. 
8.  //配置控制I/O口
9.  GPIO_InitTypeDef GPIO_InitStructure;
10.   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP; //推挽输出
11.   GPIO_InitStructure.GPIO_Pin   = RS | RW | EN;
12.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
13.   GPIO_Init(CMD_PROT, &GPIO_InitStructure);
14. 
15.   //配置数据I/O口
16.   GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP; //推挽输出
17.   GPIO_InitStructure.GPIO_Pin   = DATA;
18.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
19.   GPIO_Init(CMD_PROT, &GPIO_InitStructure); 
20. }
21. 
22. /*4线传输*/
23. void LCD1602_Write_Cmd_Data(uint8_t cmd, uint8_t data)
24. {
25. //  /*代码优化*/
26. //  if (cmd) //1 数据       
27. //    RS_HIGH;
28. //  else   //0 指令
29. //    RS_LOW;
30. 
31.   //对上面四行代码继续优化,用到了三目运算符
32.   (CMD) ? RS_HIGH : RS_LOW;
33. 
34. 
35.   //依次执行
36.   RW_LOW;
37.   EN_LOW; 
38. 
39.   GPIO_Write(DATA_PROT, data | 0x0f); Delay_ms(3);//传输高四位数据 
40.   EN_HIGH; Delay_ms(3);
41.   EN_LOW;
42. 
43.   GPIO_Write(DATA_PROT, (data << 4) | 0x0f); Delay_ms(3);//左移四位,将低四位数据传输
44.   EN_HIGH; Delay_ms(3);
45.   EN_LOW; 
46. 
47. 
48. }
49. 
50. void LCD1602_Write_Init(void)
51. {
52.   LCD1602_Write_Cmd_Data(CMD, 0x38);  //基本设置 显示模式设置
53.   LCD1602_Write_Cmd_Data(CMD, 0x33);  //设置显示模式
54.   LCD1602_Write_Cmd_Data(CMD, 0x32);  //设置8线转4线显示模式
55.   LCD1602_Write_Cmd_Data(CMD, 0x28);  //设置指定模式初始化
56.   LCD1602_Write_Cmd_Data(CMD, 0x06);  //显示光标移动位置
57.   LCD1602_Write_Cmd_Data(CMD, 0x0C);  //开启显示 不显示光标 并且光标不闪烁
58.   LCD1602_Write_Cmd_Data(CMD, 0x01);  //清除屏幕内容
59.   LCD1602_Write_Cmd_Data(CMD, 0x80);  //设置起始地址
60. }
61. 
62. //开启显示
63. void LCD1602_Open(void)
64. {
65.   LCD1602_Write_Cmd_Data(CMD, 0x38);  //基本设置 显示模式设置
66.   LCD1602_Write_Cmd_Data(CMD, 0x33);  //设置显示模式
67.   LCD1602_Write_Cmd_Data(CMD, 0x32);  //设置8线转4线显示模式
68.   LCD1602_Write_Cmd_Data(CMD, 0x28);  //设置指定模式初始化
69.   LCD1602_Write_Cmd_Data(CMD, 0x0C);
70. }
71. 
72. //关闭显示
73. void LCD1602_Shut(void)
74. {
75.   LCD1602_Write_Cmd_Data(CMD, 0x38);  //基本设置 显示模式设置
76.   LCD1602_Write_Cmd_Data(CMD, 0x33);  //设置显示模式
77.   LCD1602_Write_Cmd_Data(CMD, 0x32);  //设置8线转4线显示模式
78.   LCD1602_Write_Cmd_Data(CMD, 0x28);  //设置指定模式初始化
79.   LCD1602_Write_Cmd_Data(CMD, 0x08);
80. }
81. 
82. /**
83.  * @brief  
84.  * @param  com  写的地址   //1602 第一行数据0x80~0x8F 第二行数据0xC0~0xCF
85.  * @param  num  写的长度
86.  * @param  *dat 写的内容
87.  * @retval 无
88.  */
89. void LCD1602_Write_Word_Display(LCD_InitTypeDef  LCD_InitStructure)
90. {
91.   LCD1602_Write_Cmd_Data(CMD, LCD_InitStructure.com);
92.   for (uint8_t i = 0; i < LCD_InitStructure.num; i ++)
93.   {
94.     LCD1602_Write_Cmd_Data(DAT,*LCD_InitStructure.data++);
95.   }
96. 
97. }
98. 
99. void LCD1602_Number_Display(u8 com, u8 num) //数据范围0~255
100. {
101.  const u8 numcode[] = {"0123456789"};  //只读,不可修改
102. 
103.  LCD1602_Write_Cmd_Data(CMD, com);
104.  LCD1602_Write_Cmd_Data(DAT, numcode[num/100]);//数位分离
105.  LCD1602_Write_Cmd_Data(DAT, numcode[num/10%10]);
106.  LCD1602_Write_Cmd_Data(DAT, numcode[num%10]);
107. }
108.
1. #ifndef __LCD1602_H__
2. #define __LCD1602_H__
3. 
4. #include "stm32f10x.h"                  // Device header
5. #include "Delay.h"
6. 
7. //使用结构体
8. typedef struct{
9.  uint8_t com;
10.   uint8_t num;
11.   uint8_t *data;
12. }LCD_InitTypeDef;
13. 
14. #define RS  GPIO_Pin_0  //RS = 0,指令;RS = 1,数据
15. #define RW  GPIO_Pin_1  //RW = 0,写  ;RW = 1,读
16. #define EN  GPIO_Pin_2
17. #define CMD_PROT  GPIOC
18. 
19. #define DATA 0x00F0 //4~7引脚
20. #define DATA_PROT GPIOF
21. 
22. #define RS_HIGH GPIO_SetBits  (CMD_PROT, RS)
23. #define RS_LOW  GPIO_ResetBits(CMD_PROT, RS)
24. 
25. #define RW_HIGH GPIO_SetBits  (CMD_PROT, RW)
26. #define RW_LOW  GPIO_ResetBits(CMD_PROT, RW)
27. 
28. #define EN_HIGH GPIO_SetBits  (CMD_PROT, EN)
29. #define EN_LOW  GPIO_ResetBits(CMD_PROT, EN)
30. 
31. #define CMD 0 //代表RS = 0,指令
32. #define DAT 1 //代表RS = 1,数据
33. 
34. void LCD1602_UserInit(void);  //LCD1602初始化
35. void LCD1602_Write_Init(void);  //LCD1602写初始化
36. void LCD1602_Open(void);
37. void LCD1602_Shut(void);
38. 
39. void LCD1602_Write_Word_Display(LCD_InitTypeDef  LCD_InitStructure);
40. 
41. void LCD1602_Number_Display(u8 com, u8 num);
42. 
43. #endif
1. #include "stm32f10x.h"                  // Device header
2. //#include "Delay.h"
3. #include "LCD1602.h"
4. 
5. LCD_InitTypeDef  LCD_InitStructure;
6. 
7. int main(void)
8. {
9.  Delay_Init (72);
10. 
11.   LCD1602_UserInit();   //LCD1602初始化
12.   LCD1602_Write_Init(); //LCD1602写初始化
13.   LCD1602_Open();
14. //  LCD1602_Shut();   
15. 
16.   LCD_InitStructure.com = 0xC0; //第二行
17.   LCD_InitStructure.num = sizeof("xinniankuaile666")-1; //计算长度
18.   LCD_InitStructure.data = (u8*)&"xinniankuaile666";  //显示的内容
19.   LCD1602_Write_Word_Display(LCD_InitStructure);  
20. 
21.   while(1)
22.   {
23.     for(u8 i = 0; i < 255; i ++)
24.     {
25.       LCD1602_Number_Display(0x87, i);
26.       Delay_ms(300);
27.     }
28. 
29.   }
30. }

好像是这个函数没有取消注释才不亮 LCD1602_Open();

5c53bab3dd73b6331eecaf0d0479a75b_316cbf272e82454c83ee3b787cdb76f6.jpeg

相关文章
小巴陪你搞技术-STM32驱动1602时钟
小巴陪你搞技术-STM32驱动1602时钟
|
4月前
|
传感器
手把手在STM32F103C8T6上构建可扩展可移植的DHT11驱动
【8月更文挑战第29天】本文详细介绍在STM32F103C8T6上构建可扩展且可移植的DHT11温湿度传感器驱动的步骤,包括硬件与软件准备、硬件连接、驱动代码编写及测试。通过这些步骤,可根据实际项目需求优化和扩展代码。
124 0
|
5月前
STM32Cubemx PWM驱动加湿器模拟火山喷发效果
STM32Cubemx PWM驱动加湿器模拟火山喷发效果
71 14
|
5月前
STM32Cubemx PWM驱动SG90舵机
STM32Cubemx PWM驱动SG90舵机
180 13
|
5月前
STM32CubeMX mpu6050驱动
STM32CubeMX mpu6050驱动
72 10
|
5月前
STM32CubeMX EC11旋转编码器驱动
STM32CubeMX EC11旋转编码器驱动
246 10
|
5月前
STM32CubeMX OLED驱动
STM32CubeMX OLED驱动
71 10
|
5月前
|
芯片
STM32CubeMX TM1637驱动数码管
STM32CubeMX TM1637驱动数码管
130 6
|
5月前
STM32CubeMX WS2812B灯驱动
STM32CubeMX WS2812B灯驱动
215 1