使用STM32F1单片机控制LCD注意事项:
#include "lcd.h" #include "sys.h" #include "delay.h" u16 temp; void IO_Init1(void) //所有使用的控制端口的GPIO配置为通用推挽输出 { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,ENABLE); GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8 | GPIO_Pin_9| GPIO_Pin_4; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_2| GPIO_Pin_11| GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOE,&GPIO_InitStructure); } void IO_Init2(void) //所有使用的端口的GPIO配置为通用推挽输出 { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE); GPIO_InitStructure.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_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOD,&GPIO_InitStructure); } void IO_Init3(void) //液晶屏的数据口配置为浮空输入,因为数据口本身已经上拉,在读取 { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE); GPIO_InitStructure.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_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOD,&GPIO_InitStructure); } //LCD数据口输出函数 void LCD_dataport_write(u8 dat) { u32 temp; IO_Init2(); temp = GPIOD->ODR; temp &= 0xff00; //低8位清零; temp |= dat; GPIOD->ODR = temp; delay_ms(1); } //LCD数据口输入函数 u8 LCD_dataport_read(void) { u8 temp; IO_Init3(); temp = (u8)(GPIOD->IDR & 0x00ff); return temp; } //新LCD初始化, 先参考51程序,再参考手册, void LCD_Init() { delay_ms(40); LCD_wcmd(0x30);//功能设定:基本指令集 delay_ms(5); LCD_wcmd(0x30);//功能设定:基本指令集 delay_ms(5); LCD_wcmd(0x0C);//功能设定:基本指令集 delay_ms(5); LCD_wcmd(0x01);//清除显示 delay_ms(5); LCD_wcmd(0x06);//显示开,关光标 delay_us(5);//新增加的延时 } //新忙判断函数 void CheckBusy(void) { u8 status; LCD_dataport_write(0xFF); RS=0; delay_us(2);//新增加的延时, RW=1; delay_us(2);//新增加的延时, EN = 1; //位置移动到前面来了 delay_us(2);//新增加的延时, do { status = LCD_dataport_read(); //status = GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_7);//判断BF位 }while(status & 0x80); delay_us(2);//新增加的延时, EN=0; } //LCD写命令 void LCD_wcmd(u8 cmd) { CheckBusy(); RS=0; delay_us(2);//新增加的延时, RW=0; delay_us(2);//新增加的延时, LCD_dataport_write(cmd); delay_ms(5); //delay_us(5);//新增加的延时, EN=1; delay_us(2);//新增加的延时, //delay_ms(1); EN=0; } //LCD写数据 void LCD_wdat(u8 dat) { CheckBusy(); RS=1; delay_us(2);//新增加的延时, RW=0; delay_us(2);//新增加的延时, LCD_dataport_write(dat); delay_ms(1); EN=1; delay_ms(1); EN=0; } 向LCD12864中写入一行数据 void LCD_Wmessage(u8 *ptString,u8 address) { LCD_wcmd(address);//要显示的位置 delay_us(5); //新增加的延时 while((*ptString)!='\0') { LCD_wdat( *ptString++); delay_us(2); //新增加的延时 } }
#ifndef _LCD_H #define _LCD_H #include "sys.h" #include "delay.h" #define RS PEout(0) #define RW PBout(9) #define EN PBout(8) #define RST PEout(2) #define LINE1 0x80 #define LINE2 0x90 #define LINE3 0x88 #define LINE4 0x98 void IO_Init1(void); void IO_Init2(void); void IO_Init3(void); void CheckBusy(void); void LCD_wdat(u8 dat); void LCD_wcmd(u8 com); void LCD_Init(void); void LCD_Wmessage(u8* message,u8 address); void LCD_dataport_write(u8 dat); u8 LCD_dataport_read(void); #endif
#include "stm32f10x.h" //#include "sys.h" #include "lcd.h" #include "delay.h" //#include "usart.h" //#include "adc.h" /************************ *一行16个字节,一个汉字2字节,一个字母1字节,每个汉字只能在偶字节处起 ************************/ void soft_reset(void); int main(void) { u8 dis1[]={"2021年西安全运会"}; u8 dis2[]={"川航电子加油123!"}; delay_init(); IO_Init1(); // 控制IO初始化;控制引脚,LED能正常工作 delay_ms(50); RST = 0; //Reset LCD delay_ms(1); //Delay 1 ms RST = 1; //Release LCD reset delay_ms(5); //Delay 5 ms to wait for reset finish LCD_Init(); LCD_Wmessage(dis1,LINE1); LCD_Wmessage(dis2,LINE2); while(1); }