概述
STM32驱动LCD1602
- 硬件连接关系
- STM32CUBEIDE设置
- 代码
- 项目设置
- 最后运行
硬件连接关系
LCD1602 | STM32 |
---|---|
VCC | VCC |
GND | GND |
VO | VCC-滑动变阻 |
RS | PB1 |
RW | PB2(BOOT1) |
E | PB0 |
D0 ~ D7 | PB8 ~ PB15 |
A | PA8 |
K | PA11 |
这是普中科技的C51开发板,送了一个stm32f103c6的小核心板,C51开发板上有个LCD1602的接口就直接使用了。
STM32CUBEIDE设置
- System Core -> RCC -> HSE -> Crystal/Ceramic Resonator
- System Core -> RCC -> LSE -> Crystal/Ceramic Resonator
- System Core -> SYS -> Debug -> Serial Wire
- Connectivity -> USART1 -> Mode -> Asynchronous(Baud Rate: 115200Bits/S, Word Length: 8Bits)
- PA8:
GPIO_Output, GPIO output level: High, GPIO Mode: Output Push Pull
- PA11:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Push Pull
- PB0:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Push Pull, User Label: LCD_EN
- PB1:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Push Pull, User Label: LCD_RS
- PB2:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Push Pull, User Label: LCD_RW
- PB8:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB9:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB10:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB11:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB12:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB13:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB14:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- PB15:
GPIO_Output, GPIO output level: Low, GPIO Mode: Output Open Drain
- 设置时钟并保存
前面4行是设置晶振、JWD口、和UART调试信息。PA8,PA11是背光的控制口,设置推挽输出。PB0,PB1,PB2分别是LCD使能、LCD RS、LCD RW口,设置推挽输出。P8 ~ P15是数据输出和输入,因为输出同时要检测LCD是否忙,所以要读状态,需要设置为开漏输出。这里用的是8线输出方式。
代码
- Core->Inc文件夹下建立新的头文件"lcd1602.h"
#ifndef INC_LCD1602_H_
#define INC_LCD1602_H_
#include "main.h"
// 片选、读/写、数据/命令
#define LCD_CMD HAL_GPIO_WritePin(LCD_RS_GPIO_Port, LCD_RS_Pin, GPIO_PIN_RESET)
#define LCD_DATA HAL_GPIO_WritePin(LCD_RS_GPIO_Port, LCD_RS_Pin, GPIO_PIN_SET)
#define LCD_EN_HIGH HAL_GPIO_WritePin(LCD_EN_GPIO_Port, LCD_EN_Pin, GPIO_PIN_SET)
#define LCD_EN_LOWER HAL_GPIO_WritePin(LCD_EN_GPIO_Port, LCD_EN_Pin, GPIO_PIN_RESET)
#define LCD_WRITE HAL_GPIO_WritePin(LCD_RW_GPIO_Port, LCD_RW_Pin, GPIO_PIN_RESET)
#define LCD_READ HAL_GPIO_WritePin(LCD_RW_GPIO_Port, LCD_RW_Pin, GPIO_PIN_SET)
void lcd_init(void);
void lcd_wait_ready(void);
void lcd_write_cmd(unsigned char cmd);
void lcd_write_data(unsigned char data);
void lcd_set_cursor(unsigned char x, unsigned char y);
void lcd_area_clear(unsigned char x, unsigned char y, unsigned char len);
void lcd_full_clear(void);
void lcd_show_string(unsigned char x, unsigned char y, unsigned char *data);
void write_data(unsigned char data);
#endif /* INC_LCD1602_H_ */
- Core/Src下面建立"lcd1602.c"
#include "main.h"
#include "stdio.h"
#include "lcd1602.h"
void lcd_init(void){
lcd_write_cmd(0x38); // 16 * 2 显示 , 5 * 7 点阵, 8位接口
lcd_wait_ready();
lcd_write_cmd(0X0c); // 显示器开,光标关闭
lcd_wait_ready();
lcd_write_cmd(0x06); // 文字不动,地址自动加
lcd_wait_ready();
lcd_write_cmd(0x01); // 清屏
lcd_wait_ready();
printf("Init OK rn");
}
void lcd_wait_ready(void){
unsigned char status;
write_data(0xff);
LCD_CMD; // CMD
LCD_READ; // Read
do{
LCD_EN_HIGH; // 下降沿
status = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15);
LCD_EN_LOWER;
}while(status == 1);
}
void lcd_write_cmd(unsigned char cmd){
lcd_wait_ready();
LCD_CMD;
LCD_WRITE;
write_data(cmd);
LCD_EN_HIGH;
LCD_EN_LOWER;
lcd_wait_ready();
}
void lcd_write_data(unsigned char data){
lcd_wait_ready();
LCD_DATA;
LCD_WRITE;
write_data(data);
LCD_EN_HIGH;
LCD_EN_LOWER;
lcd_wait_ready();
}
void lcd_set_cursor(unsigned char x, unsigned char y){
unsigned char addr = 0;
// Row : y , Col : x
lcd_wait_ready();
// 从输入的屏幕计算显示RAM
if(y == 0){
addr = 0x00 + x;
}
else{
addr = 0x40 + x;
}
lcd_write_cmd(addr | 0x80);
}
void lcd_area_clear(unsigned char x, unsigned char y, unsigned char len){
lcd_set_cursor(x, y);
while(len--){
lcd_wait_ready();
lcd_write_data(' ');
}
}
void lcd_full_clear(void){
lcd_write_cmd(0x01);
}
void lcd_show_string(unsigned char x, unsigned char y, unsigned char *data){
lcd_set_cursor(x, y);
while(*data != '