矩阵键盘的逐行扫描方法使计算器变得简单(C语言)
一、环境
二、硬件部分
1. Proteus新项目
2.添加组件
3.连接线
4、硬件效果
三、软件部分
1、 Keil5新项目
2、代码:
(1思维分析
(2添加头文件
(3个延迟程序
(4个键盘扫描程序
(5个配置按钮功能
(6个修补孔
(7个深度修补坑
(8个程序入口
四、让程序运行
1、生成.hex文件
2、单片机添加程序文件
五、摘要

一、环境
我使用Keil5作为编译工具,并使用proteus进行仿真。除了Keil5,我不知道是否还有其他有用的软件可以生成.hex文件(您需要生成.hex文件才能运行MCU)。 Proteus是一款非常有用的模拟软件,带有许多原始版本。当然,我之前尝试过multisim14,这也是一个非常好的软件。它带有一个可以编写代码的文本编辑器,但是我找不到想要的原始文件。所以我选择了Proteus。
二、硬件部分
我们可以先打开Proteus:

1. Proteus新项目
在开始界面上单击创建项目,首先创建一个Proteus项目。

(注意:每个项目最好有一个单独的文件夹,以后的文件非常混乱且杂乱无章)
输入项目名称,选择文件夹,然后继续下一步。
2.添加组件

您可以直接单击红色箭头或单击“组件模式”,然后单击“ P”进入组件库。

您可以输入80C51进行过滤,我使用的是第一个80C51。
再次找到过滤器键盘,我使用小键盘-smallcalc。
接下来,寻找LED,并选择LED-BARGRAPH-GRN作为输出,这也便于调试。

选定的组件在这里。然后单击以放置组件。


3.连接线

4、硬件效果
当然,红色和蓝色点没有连接到线上,这是模拟后的效果。其中,红色为高电平,蓝色为低电平,无色为无电平或脉冲不稳定,为短路。
注:默认情况下,某些Proteus原稿已连接到电源和接地,因此未找到电源和接地引脚。例如,T80C51默认情况下连接到电源地,因此没有2 0、 40引脚。
三、软件部分
硬件部分刚刚完成。像真实的硬件一样,我们每个人都需要一个程序来使微控制器正常工作。现在让我们用Keil5编写一个程序。尽管该课程是汇编语言,但我并不习惯汇编程序,因此我尝试了C语言。目标是制作一个简单的计算器。
1、 Keil5新项目
菜单栏中项目下的新uVision项目,选择芯片** T80C51,**选择地址(您可以在Proteus项目中放置一个文件夹)。
然后创建一个.c源文件,并将该源文件添加到项目的“源组”中。
2、代码:
(1思维分析
我想制作一个带有“ +,-,*,/”的计算器。起初,我想到了分别存储数字和运算符,然后进行处理。后来,我发现无法预测输入的位数(因为一次只能输入一位,并且不能像黑色窗口一样按Enter键)。因此,我决定将数字转换为字符,将它们存储在带有运算符的char序列中,然后分析并处理该序列以查找数字和运算符。
(2添加头文件
添加头文件并设置全局变量。
#include
int cro [4] = {0xFE,0xFD,0xFB,0xF7}; //存储行值。分别是P 2. 0端口低电平,P 2. 1端口低电平…………
char indata [50]; //用于存储键盘输入的字符数
int len = 0; //序列的长度
int fnum = 0; //用于存储第一个操作数(通过处理序列获得的数字)
int lnum = 0; //用于存储第二个操作数(通过处理数字获得的数字)
int ans = 0; //存储计算结果
char op; //商店运营商
这是51单片机的头文件,其中包含51单片机的内存,端口等。
(3个延迟程序
延迟程序通常用在单片机中,并且有很多延迟方法,包括硬件延迟和软件延迟。 Nop可以用于组装,或者
MOV R0,100
DJNZ R0,$
在C语言中,您可以使用空循环来延迟,如下所示。当然还有其他方法。
void delay_ms(int n){
int i,j;
for(i = 0; i
for(j = 0; j
} //此处的值仅是近似值,当n == 1时不一定为1ms。也可以是一个准确的值。
如果循环足够或容易控制时间,则无需嵌套。
(4个键盘扫描程序
我尝试的第一件事是矩阵键盘的行反转方法,但是中间出现了一些问题,因此我暂时放弃了,转而使用逐行扫描方法。
根据书中的原理,结合以上电路图编写程序。

可以看到我们的键盘连接到P2端口,低4位是行,高4位是列,LED连接到P1端口。例如。
首先使行端口(即P2端口的低四位)输出低电平,然后读取列值。如果读取的列值不是0FFH,请按键
int keyscan(){
int temp;
P2 = 0xf0; //将11110000B发送到P12端口
temp = P2&0xf0; //读取列值
}
注意:在C语言中,将0b或0B添加到二进制系统的前面,将0添加到八进制系统,并且将0x或0X添加到十六进制系统。例如十进制123,二进制0b123或0B123,八进制0123,十六进制0x123或0X123。
通过这种方式,可以完成行输出低电平和读取列值的操作。如果该列的值不为0xf0,则表示按下了一个键,并且一位变为低。
按下一个键时,可以添加10毫秒的延迟来消除抖动。然后继续进行逐行扫描。
扫描过程是第四位逐位输出低电平,不能读取为列值0xff
int keyscan(){
int n;
int行;
int temp;
P2 = 0xf0;
temp = P2&0xf0;
if(temp!= 0xf 0) {
delay_ms(1 0) //在这里,我们需要增加10毫秒的延迟来进行去抖动,
for(n = 0; n
P2 = cro [n]; // P2端口低电平输出0
rol = P2&0xf0; //读取高四维
if(rol!= 0xf 0) {
return(row |(cro [n]&0x0f)); //在找到所按下键的列值后合成键控代码,然后返回
休息;
}
}
}
}
这是逐行扫描的主要过程。
(5个配置按钮功能
这时,我们发现密钥正确,如何使它执行特定的程序?例如,如果您现在按“ 1”,则它不代表数字“ 1”。此时,我们需要为键配置功能或含义。
我这样定义它:
无效行为(int键){
switch(key){
情况0x77:indata [len ++] ='+'; P1 = 0x80; break; //输入操作员,并输出与操作员按钮对应的行。并存储在先前定义的数组中,长度为+1
case 0xB7:show(); break; //“ =”键的功能是显示计算结果
情况0xD7:indata [len ++] ='0'; P1 = 0x00; break; //输入是一个数字,并输出相应的二进制数字
case 0xE7:clear(); break; //清除键的功能是清除
case 0x7B:indata [len ++] ='-'; P1 = 0x40; break;
case 0xBB:indata [len ++] ='3'; P1 = 0x03; break;
case 0xDB:indata [len ++] ='2'; P1 = 0x02; break;
case 0xEB:indata [len ++] ='1'; P1 = 0x01; break;
case 0x7D:indata [len ++] ='*'; P1 = 0x20; break;
case 0xBD:indata [len ++] ='6'; P1 = 0x06; break;
case 0xDD:indata [len ++] ='5'; P1 = 0x05; break;
case 0xED:indata [len ++] ='4'; P1 = 0x04; break;
case 0x7E:indata [len ++] ='/'; P1 = 0x10; break;
case 0xBE:indata [len ++] ='9'; P1 = 0x09; break;
case 0xDE:indata [len ++] ='8'; P1 = 0x08; break;
case 0xEE:indata [len ++] ='7'; P1 = 0x07; break;
default:break;
}
}
至此,我们的基本要求已经完成。接下来是最完美的部分。
(6个修补孔
刚才使用的未定义函数show()clear()。现在让我们编写这两个函数。
首先,“ =”键的功能函数show()
void show(){
decode(); //此函数可以将存储密钥的字符数组转换为可以计算的数字。
operat(); //将字符类型编号转换为int类型编号之后,就该进行计算了。这是一个算术函数。
P1 = ans; //最后,将计算结果输出到LED。由于先前的定义是全局变量,因此无需传递参数
}
下一步是重置按钮的功能,重置。
void clear(){
int i;
for(i = 0; i
indata [i] ='\ 0';
}
len = 0;
fnum = 0;
lnum = 0;
ans = 0;
op ='\ 0';
for(i = 0; i
P1 = 0xff;
delay_ms(2 0);
P1 = 0x00;
delay_ms(2 0);
}
}
(7个深度修补坑
在上一节中,我确切地按了什么键以输出相应的值。但! ! !我们如何对此感到满意?好的计算器呢?
是的!现在,让我们填补算术函数中的漏洞。
首先是将字符数组的数据转换为可以在数学上进行运算的数字。
无效的解码(){
int i;
int j;
for(i = 0; i
if(indata [i]> ='0'&& indata [i]
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/bofangqi/article-370313-1.html
可以公开武装南海岛礁