单片机课堂思考题-2000秒倒计时?

举报
zhangrelay 发表于 2021/11/04 00:35:34 2021/11/04
【摘要】 99秒倒计时,改为2000(6666)秒倒计时。 #include<8052.h> #define LSC P1_7 //特殊功能寄存器的位定义,#define LSB P1_6 //3-8译码器的输入端,#define LSA P1_5 ...

99秒倒计时,改为2000(6666)秒倒计时。


  
  1. #include<8052.h>
  2. #define LSC P1_7 //特殊功能寄存器的位定义,
  3. #define LSB P1_6 //3-8译码器的输入端,
  4. #define LSA P1_5 //控制三极管Q2~Q6的导通
  5. unsigned char smgduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0x0f8,0x80,0x90};
  6. //共阳极的显示代码表0~9
  7. unsigned char T0RH = 0; //T0 重载值的高字节
  8. unsigned char T0RL = 0; //T0 重载值的低字节
  9. unsigned int cnt;
  10. char sec;
  11. char sec_all=99;
  12. char count=0;
  13. /*数码管显示函数*/
  14. void LedScan(unsigned char pos,unsigned char dispcode);
  15. void EXINT0() __interrupt 0;
  16. void Timer0() __interrupt 1;
  17. void EXINT1() __interrupt 2;
  18. void ConfigTimer0(unsigned int);
  19. void main()
  20. {
  21. cnt = 0; //中断次数计数器
  22. sec = sec_all; //秒数初值
  23. ConfigTimer0(2); //配置 T0 定时 2ms
  24. EA=1; //开中断
  25. IT0=1;
  26. EX0=1;
  27. IT1=1;
  28. EX1=1;
  29. PX1=1;
  30. TR0=1; //启动 T0
  31. while(1)
  32. {
  33. LedScan(0,smgduan[sec%10]); //显示个位值
  34. LedScan(1,smgduan[sec/10]); //显示十位值
  35. if(count%2==0)
  36. {
  37. TR0 = 1;
  38. }
  39. else
  40. {
  41. TR0 = 0;
  42. }
  43. }
  44. }
  45. void EXINT0() __interrupt 0
  46. {
  47. count++;
  48. }
  49. void EXINT1() __interrupt 2
  50. {
  51. sec_all=0;
  52. }
  53. /* 配置T0, ms-T0定时时间 */
  54. void ConfigTimer0(unsigned int ms)
  55. {
  56. unsigned long tmp; //临时变量
  57. tmp = 11059200 / 12; //定时器计数频率
  58. tmp = (tmp * ms) / 1000; //计算所需的计数值
  59. tmp = 65536 - tmp; //计算定时器重载值
  60. tmp = tmp + 18; //补偿中断响应延时造成的误差
  61. T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
  62. T0RL = (unsigned char)tmp;
  63. TMOD &= 0xF0; //清零 T0 的控制位
  64. TMOD |= 0x01; //配置 T0 为模式 1
  65. TH0 = T0RH; //加载 T0 重载值
  66. TL0 = T0RL;
  67. ET0 = 1; //使能 T0 中断
  68. }
  69. /* T0 中断服务函数,完成数码管、按键扫描与秒表计数 */
  70. void Timer0() __interrupt 1
  71. {
  72. TH0 = T0RH; //重新加载重载值
  73. TL0 = T0RL;
  74. cnt++; //中断次数加1
  75. if (cnt >= 500) //中断500次=1s
  76. {
  77. cnt = 0;
  78. sec--; //达到50次后计数值清零
  79. if (sec < 0) //当显示值到0后,从sec_all开始
  80. {
  81. sec = sec_all;
  82. }
  83. }
  84. }
  85. /*******************************************************************************
  86. 数码管显示
  87. *******************************************************************************/
  88. void LedScan(unsigned char pos,unsigned char dispcode)
  89. {
  90. unsigned char i;
  91. for(i=0;i<=pos;i++)
  92. {
  93. switch(pos) //位选,选择点亮的数码管,
  94. {
  95. case(0):
  96. LSA=1;LSB=0;LSC=0; break;//显示第0位
  97. case(1):
  98. LSA=0;LSB=1;LSC=0; break;//显示第1位
  99. case(2):
  100. LSA=1;LSB=1;LSC=0; break;//显示第2位
  101. case(3):
  102. LSA=0;LSB=0;LSC=1; break;//显示第3位
  103. }
  104. P0=dispcode;//发送段码
  105. }
  106. }

 

