LCD1602驱动(STM32)5V和3.3V

一、前期准备
单片机:STM32F103ZET6
开发环境:MDK5.14
库函数:标准库V3.5
LCD1602模块:淘宝有售
这里写图片描述
二、实验效果
3.3V LCD1602
3.3V LCD1602

5V 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);    //清屏
}

由于作者能力有限,有不妥之处欢迎指正,邮箱[email protected]

猜你喜欢

转载自blog.csdn.net/huazhen1234/article/details/80322117
今日推荐