LCD1602.c
#include "LCD1602.h"
#include "delay.h"
void GPIO_INIT(void)
{ //GPIO初始化
GPIO_InitTypeDef GPIO;
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //禁用jtag,不然写入程序和程序执行都会受影响
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //打开GPIOA~C
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO.GPIO_Pin = EN|RW|RS;
GPIO.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO);
GPIO.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO);
}
void LCD_INIT(void)
{ //初始化
GPIO_INIT();
GPIO_Write(GPIOA, 0x0000);
GPIO_Write(GPIOC, 0x0000);
delay_us(500);
LCD_WRITE_CMD(0x38);
LCD_WRITE_CMD(0x0d); //开启光标和闪烁
LCD_WRITE_CMD(0x06);
LCD_WRITE_CMD(0x01);
}
void LCD_WRITE_CMD(char CMD)
{
//写入命令函数
ReadBusy();
GPIO_ResetBits(GPIOC, RS);
GPIO_ResetBits(GPIOC, RW);
GPIO_ResetBits(GPIOC, EN);
GPIO_Write(GPIOA, CMD); //
GPIO_SetBits(GPIOC, EN);
GPIO_ResetBits(GPIOC, EN);
}
void LCD_WRITE_ByteDATA(char ByteData)
{ //写入单个Byte函数
ReadBusy();
GPIO_SetBits(GPIOC, RS);
GPIO_ResetBits(GPIOC, RW);
GPIO_ResetBits(GPIOC, EN);
GPIO_Write(GPIOA, ByteData);
GPIO_SetBits(GPIOC, EN);
GPIO_ResetBits(GPIOC, EN);
}
void LCD_WRITE_StrDATA(char *StrData,char row, char col)
{//写入字符串
char baseAddr = 0x00; //定义256位地址
if (row)
{
baseAddr = 0xc0;
}
else
{
baseAddr = 0x80;
}
baseAddr += col;
while (*StrData != '\0')
{
LCD_WRITE_CMD(baseAddr);
LCD_WRITE_ByteDATA(*StrData);
baseAddr++;
StrData++;
}
}
void ReadBusy(void)
{ //读忙函数,读忙之前记得更改引脚的工作方式!!!因为STM32的IO不是准双向IO
GPIO_InitTypeDef GPIO;
GPIO_Write(GPIOA, 0x00ff);
GPIO.GPIO_Pin = GPIO_Pin_7; //选定GPIOA的第七Pin
GPIO.GPIO_Mode = GPIO_Mode_IN_FLOATING; //第七Pin的工作方式为浮空输入模式,用于检测LCD1602的忙状态
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO);
GPIO_ResetBits(GPIOC, RS);//RS拉低
GPIO_SetBits(GPIOC, RW);//RW拉高
GPIO_SetBits(GPIOC, EN); //使能开
while( GPIO_ReadInputDataBit( GPIOA, GPIO_Pin_7 ) ); //读第七Pin状态,如果一直为1则循环等待
GPIO_ResetBits(GPIOC, EN);//使能关
GPIO.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; //使GPIOA的状态还原成推挽模式
GPIO.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO);
}
void WUserImg(char pos,char *ImgInfo)
{ //写入用户自定义图像
char cgramAddr; //CGRAM的用户自定义字符位
if( pos <= 1 ) cgramAddr = 0x40; //
if( pos > 1 && pos <= 3 ) cgramAddr = 0x50;
if( pos > 3 && pos <= 5 ) cgramAddr = 0x60;
if( pos > 5 && pos <= 7 ) cgramAddr = 0x70;
LCD_WRITE_CMD( (cgramAddr + (pos%2) * 8) ); //指定字模写入的地址,一般从0x40开始,0x78结束
while( *ImgInfo != '\0' )
{ //循环写入tem数据,即用户取模的数据
LCD_WRITE_ByteDATA( *ImgInfo );
ImgInfo++;
}
}
LCD1602.h
#ifndef LCD1602_H
#define LCD1602_H
#include "sys.h"
#define BUSY 0x80 //忙标志
#define RS GPIO_Pin_13 //设置PC13为RS
#define RW GPIO_Pin_14 //PC14为RW
#define EN GPIO_Pin_15 //PC15为EN使能
void ReadBusy(void);
void LCD_WRITE_CMD(char CMD);
void LCD_WRITE_StrDATA(char *StrData, char row, char col);
void LCD_WRITE_ByteDATA(char ByteData);
void LCD_INIT(void);
void GPIO_INIT(void);
void WUserImg(char pos,char *ImgInfo);
#endif
|