51单片机矩阵按键输入数字LCD1602显示(已验证)

主函数

#include "stdio.h"
#include "lcd.h"
#include "key.h"
#include "tim0.h"

sbit k1 = P3^1;

//延时函数
void delay(u16 i)
{
	while (i--);
}

//矩阵键盘输入数字,用LCD1602显示
void main(void) 
{
	uchar a = 16;
	int i = 0;
	LcdInit();									                 //LCD初始化
	LcdShowString(1, 1, "                ", 16); //固定显示第一行
	LcdSetAddr(2, 1);
	while (1)        //循环扫描矩阵键盘
	{
		a = keyscan();
		if (a != 16)   //判断是否有按下
		{
			if (i == 16) //判断第二行是否满
			{
				i = 0;
				LcdShowString(2, 1, "                ", 16); //若第二行满则清空
				LcdSetAddr(2, 1);
			}
			switch (a)   //根据键值显示相应字符
			{
			case 0: 
				LcdWriteData('0');
				i++;
				break;
			case 1: 
				LcdWriteData('1');
				i++;
				break;
			case 2: 
				LcdWriteData('2');
				i++;
				break;
			case 3: 
				LcdWriteData('3');
				i++;
				break;
			case 4: 
				LcdWriteData('4');
				i++;
				break;
			case 5: 
				LcdWriteData('5');
				i++;
				break;
			case 6: 
				LcdWriteData('6');
				i++;
				break;
			case 7: 
				LcdWriteData('7');
				i++;
				break;
			case 8: 
				LcdWriteData('8');
				i++;
				break;
			case 9: 
				LcdWriteData('9');
				i++;
				break;
			case 10: 
				LcdWriteData('X');
				i++;
				break;
			case 11: 
				LcdWriteData('X');
				i++;
				break;
			case 12: 
				LcdWriteData('X');
				i++;
				break;
			case 13: 
				LcdWriteData('X');
				i++;
				break;
			case 14: 
				LcdWriteData('X');
				i++;
				break;
			case 15: 
				LcdWriteData('X');
				i++;
				break;
			}
		}
	}
}

lcd.c文件

#include "lcd.h"

void Lcd1602_Delay1ms(uint c) //在12MHZ晶振下,12分频单片机的延时。误差 0us。
{
	uchar a, b;
	for (; c > 0; c--)
	{
		for (b = 199; b > 0; b--)
		{
			for (a = 1; a > 0; a--)
				;
		}
	}
}

void LcdWriteCom(uchar com) //写入命令
{
	LCD1602_E = 0;	//使能
	LCD1602_RS = 0; //选择发送命令
	LCD1602_RW = 0; //选择写入

	LCD1602_DATAPINS = com; //放入命令
	Lcd1602_Delay1ms(1);	//等待数据稳定

	LCD1602_E = 1;		 //写入时序
	Lcd1602_Delay1ms(5); //保持时间
	LCD1602_E = 0;
}

void LcdWriteData(uchar dat) //写入数据
{
	LCD1602_E = 0;	//使能清零
	LCD1602_RS = 1; //选择输入数据
	LCD1602_RW = 0; //选择写入

	LCD1602_DATAPINS = dat; //写入数据
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;		 //写入时序
	Lcd1602_Delay1ms(5); //保持时间
	LCD1602_E = 0;
}

void LcdInit() //LCD初始化子程序
{
	LcdWriteCom(0x38); //开显示
	LcdWriteCom(0x0c); //开显示不显示光标
	LcdWriteCom(0x06); //写一个指针加1
	LcdWriteCom(0x01); //清屏
	LcdWriteCom(0x80); //设置数据指针起点
}

void LcdSetAddr(u8 y, u8 x)//设定1602指定行列:  y:行;x:列;
{
	u8 addr;
	addr = (y - 1) * 64 + (x - 1) + 128;
	LcdWriteCom(addr);
}

void LcdShowStr(u8 y, u8 x, u8 str)//在1602指定行列显示指定字符
{
	u8 addr;
	addr = (y - 1) * 64 + (x - 1) + 128;
	LcdWriteCom(addr);
	LcdWriteData(str);
}

void LcdShowString(u8 y, u8 x, u8 str[], u8 n)
{
	u8 i = 0;
	LcdShowStr(y, x, str[0]);
	for (i = 1; i < n; i++)
	{
		LcdWriteData(str[i]);
		if ((x + i) == 16)
		{
			LcdSetAddr(y, 0);
		}
	}
}

key.c文件

#include "reg52.h"
#include "delay.h"
#include "key.h"

/***********IO口定义*************/
#define KEY P1
sbit K1 = P3 ^ 1;
sbit K2 = P3 ^ 0;
sbit K3 = P3 ^ 2;
sbit K4 = P3 ^ 3;

int keyscan(void) //矩阵键盘扫描
{
	uchar keyvalue = 16;
	char a = 0;
	KEY = 0x0f;		 //高四位置为低电平
	if (KEY != 0X0F) //如果此时io口不是设置的值说明行有按键按下
	{
		delay_ms(80); //延时消抖
		/**********************************key的值是高低扫描都为0时候的值******************************************************/
		if (KEY != 0x0f)
		{
			KEY = 0x0F; //输出行信号进行列检测
			switch (KEY)
			{
			case (0x07):
				keyvalue = 0;
				break; //当不同列的值按下的时候低四位的值会有所不同由此,由此判断出是哪一列
			case (0x0b):
				keyvalue = 1;
				break;
			case (0x0d):
				keyvalue = 2;
				break;
			case (0x0e):
				keyvalue = 3;
				break;
			}
			KEY = 0xF0; //输出列信号进行检测
			switch (KEY)
			{
			case (0x70):
				keyvalue = keyvalue;
				break; //当不同列的值按下的时候高四位的值会有所不同由此,由此判断出是哪一行
			case (0xb0):
				keyvalue = keyvalue + 4;
				break;
			case (0xd0):
				keyvalue = keyvalue + 8;
				break;
			case (0xe0):
				keyvalue = keyvalue + 12;
				break;
			}
		}
		while ((a < 50) && (KEY != 0XF0))
		{
			delay_ms(100);
			a++;
		}
	}
	return keyvalue;
}

delay.c文件

#include "delay.h"


void  delay_ms(uint x)//延时xms
{
	uint i,j;
	for(i = x;i > 0;i --)
		for(j = 110;j > 0;j --);
}

  • 20
    点赞
  • 165
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值