STM32F1外设底层驱动-LCD12864(能显示汉字,字符,待更新)

使用STM32F1单片机控制LCD注意事项:

  1. STM32F1单片机非5V兼容的IO口"千万不能"接5V的LCD;
  2. 对数据口进行读取的时候,数据口应设置为“输入模式”;但写数据的时候,数据口应设置为“通用推挽输出模式”;
  3. 当程序没有什么问题,却无法显示的时候,不妨将相关的文件拷贝到一个可以正常工作的新工程里试试;
lcd.c
#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); //新增加的延时
	}
}

lcd.h
#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

main.c
#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);
	
}


  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值