找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1871|回复: 8
打印 上一主题 下一主题
收起左侧

单片机控制数码管定时息屏问题

[复制链接]
跳转到指定楼层
楼主
ID:162811 发表于 2021-10-12 23:14 来自手机 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
如何让4位数码管在单片机开机时显示数值123,10秒后自动关闭数码管显示;同时在按键后数码管又重新显示123,10秒无按键后自动关闭数码管?
考虑用定时器中断,没搞定
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:624769 发表于 2021-10-12 23:38 | 只看该作者
你数码管本来就是通过定时器动态扫描来显示的吧?
假定,你的定时器,是1ms, 扫描一次的, 你就做个变量,初值10000,每没进入定时器一次就-1, = 0了,
标志位Disp_Off = 1, 进入中断后,发现 Disp_Off = 1; 就不操作动态扫描直接退出中断。
一旦按键了,Disp_Off = 0; 那么,动态扫描就又被激活了。
多简单的事?
回复

使用道具 举报

板凳
ID:161164 发表于 2021-10-13 00:11 | 只看该作者
为了方便演示,我把十秒改成了三秒



参考代码


回复

使用道具 举报

地板
ID:960157 发表于 2021-10-13 06:36 | 只看该作者
贴出程序,大家帮你改改。。。
回复

使用道具 举报

5#
ID:332444 发表于 2021-10-13 08:03 | 只看该作者
中断计时有按键置1时间到置0
回复

使用道具 举报

6#
ID:554500 发表于 2021-10-13 08:28 | 只看该作者
添加一个变量。用定时器累计,变量大于或等于10s,就熄屏并且关闭定时器。
小于10S的时候。每次按按键把变量清零一次。
熄屏期间按按键,打开显示,变量清零,开启定时器。

结束!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
回复

使用道具 举报

7#
ID:960619 发表于 2021-10-13 08:39 来自手机 | 只看该作者
定时器里加个如果变量x大于0{X==0}关闭标志位置1.每次按键刷新x=10s,也就是按键一松开,就开始10s倒计时,中间无按键按下10s后关闭,有按键按下x重置为10s
回复

使用道具 举报

