1.18 1602 显示屏
1.18.1 模块来源
采购链接: 黄绿屏 1602 液晶屏 LCD1602A LCD-1602-5V 5V 黑字体 带背光 资料下载链接: http://pan.baidu.com/s/1c0ARSIk
1.18.2 规格参数
工作电压: 3~5V
工作电流:最大 24mA
**模块尺寸:**12(H) x 38(V) MM
像素大小:16 列 2 行 每一列 8x8 的点阵
通信协议:8 位并口
1.18.3 移植过程
我们的目标是将例程移植至梁山派 GD32F470 上。按照以下步骤,即可完成移植。
- 将源码导入工程;
- 根据编译报错处进行粗改;
- 修改引脚配置;
- 修改时序配置;
- 移植验证。
1.18.3.1 查看资料
打开厂家资料例程。
在 main.c 文件发现对屏幕的初始化配置函数为 OLCD_Init(); ,该函数里包含了对屏幕引脚的配置、对屏幕显示方式的配置。
我们主要修改的是引脚的初始化与时序的延时修改。
1.18.3.2 移植至工程
将厂家资料路径下的 1602.c 文件,复制到自己的工程中。自己的工程至少需要有毫秒级延时函数。(工程可以参考文件 1.18.3.2 空白工程下载)
打开自己的工程,将我们刚刚复制过来的文件导入.c 文件。
选择导入复制过来的文件夹里面的全部.c 文件。
导入完成后,工程目录下会出现新导入的文件。(原工程目录见图 1.18.3.5 C 文件导入步骤)
新建一个文件命名为 1602.h,并放置在 Hardware 文件夹下。
添加.h 路径
在弹出的路径窗口,选择添加新路径
选择 Hardware 文件夹的路径,我们的.h 就在里面。因为是选择导入路径,所以不会显示该文件夹下有什么文件。
添加完成
添加 sys.h 文件,它的内容主要是位带操作部分,这里提供给 GD32F450/GD32F470 的位带操作文件给大家。
将 sys.h 文件复制到工程的 User 目录下即可。
1.18.3.3 引脚选择
选择好引脚后,进入工程开始编写屏幕引脚初始化代码。
为了方便后续移植,我在 1602.h 处宏定义了每一个引脚,后续根据需要进行修改即可。
#define RCU_LCD_RS RCU_GPIOA//RS
#define PORT_LCD_RS GPIOA
#define GPIO_LCD_RS GPIO_PIN_0
#define RCU_LCD_RW RCU_GPIOF//RW
#define PORT_LCD_RW GPIOF
#define GPIO_LCD_RW GPIO_PIN_8
#define RCU_LCD_E RCU_GPIOF//E
#define PORT_LCD_E GPIOF
#define GPIO_LCD_E GPIO_PIN_6
#define RCU_LCD_DB0 RCU_GPIOA//DB0
#define PORT_LCD_DB0 GPIOA
#define GPIO_LCD_DB0 GPIO_PIN_2
#define RCU_LCD_DB1 RCU_GPIOC//DB1
#define PORT_LCD_DB1 GPIOC
#define GPIO_LCD_DB1 GPIO_PIN_2
#define RCU_LCD_DB2 RCU_GPIOA//DB2
#define PORT_LCD_DB2 GPIOA
#define GPIO_LCD_DB2 GPIO_PIN_3
#define RCU_LCD_DB3 RCU_GPIOA//DB3
#define PORT_LCD_DB3 GPIOA
#define GPIO_LCD_DB3 GPIO_PIN_5
#define RCU_LCD_DB4 RCU_GPIOA//DB4
#define PORT_LCD_DB4 GPIOA
#define GPIO_LCD_DB4 GPIO_PIN_7
#define RCU_LCD_DB5 RCU_GPIOC//DB5
#define PORT_LCD_DB5 GPIOC
#define GPIO_LCD_DB5 GPIO_PIN_5
#define RCU_LCD_DB6 RCU_GPIOB//DB6
#define PORT_LCD_DB6 GPIOB
#define GPIO_LCD_DB6 GPIO_PIN_1
#define RCU_LCD_DB7 RCU_GPIOB//DB7
#define PORT_LCD_DB7 GPIOB
#define GPIO_LCD_DB7 GPIO_PIN_10
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
将 1602.c 修改为如下代码。
void LCDInit(void) //LCM初始化
{
/* 开启引脚时钟 */
rcu_periph_clock_enable(RCU_LCD_RS);
rcu_periph_clock_enable(RCU_LCD_RW);
rcu_periph_clock_enable(RCU_LCD_E);
rcu_periph_clock_enable(RCU_LCD_DB0);
rcu_periph_clock_enable(RCU_LCD_DB1);
rcu_periph_clock_enable(RCU_LCD_DB2);
rcu_periph_clock_enable(RCU_LCD_DB3);
rcu_periph_clock_enable(RCU_LCD_DB4);
rcu_periph_clock_enable(RCU_LCD_DB5);
rcu_periph_clock_enable(RCU_LCD_DB6);
rcu_periph_clock_enable(RCU_LCD_DB7);
/* RS配置为上拉推挽输出50MHZ模式 */
gpio_mode_set(PORT_LCD_RS,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_RS);
gpio_output_options_set(PORT_LCD_RS,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_RS);
gpio_mode_set(PORT_LCD_RW,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_RW);
gpio_output_options_set(PORT_LCD_RW,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_RW);
gpio_mode_set(PORT_LCD_E,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_E);
gpio_output_options_set(PORT_LCD_E,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_E);
gpio_mode_set(PORT_LCD_DB0,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_DB0);
gpio_output_options_set(PORT_LCD_DB0,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_DB0);
gpio_mode_set(PORT_LCD_DB1,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_DB1);
gpio_output_options_set(PORT_LCD_DB1,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_DB1);
gpio_mode_set(PORT_LCD_DB2,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_DB2);
gpio_output_options_set(PORT_LCD_DB2,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_DB2);
gpio_mode_set(PORT_LCD_DB3,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_DB3);
gpio_output_options_set(PORT_LCD_DB3,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_DB3);
gpio_mode_set(PORT_LCD_DB4,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_DB4);
gpio_output_options_set(PORT_LCD_DB4,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_DB4);
gpio_mode_set(PORT_LCD_DB5,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_DB5);
gpio_output_options_set(PORT_LCD_DB5,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_DB5);
gpio_mode_set(PORT_LCD_DB6,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_DB6);
gpio_output_options_set(PORT_LCD_DB6,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_DB6);
gpio_mode_set(PORT_LCD_DB7,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLUP,GPIO_LCD_DB7);
gpio_output_options_set(PORT_LCD_DB7,GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_LCD_DB7);
LCD_Data(0);
WriteCommandLCD(0x38,0); //三次显示模式设置,不检测忙信号
delay_1ms(5);
WriteCommandLCD(0x38,0);
delay_1ms(5);
WriteCommandLCD(0x38,0);
delay_1ms(5);
WriteCommandLCD(0x38,1); //显示模式设置,开始要求每次检测忙信号
delay_1ms(5);
WriteCommandLCD(0x08,1); //关闭显示
delay_1ms(5);
WriteCommandLCD(0x01,1); //显示清屏
delay_1ms(5);
WriteCommandLCD(0x06,1); // 显示光标移动设置
delay_1ms(5);
WriteCommandLCD(0x0C,1); // 显示开及光标设置
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
将 1602.h 修改如下。
/********************************************************************************
* 测试硬件:立创·梁山派开发板GD32F470ZGT6 使用主频200Mhz 晶振25Mhz
* 版 本 号: V1.0
* 修改作者: LC
* 修改日期: 2023年06月12日
* 功能介绍:
******************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:https://dri8c0qdfb.feishu.cn/docx/EGRVdxunnohkrNxItYTcrwAnnHe
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*********************************************************************************/
#ifndef _1602_H_
#define _1602_H_
#define RCU_LCD_RS RCU_GPIOA//RS
#define PORT_LCD_RS GPIOA
#define GPIO_LCD_RS GPIO_PIN_0
#define RCU_LCD_RW RCU_GPIOF//RW
#define PORT_LCD_RW GPIOF
#define GPIO_LCD_RW GPIO_PIN_8
#define RCU_LCD_E RCU_GPIOF//E
#define PORT_LCD_E GPIOF
#define GPIO_LCD_E GPIO_PIN_6
#define RCU_LCD_DB0 RCU_GPIOA//DB0
#define PORT_LCD_DB0 GPIOA
#define GPIO_LCD_DB0 GPIO_PIN_2
#define RCU_LCD_DB1 RCU_GPIOC//DB1
#define PORT_LCD_DB1 GPIOC
#define GPIO_LCD_DB1 GPIO_PIN_2
#define RCU_LCD_DB2 RCU_GPIOA//DB2
#define PORT_LCD_DB2 GPIOA
#define GPIO_LCD_DB2 GPIO_PIN_3
#define RCU_LCD_DB3 RCU_GPIOA//DB3
#define PORT_LCD_DB3 GPIOA
#define GPIO_LCD_DB3 GPIO_PIN_5
#define RCU_LCD_DB4 RCU_GPIOA//DB4
#define PORT_LCD_DB4 GPIOA
#define GPIO_LCD_DB4 GPIO_PIN_7
#define RCU_LCD_DB5 RCU_GPIOC//DB5
#define PORT_LCD_DB5 GPIOC
#define GPIO_LCD_DB5 GPIO_PIN_5
#define RCU_LCD_DB6 RCU_GPIOB//DB6
#define PORT_LCD_DB6 GPIOB
#define GPIO_LCD_DB6 GPIO_PIN_1
#define RCU_LCD_DB7 RCU_GPIOB//DB7
#define PORT_LCD_DB7 GPIOB
#define GPIO_LCD_DB7 GPIO_PIN_10
// x ? 置1 : 置0
#define PIN_HIGH_OR_LOW(port,gpio,x) {((x) ? (GPIO_OCTL(port)|=(uint32_t)(gpio)) : (GPIO_OCTL(port)&=~(uint32_t)(gpio)));}
// 先清除该位,空出位置 根据x判断是设置位还是清除位
#define BIT_DB7(x) { GPIO_OCTL(PORT_LCD_DB7) &= ((uint32_t)~(GPIO_LCD_DB7)); PIN_HIGH_OR_LOW( PORT_LCD_DB7, GPIO_LCD_DB7, x) }
#define BIT_DB6(x) { GPIO_OCTL(PORT_LCD_DB6) &= ((uint32_t)~(GPIO_LCD_DB6)); PIN_HIGH_OR_LOW( PORT_LCD_DB6, GPIO_LCD_DB6, x) }
#define BIT_DB5(x) { GPIO_OCTL(PORT_LCD_DB5) &= ((uint32_t)~(GPIO_LCD_DB5)); PIN_HIGH_OR_LOW( PORT_LCD_DB5, GPIO_LCD_DB5, x) }
#define BIT_DB4(x) { GPIO_OCTL(PORT_LCD_DB4) &= ((uint32_t)~(GPIO_LCD_DB4)); PIN_HIGH_OR_LOW( PORT_LCD_DB4, GPIO_LCD_DB4, x) }
#define BIT_DB3(x) { GPIO_OCTL(PORT_LCD_DB3) &= ((uint32_t)~(GPIO_LCD_DB3)); PIN_HIGH_OR_LOW( PORT_LCD_DB3, GPIO_LCD_DB3, x) }
#define BIT_DB2(x) { GPIO_OCTL(PORT_LCD_DB2) &= ((uint32_t)~(GPIO_LCD_DB2)); PIN_HIGH_OR_LOW( PORT_LCD_DB2, GPIO_LCD_DB2, x) }
#define BIT_DB1(x) { GPIO_OCTL(PORT_LCD_DB1) &= ((uint32_t)~(GPIO_LCD_DB1)); PIN_HIGH_OR_LOW( PORT_LCD_DB1, GPIO_LCD_DB1, x) }
#define BIT_DB0(x) { GPIO_OCTL(PORT_LCD_DB0) &= ((uint32_t)~(GPIO_LCD_DB0)); PIN_HIGH_OR_LOW( PORT_LCD_DB0, GPIO_LCD_DB0, x) }
#define LCD_RS PAout(0)//定义引脚
#define LCD_RW PFout(8)
#define LCD_E PFout(6)
//#define LCD_Data(x) {}
#define Busy 0x80 //用于检测LCD状态字中的Busy标识
#define LCD_Data(dat){\
BIT_DB7( (dat>>7)&0x01 );\
BIT_DB6( (dat>>6)&0x01 );\
BIT_DB5( (dat>>5)&0x01 );\
BIT_DB4( (dat>>4)&0x01 );\
BIT_DB3( (dat>>3)&0x01 );\
BIT_DB2( (dat>>2)&0x01 );\
BIT_DB1( (dat>>1)&0x01 ); \
BIT_DB0( (dat>>0)&0x01 ); \
}
void WriteDataLCD(unsigned char WDLCD);
void WriteCommandLCD(unsigned char WCLCD,unsigned char BuysC);
void LCDInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char *DData);
#endif
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
到这里就移植完成了。
1.18.4 移植验证
在 main.c 中输入代码如下
/********************************************************************************
* 测试硬件:立创·梁山派开发板GD32F470ZGT6 使用主频200Mhz 晶振25Mhz
* 版 本 号: V1.0
* 修改作者: LC
* 修改日期: 2023年06月12日
* 功能介绍:
******************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:https://dri8c0qdfb.feishu.cn/docx/EGRVdxunnohkrNxItYTcrwAnnHe
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*********************************************************************************/
#include "gd32f4xx.h"
#include "systick.h"
#include "stdio.h"
#include "1602.h"
int main(void)
{
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // 优先级分组
systick_config(); //滴答定时器初始化 1ms
delay_1ms(500); //启动等待,等LCD讲入工作状态
LCDInit(); //LCM初始化
delay_1ms(5); //延时片刻(可不要)
while(1)
{
DisplayListChar(0, 0, "www.lckfb.com");
DisplayListChar(0, 5, "kfb");
delay_1ms(1000);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
上电效果
移植成功案例