banner
NEWS LETTER

STM32基于HAL库驱动LCD1602

Scroll down

LCD1602引脚定义

引脚编号 功能 描述
1 VSS (地) 用于连接电源地
2 VDD (电源正) 用于连接正向电源(通常为+5V)
3 Vee 控制LCD的对比度,可通过外部10K电位器调节
4 RS (命令/数据) 控制数据的传输方式:0表示命令,1表示数据
5 RW (读/写) 控制数据的读写操作:0表示写入数据,1表示读取数据
6 E (使能) 使能信号,用于触发LCD读写操作
7-14 D0-D7 数据线 用于传输8位数据(4位模式下,只需连接D4-D7即可)
15 A (背光阳极) 背光电源的阳极(通常接VDD或外部电源)
16 K (背光阴极) 背光电源的阴极(通常接地)

LCD1602指令表

GPIO初始化

GPIO.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef _GPIO_H
#define _GPIO_H

#include "stm32f1xx_hal.h"



#define RS_Pin          GPIO_PIN_0
#define RS_GPIO_Port    GPIOA
#define RW_Pin          GPIO_PIN_1
#define RW_GPIO_Port    GPIOA
#define E_Pin           GPIO_PIN_2
#define E_GPIO_Port     GPIOA

void gpio_init(void);

#endif

GPIO.c

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
#include "GPIO.h"  

void lcd_gpio_init(void)
{

    GPIO_InitTypeDef gpio_initstruct;
    __HAL_RCC_GPIOA_CLK_ENABLE();                          /* IO口PA时钟使能 */
    gpio_initstruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2; /* RS RW E引脚 */
    gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽输出 */
    gpio_initstruct.Pull = GPIO_PULLUP;                    /* 上拉 */
    gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
    HAL_GPIO_Init(GPIOA, &gpio_initstruct);                /* 初始化RS RW E引脚 */

    __HAL_RCC_GPIOB_CLK_ENABLE();                          /* IO口PB时钟使能 */
    gpio_initstruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7; /* DB0-DB7引脚 */
    gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽输出 */
    gpio_initstruct.Pull = GPIO_PULLUP;                    /* 上拉 */
    gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
    HAL_GPIO_Init(GPIOB, &gpio_initstruct);                /* 初始化DB0-DB7引脚 */

}




void gpio_init(void)

{
    lcd_gpio_init();
}

LCD1602驱动代码

LCD1602.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef LCD_LCD1602_H
#define LCD_LCD1602_H

#include "main.h"
#include "GPIO.h"

typedef unsigned char u8;

void initLCD(u8,u8,GPIO_TypeDef*);//初始化LCD  参数为显示位置 如 (0,0) 表示 第一行第一列
void writeComd(u8);//写指令
void writeData(u8);//写数据
void deleteData();//删除一位
void makeCursor(u8);//显示光标 参数为光标是否闪烁 0:光标闪烁 1:光标不闪烁 2:关闭光标
void writeText(u8*);//写文本

void WritePos(u8 xPos,u8 yPos);//设置显示位置
void WriteString(u8 xPos,u8 yPos,unsigned char *s);//写字符串

#endif //LCD_LCD1602_H

LCD1602.C

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
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
100
101
102
103
104
105
#include "LCD1602.h"

GPIO_TypeDef *GPIOP;
volatile static u8 position = 0x80;

void initLCD(u8 x,u8 y, GPIO_TypeDef *DATA_PORT) {
    GPIOP = DATA_PORT;
    HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, 0);
   
    if (y) position=0xC0;
    position+=x;
   
    writeComd(0x38);
    writeComd(0x0c);
    writeComd(0x06);
    writeComd(0x01);

    writeComd(position);
    HAL_Delay(2);
}

void writeComd(u8 comd) {
    HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, 0);
    HAL_GPIO_WritePin(RW_GPIO_Port, RW_Pin, 0);

    GPIOP->ODR = comd;

    HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, 1);
    HAL_Delay(1);
    HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, 0);
}

void writeData(u8 data) {
    HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, 1);
    HAL_GPIO_WritePin(RW_GPIO_Port, RW_Pin, 0);

    GPIOP->ODR = data;

    HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, 1);
    HAL_Delay(1);
    HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, 0);

    if (position == 0x8F) {
        writeComd(0xc0);
        position = 0xc0;
        return;
    }
    position++;
}

void deleteData() {
    if (position==0x80)return;
    writeComd(0x10);
    position--;
    writeData(0x01);
    writeComd(0x10);
    if (position == 0xc0) {
        writeComd(0x8f);
        writeData(0x01);
        writeComd(0x10);
        position = 0x8f;
        return;
    }
    position--;
}

void makeCursor(u8 cfg) { //0;flash 1:stop flash
    if (cfg >= 2) {
        writeComd(0x0c);
        return;
    }
    writeComd(0x0f - cfg);
}

void writeText(u8 *text) {
    while ((*text) != 0) {
        writeData(*text);
        text++;
    }
}

void WritePos(u8 xPos,u8 yPos)  
{

    static u8 tmp;
    xPos&=0x0f;           // x位置范围是0~15
    yPos&=0x01;           // y位置范围是0~1
    if(yPos==0)           // 显示第一行
        tmp=xPos;         // 第一行字符地址从 0x00 开始
    else
        tmp=xPos+0x40;    // 第二行字符地址从 0x40 开始
    tmp|=0x80;            // 设置 RAM 地址
    writeComd(tmp);
}
void WriteString(u8 xPos,u8 yPos,unsigned char *s)
{  
    unsigned char i=0;
    WritePos(xPos,yPos);          // 起始坐标
    while(s[i])
    {
        writeData(s[i]);
        i++;
        if (i>=16)  break;    // 超出16个字符外的数据丢弃
    }
}
其他文章
cover
二极管初识
  • 23/11/08
  • 10:06
  • 学习