一、前期准备
单片机:STM32F103ZET6
开发环境:MDK5.14
库函数:标准库V3.5
LCD1602模块:淘宝有售
二、实验效果
3.3V LCD1602
5V LCD1602
三、驱动原理
由于STM32的IO驱动能力只有3.3V,所以要想直连的话,必须买3.3V的模块。如果要用5V的模块,必须加上拉电阻,输出采用开漏输出,如上图所示加上上拉电阻。,四小节驱动包括了3.3V和5V的驱动。模块的第三脚VO是对比度调节用的,3.3V的对地接1.5K左右的电阻,5V的对地接2K左右的电阻,俩个电阻值均实验得出,亲测有效。
需要完整工程或者有问题的请加QQ:1002521871,验证:呵呵。
四、驱动代码
lcd1602.h
#ifndef __LCD_1602_H__
#define __LCD_1602_H__
#include "stm32f10x.h"
#include "gpio.h"
#include "delay.h"
#define POWER_5V0
//#define POWER_3V3
//IO Definitions
#define RS PCout(0)
#define RW PCout(1)
#define EN PCout(2)
#define RS_Pin GPIO_Pin_0
#define RW_Pin GPIO_Pin_1
#define EN_Pin GPIO_Pin_2
typedef enum
{
cmd,
data
}Write_Mode;
extern void LCD1602Configuration(void);
extern void LCD_Show_Str(uint8_t x, uint8_t y, uint8_t *str);
extern void LCD_ClearScreen(void);
#endif
lcd1602.c
#include "lcd1602.h"
void LCD_Wait_Ready(void)
{
uint8_t status;
GPIOD->ODR = 0xFF;
RS = 0;
RW = 1;
do
{
EN = 1;
DelayMs(5);
status = GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_7);
EN = 0;
}while(status & 0x80);
}
void LCD_Write_Cmd(uint8_t cmd)
{
LCD_Wait_Ready();
RS = 0;
RW = 0;
GPIOD->ODR = cmd;
EN = 1;
EN = 0;
}
void LCD_Write_Dat(uint8_t dat)
{
LCD_Wait_Ready();
RS = 1;
RW = 0;
GPIOD->ODR = dat;
EN = 1;
EN = 0;
}
void LCD_ClearScreen(void)
{
LCD_Write_Cmd(0x01);
}
void LCD_Set_Cursor(uint8_t x, uint8_t y)
{
uint8_t addr;
if (y == 0)
addr = 0x00 + x;
else
addr = 0x40 + x;
LCD_Write_Cmd(addr | 0x80);
}
void LCD_Show_Str(uint8_t x, uint8_t y, uint8_t *str)
{
LCD_Set_Cursor(x, y);
while(*str != '\0')
{
LCD_Write_Dat(*str++);
}
}
void LCD1602Configuration(void)
{
GPIO_InitTypeDef GPIO;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC, ENABLE);
//Control IO
GPIO.GPIO_Pin = RS_Pin | RW_Pin | EN_Pin;
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
#if defined (POWER_3V3)
GPIO.GPIO_Mode = GPIO_Mode_Out_PP;
#elif defined (POWER_5V0)
GPIO.GPIO_Mode = GPIO_Mode_Out_OD;
#endif
GPIO_Init(GPIOC, &GPIO);
//Data Port IO, PD0 ~ PD7
GPIO.GPIO_Pin = 0xFF;
GPIO_Init(GPIOD, &GPIO);
LCD_Write_Cmd(0x38); //16*2显示,5*7点阵,8位数据口
LCD_Write_Cmd(0x0c); //开显示,光标关闭
LCD_Write_Cmd(0x06); //文字不动,地址自动+1
LCD_Write_Cmd(0x01); //清屏
}
由于作者能力有限,有不妥之处欢迎指正,邮箱alex_hua@foxmail.com