51单片机005:用动态扫描方法和定时器1在数码管显示出秒表,精确到1%秒,即后两位显示1%秒(xx.yy),一直循环下去,按K1停止计时,K2重新开始,K3清0停表。
题目:用动态扫描方法和定时器1在数码管显示出秒表,精确到1%秒,即后两位显示1%秒(xx.yy),一直循环下去,按K1停止计时,K2重新开始,K3清0停表。
思路:
1、“用动态扫描方法和定时器1”:
动态扫描要用到数码管的位选和段选,定时器要初始化、编写中断服务函数。
2、“后两位显示1%秒(xx.yy)”:
定义分钟和秒的变量,定时器计数变量每过1s,秒变量++,当秒变量达到60时,分钟变量++。
3、“按K1停止计时,K2重新开始,K3清0停表”
独立按键,通过看按键是否为低电平,判断按键是否按下。通过延时进行消抖。由于要经常检查按键情况,所以应该写到死循环里。
通过控制TCON寄存器中的TR1/TR0运行控制寄存器,控制定时器运行,进一步控制秒表停止计时和重新开始计时。将分钟变量和时钟变量清零即可将秒表清零。
涉及原理图:
代码:
#include "reg52.h" //定义数码管位选信号控制脚 sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC=P2^4; //定义独立按键控制脚 sbit KEY1=P3^1; sbit KEY2=P3^0; sbit KEY3=P3^2; unsigned int h,min,sec; //时变量,分钟变量,秒变量 //共阴极数码管显示0~F的段码数据 unsigned char gsmg_code[18]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x80}; //延时函数 void delay_10us(unsigned int ten_us) { while(ten_us--); } /*****************************数码管*****************************/ void shumaguan(unsigned char location,number) { P0=0x00; switch(location) { case 8:LSC=0;LSB=0;LSA=0;break; case 7:LSC=0;LSB=0;LSA=1;break; case 6:LSC=0;LSB=1;LSA=0;break; case 5:LSC=0;LSB=1;LSA=1;break; case 4:LSC=1;LSB=0;LSA=0;break; case 3:LSC=1;LSB=0;LSA=1;break; case 2:LSC=1;LSB=1;LSA=0;break; case 1:LSC=1;LSB=1;LSA=1;break; } P0=gsmg_code[number]; } void smg_display(unsigned int h,min,sec) { shumaguan(1,h/10); delay_10us(100); shumaguan(2,h%10); delay_10us(100); shumaguan(3,17); //. delay_10us(100); shumaguan(4,min/10); delay_10us(100); shumaguan(5,min%10); delay_10us(100); shumaguan(6,17); //. delay_10us(100); shumaguan(7,sec/10); delay_10us(100); shumaguan(8,sec%10); delay_10us(100); } /*************************定时器*******************************/ void time0_init(void) { TMOD|=0X01;//选择为定时器0模式,工作方式1 TH0=(65535-10000)/256; TL0=(65535-10000)%256; ET0=1;//打开定时器0中断允许 EA=1;//打开总中断 TR0=1;//打开定时器 } void servicetime0() interrupt 1 { unsigned char count; TH0=(65535-50000)/256; //重装初值 TL0=(65535-50000)%256; count++; if(count==20) { count=0; sec++; if(sec == 60) { sec=0; min++; if(min == 60) { min=0; h++; if(h == 100) { h=0; min=0; sec=0; } } } } } void main() { time0_init(); while(1) { smg_display(h,min,sec); //K1停止记时 if (KEY1 == 0) { delay_10us(100); // 延时消抖 if (KEY1 == 0) // 再次检测按键1是否按下 { TR0 = 0; while(KEY1 == 0) smg_display(h,min,sec); } } } //K2重新开始 if (KEY2 == 0) { delay_10us(100); // 延时消抖 if (KEY2 == 0) // 再次检测按键2是否按下 { TR0 = 1; while(KEY2 == 0) { smg_display(h,min,sec); } } } //K3秒表清零 if (KEY3 == 0) { delay_10us(100); // 延时消抖 if (KEY3 == 0) // 再次检测按键3是否按下 { sec=0; min=0; h=0; TR0 = 0; while(KEY3 == 0) { smg_display(h,min,sec); } } } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程