单片机补充案例--LED数码管99秒倒计时

举报
zhangrelay 发表于 2021/07/15 00:15:29 2021/07/15
5k+ 0 0
【摘要】 说明:使用数码管实现倒计时显示 设备: 倒计时 可使用按钮作适当控制,暂停,开始,计时复位等。 程序: #include<8052.h> #define LSC P1_7 //特殊功能寄存器的位定义,#define LSB P1_6 //3-8译码器的输入端,#define LSA P1_5 //控制三极管Q2~Q6的导通unsign...

说明:使用数码管实现倒计时显示

设备:

可使用按钮作适当控制,暂停,开始,计时复位等。

程序:


      #include<8052.h> 
      #define LSC P1_7 //特殊功能寄存器的位定义,
      #define LSB P1_6 //3-8译码器的输入端,
      #define LSA P1_5 //控制三极管Q2~Q6的导通
      unsigned char smgduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0x0f8,0x80,0x90};//共阳极的显示代码表0~9
      unsigned char T0RH = 0; 	//T0 重载值的高字节
      unsigned char T0RL = 0; 	//T0 重载值的低字节
      unsigned int cnt;
      signed char sec;
      signed char sec_all=99;
      signed char count=0;
      /*在51单片机11MHZ时钟下的延时函数*/
      void Delayms(unsigned int c);   //误差 0us
      /*数码管显示函数*/
      void LedScan(unsigned char pos,unsigned char dispcode);
      void EXINT0() __interrupt 0;
      void Timer0() __interrupt 1;
      void EXINT1() __interrupt 2;
      void ConfigTimer0(unsigned int);
      void main()
      {
      	cnt = 0; //中断次数计数器
      	sec = sec_all; //秒数初值
      	ConfigTimer0(2); //配置 T0 定时 2ms
      	EA=1; //开中断
      	IT0=1;
      	EX0=1;
      	IT1=1;
      	EX1=1;
      	PX1=1;
       TR0=1; //启动 T0
     	while(1)
      	{
      		LedScan(0,smgduan[sec%10]); //显示个位值
      		LedScan(1,smgduan[sec/10]); //显示十位值
     		if(count%2==0)
      		{
       TR0 = 1;
      		}
     		else
      		{
       TR0 = 0;
      		}
      	}
      }
      void EXINT0() __interrupt 0
      {
      	count++;
      }
      void EXINT1() __interrupt 2
      {
      	sec_all=0;
      }
      /* 配置T0, ms-T0定时时间 */
      void ConfigTimer0(unsigned int ms)
      {
     	unsigned long tmp; 	 //临时变量
      	tmp = 11059200 / 12; 	 //定时器计数频率
      	tmp = (tmp * ms) / 1000;  //计算所需的计数值
      	tmp = 65536 - tmp; 	 //计算定时器重载值
      	tmp = tmp + 18; 	 //补偿中断响应延时造成的误差
      	T0RH = (unsigned char)(tmp>>8); 	//定时器重载值拆分为高低字节
      	T0RL = (unsigned char)tmp;
      	TMOD &= 0xF0; 		//清零 T0 的控制位
      	TMOD |= 0x01; 		//配置 T0 为模式 1
      	TH0 = T0RH; 		//加载 T0 重载值
      	TL0 = T0RL;
      	ET0 = 1; 		//使能 T0 中断
      }
      /* T0 中断服务函数,完成数码管、按键扫描与秒表计数 */
      void Timer0() __interrupt 1
      {
      	TH0 = T0RH; 	//重新加载重载值
      	TL0 = T0RL;
      	cnt++; 		//中断次数加1
     	if (cnt >= 500) //中断500次=1s
      	{
      		cnt = 0;
      		sec--;   //达到50次后计数值清零
     		if (sec < 0)   //当显示值到0后,从sec_all开始
      		{
      			sec = sec_all;
      		}
      	}
      }
      void Delayms(unsigned int c) //误差 0us
      {
      unsigned char a,b;
     	for (; c>0; c--)
      	{
     		 for (b=199;b>0;b--)
      		 {
      for(a=1;a>0;a--);
      		 }
      	}
      }
      /*******************************************************************************
      * 函 数 名 : segdisp
      * 函数功能 : 数码管显示
      * 输 入 : i-pos,d-dispcode
      * 输 出 : 无
      *******************************************************************************/
      void LedScan(unsigned char pos,unsigned char dispcode)
       {
      unsigned char i;
      for(i=0;i<=pos;i++)
       {
     	switch(pos)	 //位选,选择点亮的数码管,
      	{
     		case(0):
      		LSA=1;LSB=0;LSC=0; break;//显示
     		case(1):
      		LSA=0;LSB=1;LSC=0; break;//显示第1位
     		case(2):
      		LSA=1;LSB=1;LSC=0; break;//显示第2位
     		case(3):
      		LSA=0;LSB=0;LSC=1; break;//显示第3位
      	}
      	P0=dispcode;//发送段码 
       }
      }
  
 

文章来源: zhangrelay.blog.csdn.net,作者:zhangrelay,版权归原作者所有,如需转载,请联系作者。

原文链接:zhangrelay.blog.csdn.net/article/details/109667084

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。