修改:


  
  1. #include<8052.h>
  2. #define LSC P1_7 //特殊功能寄存器的位定义,
  3. #define LSB P1_6 //3-8译码器的输入端,
  4. #define LSA P1_5 //控制三极管Q2~Q6的导通
  5. unsigned char smgduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0x0f8,0x80,0x90};
  6. //共阳极的显示代码表0~9
  7. unsigned char T0RH = 0; //T0 重载值的高字节
  8. unsigned char T0RL = 0; //T0 重载值的低字节
  9. unsigned int cnt;
  10. int sec;
  11. int sec_all=6666;
  12. int count=0;
  13. /*数码管显示函数*/
  14. void LedScan(unsigned char pos,unsigned char dispcode);
  15. void EXINT0() __interrupt 0;
  16. void Timer0() __interrupt 1;
  17. void EXINT1() __interrupt 2;
  18. void ConfigTimer0(unsigned int);
  19. void main()
  20. {
  21. cnt = 0; //中断次数计数器
  22. sec = sec_all; //秒数初值
  23. ConfigTimer0(2); //配置 T0 定时 2ms
  24. EA=1; //开中断
  25. IT0=1;
  26. EX0=1;
  27. IT1=1;
  28. EX1=1;
  29. PX1=1;
  30. TR0=1; //启动 T0
  31. while(1)
  32. {
  33. LedScan(0,smgduan[sec%10]); //显示个位值
  34. LedScan(1,smgduan[sec/10%10]); //显示十位值
  35. LedScan(2,smgduan[sec/100%10]); //显示个位值
  36. LedScan(3,smgduan[sec/1000]); //显示十位值
  37. if(count%2==0)
  38. {
  39. TR0 = 1;
  40. }
  41. else
  42. {
  43. TR0 = 0;
  44. }
  45. }
  46. }
  47. void EXINT0() __interrupt 0
  48. {
  49. count++;
  50. }
  51. void EXINT1() __interrupt 2
  52. {
  53. sec_all=0;
  54. }
  55. /* 配置T0, ms-T0定时时间 */
  56. void ConfigTimer0(unsigned int ms)
  57. {
  58. unsigned long tmp; //临时变量
  59. tmp = 11059200 / 12; //定时器计数频率
  60. tmp = (tmp * ms) / 1000; //计算所需的计数值
  61. tmp = 65536 - tmp; //计算定时器重载值
  62. tmp = tmp + 18; //补偿中断响应延时造成的误差
  63. T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
  64. T0RL = (unsigned char)tmp;
  65. TMOD &= 0xF0; //清零 T0 的控制位
  66. TMOD |= 0x01; //配置 T0 为模式 1
  67. TH0 = T0RH; //加载 T0 重载值
  68. TL0 = T0RL;
  69. ET0 = 1; //使能 T0 中断
  70. }
  71. /* T0 中断服务函数,完成数码管、按键扫描与秒表计数 */
  72. void Timer0() __interrupt 1
  73. {
  74. TH0 = T0RH; //重新加载重载值
  75. TL0 = T0RL;
  76. cnt++; //中断次数加1
  77. if (cnt >= 500) //中断500次=1s
  78. {
  79. cnt = 0;
  80. sec--; //达到50次后计数值清零
  81. if (sec < 0) //当显示值到0后,从sec_all开始
  82. {
  83. sec = sec_all;
  84. }
  85. }
  86. }
  87. /*******************************************************************************
  88. 数码管显示
  89. *******************************************************************************/
  90. void LedScan(unsigned char pos,unsigned char dispcode)
  91. {
  92. unsigned char i;
  93. for(i=0;i<=pos;i++)
  94. {
  95. switch(pos) //位选,选择点亮的数码管,
  96. {
  97. case(0):
  98. LSA=1;LSB=0;LSC=0; break;//显示第0位
  99. case(1):
  100. LSA=0;LSB=1;LSC=0; break;//显示第1位
  101. case(2):
  102. LSA=1;LSB=1;LSC=0; break;//显示第2位
  103. case(3):
  104. LSA=0;LSB=0;LSC=1; break;//显示第3位
  105. }
  106. P0=dispcode;//发送段码
  107. }
  108. }

 

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

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

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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