找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4966|回复: 0
收起左侧

单片机正逆向秒表流水灯Proteus仿真+代码

[复制链接]
ID:412951 发表于 2018-11-30 18:36 | 显示全部楼层 |阅读模式
    这是楼主学习单片机时做的,很适合新手学习定时器和外部中断时做参考。    左侧为单片机最小系统,左上按键为复位键,右侧P3口为两个外部中断,INT0为开始/暂停按键(用定时器控制),INT1为模式切换按键。
    流水灯没有用循环函数写,其与定时器结合,可以用外部中断INT0实时控制。
    keil所有文件和proteus仿真都已上传,程序注释标的很清楚,适合新手学习。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

正向秒表

正向秒表

逆向秒表

逆向秒表

实时可控流水灯

实时可控流水灯

proteus仿真

proteus仿真


单片机正逆向秒表流水灯源程序如下:
  1. #include<reg51.h>
  2. #include"main.h"
  3. #include"delay.h"
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. unsigned long int g_unDisNum;                                                                   //用于计数,从00000到99999
  7. unsigned long int g_unDisNum1;                                                                   //用于计数,从99999到00000
  8. uchar i,K,m,g_ucNum;
  9. uint c=0;
  10. uchar code table[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};  //流水灯显示模式一
  11. uchar code table1[]={0x55,0xAA};                                                            //流水灯显示模式二
  12. uchar code table2[]={0x00,0xFF};                                                            //流水灯显示模式三
  13. uchar code DIS_CODE[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //共阴极数码管显示代码
  14. void disp_numu(unsigned long int num1)                                       //数码管显示函数,显示5位数字
  15. {        
  16.         uchar sep_num1=0;
  17.         uchar ten_num1=0;
  18.         uchar hund_num1=0;  
  19.         uchar thou_num1=0;
  20.         uchar tent_num1=0;
  21.         
  22.         sep_num1=num1%10;                                                                          //数码管的个十百千万位
  23.         ten_num1=(num1%100)/10;
  24.         hund_num1=(num1%1000)/100;
  25.         thou_num1=(num1%10000)/1000;
  26.         tent_num1=(num1%100000)/10000;
  27.         
  28.         P2=0xFE;                                                                                          //通过扫描的方式显示
  29.         P0=DIS_CODE[tent_num1];
  30.         delay_ms(1);

  31.         P2=0xFD;
  32.         P0=DIS_CODE[thou_num1];
  33.         delay_ms(1);

  34.         P2=0xFB;
  35.         P0=DIS_CODE[hund_num1];
  36.         delay_ms(1);

  37.         P2=0xF7;
  38.         P0=DIS_CODE[ten_num1];
  39.         delay_ms(1);

  40.         P2=0xEF;
  41.         P0=DIS_CODE[sep_num1];

  42. }
  43. void modea()                                                          //正序按秒从00000递增至99999
  44. {
  45.         if(g_ucNum>=200)                                          //g_ucNum增至200正好1秒,将g_ucNum清零,g_unDisNum增1
  46.         {
  47.         g_ucNum=0;                                                         
  48.         g_unDisNum++;        
  49.         }
  50.         disp_numu(g_unDisNum);
  51.         P1=0x00;
  52. }
  53. void modeb()                                                          //倒序按秒从99999递减至00000
  54. {
  55.         if(g_ucNum>=200)                                          //g_ucNum增至200正好1秒,将g_ucNum清零,g_unDisNum1减1
  56.         {
  57.         g_ucNum=0;
  58.         g_unDisNum1--;        
  59.         }
  60.         disp_numu(g_unDisNum1);
  61.         P1=0x00;

  62. }
  63. void mode1()                                                           //正序流水灯,为了实时暂停、开始流水灯,mode1mode2mode3mode4均采用定时器中断的方式控制
  64. {
  65.         P1=table[i%8];
  66.         if(g_ucNum>=20)
  67.         {
  68.         g_ucNum=0;
  69.         i++;        
  70.         }
  71.         P2=0xFF;                                                          //清除右侧数码管余辉
  72.         
  73. }
  74. void mode2()                                                              //倒序流水灯
  75. {
  76.         P1=table[i%8];
  77.         if(g_ucNum>=20)
  78.         {
  79.         g_ucNum=0;
  80.         i--;        
  81.         }
  82. }
  83. void mode3()                                                          //混合亮灭流水灯
  84. {
  85.         P1=table1[i%2];
  86.         if(g_ucNum>=20)
  87.         {
  88.         g_ucNum=0;
  89.         i++;        
  90.         }
  91. }
  92. void mode4()                                                           //全亮全灭流水灯
  93. {
  94.         P1=table2[i%2];
  95.         if(g_ucNum>=20)
  96.         {
  97.         g_ucNum=0;
  98.         i++;        
  99.         }
  100. }                                                                                 
  101. void mode5()                                                          //初始状态 数码管88888二极管1111 1111
  102. {        uchar m;
  103.         for(m=0;m<10;m++)
  104.         {
  105.         P2=0xFE;
  106.         P0=0x7F;
  107.         delay_ms(2);
  108.         P2=0xFD;
  109.         P0=0x7F;
  110.         delay_ms(2);
  111.         P2=0xFB;
  112.         P0=0x7F;
  113.         delay_ms(2);
  114.         P2=0xF7;
  115.         P0=0x7F;
  116.         delay_ms(2);
  117.         P2=0xEF;
  118.         P0=0x7F;
  119.         delay_ms(2);
  120.         P1=0x00;
  121.         delay_ms(2);
  122.         }        
  123. }
  124. void int0_inter()interrupt 0                          //INT0外部中断,可暂停、开始所有的单片机状态
  125. {        if(c%2==0)
  126.         {
  127.         g_ucNum=0;                                                         
  128.         TL0=0x18;                                                          //定时器赋初值TL0=(8192-5000)%32
  129.         TH0=0x63;                                                          //THO=(8192-5000)/32
  130.         TR0=1;                                                                  //T0定时器计数
  131.         c++;                                                                  //通过参数c,用一个外部中断按键开关定时器控制单片机的开始与暂停
  132.         }
  133.         else
  134.         {
  135.         TR0=0;                                                                  //T0定时器计数停止计数
  136.         c++;                                                                  //通过参数c,用一个外部中断按键开关定时器控制单片机的开始与暂停
  137.         }
  138. }
  139. void timer0_inter()interrupt 1                          //定时器中断
  140. {
  141.         g_ucNum++;
  142.         TL0=0x18;
  143.         TH0=0x63;
  144. }
  145. void int1_inter()interrupt 2                          //INT1外部中断,切换单片机状态
  146. {
  147.         if(!INT1)
  148.         {
  149.         delay_ms(2);
  150.         if(!INT1)
  151.         {
  152.         K++;
  153.         if(K==7)
  154.         K=1;
  155.         }
  156.         while(!INT1);
  157.         }
  158. }
  159. void main(void)
  160. {
  161.         g_unDisNum=0;                                                  //正序秒表初值
  162.         g_unDisNum1=99999;                                          //逆序秒表初值
  163.         g_ucNum=0;                                                          //定时计数初值
  164.         P0=0xFF;
  165.         P2=0xFF;
  166.         P3=0xFF;
  167.         
  168.         IT0=1;                                                                  //外部中断0下降沿触发
  169.         IT1=1;                                                                  //外部中断1下降沿触发
  170.         EX0=1;                                                                  //外部中断0打开
  171.         EX1=1;                                                                  //外部中断1打开
  172.         TMOD=0;                                                                  //定时器工作模式,工作方式0
  173.         TL0=0x18;                                                          //定时器赋初值TL0=(8192-5000)%32
  174.         TH0=0x63;                                                          //THO=(8192-5000)/32
  175.         ET0=1;                                                                  //打开T/C0溢出中断
  176.         EA=1;                                                                  //打开全局中断
  177.         while(1)
  178.         {
  179.         switch(K)
  180.         {
  181.         case 1:modea();break;
  182.         case 2:modeb();break;
  183.         case 3:mode1();break;
  184.         case 4:mode2();break;
  185.         case 5:mode3();break;
  186.         case 6:mode4();break;
  187.         default:mode5();break;
  188.         }
  189.         }
  190. }
复制代码
0.png

所有资料51hei提供下载:
正逆向秒表流水灯.rar (63.98 KB, 下载次数: 27)

评分

参与人数 1黑币 +90 收起 理由
admin + 90 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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