STM32的LCD1602显示程序

STM32的LCD1602显示程序

​ 以下为课设期间为1602显示屏驱动写的stm32的程序,其中参考了许多大佬的例子

​ 程序设计:STM32入门之LCD1602驱动_TTOWFIVE-CSDN博客_stm32驱动lcd1602

​ 硬件原理:lcd1602简介,LCD1602中文资料 - 光电显示 - 电子发烧友网 (elecfans.com)

​ D7D0用的是PD0PD7,RS为PB10,E为PB11,RW为PB12,使用的板子是STM32F103VET6

​ 下面是我的程序,只完成了基础功能,并没有自定义字模部分的代码

lcd.h

#ifndef __LCD_H
#define __LCD_H
#include "stm32f10x.h"
/////////////////////////////////////////////////////////
#define D0_1 GPIO_SetBits(GPIOD,GPIO_Pin_0)
#define D0_0 GPIO_ResetBits(GPIOD,GPIO_Pin_0)
#define D1_1 GPIO_SetBits(GPIOD,GPIO_Pin_1)
#define D1_0 GPIO_ResetBits(GPIOD,GPIO_Pin_1)
#define D2_1 GPIO_SetBits(GPIOD,GPIO_Pin_2)
#define D2_0 GPIO_ResetBits(GPIOD,GPIO_Pin_2)
#define D3_1 GPIO_SetBits(GPIOD,GPIO_Pin_3)
#define D3_0 GPIO_ResetBits(GPIOD,GPIO_Pin_3)
#define D4_1 GPIO_SetBits(GPIOD,GPIO_Pin_4)
#define D4_0 GPIO_ResetBits(GPIOD,GPIO_Pin_4)
#define D5_1 GPIO_SetBits(GPIOD,GPIO_Pin_5)
#define D5_0 GPIO_ResetBits(GPIOD,GPIO_Pin_5)
#define D6_1 GPIO_SetBits(GPIOD,GPIO_Pin_6)
#define D6_0 GPIO_ResetBits(GPIOD,GPIO_Pin_6)
#define D7_1 GPIO_SetBits(GPIOD,GPIO_Pin_7)
#define D7_0 GPIO_ResetBits(GPIOD,GPIO_Pin_7)
#define RS_1 GPIO_SetBits(GPIOB,GPIO_Pin_10)
#define RS_0 GPIO_ResetBits(GPIOB,GPIO_Pin_10)
#define RW_1 GPIO_SetBits(GPIOB,GPIO_Pin_12)
#define RW_0 GPIO_ResetBits(GPIOB,GPIO_Pin_12)
#define E_1 GPIO_SetBits(GPIOB,GPIO_Pin_11)
#define E_0 GPIO_ResetBits(GPIOB,GPIO_Pin_11)
/////////////////////////////////////////////////////////

void LCD_Init(void);//初始化
void LCD_Clear(void);//清除显示
void LCD_CursorReset(void);//光标返回
void LCD_SetInput(u16,u16);//置输入模式
void LCD_Display(u16,u16,u16);//显示开关控制
void LCD_COD(u16,u16);//光标或显示移动指令
void LCD_Mode(u16,u16,u16);//工作方式设置
void LCD_CGRAM_Addr(u8);//设置CGRAN地址,除置位位以外共六位
void LCD_DDRAM_Addr(u8);//设置DDRAM地址,除置位位以外共七位
void LCD_RB(void);//当1602处于忙状态时,不接受指令,当不忙时,接受指令
void LCD_Write(u8);//写入数据
void LCD_Read(void);//读取数据
void LCD_WriteStr(u8*,int);//写入字符串
#endif

lcd.c

#include "lcd.h"
#include "stm32f10x_gpio.h"
void LCD_Init(void)
{
	GPIO_InitTypeDef GPIO_LCDStr;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	GPIO_LCDStr.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_LCDStr.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_LCDStr.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_Init(GPIOD,&GPIO_LCDStr);
	
	GPIO_LCDStr.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_10;
	
	GPIO_Init(GPIOB,&GPIO_LCDStr);
}

///////////////////////////////////////
///////////////////////////////////////

void LCD_Clear(void)
{	
	E_0;
	LCD_RB();
	RS_0;RW_0;
	GPIO_Write(GPIOD,0x01);
	E_1;
	E_0;
}

/////////////////////////////////////////
/////////////////////////////////////////

void LCD_CursorReset(void)
{
	E_0;
	LCD_RB();
	RS_0;RW_0;
	GPIO_Write(GPIOD,0x02);
	E_1;
	E_0;
}

///////////////////////////////////////////
///////////////////////////////////////////

