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