Proteus-32单片机使用lcd1602屏幕显示按键值

0、LCD1602屏幕介绍

LCD1602 是一种常见的字符型液晶显示屏,广泛应用于各种电子设备中,用于显示文本信息。它通常具有16个字符宽和2行的显示能力,因此得名“LCD1602”。以下是关于LCD1602的详细介绍,包括其特点、引脚定义、工作原理以及如何与微控制器(如51单片机或STM32)连接和控制。


  •  LCD1602的特点

  • 显示能力:16个字符宽,2行显示,共32个字符。

  • 字符集:内置5x8点阵字符集,支持ASCII字符和部分扩展字符。

  • 接口类型:并行数据接口,支持4位或8位数据传输。

  • 背光:部分型号带有背光功能,可在低光环境下使用。

  • 低功耗:工作电压通常为4.5V至5.5V,功耗低。

  • 易于控制:通过简单的指令集控制显示内容。


  • 引脚定义

LCD1602通常有16个引脚,具体定义如下:

引脚号引脚名称功能描述
1VSS地(GND)
2VDD电源正极(+5V)
3V0对比度调整(通过电位器调节)
4RS寄存器选择(0=指令寄存器,1=数据寄存器)
5RW读写选择(0=写,1=读)
6E使能信号(上升沿触发)
7-14D0-D7数据线(8位数据传输)
15A背光正极(部分型号)
16K背光负极(部分型号)

  • .工作原理

LCD1602通过并行数据接口与微控制器通信,支持4位和8位数据传输模式。以下是其基本工作原理:

(1)指令和数据传输
  • 指令寄存器:用于接收控制指令(如清屏、设置光标位置等)。

  • 数据寄存器:用于接收要显示的字符数据。

  • RS引脚:用于选择当前操作是写入指令还是数据。

  • RW引脚:用于选择当前操作是写入还是读取。

  • E引脚:使能信号,上升沿触发数据或指令的读取。

(2)显示控制
  • 清屏指令:清除显示内容。

  • 光标控制:设置光标位置。

  • 字符显示:将字符数据写入指定位置。


  • 初始化和控制

以下是使用51单片机控制LCD1602的初始化和控制代码示例:

(1)硬件连接
  • 数据线(D0-D7)连接到51单片机的P0口。

  • 控制线

    • RS:连接到P2^0。

    • RW:连接到P2^1。

    • E:连接到P2^2。

  • 电源和地:连接到51单片机的电源和地。

1、开发环境

  • proteus8.17 :制作stm32f103c8t6 和lcd1602连接电路图
  • keil mdk 编写stm32工程实现代码

2、LCD1602.h代码

 

#ifndef __LCD1602_H
#define __LCD1602_H


#include"stm32f10x.h"

//lcd1602引脚定义
#define LCD1602_Timer_GPIOA RCC_APB2Periph_GPIOA
#define LCD1602_Timer_GPIOB RCC_APB2Periph_GPIOB
#define LCD1602_GPIOA GPIOA
#define LCD1602_GPIOB GPIOB
#define LCD1602_RS GPIO_Pin_8
#define LCD1602_RW GPIO_Pin_6
#define LCD1602_E GPIO_Pin_7
#define LCD1602_IO GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15

#define LCD1602_I0_SET() GPIO_SetBits(GPIOB, LCD1602_IO)

#define LCD1602_RS_SET() GPIO_SetBits(GPIOA,LCD1602_RS)
#define LCD1602_RS_RESET() GPIO_ResetBits(GPIOA,LCD1602_RS)

#define LCD1602_RW_SET() GPIO_SetBits(GPIOB,LCD1602_RW)
#define LCD1602_RW_RESET() GPIO_ResetBits(GPIOB,LCD1602_RW)

#define LCD1602_E_SET() GPIO_SetBits(GPIOB,LCD1602_E)
#define LCD1602_E_RESET() GPIO_ResetBits(GPIOB,LCD1602_E)

   
//初始化函数
void LCD1602_Init(void);
//显示数字 

void LCD1602_ShowNum(unsigned char x,unsigned char y,unsigned char *str,unsigned char i);
/*显示字符串函数
	x:0,1两行
	y:0到15个列
	str:显示字符串
*/
void LCD1602_ShowStr(unsigned char x,unsigned char y,unsigned char *str);
//清屏函数
void LCD1602_Clear(void);

#endif

3、LCD1602.c代码

