单片机入门-C51语言实现矩阵键盘和数码管调整时钟的时分秒
单片机入门,这里介绍C51语言实现矩阵键盘和数码管调整时钟的时分秒,模拟电子钟的部分功能。一般步骤如下:
1.声明相应的变量去保存时分秒信号,保存用户的功能按键。
2.编写显示时分秒的函数
3.按键扫描,保存用户功能按键,根据用户选择调整时分秒。
视频教程如下:
视频加载中...
电路图如下:
代码如下:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
uchar jianhao=16,hang=4,lie=0,keydat=16;
uchar hour=15,minute=40,second=23;
uchar sel=0;
void keyscan(); //行列式键盘扫描函数
void display(uchar hour,uchar minute,uchar second);
void delayms(uchar t); //延时函数
void main(void)
{
while(1)
{
display(hour,minute,second);
keyscan();
}
}
void keyscan() //行列式键盘扫描函数,返回值为按下键的键值
{
P3=0x0f;//同时扫描4列
if(P3!=0x0f)
{ delayms(10);
if(P3!=0x0f)
{
switch(P3)//判断是哪一行有键按下
{
case 0x0e : hang=0;
break;
case 0x0d :hang=1;
break;
case 0x0b : hang=2;
break;
case 0x07 : hang=3;
break;
}
P3=0xef;//扫描P3.4列
if(P3!=0xef)//此列的行值不全为0,说明此列有键按下
{delayms(10);
if(P3!=0xef)
lie=0;//取列码
}
P3=0xdf;
if(P3!=0xdf)
{delayms(10);
if(P3!=0xdf)
lie=1;
}
P3=0xbf;
if(P3!=0xbf)
{delayms(10);
if(P3!=0xbf)
lie=2;
}
P3=0x7f;
if(P3!=0x7f)
{delayms(10);
if(P3!=0x7f)
lie=3;
}
jianhao=4*hang+lie;//键码=4 X行码+列码
P3=0x0f;
while(P3!=0x0f);//键释放了吗
}
keydat=jianhao;
switch(keydat)
{ case 1:sel=1;break;
case 2:sel=2;break;
case 3:sel=3;break;
}
if (keydat==10)//a键按下,+1;
{
switch(sel)
{ case 1:hour++;break;
case 2:minute++;break;
case 3:second++;break;
}
}
}
}
void display(uchar hour,uchar minute,uchar second)
{
P2=0x01;
P0=tab[hour/10];
delayms(2);
P2=0x02;
P0=tab[hour%10];
delayms(2);
P2=0x04;
P0=0xbf;
delayms(2);
P2=0x08;
P0=tab[minute/10];
delayms(2);
P2=0x10;
P0=tab[minute%10];
delayms(2);
P2=0x20;
P0=0xbf;
delayms(2);
P2=0x40;
P0=tab[second/10];
delayms(2);
P2=0x80;
P0=tab[second%10];
delayms(2);
}
void delayms(uchar t)
{
uchar x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}
单片机之路—通过时间片轮询法解决按键失灵问题
1、概述
(迟到的同学需要先看一下我上一篇独立按键操作的文章哦)上次文章中我们通过按键去控制流水灯的流水花式,我们发现按键会出现失灵的情况。原因是我们把按键扫描的执行任务优先级和执行流水灯的任务优先级放在一起了,互不能相互打断,但是,在我们的理解来说按键扫描的任务要比流水灯的任务优先级高才对。好比说,你正在写作业,你妈妈叫你写完作业后烧一壶开水。我们先要去听取并记住妈妈的指令,然后写完作业后才去执行烧开水的任务。在我们的程序中,妈妈下达的烧开水的指令就是用户按下按键通知程序执行完这次流水灯操作后去执行另外一种样式的流水灯。这个过程中程序需要先获取到按键的指令,并且记录下来,等执行完当前的任务后,再去执行新的任务。否则任务紧急任务(扫描按键)出现延时执行的情况,导致执行结果不是我们想要的。
2、时间片轮询法
显然的,按键扫描任务是一个要求实时性高的任务,所以在按键按下时,我们需要立即去查询当前的按键状态,并记录当前的按键状态。现在我们问题就是执行一次循环时间太长了,有没有办法使得执行一次循环更快,在很短的时间就能执行完一次循环,每个循环中都去检查一下按键的状态,这样就不会错过扫描按键的时机了。每一个时间片进行计数,计数到设定数值时,再去执行实时性要求不高的任务,比如流水灯切换任务。
时间片轮询法流程图
3、时间片轮询法在按键检测中的应用
我们开看在按键切换流水灯流水花式的程序中,怎么使用时间片轮询法。首先,在主循环之前定义一个按键状态记录的寄存器
unsigned char KeyNum = 0;
将主循环分成5ms每次的小循环,并且定义一个循环计数寄存器
void main()
{
unsigned char i;
unsigned char KeyNum = 0;
unsigned char Count = 0;
for(;;)
{
Count++;
if(Count >=250)
{
Count = 0; //防止溢出操作
}
delay_ms(5);
}
}
对计数进行判断,到设定计数执行对应的任务
void main()
{
unsigned char KeyNum = 0;//按键状态记录
unsigned char Count = 0;//计数记录
unsigned char LEDStatus= 1; //流水灯状态记录
for(;;)
{
Count++;
if(Count >200)
{
Count = 0; //计数清零
}
if((Count == 100)||(Count == 200))
{
if(KeyNum == 1)
{
//闪烁花式
if(Count == 100)
{
LedDisplay(0xAA);
}
else if(Count == 200)
{
LedDisplay(0x55);
}
}
else if(KeyNum == 2)
{
//流水花式
LedDisplay(~dat);
dat = 0x01<<LEDStatus;
LEDStatus++;
if(LEDStatus>=8)
{
LEDStatus = 0;
}
}
else
{
LedDisplay(0x00);
}
}
delay_ms(5);
}
}
4、总结
虽然这样能够实现功能,但是我们发现程序中需要定义很多的寄存器变量来保存程序的执行状态,搞得程序很繁琐,不够清爽。是否有一种方法可以让单片机在检测到触发事件时,自动记录程序的执行状态,并且去执行事件。执行完成事件后回来继续执行程序。实际是有的,那就是单片机的中断机制,我们可以通过单片机的中断机制实现程序的前后台系统。关注我,下次文章我带大家学习51单片机的外部中断。
相关问答
怎么用 按键 调整 单片机 的延时 时间 -ZOL问答延时函数的时间用按键调节就行了这个好说你好!这个要看你总体的实现功能要求了,代码完成了吗用不同的占空比控制LED的亮度,手里没有ATtiny2313的,有一个51的...
51 单片机 怎样用 按键 设定定时 时间 ?1.程序中通过扫描按键,获得按键值,并付给按键变量。2.确定按键完成的条件(按确定键或一定延时量)3.按键完成后,处理按键变量,并计算为设定延时值4.时钟...
单片机按键 防抖动延时多长才合适?单片机按键防抖动延时的合适时间应该根据具体的硬件实际情况来确定。通常情况下,建议设置为10-20ms左右。这个时间足够长,可以保证按键防抖效果好,避免误操作...
用51 单片机 怎么写程序在 一段时间 内按钮按一下是1,按两下是2,...用定时器,按键按下的时候计时使用51单片机实现这种逻辑需要设置多个步骤:初始化定时器、配置按键中断、写入相应的代码处理按钮输入(比如P0口)。当接收到第一...
单片机 开关按下是1还是0?一般来说,应该是低电平,即0。如果开关一端连续单片机io口,叧一端直接接切,则开关导通时,此io口可量出低电平,但如果是用扫描方式连接按键,由于扫描频率很...
单片机 设计中一个 按键 有多个功能是如何实现的?这很简单,1。如果有功能键这就不说了。2。用时间来区分。3。按规定时间里按下几次。4。连续按下“摩尔玛”。5。每按以下循环变换功能。6。在不同状态下...
51 单片机 , 按键 控制流水灯程序,懂的进!八个LED灯与 单片机 P1口...[最佳回答]假如,你的程序在执行key_scan();是触发了两次中断导致num>20,你的显示函数将永远被跳过,你应该写成if(num>20)��{���num=0;���display();�.....
单片机按键 开关是什么?单片机按键开关是一种应用于单片机系统的输入设备,通常由按键和额外的元器件(如电容器和电阻器等)组成。其作用是在按键被按下之后,产生一个由0到1的状态转变...
求一个51 单片机 定时闹钟程序。要C语言。能够调 时间 - hL0lQS...我来发一个C语言211351单片机时钟程序,希望5261能帮到你/*程序功能:4102带定时闹铃时钟*//*-------...
单片机 的 按键 开启和复位电路图-ZOL问答单片机的复位有上电复位和按钮手动复位两种。如图(a)所示为上电复位电路,图(b)所示为上电按键复位电路。上电复位是利用电容充电来实现的,即上电瞬间RST端的电...