STM32F103C8T6驱动LCD1602
时间: 2023-10-30 13:14:22 浏览: 152
要驱动LCD1602需要使用STM32F103C8T6的GPIO口,首先需要确定使用的是4位还是8位数据总线。接线图如下:
```
LCD1602 STM32F103C8T6
----------------------------------
RS PA0
RW GND
E PA1
D0 NC
D1 NC
D2 NC
D3 NC
D4 PA2
D5 PA3
D6 PA4
D7 PA5
```
其中,RS为寄存器选择,RW为读写控制,E为操作使能,D0-D7为数据总线。
接线好后,需要编写STM32F103C8T6的驱动程序,以下是一个简单的4位数据总线驱动程序示例:
```c
#include "stm32f10x.h"
#include "lcd1602.h"
void delay_us(uint32_t us)
{
volatile uint32_t i = 7 * us;
while (i--) {}
}
void delay_ms(uint32_t ms)
{
volatile uint32_t i = 7000 * ms;
while (i--) {}
}
void lcd1602_send_byte(uint8_t data, uint8_t mode)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_0); // RS: 0
GPIO_WriteBit(GPIOA, GPIO_Pin_2, (BitAction)(data & 0x10)); // D4
GPIO_WriteBit(GPIOA, GPIO_Pin_3, (BitAction)(data & 0x20)); // D5
GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)(data & 0x40)); // D6
GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)(data & 0x80)); // D7
GPIO_SetBits(GPIOA, GPIO_Pin_1); // E: 1
delay_us(10);
GPIO_ResetBits(GPIOA, GPIO_Pin_1); // E: 0
delay_us(10);
GPIO_ResetBits(GPIOA, GPIO_Pin_2); // D4: 0
GPIO_ResetBits(GPIOA, GPIO_Pin_3); // D5: 0
GPIO_ResetBits(GPIOA, GPIO_Pin_4); // D6: 0
GPIO_ResetBits(GPIOA, GPIO_Pin_5); // D7: 0
delay_us(50);
GPIO_ResetBits(GPIOA, GPIO_Pin_0); // RS: 0
GPIO_WriteBit(GPIOA, GPIO_Pin_2, (BitAction)(data << 4 & 0x10)); // D4
GPIO_WriteBit(GPIOA, GPIO_Pin_3, (BitAction)(data << 4 & 0x20)); // D5
GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)(data << 4 & 0x40)); // D6
GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)(data << 4 & 0x80)); // D7
GPIO_SetBits(GPIOA, GPIO_Pin_1); // E: 1
delay_us(10);
GPIO_ResetBits(GPIOA, GPIO_Pin_1); // E: 0
delay_us(10);
GPIO_ResetBits(GPIOA, GPIO_Pin_2); // D4: 0
GPIO_ResetBits(GPIOA, GPIO_Pin_3); // D5: 0
GPIO_ResetBits(GPIOA, GPIO_Pin_4); // D6: 0
GPIO_ResetBits(GPIOA, GPIO_Pin_5); // D7: 0
delay_us(50);
}
void lcd1602_init(void)
{
delay_ms(100);
lcd1602_send_byte(0x33, 0); // 初始化
delay_ms(5);
lcd1602_send_byte(0x32, 0); // 初始化
delay_us(100);
lcd1602_send_byte(0x28, 0); // 设置数据位数、显示行数
delay_us(100);
lcd1602_send_byte(0x06, 0); // 设置输入模式
delay_us(100);
lcd1602_send_byte(0x0C, 0); // 开启显示
delay_us(100);
lcd1602_send_byte(0x01, 0); // 清屏
delay_ms(5);
}
void lcd1602_puts(uint8_t x, uint8_t y, char* str)
{
uint8_t i = 0;
if (y == 0) {
lcd1602_send_byte(0x80 + x, 0);
} else {
lcd1602_send_byte(0xC0 + x, 0);
}
while (str[i]) {
lcd1602_send_byte(str[i], 1);
i++;
}
}
int main(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
lcd1602_init();
while (1) {
lcd1602_puts(0, 0, "Hello, world!");
delay_ms(1000);
lcd1602_send_byte(0x01, 0); // 清屏
delay_ms(5);
}
}
```
在程序中,`lcd1602_send_byte()`函数用来发送数据或指令,`lcd1602_init()`函数用来初始化LCD1602,`lcd1602_puts()`函数用来在指定位置打印字符串。`delay_us()`和`delay_ms()`函数用来进行延时,可以根据需要进行调整。
该程序通过GPIO控制LCD1602,可以在LCD上显示Hello, world!。你可以根据需要修改代码,添加更多功能。
阅读全文