#include"lcd1602.h"
void LCD1602_GPIO_Init_Out()//LCD1602端口初始化,配置为输出
{ 
   
	 GPIO_InitTypeDef GPIO_InitStructrue;
	 RCC_APB2PeriphClockCmd(LCD1602_Timer_GPIOA | LCD1602_Timer_GPIOB, ENABLE);//使能端口时钟
	 GPIO_InitStructrue.GPIO_Mode = GPIO_Mode_Out_OD;//开漏输出
	 GPIO_InitStructrue.GPIO_Pin = LCD1602_RS; 
	 GPIO_InitStructrue.GPIO_Speed = GPIO_Speed_10MHz;//低速输出
	 GPIO_Init(LCD1602_GPIOA, &GPIO_InitStructrue);//初始化
	
	 GPIO_InitStructrue.GPIO_Mode = GPIO_Mode_Out_OD;//开漏输出
	 GPIO_InitStructrue.GPIO_Pin = LCD1602_RW |  LCD1602_E | LCD1602_IO ; 
	 GPIO_InitStructrue.GPIO_Speed = GPIO_Speed_10MHz;// 低速输出
	 GPIO_Init(LCD1602_GPIOB, &GPIO_InitStructrue);//初始化
}

void LCD1602_GPIO_Init_Inupt()//LCD1602端口初始化,配置为输入
{ 
   
	 GPIO_InitTypeDef GPIO_InitStructrue;
	 RCC_APB2PeriphClockCmd(LCD1602_Timer_GPIOB, ENABLE);//使能端口时钟
	 
	
	 GPIO_InitStructrue.GPIO_Mode =  GPIO_Mode_IN_FLOATING;//浮空输入
	 GPIO_InitStructrue.GPIO_Pin =  GPIO_Pin_15; 
	 GPIO_Init(LCD1602_GPIOB, &GPIO_InitStructrue);//初始化
}


void LCD1602_WaitReady(void)//用于LCD忙检测
{ 
   
	u8 sta = 0;
  LCD1602_GPIO_Init_Out();//LCD1602端口初始化,配置为输出
	GPIOB->ODR =0xff00;
  LCD1602_RS_RESET();
	LCD1602_RW_SET();//读状态
	LCD1602_GPIO_Init_Inupt();//LCD1602端口初始化,配置为输入
	do{ 
   
		LCD1602_E_SET();
		sta = GPIO_ReadInputDataBit(LCD1602_GPIOB, GPIO_Pin_15);
		LCD1602_E_RESET();
	  }
		while(sta);
		LCD1602_GPIO_Init_Out();//LCD1602端口初始化,配置为输出
}

void LCD1602_WriteCmd(u16 cmd)//用于写指令
{ 
   
	LCD1602_WaitReady();//等待液晶准备好
	LCD1602_RS_RESET();
	LCD1602_RW_RESET();//写指令
	GPIOB->ODR &=((cmd<< 8)|0x0000);
	LCD1602_E_SET();
	LCD1602_E_RESET();//高脉冲

}

void LCD1602_WriteDate(u16 date)//用于写数据
{ 
   
	LCD1602_WaitReady();//等待液晶准备好
	LCD1602_RS_SET();
	LCD1602_RW_RESET();//写数据
	GPIOB->ODR &=((date << 8)|0x0000);
	LCD1602_E_SET();
	LCD1602_E_RESET();//高脉冲
}

void LCD1620_SetAddress(unsigned char x,unsigned char y)
{ 
   
	if(y == 0)
	LCD1602_WriteCmd(0x80 | x);//从第一行开始显示
	else 
	LCD1602_WriteCmd(0x80 | 0x40 | x);//从第二行开始显示
}

void LCD1602_ShowStr(unsigned char x,unsigned char y,unsigned char *str)//LCD1602显示字符串
{ 
   
	LCD1620_SetAddress(x,y);//设置数据地址指针
	while(*str != '\0')
	LCD1602_WriteDate(*str++);//写数据 
}

void LCD1602_ShowChar(unsigned char x,unsigned char y,unsigned char date)//LCD1602显示字符
{ 
   
	LCD1620_SetAddress(x,y);//设置数据地址指针
	LCD1602_WriteDate(date);//写数据 
}
               
