数列极限的几何解释:单片机 数码管LED 显示电子钟(C语言)转载

来源:百度文库 编辑:偶看新闻 时间:2024/04/27 16:52:21
单片机 数码管LED 显示电子钟(C语言)转载2010-10-22 01:32
  • /**************************************************************************
  • * 标题: 数码管显示电子钟(C语言)
  • * 作者: wentao
  • * 日期: 2007.3.3
  • * 软件: Keil C51 V8.02
  • * 芯片: AT89X51
  • * 说明: 实验板实测通过,数码管为8位共阳
  • * 声明: 自用存档!另仅供需要的朋友参考,请勿用做不道德转载及商业用途!
  • **************************************************************************/  
  •   
  • #include   
  • #include   
  • #define uchar unsigned char   
  •   
  • void delay_ms(uchar ms);  // 延时毫秒@12M,ms最大值255   
  • void key_scan();          // 按键扫描   
  • void key_to();            // 按键处理   
  •   
  • uchar code dis_code[11] = {0xc0,0xf9,0xa4,0xb0,0x99,       //段码表   
  •                           // 0     1     2     3     4          对应内容   
  •                             0x92,0x82,0xf8,0x80,0x90,0xbf};   
  •                           // 5     6     7     8     9     -   
  •   
  • uchar data dis[8];       // dis[0]为秒个位值,dis[1]为秒十位值   
  •                          // dis[2],dis[5]为'-'段码的偏移量   
  •                          // dis[3]为分个位值,dis[4为分十位值   
  •                          // dis[6]为时个位值,dis[7]为时十位值   
  •   
  • uchar data sec = 0;      // 秒计数器(00s-59s)   
  • uchar data min = 0;      // 分计数器(00m-59m)   
  • uchar data hou = 0;      // 时计数器)00h-23h)   
  •   
  • uchar data cou   = 0;     // 软计数器,对10ms时基信号累加到1s   
  •   
  • uchar data dis_b;        // dis_b为位码选通数码管   
  • uchar data dis_r;        // dis_r为取段码时的偏移量   
  •   
  • uchar data key_v = 0;    // 存储键值   
  • uchar data key_t = 0;    // 按键扫描中临时存储键值   
  •   
  • void main()   
  • {   
  •     P2 = 0xff;           // 关所有数码管   
  •     P1 = 0xff;           // p1为准双向口,作输入时先写1   
  •      dis[2] = 10;         // '-'在段码表中偏移量为10   
  •      dis[5] = 10;         // '-'在段码表中偏移量为10   
  •      dis_b = 0x7f;        // 初始选通P2.7口数码管   
  •      dis_r = 0;           // 初始化偏移量为0   
  •        
  •     TMOD = 0x11;         // 定时/计数器0,1工作于方式1   
  •     TH0 = 0xd8;          // 预置定时常数55536(d8f0),产生10ms时基信号   
  •     TL0 = 0xf0;   
  •     TH1 = 0xfc;          // 预置定时常数64536(fc18),产生1ms间隔用于动态显示   
  •     TH1 = 0x18;   
  •     EA = 1;              // 开总中断   
  •     ET0 = 1;             // 定时/计数器0允许中断   
  •     ET1 = 1;             // 定时/计数器1允许中断   
  •     TR0 = 1;             // 开闭定时/计数器0   
  •     TR1 = 1;             // 启动定时/计数器1   
  •     while(1)   
  •      {   
  •          key_t = P1;            // 读入键值   
  •         if(key_t != key_v)     // 键值改变   
  •          {   
  •              delay_ms(10);      // 延时10ms消抖   
  •              key_t = P1;        // 再次读入键值   
  •             if(key_t != key_v) // 键值仍未改变则不是抖动   
  •              {   
  •                  key_v = key_t; // 保存键值   
  •                  key_to();      // 键处理   
  •              }   
  •          }   
  •      }   
  • }   
  • void key_to()                  // 按键处理子程序   
  • {   
  •     if(key_v == 0xef)          // P1.4口键值   
  •      {   
  •         if(min == 59)          // 分计数已加到59   
  •              min = 0;           // 清零之   
  •         else  
  •              min++;             // 否则加1   
  •      }   
  •     else  
  •      {   
  •         if(key_v == 0xdf)      // P1.5口键值   
  •          {   
  •             if(hou == 23)      // 时计数已加到23   
  •                  hou = 0;       // 清零之   
  •             else  
  •                  hou++;         // 否则加1   
  •          }   
  •      }   
  • }   
  • void tiem0(void) interrupt 1   // T/C0中断服务程序(产生10ms时基信号)   
  • {   
  •      cou++;                     // 软计数器加1   
  •     if(cou == 100)             // 计数值到100(1s)   
  •      {   
  •          cou = 0;               // 软计数器清零   
  •          sec++;                 // 秒计数器加1(进位10ms*100=1s)   
  •         if(sec == 60)          // 秒计数值到60   
  •          {   
  •              sec = 0;           // 秒计数器清零   
  •              min++;             // 分计数器加1(进位60s=1m)   
  •             if(min == 60)      // 分计数到60   
  •              {   
  •                  min = 0;       // 分计数器清零   
  •                  hou++;         // 时计数器加1(进位60m=1h)   
  •                 if(hou == 23)  // 时计数到23   
  •                      hou = 0;   // 时计数器清零   
  •              }   
  •          }   
  •      }   
  •     TH0 = 0xd8;                // 重置定时常数   
  •     TL0 = 0xf0;   
  • }   
  • void time1(void) interrupt 3   // T/C1中断服务程序(延时1ms数码管动态显示)   
  • {   
  •      dis[0] = sec % 10;         // 秒计数器个位赋绐dis[0]   
  •      dis[1] = sec / 10;         // 秒计数器十位赋绐dis[1]   
  •      dis[3] = min % 10;         // 分计数器个位赋绐dis[3]   
  •      dis[4] = min / 10;         // 分计数器十位赋绐dis[4]   
  •      dis[6] = hou % 10;         // 时计数器个位赋绐dis[6]   
  •      dis[7] = hou / 10;         // 时计数器十位赋绐dis[7]   
  •   
  •     P0 = dis_code[dis[dis_r]]; // 段码送P0口(dis[0]...dis[7])   
  •     P2 = dis_b;                // 位码送P2口   
  •   
  •      dis_r++;                   // 偏移量加1,下次中断时显示下个数   
  •      dis_r &= 0x07;             // dis_r增到8时自动清0(使之在0到7间循环)   
  •        
  •      dis_b = _cror_(dis_b,1);   // 位码循环右移,下次中断时选通下个数码管   
  •   
  •     TH1 = 0xfc;                // 重置定时常数   
  •     TL1 = 0x18;   
  •   
  • }   
  • void delay_ms(uchar ms)       // 延时毫秒@12M,ms最大值255   
  • {   
  •     uchar i;   
  •     while(ms--)   
  •         for(i = 0; i < 124; i++);   
  • }