void LCD_SetInput(u16 ID,u16 S)
{
	E_0;
	LCD_RB();
	RS_0;RW_0;D7_0;D6_0;D5_0;D4_0;D3_0;D2_1;
	if(ID==1)/*高电平光标右移,低电平左移*/
		D1_1;
	else if(ID==0)
		D1_0;
	
	if(S==1)/*屏幕上所有的文字是否左移或右移,高电平有效,低电平无效*/
		D0_1;
	else if(S==0)
		D0_0;
	E_1;
	E_0;
	
}
/////////////////////////////////////////////
/////////////////////////////////////////////

void LCD_Display(u16 D,u16 C,u16 B)
{
	E_0;
	LCD_RB();
	RS_0;RW_0;D7_0;D6_0;D5_0;D4_0;D3_1;
	if(D==1)//高电平开,低电平关
		D2_1;
	else if(D==0)
		D2_0;
	
	if(C==1)//高电平有光标,低电平无光标
		D1_1;
	else if(C==0)
		D1_0;
	
	if(B==1)//光标是否闪烁,高电平闪烁,低电平无
		D0_1;
	else if(B==0)
		D0_0;
	E_1;
	E_0;
	
}
//////////////////////////////////////////////
//////////////////////////////////////////////

void LCD_COD(u16 SC,u16 RL)
{
	E_0;
	LCD_RB();
	RS_0;RW_0;D7_0;D6_0;D5_0;D4_1;D1_1;D0_1;
	if(SC==1)//高电平显示移动的文字,低电平移动坐标
		D3_1;
	else if(SC==0)
		D3_0;
	
	if(RL==1)//高电平右移,低电平左移
		D2_1;
	else if(RL==0)
		D2_0;
	E_1;
	E_0;
	
}
//////////////////////////////////////////////
//////////////////////////////////////////////

void LCD_Mode(u16 DL,u16 N,u16 F)
{
	E_0;
	LCD_RB();
	E_1;
	RS_0;RW_0;D7_0;D6_0;D5_1;D1_1;D0_1;
	if(DL==1)//高电平八位数据接口,低电平四位数据接口
		D4_1;
	else if(DL==0)
		D4_0;
	
	if(N==1)//高电平两行显示,低电平一行显示
		D3_1;
	else if(N==0)
		D3_0;
	
	if(F==1)//高电平5x10点阵,低电平5x8点阵
		D2_1;
	else if(F==0)
		D2_0;
	E_0;
	
}
////////////////////////////////////////////
////////////////////////////////////////////
void LCD_CGRAM_Addr(u8 addr)//
{
	E_0;
	LCD_RB();
	RS_0; 
	RW_0;
	D6_1;
	E_1; 
	E_0;
}
///////////////////////////////////////
///////////////////////////////////////

void LCD_DDRAM_Addr(u8 addr)//
{
	E_0;
	LCD_RB();
	RS_0;RW_0;
	GPIO_Write(GPIOD,0x0000);//清空地址
	GPIO_Write(GPIOD,addr);
	E_1;
	E_0;
	
}
/////////////////////////////////////////
/////////////////////////////////////////
void LCD_RB(void)//
{
	GPIO_InitTypeDef pp;
	RS_0;RW_1;
	pp.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	pp.GPIO_Speed=GPIO_Speed_50MHz;
	pp.GPIO_Pin=GPIO_Pin_7;
	GPIO_Init(GPIOD,&pp);//将端口设为输入
	
	E_1;
	while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_7));//若忙信号存在,则一直循环,直至忙信号结束
	E_0;

	pp.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;
	pp.GPIO_Mode=GPIO_Mode_Out_PP;
	pp.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOD,&pp);//将端口重新设为输出

}
/////////////////////////////////////////////
/////////////////////////////////////////////
void LCD_Write(u8 data)//
{
	LCD_RB();
	RS_1;
	RW_0;
	E_1;
	GPIO_Write(GPIOD,data);
	E_0;
		
}
//////////////////////////////////////
//////////////////////////////////////
void LCD_Read(void)//
{
	LCD_RB();
	RS_1;RW_1;E_1;
	 
	E_0;
}
//////////////////////////////////////
//////////////////////////////////////
void LCD_WriteStr(u8 *str,int length)//
{
	int i=0;
	for(i=0;i<length;i++)
	{if(i<=15)
		{
			LCD_DDRAM_Addr(0x80+i);
			LCD_Write(str[i]);
		}
		else
		{
			LCD_DDRAM_Addr(0xc0+i-16);
			LCD_Write(str[i]);
		}
	}
}

main.c

#include "lcd.h"
#include "string.h"
int main()
{ 
	u8 strMCU[]=" **** YOU 1602!   TEST    TEST  ";
	LCD_Init();
	LCD_Clear();
	LCD_SetInput(1,0);
	LCD_Display(1,0,0);
	LCD_Mode(1,1,0);
	LCD_WriteStr(strMCU,strlen(strMCU));
上一篇:串口接收字符1-4(②配置GPIO结构体)


下一篇:基于STM32环境温湿度采集