基于stm32f103rct6 的 LCD1602a 四线驱动

基于stm32f103rct6的LCD1602a 四线驱动

硬件连线

PA0 PA1 PA2 分别连接LCD1602a的 RS RW EN
PA4 PA5 PA6 PA7 分别连接D4 D5 D6 D7

代码部分

本文使用延时策略替代忙等待,因此需要导入 delay 模块

“delay.h”

#ifndef __DELAY_H
#define __DELAY_H

void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);

#endif

“delay.c”

#include "stm32f10x.h"

/**
  * @brief  微秒级延时
  * @param  xus 延时时长,范围:0~233015
  * @retval 无
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器
}

/**
  * @brief  毫秒级延时
  * @param  xms 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒级延时
  * @param  xs 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
} 

“lcd1602.h”

/*
	lcd1602.h
*/

#ifndef __LCD1602_H
#define __LCD1602_H	  
#include "stm32f10x.h"
#define LCD_DATA_PORT GPIOA
 
//RS接口
#define	LCD_RS_Set()	GPIO_SetBits(GPIOA, GPIO_Pin_0)
#define	LCD_RS_Clr()	GPIO_ResetBits(GPIOA, GPIO_Pin_0)
 
//RW接口
#define	LCD_RW_Set()	GPIO_SetBits(GPIOA, GPIO_Pin_1)
#define	LCD_RW_Clr()	GPIO_ResetBits(GPIOA, GPIO_Pin_1)
 
//enable接口
#define	LCD_EN_Set()	GPIO_SetBits(GPIOA, GPIO_Pin_2)
#define	LCD_EN_Clr()	GPIO_ResetBits(GPIOA, GPIO_Pin_2)
 
 
#define u8  unsigned char 
 
void GPIO_Configuration(void);
void LCD1602_Wait_Ready(void);
void LCD1602_Write_Cmd(u8 cmd);
void LCD1602_Write_Dat(u8 dat);
void LCD1602_ClearScreen(void);
void LCD1602_Set_Cursor(u8 x, u8 y);
void LCD1602_Show_Str(u8 x, u8 y, u8 *str);
void LCD1602_Init(void);
void DATAOUT(u8 x);
void LCD1602_Show_num(u8 x,u8 y,u8 num,u8 length);


#endif

“lcd1602.c”

/*
	lcd1602.c
*/
#include "lcd1602.h"
#include "Delay.h"

/* 因为使用的都是GPIOA的输出,因此在写入ODR时可能会改变RW RS EN的值,因此单独写了一个函数*/

void DATAOUT(u8 x)
{
	if(x&0x80){
		GPIOA->ODR |= 0x80;
	}else{
		GPIOA->ODR &= 0x7f;
	}
	if(x&0x40){
		GPIOA->ODR |= 0x40;
	}else{
		GPIOA->ODR &= 0xbf;
	}
	if(x&0x20){
		GPIOA->ODR |= 0x20;
	}else{
		GPIOA->ODR &= 0xdf;
	}
	if(x&0x10){
		GPIOA->ODR |= 0x10;
	}else{
		GPIOA->ODR &= 0xef;
	}
	
}


void GPIO_Configuration(void)
{
	GPIO_InitTypeDef	GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|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(GPIOA, &GPIO_InitStructure);				
	
}
 

void LCD1602_Write_Cmd(u8 cmd)
{
	
//	直接延时实现忙等待
	Delay_ms(5);
	
	DATAOUT(cmd);	//输出高四位
	LCD_RS_Clr();   // 0
	LCD_RW_Clr();	// 0

	LCD_EN_Set();
	LCD_EN_Clr();
	
	DATAOUT(cmd<<4); //将低四位左移后输出
	LCD_EN_Set();
	LCD_EN_Clr();
}
 
/* ?1602???????*/
void LCD1602_Write_Dat(u8 dat)
{
//	延时实现忙等待
	Delay_ms(5);
	LCD_RS_Set();   //1
	LCD_RW_Clr();   //0
	
	DATAOUT(dat);   
	LCD_EN_Set();  
	LCD_EN_Clr();
	
	DATAOUT(dat<<4); 
	LCD_EN_Set(); 
	LCD_EN_Clr();
	
}
 

void LCD1602_ClearScreen(void)
{	//清屏命令0x01
	LCD1602_Write_Cmd(0x01);
	
}
 

void LCD1602_Set_Cursor(u8 x, u8 y)
{
	u8 address
	
	if (y == 0)
		address0x00 + x;
	else
		address0x40 + x;
	LCD1602_Write_Cmd(address|0x80);
}
 

void LCD1602_Show_Str(u8 x, u8 y, u8 *str)
{
	LCD1602_Set_Cursor(x, y);
	while(*str != '\0')
	{
		LCD1602_Write_Dat(*str++);
	}
}

void LCD1602_Show_num(u8 x,u8 y,u8 num,u8 length)
{
	u8 str[length+1];
	for(int i=length-1;i>=0;i--){
		str[i]='0'+num%10;
		num/=10;
	}
	LCD1602_Show_Str(x, y, str);
	
}
 
void LCD1602_Init(void)
{
	LCD1602_Write_Cmd(0x28);	//16*2显示,5*7点阵,4位数据口
	LCD1602_Write_Cmd(0x0C);	//开显示,光标关闭
	LCD1602_Write_Cmd(0x06);	//文字不动,地址自动+1
	LCD1602_Write_Cmd(0x01);	//清屏
}

“main.c”

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LCD1602.h"

int main(void)
{	
	u8 str[] = "LJF001 by HZY";
	u8 str1[] = "I love STM32";
	
	GPIO_Configuration();
	LCD1602_Init();
	LCD1602_ClearScreen();
	LCD1602_Show_Str(2, 0, str);     
	LCD1602_Show_Str(2, 1, str1);
		
	while(1){
	
	}
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值