用stm32f103c8t6写LCD1602程序
时间: 2023-08-30 16:05:18 浏览: 44
好的,下面是一个简单的示例程序,可以在STM32F103C8T6上使用标准的GPIO库和库函数来控制LCD1602显示屏。
首先需要包含相关的库文件和头文件:
```c
#include "stm32f10x.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "delay.h"
#include "lcd1602.h"
```
其中,`delay.h`和`lcd1602.h`是自己编写的头文件,包含了相关的函数声明和宏定义。
接下来定义一些常量,用于指定GPIO口和LCD1602的各种参数:
```c
#define GPIO_LCD_RS GPIO_Pin_0
#define GPIO_LCD_RW GPIO_Pin_1
#define GPIO_LCD_EN GPIO_Pin_2
#define GPIO_LCD_D4 GPIO_Pin_3
#define GPIO_LCD_D5 GPIO_Pin_4
#define GPIO_LCD_D6 GPIO_Pin_5
#define GPIO_LCD_D7 GPIO_Pin_6
#define GPIO_LCD_DATA GPIO_LCD_D4|GPIO_LCD_D5|GPIO_LCD_D6|GPIO_LCD_D7
#define GPIO_LCD_CMD GPIO_LCD_RS|GPIO_LCD_RW|GPIO_LCD_EN
#define LCD_CMD_CLEAR 0x01
#define LCD_CMD_RETURN_HOME 0x02
#define LCD_CMD_ENTRY_MODE 0x04
#define LCD_CMD_DISPLAY_CONTROL 0x08
#define LCD_CMD_SHIFT 0x10
#define LCD_CMD_FUNCTION_SET 0x20
#define LCD_CMD_CGRAM_ADDRESS 0x40
#define LCD_CMD_DDRAM_ADDRESS 0x80
#define LCD_ENTRY_MODE_RIGHT 0x00
#define LCD_ENTRY_MODE_LEFT 0x02
#define LCD_ENTRY_MODE_SHIFT_DISABLE 0x00
#define LCD_ENTRY_MODE_SHIFT_ENABLE 0x01
#define LCD_DISPLAY_CONTROL_DISPLAY_ON 0x04
#define LCD_DISPLAY_CONTROL_DISPLAY_OFF 0x00
#define LCD_DISPLAY_CONTROL_CURSOR_ON 0x02
#define LCD_DISPLAY_CONTROL_CURSOR_OFF 0x00
#define LCD_DISPLAY_CONTROL_BLINK_ON 0x01
#define LCD_DISPLAY_CONTROL_BLINK_OFF 0x00
#define LCD_FUNCTION_SET_8BIT 0x10
#define LCD_FUNCTION_SET_4BIT 0x00
#define LCD_FUNCTION_SET_2LINE 0x08
#define LCD_FUNCTION_SET_1LINE 0x00
#define LCD_FUNCTION_SET_5X10DOTS 0x04
#define LCD_FUNCTION_SET_5X8DOTS 0x00
```
其中,`GPIO_LCD_RS`、`GPIO_LCD_RW`、`GPIO_LCD_EN`、`GPIO_LCD_D4`、`GPIO_LCD_D5`、`GPIO_LCD_D6`和`GPIO_LCD_D7`分别对应LCD1602的RS、RW、EN和D4~D7引脚,`GPIO_LCD_DATA`和`GPIO_LCD_CMD`是用于设置GPIO口的控制命令。
接下来定义一些函数,用于初始化LCD1602和发送命令或数据:
```c
void lcd1602_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_LCD_CMD|GPIO_LCD_DATA;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB, GPIO_LCD_CMD|GPIO_LCD_DATA);
lcd1602_command(LCD_CMD_FUNCTION_SET|LCD_FUNCTION_SET_4BIT|LCD_FUNCTION_SET_2LINE|LCD_FUNCTION_SET_5X8DOTS);
lcd1602_command(LCD_CMD_DISPLAY_CONTROL|LCD_DISPLAY_CONTROL_DISPLAY_ON|LCD_DISPLAY_CONTROL_CURSOR_OFF|LCD_DISPLAY_CONTROL_BLINK_OFF);
lcd1602_command(LCD_CMD_ENTRY_MODE|LCD_ENTRY_MODE_RIGHT|LCD_ENTRY_MODE_SHIFT_DISABLE);
lcd1602_command(LCD_CMD_CLEAR);
lcd1602_command(LCD_CMD_RETURN_HOME);
delay_ms(2);
}
void lcd1602_command(uint8_t cmd)
{
GPIO_ResetBits(GPIOB, GPIO_LCD_RS|GPIO_LCD_RW);
GPIO_SetBits(GPIOB, GPIO_LCD_EN);
GPIO_ResetBits(GPIOB, GPIO_LCD_DATA);
GPIO_SetBits(GPIOB, (cmd&0xF0)<<8);
delay_us(20);
GPIO_ResetBits(GPIOB, GPIO_LCD_EN);
GPIO_ResetBits(GPIOB, GPIO_LCD_DATA);
GPIO_SetBits(GPIOB, (cmd&0x0F)<<12);
GPIO_SetBits(GPIOB, GPIO_LCD_EN);
delay_us(20);
GPIO_ResetBits(GPIOB, GPIO_LCD_EN);
delay_us(100);
}
void lcd1602_data(uint8_t data)
{
GPIO_SetBits(GPIOB, GPIO_LCD_RS);
GPIO_ResetBits(GPIOB, GPIO_LCD_RW);
GPIO_SetBits(GPIOB, GPIO_LCD_EN);
GPIO_ResetBits(GPIOB, GPIO_LCD_DATA);
GPIO_SetBits(GPIOB, (data&0xF0)<<8);
delay_us(20);
GPIO_ResetBits(GPIOB, GPIO_LCD_EN);
GPIO_ResetBits(GPIOB, GPIO_LCD_DATA);
GPIO_SetBits(GPIOB, (data&0x0F)<<12);
GPIO_SetBits(GPIOB, GPIO_LCD_EN);
delay_us(20);
GPIO_ResetBits(GPIOB, GPIO_LCD_EN);
delay_us(100);
}
```
其中,`lcd1602_init()`函数用于初始化LCD1602,设置相关的参数。`lcd1602_command()`函数用于发送命令,`lcd1602_data()`函数用于发送数据。
最后,可以在`main()`函数中调用这些函数,来使用LCD1602显示屏:
```c
int main(void)
{
/* 初始化系统时钟 */
SystemInit();
/* 初始化延时函数 */
delay_init();
/* 初始化LCD1602 */
lcd1602_init();
/* 显示字符串 */
lcd1602_command(LCD_CMD_RETURN_HOME);
lcd1602_data('H');
lcd1602_data('e');
lcd1602_data('l');
lcd1602_data('l');
lcd1602_data('o');
lcd1602_data(',');
lcd1602_data(' ');
lcd1602_data('W');
lcd1602_data('o');
lcd1602_data('r');
lcd1602_data('l');
lcd1602_data('d');
lcd1602_data('!');
while (1)
{
}
}
```
需要注意的是,使用GPIO口控制LCD1602需要先将对应的GPIO口设置为输出模式,并将电平设置为低电平。发送命令或数据时,需要先将RS引脚设置为逻辑低电平,然后将RW引脚设置为逻辑低电平,再将EN引脚设置为逻辑高电平,发送数据或命令,最后将EN引脚设置为逻辑低电平。发送数据或命令时,需要将高四位和低四位分别发送。发送完毕后需要适当延时,才能保证LCD1602正确接收到数据。