第二十四节.docx
- 文档编号:8164612
- 上传时间:2023-01-29
- 格式:DOCX
- 页数:16
- 大小:19.51KB
第二十四节.docx
《第二十四节.docx》由会员分享,可在线阅读,更多相关《第二十四节.docx(16页珍藏版)》请在冰豆网上搜索。
第二十四节
第二十四节:
独立按键控制跑马灯的启动和暂停。
开场白:
上一节讲了独立按键控制跑马灯的速度。
这一节继续要教会大家一个知识点:
如何通过一个中间变量把按键跟跑马灯的启动和暂停有效关联起来。
具体内容,请看源代码讲解。
(1)硬件平台:
基于朱兆祺51单片机学习板。
在上一节的基础上,增加一个启动和暂停按键,用矩阵键盘中的S13键作为启动和暂停独立按键,记得把输出线P0.4一直输出低电平,模拟独立按键的触发地GND。
(2)实现功能:
在上一节的基础上,第1个至第8个LED灯一直不亮。
在第9个至第16个LED灯,依次逐个亮灯并且每次只能亮一个灯。
每按一次独立按键S13键,原来运行的跑马灯会暂停,原来暂停的跑马灯会运行。
其它跟上一节一样,用S1来改变方向,用S5和S9来改变速度。
(3)源代码讲解如下:
#include"REG52.H"
#defineconst_voice_short 40 //蜂鸣器短叫的持续时间
#defineconst_key_time1 20 //按键去抖动延时的时间
#defineconst_key_time2 20 //按键去抖动延时的时间
#defineconst_key_time3 20 //按键去抖动延时的时间
#defineconst_key_time4 20 //按键去抖动延时的时间
voidinitial_myself();
voidinitial_peripheral();
voiddelay_short(unsignedintuiDelayShort);
voiddelay_long(unsignedintuiDelaylong);
voidled_flicker_09_16();//第9个至第16个LED的跑马灯程序,逐个亮并且每次只能亮一个.
voidhc595_drive(unsignedcharucLedStatusTemp16_09,unsignedcharucLedStatusTemp08_01);
voidled_update(); //LED更新函数
voidT0_time(); //定时中断函数
voidkey_service();//按键服务的应用程序
voidkey_scan();//按键扫描函数放在定时中断里
sbithc595_sh_dr=P2^3;
sbithc595_st_dr=P2^4;
sbithc595_ds_dr=P2^5;
sbitbeep_dr=P2^7;//蜂鸣器的驱动IO口
sbitkey_sr1=P0^0;//对应朱兆祺学习板的S1键
sbitkey_sr2=P0^1;//对应朱兆祺学习板的S5键
sbitkey_sr3=P0^2;//对应朱兆祺学习板的S9键
sbitkey_sr4=P0^3;//对应朱兆祺学习板的S13键
sbitkey_gnd_dr=P0^4;//模拟独立按键的地GND,因此必须一直输出低电平
unsignedcharucKeySec=0; //被触发的按键编号
unsignedint uiKeyTimeCnt1=0;//按键去抖动延时计数器
unsignedcharucKeyLock1=0;//按键触发后自锁的变量标志
unsignedint uiKeyTimeCnt2=0;//按键去抖动延时计数器
unsignedcharucKeyLock2=0;//按键触发后自锁的变量标志
unsignedint uiKeyTimeCnt3=0;//按键去抖动延时计数器
unsignedcharucKeyLock3=0;//按键触发后自锁的变量标志
unsignedint uiKeyTimeCnt4=0;//按键去抖动延时计数器
unsignedcharucKeyLock4=0;//按键触发后自锁的变量标志
unsignedint uiVoiceCnt=0; //蜂鸣器鸣叫的持续时间计数器
unsignedcharucLed_dr1=0; //代表16个灯的亮灭状态,0代表灭,1代表亮
unsignedcharucLed_dr2=0;
unsignedcharucLed_dr3=0;
unsignedcharucLed_dr4=0;
unsignedcharucLed_dr5=0;
unsignedcharucLed_dr6=0;
unsignedcharucLed_dr7=0;
unsignedcharucLed_dr8=0;
unsignedcharucLed_dr9=0;
unsignedcharucLed_dr10=0;
unsignedcharucLed_dr11=0;
unsignedcharucLed_dr12=0;
unsignedcharucLed_dr13=0;
unsignedcharucLed_dr14=0;
unsignedcharucLed_dr15=0;
unsignedcharucLed_dr16=0;
unsignedcharucLed_update=0; //刷新变量。
每次更改LED灯的状态都要更新一次。
unsignedcharucLedStep_09_16=0;//第9个至第16个LED跑马灯的步骤变量
unsignedint uiTimeCnt_09_16=0;//第9个至第16个LED跑马灯的统计定时中断次数的延时计数器
unsignedcharucLedStatus16_09=0; //代表底层74HC595输出状态的中间变量
unsignedcharucLedStatus08_01=0; //代表底层74HC595输出状态的中间变量
unsignedcharucLedDirFlag=0; //方向变量,把按键与跑马灯关联起来的核心变量,0代表正方向,1代表反方向
unsignedint uiSetTimeLevel_09_16=300; //速度变量,此数值越大速度越慢,此数值越小速度越快。
unsignedcharucLedStartFlag=1; //启动和暂停的变量,0代表暂停,1代表启动
voidmain()
{
initial_myself();
delay_long(100);
initial_peripheral();
while
(1)
{
led_flicker_09_16();//第9个至第16个LED的跑马灯程序,逐个亮并且每次只能亮一个.
led_update(); //LED更新函数
key_service();//按键服务的应用程序
}
}
voidkey_scan()//按键扫描函数放在定时中断里
{
if(key_sr1==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
{
ucKeyLock1=0;//按键自锁标志清零
uiKeyTimeCnt1=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。
}
elseif(ucKeyLock1==0)//有按键按下,且是第一次被按下
{
uiKeyTimeCnt1++;//累加定时中断次数
if(uiKeyTimeCnt1>const_key_time1)
{
uiKeyTimeCnt1=0;
ucKeyLock1=1; //自锁按键置位,避免一直触发
ucKeySec=1; //触发1号键
}
}
if(key_sr2==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
{
ucKeyLock2=0;//按键自锁标志清零
uiKeyTimeCnt2=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。
}
elseif(ucKeyLock2==0)//有按键按下,且是第一次被按下
{
uiKeyTimeCnt2++;//累加定时中断次数
if(uiKeyTimeCnt2>const_key_time2)
{
uiKeyTimeCnt2=0;
ucKeyLock2=1; //自锁按键置位,避免一直触发
ucKeySec=2; //触发2号键
}
}
if(key_sr3==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
{
ucKeyLock3=0;//按键自锁标志清零
uiKeyTimeCnt3=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。
}
elseif(ucKeyLock3==0)//有按键按下,且是第一次被按下
{
uiKeyTimeCnt3++;//累加定时中断次数
if(uiKeyTimeCnt3>const_key_time3)
{
uiKeyTimeCnt3=0;
ucKeyLock3=1; //自锁按键置位,避免一直触发
ucKeySec=3; //触发3号键
}
}
if(key_sr4==1)//IO是高电平,说明按键没有被按下,这时要及时清零一些标志位
{
ucKeyLock4=0;//按键自锁标志清零
uiKeyTimeCnt4=0;//按键去抖动延时计数器清零,此行非常巧妙,是我实战中摸索出来的。
}
elseif(ucKeyLock4==0)//有按键按下,且是第一次被按下
{
uiKeyTimeCnt4++;//累加定时中断次数
if(uiKeyTimeCnt4>const_key_time4)
{
uiKeyTimeCnt4=0;
ucKeyLock4=1; //自锁按键置位,避免一直触发
ucKeySec=4; //触发4号键
}
}
}
voidkey_service()//按键服务的应用程序
{
switch(ucKeySec)//按键服务状态切换
{
case1:
//改变跑马灯方向的按键对应朱兆祺学习板的S1键
if(ucLedDirFlag==0)//通过中间变量改变跑马灯的方向
{
ucLedDirFlag=1;
}
else
{
ucLedDirFlag=0;
}
uiVoiceCnt=const_voice_short;//按键声音触发,滴一声就停。
ucKeySec=0; //响应按键服务处理程序后,按键编号清零,避免一致触发
break;
case2:
//加速按键对应朱兆祺学习板的S5键uiSetTimeLevel_09_16越小速度越快
uiSetTimeLevel_09_16=uiSetTimeLevel_09_16-10;
if(uiSetTimeLevel_09_16<50) //最快限定在50
{
uiSetTimeLevel_09_16=50;
}
uiVoiceCnt=const_voice_short;//按键声音触发,滴一声就停。
ucKeySec=0; //响应按键服务处理程序后,按键编号清零,避免一致触发
break;
case3:
//减速按键对应朱兆祺学习板的S9键 uiSetTimeLevel_09_16越大速度越慢
uiSetTimeLevel_09_16=uiSetTimeLevel_09_16+10;
if(uiSetTimeLevel_09_16>550) //最慢限定在550
{
uiSetTimeLevel_09_16=550;
}
uiVoiceCnt=const_voice_short;//按键声音触发,滴一声就停。
ucKeySec=0; //响应按键服务处理程序后,按键编号清零,避免一致触发
break;
case4:
//启动和暂停按键对应朱兆祺学习板的S13键 ucLedStartFlag为0时代表暂停,为1时代表启动
if(ucLedStartFlag==1) //启动和暂停两种状态循环切换
{
ucLedStartFlag=0;
}
else //启动和暂停两种状态循环切换
{
ucLedStartFlag=1;
}
uiVoiceCnt=const_voice_short;//按键声音触发,滴一声就停。
ucKeySec=0; //响应按键服务处理程序后,按键编号清零,避免一致触发
break;
}
}
voidled_update() //LED更新函数
{
if(ucLed_update==1)
{
ucLed_update=0; //及时清零,让它产生只更新一次的效果,避免一直更新。
if(ucLed_dr1==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x01;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xfe;
}
if(ucLed_dr2==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x02;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xfd;
}
if(ucLed_dr3==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x04;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xfb;
}
if(ucLed_dr4==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x08;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xf7;
}
if(ucLed_dr5==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x10;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xef;
}
if(ucLed_dr6==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x20;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xdf;
}
if(ucLed_dr7==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x40;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0xbf;
}
if(ucLed_dr8==1)
{
ucLedStatus08_01=ucLedStatus08_01|0x80;
}
else
{
ucLedStatus08_01=ucLedStatus08_01&0x7f;
}
if(ucLed_dr9==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x01;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xfe;
}
if(ucLed_dr10==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x02;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xfd;
}
if(ucLed_dr11==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x04;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xfb;
}
if(ucLed_dr12==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x08;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xf7;
}
if(ucLed_dr13==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x10;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xef;
}
if(ucLed_dr14==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x20;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xdf;
}
if(ucLed_dr15==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x40;
}
else
{
ucLedStatus16_09=ucLedStatus16_09&0xbf;
}
if(ucLed_dr16==1)
{
ucLedStatus16_09=ucLedStatus16_09|0x80;
}
else
{
ucLedStatus16_09=ucLedStatus
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第二 十四
![提示](https://static.bdocx.com/images/bang_tan.gif)