单片机 数码管led 显示电子钟(c语言)转载,单片机 数码管LED 显示电子钟(C语言)转载...

单片机 数码管LED 显示电子钟(C语言)转载

2018-11-24

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++);    }

7054295_1.jpg

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。

http://www.pinlue.com/style/images/nopic.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值