51单片机入门程序——秒表程序示例

下午自学了一下单片机的前几章的知识,理解了数码管的显示原理以及静态显示和动态扫描的编程方法。其中,比较重要的几个概念有:数码管公共端类型(共阴极、共阳极)、位选(决定多位数码管中哪一位显示)、段选(决定数码管显示的数字),另外还有锁存器(教材P36,可通过控制锁存端来改变数据输出的状态)。

上周单片机实验课的内容是编一个秒表,在4位数码管中分别显示分和秒还有分秒,即最多可显示“9:59.9”。这里我用两个键实现了秒表的启动/暂停和清零功能,代码如下:

[cpp]  view plain  copy
  1. #include <reg51.h>  
  2. #define uint unsigned int  
  3. #define uchar unsigned char  
  4. sbit S1 = P1^3;  
  5. sbit S2 = P1^1;  
  6. sbit S3 = P1^2;  
  7. sbit S4 = P1^0;  
  8. sbit beep = P2^7;  
  9. sbit a = P0^0;  
  10. sbit b = P0^1;  
  11. sbit c = P0^2;  
  12. sbit d = P0^3;  
  13. sbit e = P0^4;  
  14. sbit f = P0^5;  
  15. sbit g = P0^6;  
  16. sbit p = P0^7;  
  17. sbit key1 = P1^4;  
  18. sbit key2 = P1^5;  
  19. sbit key3 = P3^6;  
  20. sbit key4 = P3^7;  
  21. uchar num,kms,sec,min;  
  22. uchar code N[10] = {0xc0, 0xf9 ,0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; //0, 1, 2, 3, ...8, 9  
  23. uchar code Z[10] = {0x40, 0x79 ,0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10}; //0., 1., 2., ... 8., 9.  
  24.   
  25. void delayms(uint xms)  
  26. {  
  27.     uint i,j;  
  28.     for(i = xms; i > 0; i--)  
  29.         for(j = 110; j > 0; j--);  
  30. }  
  31.   
  32. void init()  
  33. {  
  34.     TMOD = 0x01;  
  35.     TH0 = 0x3c;  
  36.     TL0 = 0xb0;  
  37.     S3 = 1;  
  38.     S1 = S2 = S4 = 0;  
  39.     P0 = N[0];  
  40.     delayms(5);  
  41.   
  42.     S3 = 0;  
  43.     S1 = S2 = S4 = 1;  
  44.     P0 = Z[0];  
  45.     delayms(5);  
  46.   
  47.     EA = 1;  
  48.     TR0 = 0;  
  49.     ET0 = 1;      
  50.     kms = sec = min = 0;  
  51. }  
  52.   
  53. void display()  
  54. {  
  55.     uchar shi, ge;  
  56.     if(kms >= 0)  
  57.     {  
  58.         S4 = 0;  
  59.         S1 = S2 = S3 = 1;  
  60.         P0 = N[kms];  
  61.     }  
  62.     delayms(5);  
  63.     if(sec >= 0)  
  64.     {  
  65.         shi = sec/10;  
  66.         ge = sec%10;  
  67.   
  68.         S3 = 0;  
  69.         S1 = S2 = S4 = 1;  
  70.         P0 = Z[ge];  
  71.         delayms(5);  
  72.   
  73.         S2 = 0;  
  74.         S1 = S3 = S4 = 1;  
  75.         P0 = N[shi];  
  76.     }  
  77.     delayms(5);  
  78.     if(min >= 0)  
  79.     {  
  80.         S1 = 0;  
  81.         S2 = S3 = S4 = 1;  
  82.         P0 = N[min];  
  83.     }  
  84.     delayms(5);  
  85. }  
  86.   
  87. void keyscan()  
  88. {  
  89.     if(key1 == 0)  
  90.     {  
  91.         delayms(10);  
  92.         if(key1 == 0)  
  93.         {  
  94.             while(!key1);  
  95.             TR0 = ~TR0;  
  96.         }  
  97.     }  
  98.     if(key2 == 0)  
  99.     {  
  100.         delayms(10);  
  101.         if(key2 == 0)  
  102.         {  
  103.             min = sec = kms = 0;  
  104.             while(!key1);  
  105.         }  
  106.     }  
  107. }  
  108.   
  109. main()  
  110. {  
  111.     init();  
  112.     while(1)  
  113.     {  
  114.         keyscan();  
  115.         display();        
  116.     }  
  117. }  
  118.   
  119. void T0_time() interrupt 1  
  120. {  
  121.     TH0 = 0x3c;  
  122.     TL0 = 0xb0;  
  123.         num++;  
  124.     if(num == 2)  
  125.     {  
  126.         num = 0;  
  127.         kms++;  
  128.         if(kms == 10)  
  129.         {  
  130.             kms = 0;  
  131.             sec++;  
  132.             if(sec == 60)  
  133.             {  
  134.                 sec = 0;  
  135.                 min++;  
  136.                 if(min == 10)  
  137.                 {  
  138.                     TR0 = 0;  
  139.                     min = 9;  
  140.                     sec = 59;  
  141.                     kms = 9;  
  142.                 }  
  143.             }  
  144.         }  
  145.     }  
  146. }   

程序通过“Keil uVision4”调试,大家也可以在板子上运行一下试试。

注意:需要根据板子的端口定义相关变量,不要不分青红皂白就直接使用我的程序哈。

最后上个图,第一次做单片机,希望以后还有时间可以做更深入的更好玩的东西。


猜你喜欢

转载自blog.csdn.net/yelin042/article/details/80699786