void LCD1602_ShowNum(unsigned char x,unsigned char y,unsigned char *str,unsigned char i)//LCD1602显示数字
{ 
   
	LCD1620_SetAddress(x,y);//设置数据地址指针
	str = str+ i;
	LCD1602_WriteDate(*str);//写数据
}

 void LCD1602_Init(void)//液晶初始化函数
{ 
   
	LCD1602_GPIO_Init_Out();
	LCD1602_WriteCmd(0x38);//设置16*2显示,5*7点阵,8位数据接口
	LCD1602_WriteCmd(0x0c);//开显示,显示光标,光标不闪烁
	LCD1602_WriteCmd(0x06);//光标加1,屏幕显示不移动
	LCD1602_WriteCmd(0x01);//清屏
}

void LCD1602_Clear(void)
{

	LCD1602_WriteCmd(0x01);//清屏
}

4、key.c key.h按键代码

#include "stm32f10x.h"                  // Device header
#include "delay.h" 




/**
  * 函    数:按键初始化
  * 参    数:无
  * 返 回 值:无
  */
void Key_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);		//开启GPIOB的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 |GPIO_Pin_14  ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);						//将PB1和PB11引脚初始化为上拉输入
}

/**
  * 函    数:按键获取键码
  * 参    数:无
  * 返 回 值:按下按键的键码值,范围:0~2,返回0代表没有按键按下
  * 注意事项:此函数是阻塞式操作,当按键按住不放时,函数会卡住,直到按键松手
  */

uint8_t Key_GetNum(void)
{
	uint8_t KeyNum = 0;		//定义变量,默认键码值为0
	

		//按键1 检测
	if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_13) == 0)			//读PB1输入寄存器的状态,如果为0,则代表按键1按下
	{
		Delay_ms(100);											//延时消抖
		while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_13) == 0);	//等待按键松手
		//Delay_ms(2);											//延时消抖
		KeyNum = 1;												//置键码为1
	}
	//按键2 检测
	if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_14) == 0)			//读PB11输入寄存器的状态,如果为0,则代表按键2按下
	{
		Delay_ms(100);											//延时消抖
		while (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_14) == 0);	//等待按键松手
		//Delay_ms(2);											//延时消抖
		KeyNum = 2;												//置键码为2
	}
	

	
	return KeyNum;			//返回键码值,如果没有按键按下,所有if都不成立,则键码为默认值0
}

#ifndef __KEY_H
#define __KEY_H
#include "stm32f10x.h"                  // Device header

void Key_Init(void);
uint8_t Key_GetNum(void);

#endif

 5、主函数代码

#include "stm32f10x.h"                  // Device header
#include "lcd1602.h" 
#include "stdio.h" 

#include "Key.h" 


char time=30;

void Buzzer_delay(u32 ms)
{
	while(ms--);
}

//蜂鸣器
void Buzzer_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStruct);
    GPIO_WriteBit(GPIOA,GPIO_Pin_10,(BitAction)0);	//输出高电平 GPIO_SetBits(GPIOA, GPIO_Pin_0)
}
//蜂鸣器驱动

void Buzzer_run(uint16_t xms)
{
			uint16_t i;
			for(i=0;i<xms;i++)
			{
					GPIO_WriteBit(GPIOA,GPIO_Pin_10,(BitAction)1);
					Buzzer_delay(2);
					GPIO_WriteBit(GPIOA,GPIO_Pin_10,(BitAction)1);
					Buzzer_delay(2);
			}
}


//主函数
int main(void)
{
  unsigned char getKey,count=0;
	char buff5[16];
	LCD1602_Init();//lcd1602初始化
	Key_Init();//按键初始化
	//Buzzer_Init();//蜂鸣器初始化

	LCD1602_ShowStr(0,0,"Hello Everyone!");
	LCD1602_ShowStr(0,1,"Testing:");
	count=2;
	while (1)
	{
	
		getKey=Key_GetNum();
	
		if(getKey ==1)
		{
			count=count+1;
			if(count>10)
			{
				count=0;
			}
			
		}
		if(getKey ==2)
		{
			count=count-1;
			if(count<0)
			{
				count=10;
			}
			
		}
//		if(count>5)
//		{
//			Buzzer_run(20);
//		}
		//显示数字
		sprintf(buff5,"%d",count);
		LCD1602_ShowStr(9,1,(unsigned char *)buff5);
		Buzzer_delay(4000);

		
	}//while line
	
}

 6、proteus 电路连接图

7、实现效果:左按键+数值,右按键-数值

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值