1、简易秒表制作 1子情境内容:制作简易秒表,利用按键构成键盘实现秒表的启动、停止与复位,利用LED数码管显示时间。 2 子情境目标: (1)通过简易秒表的制作,进一步熟悉LED数码管与单片机的接口电路 (2)学习定时/计数器、中断技术的综合运用并会使用简易键盘 3 知识点链接 独立式按键的使用:图5-49为按键与单片机的连接图。 机械式按键再按下或释放时,由于机械弹性作用的影响,通常伴随有一定时间的触点机械抖动,然后其触点才稳定下来。其抖动过程如图5—50所示,抖动时间的长短与开关的机械特性有关,一般为5~10ms。 在触点抖动期间检测按键的通与断状态,可能导致判断出错。即按键一
2、次按下或释放被错误地认为是多次操作,这种情况是不允许出现的。为了克服按键触点机械抖动所致的检测误判,必须采取去抖动措施,可从硬件、软件两方面予以考虑。本子情境中采用软件去抖. 图按键与单片机连接图 图按键被按下时电压的变化 4 任务步骤 4.1 步骤一:PROTEUS电路设计,简易秒表的原理图如图5-51所示. 1、选取元器件 ①单片机:AT89C51 ②两位共阴极蓝色数码管:7SEG-MPX2—CC-BLUE ③排阻:RESPACK-8 ④按钮:BUTTON 2、放置元器件、放置电源和地、连线、元器件属性设置 简易秒表的原理图如图5-51所示,整个电路设计操
3、作都在ISIS平台中进行。与子情景3相似,故不详述。 图简易秒表的原理图 4.2 步骤二:源程序设计与目标代码文件生成 (1)程序流程图 开始 位,变量,数组,子程序声明 主程序 启动键是否按下? no yes 按键防抖 停止键是否按下? no yes 复位键是否按下? no yes 按键防抖 按键防抖 开定时器 关定时器 秒表清零 是否到20次50ms`? no yes 秒表清零 数码管显示 是否到60秒`? 秒加1 yes no 图5-52 秒表流程图 (2)源程序设计 #include〈reg52。h〉
4、#define uint unsigned int #define uchar unsigned char sbit key1=P3^0; //定义”启动”按钮 sbit key2=P3^1; //定义"停止"按钮 sbit key3=P3^2; //定义"复位”按钮 uchar temp,aa,shi,ge; uchar code table[]={ 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,
5、0x79,0x71}; //共阴极数码管编码 void display(uchar shi,uchar ge); //声明显示子函数 void delay(uint z); //声明延时子函数 void init(); //声明初始化函数 void main() { init(); //调用初始化子程序 while(1) { if(key1==0) //检测”启动"按钮是否按下 {
6、 delay(10); //延时去抖动 if(key1==0) //再次检测”启动”按钮是否按下 { while(!key1); //松手检测,若按键没有释放,key1始终为0,那么!key1始终为1,程序就一直停在此while语句处 TR0=1; //启动定时器开始工作 } } if(key2==0) //检测"停止”按钮是否按下 { delay(10); //延时去抖动 if(key2==0) //再次检测”
7、停止”按钮是否按下 { while(!key2); //松手检测 TR0=0; //关闭定时器 } } if(key3==0) //检测”复位”按钮是否按下 { delay(10); //延时去抖动 if(key3==0) //再次检测"复位”按钮是否按下 { while(!key3); //松手检测 temp=0; //将变量temp的值清零 shi=0; //将十位清零 g
8、e=0; //将个位清零 TR0=0; //关闭定时器 } } display(shi,ge); //调用显示子函数 } } void delay(uint z) //延时子函数 { uint x,y; for(x=z;x>0;x—-) for(y=110;y〉0;y-—); } void display(uchar shi,uchar ge) //显示子程序 { P2=0xbf; P0=table[shi]; delay(10); P2=0x7f;
9、P0=table[ge]; delay(10); //使用动态扫描的方法实现数码管显示 } void init() //初始化子程序 { temp=0; TMOD=0x01; //使用定时器T0的方式1 TH0=(65536-50000)/256; TL0=(65536-50000)%256; //定时50ms中断一次 EA=1; //中断总允许 ET0=1; //允许定时器T0中断 } void timer0(
10、) interrupt 1 { TH0=(65536—50000)/256;//重新赋初值 TL0=(65536—50000)%256; aa++; //中断一次变量aa的值加1 if(aa==20) //中断20次后,定时时间为20*50ms=1000ms=1s,将变量temp的值加1 { aa=0; temp++; if(temp==60) //秒表到达60s后回零 { temp=0; } shi=temp%100/10; ge=temp%10;
11、 //分离个位和十位 } } 4.3 步骤三:PROTEUS仿真 加载目标代码文件,双击编辑窗口的AT89C51器件,在弹出属性编辑对话框Program File一栏中单击打开按钮,出现文件浏览对话框,找到miaobiao。hex文件,单击“打开”按钮,完成添加文件。单击按钮,启动仿真,仿真运行片段如图所示. 按下“启动”按钮后,秒表开始计时,如图所示. 按下“停止"按钮,秒表停止计时。 按下“复位”按钮,秒表回到最初始的状态,如图所示。 图按下“启动”按钮后秒表开始计时 图按下“复位"按钮后,秒表回到最初始的状态 5 扩展练习 此子情境设计的秒表只能显示两位整数,如果要记录110跨栏12:88秒的成绩,则必须再增加两位数码管来显示小数位。想想硬件和软件应该做如何改动。