8#
ID:162811 发表于 2021-10-13 13:18 | 只看该作者
经过上午折腾,功能基本可用了。谢谢各位帮助!
  1. #include <reg52.h> //51头文件
  2. #define uchar unsigned char//宏定义
  3. #define uint  unsigned int//宏定义
  4. #define ulong        unsigned long//宏定义

  5. #define DPort P0   //显示数值
  6. #define WPort P2   //显示位数

  7. sbit KEY_ADD=P3^5;  //定义按键输入端口
  8. sbit KEY_DEC=P3^4;

  9. ulong lednum=7890;

  10. //数码管段位选表
  11. uchar code dofly_DuanMa[10]= {0x50,0x5f,0x32,0x16,0x1d,0x94,0x90,0x5e,0x10,0x14}; // 显示段码值0~9
  12. uchar code dofly_WeiMa[4]= {0x7f,0xbf,0xef,0xdf}; //分别对应相应的数码管点亮,即位码

  13. void DelayUs2x(uchar t);//函数声明
  14. void DelayMs(uchar t);
  15. void Display(ulong Num);
  16. void Init_Timer0(void);

  17. /*------------------------------------------------
  18.                     主函数
  19. ------------------------------------------------*/
  20. void main (void)
  21. {
  22.     uchar num=0,key_press_num;
  23.     KEY_ADD=1; //按键输入端口电平置高
  24.     KEY_DEC=1;
  25.     Init_Timer0();

  26.     while (1)         //主循环
  27.     {

  28.         if(!KEY_ADD)  //如果检测到低电平,说明按键按下
  29.         {
  30.             DelayMs(10); //延时去抖,一般10-20ms
  31.             if(!KEY_ADD)     //再次确认按键是否按下,没有按下则退出
  32.             {
  33.                 while(!KEY_ADD)
  34.                 {
  35.                     key_press_num++;
  36.                     DelayMs(10);           //10x200=2000ms=2s
  37.                     if(key_press_num==200) //大约2s
  38.                     {
  39.                         key_press_num=0;    //如果达到长按键标准
  40.                         //则进入长按键动作
  41.                         while(!KEY_ADD)     //这里用于识别是否按
  42.                             //键还在按下,如果按
  43.                             //下执行相关动作,否则退出
  44.                         {
  45.                             lednum++;//长按加操作
  46.                             DelayMs(50);//用于调节长按循环操作
  47.                             //的速度,可以自行调整此值以便达到最佳效果
  48.                         }
  49.                     }
  50.                 }
  51.                 key_press_num=0;//防止累加造成错误识别
  52. //                lednum++;//短按加操作
  53.                                                                         TR0=1;
  54.             }
  55.         }

  56.         if(!KEY_DEC)  //如果检测到低电平,说明按键按下
  57.         {
  58.             DelayMs(10); //延时去抖,一般10-20ms
  59.             if(!KEY_DEC) //再次确认按键是否按下,没有
  60.                 //按下则退出
  61.             {
  62.                 while(!KEY_DEC)
  63.                 {
  64.                     key_press_num++;
  65.                     DelayMs(10);
  66.                     if(key_press_num==200) //大约2s
  67.                     {
  68.                         key_press_num=0;
  69.                         while(!KEY_DEC)
  70.                         {
  71.                             lednum--;//长按减操作
  72.                             DelayMs(50);
  73. //用于调节长按循环操作的速度
  74.                         }
  75.                     }
  76.                 }
  77.                 key_press_num=0;//防止累加造成错误识别
  78. //                lednum--;//短按减操作
  79.                                                                 TR0=0;
  80.                                                                 P0=0xff;

  81.             }
  82.         }
  83. //        Display(lednum); //显示
  84.         //主循环中添加其他需要一直工作的程序

  85.     }
  86. }
  87. /*------------------------------------------------
  88. uS延时函数,含有输入参数 unsigned char t,无返回值
  89. unsigned char 是定义无符号字符变量,其值的范围是
  90. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  91. 长度如下 T=tx2+5 uS
  92. ------------------------------------------------*/
  93. void DelayUs2x(unsigned char t)
  94. {
  95.     while(--t);
  96. }
  97. /*------------------------------------------------
  98. mS延时函数,含有输入参数 unsigned char t,无返回值
  99. unsigned char 是定义无符号字符变量,其值的范围是
  100. 0~255 这里使用晶振12M,精确延时请使用汇编
  101. ------------------------------------------------*/
  102. void DelayMs(unsigned char t)
  103. {
  104.     while(t--)
  105.     {
  106.         //大致延时1mS
  107.         DelayUs2x(245);
  108.         DelayUs2x(245);
  109.     }
  110. }
  111. /*------------------------------------------------
  112. 显示函数,用于动态扫描数码管
  113. 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
  114. 如输入0表示从第一个显示。
  115. Num表示需要显示的位数,如需要显示99两位数值则该值输入2
  116. ------------------------------------------------*/
  117. void Display(ulong num)
  118. {
  119.     static uint i=0;
  120.     uchar TempData[4]; //存储临时显示值的变量
  121.     if (num>999)
  122.     {
  123.         TempData[0]=dofly_DuanMa[num/1000];//千位
  124.         TempData[1]=dofly_DuanMa[num%1000/100];//百位
  125.         TempData[2]=dofly_DuanMa[num%100/10]-0x10;//十位
  126.         TempData[3]=dofly_DuanMa[num%10];//个位
  127.         DPort=0xff;   //清空数据,防止有交替重影
  128.         WPort=dofly_WeiMa[i]; //取位码
  129.         DPort=TempData[i]; //取显示数据,段码
  130.         i++;
  131.         if(i==4) i=0;
  132.     }
  133.     else
  134.     {
  135.         TempData[1]=dofly_DuanMa[num%1000/100];//百位
  136.         TempData[2]=dofly_DuanMa[num%100/10]-0x10;//十位
  137.         TempData[3]=dofly_DuanMa[num%10];//个位
  138.         DPort=0xff;   //清空数据,防止有交替重影
  139.         WPort=dofly_WeiMa[i+1]; //取位码
  140.         DPort=TempData[i+1]; //取显示数据,段码
  141.         i++;
  142.         if(i==3) i=0;
  143.     }
  144. }
  145. /*------------------------------------------------
  146.                     定时器初始化子程序
  147. ------------------------------------------------*/
  148. void Init_Timer0(void)
  149. {
  150.     TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
  151. //TH0=0x00;              //给定初值
  152. //TL0=0x00;
  153.     EA=1;            //总中断打开
  154.     ET0=1;           //定时器中断打开
  155.     TR0=1;           //定时器开关打开
  156. }
  157. /*------------------------------------------------
  158.                  定时器中断子程序
  159. ------------------------------------------------*/
  160. void Timer0_isr(void) interrupt 1
  161. {
  162.     TH0=(65536-5000)/256;                  //重新赋值 2ms
  163.     TL0=(65536-5000)%256;
  164.     Display(lednum);

  165. }
复制代码


回复

使用道具 举报

9#
ID:162811 发表于 2021-10-13 14:19 | 只看该作者
感谢解答!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表