找回密码
 立即注册
楼主: cha***

从零开始做一个数码管时钟-开天斧,程序开源 | 已完结

[复制链接]
  • TA的每日心情
    开心
    19 小时前
  • 签到天数: 108 天

    [LV.6]常住居民II

    13

    主题

    199

    回帖

    619

    积分

    高级会员

    积分
    619
     楼主| 发表于 2024-1-26 11:04:33 | 显示全部楼层
    元件和线路测试成功后,主要就是修改程序逻辑了
    我考虑的是做一个小时钟,带按钮,平时就正常冒号闪烁显示时间
    按mode按钮后分钟闪烁,可以通过up/down按钮来调整分钟
    再按一次mode按钮后时钟闪烁,可以通过up/down按钮来调整小时
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    19 小时前
  • 签到天数: 108 天

    [LV.6]常住居民II

    13

    主题

    199

    回帖

    619

    积分

    高级会员

    积分
    619
     楼主| 发表于 2024-1-26 11:05:54 | 显示全部楼层
    为了显示方便,我用seg_4bit_data[4]来直接储存需要显示的内容,用Timer4来循环显示seg_4bit_data的数据
    1. //2毫秒@6.000MHz
    2. void Timer4_Isr(void) interrupt 20
    3. {
    4.     switch(t4_iter)
    5.     {
    6.     case 0:     //seg1
    7.         SEG_4 = 0;
    8.         t4_iter = 1;
    9.         SEG_LED = seg_4bit_data[0];
    10.         SEG_1 = 1;
    11.         break;
    12.     case 1:     //seg2
    13.         SEG_1 = 0;
    14.         t4_iter = 2;
    15.         SEG_LED = seg_4bit_data[1];
    16.         SEG_2 = 1;
    17.         break;
    18.     case 2:     //seg3
    19.         SEG_2 = 0;
    20.         t4_iter = 3;
    21.         SEG_LED = seg_4bit_data[2];
    22.         SEG_3 = 1;
    23.         break;
    24.     case 3:     //seg4
    25.         SEG_3 = 0;
    26.         t4_iter = 0;
    27.         SEG_LED = seg_4bit_data[3];
    28.         SEG_4 = 1;
    29.         break;
    30.     }
    31. }
    复制代码
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    19 小时前
  • 签到天数: 108 天

    [LV.6]常住居民II

    13

    主题

    199

    回帖

    619

    积分

    高级会员

    积分
    619
     楼主| 发表于 2024-1-26 11:07:45 | 显示全部楼层
    最开始所有代码都写在main.c中,发现实在太乱套了,于是,数码管设置相关的函数被抽离出来,写到了seg.h中
    1. #ifndef SEG_H
    2. #define SEG_H
    3. #include "STC8H.h"
    4. #define SEG_NULL 0xff
    5. //led数字
    6. uchar xdata seg_led_data[]={
    7.                 0xC0,  //"0"
    8.                 0xF9,  //"1"
    9.                 0xA4,  //"2"
    10.                 0xB0,  //"3"
    11.                 0x99,  //"4"
    12.                 0x92,  //"5"
    13.                 0x82,  //"6"
    14.                 0xF8,  //"7"
    15.                 0x80,  //"8"
    16.                 0x90,  //"9"
    17.                 0x88,  //"A"
    18.                 0x83,  //"B"
    19.                 0xC6,  //"C"
    20.                 0xA1,  //"D"
    21.                 0x86,  //"E"
    22.                 0x8E,  //"F"
    23.                 0x89,  //"H"
    24.                 0xC7,  //"L"
    25.                 0xC8,  //"n"
    26.                 0xC1,  //"u"
    27.                 0x8C,  //"P"
    28.                 0xA3,  //"o"
    29.                 0xBF,  //"-"
    30.                 0xFF,  //熄灭
    31. };
    32. //4位数码管的具体数据
    33. uchar seg_4bit_data[4] = {SEG_NULL,SEG_NULL,SEG_NULL,SEG_NULL};
    34. //设置前2个数码管,show_dot为是否显示冒号
    35. void SetSeg4BitData_1(uchar d,uchar show_dot)
    36. {
    37.     if(d == SEG_NULL)
    38.     {
    39.         seg_4bit_data[0] = 0xff;
    40.         if(show_dot)
    41.             seg_4bit_data[1] = 0x7f;
    42.         else
    43.             seg_4bit_data[1] = 0xff;
    44.     }
    45.     else
    46.     {
    47.         seg_4bit_data[0] = seg_led_data[d/10];
    48.         if(show_dot)
    49.             seg_4bit_data[1] = seg_led_data[d%10] & 0x7f;
    50.         else
    51.             seg_4bit_data[1] = seg_led_data[d%10];
    52.     }
    53. }
    54. //设置后2个数码管
    55. void SetSeg4BitData_2(uchar d)
    56. {
    57.     if(d == SEG_NULL)
    58.     {
    59.         seg_4bit_data[2] = 0xff;
    60.         seg_4bit_data[3] = 0xff;
    61.     }
    62.     else
    63.     {
    64.         seg_4bit_data[2] = seg_led_data[d/10];
    65.         seg_4bit_data[3] = seg_led_data[d%10];
    66.     }
    67. }
    68. #endif  //SEG_H
    复制代码

    外部直接调用SetSeg4BitData_1,SetSeg4BitData_2来设置前2位数码管和后2位数码管所显示的内容,也就是seg_4bit_data的内容
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    19 小时前
  • 签到天数: 108 天

    [LV.6]常住居民II

    13

    主题

    199

    回帖

    619

    积分

    高级会员

    积分
    619
     楼主| 发表于 2024-1-26 11:09:21 | 显示全部楼层
    将时间相关的代码放到了clock.h文件中
    1. #ifndef CLOCK_H
    2. #define CLOCK_H
    3. uchar hour=0,minute=0,second=0;
    4. void AddSec()
    5. {
    6.     if(second >= 59)
    7.     {
    8.         second = 0;
    9.         if(minute >= 59)
    10.         {
    11.             minute = 0;
    12.             if(hour >= 23)
    13.                 hour = 0;
    14.             else
    15.                 ++hour;
    16.         }
    17.         else
    18.             ++minute;
    19.     }
    20.     else
    21.         ++second;
    22. }
    23. #endif //CLOCK_H
    复制代码

    AddSec来实现增加一秒,以及自动增加分钟和小时
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    19 小时前
  • 签到天数: 108 天

    [LV.6]常住居民II

    13

    主题

    199

    回帖

    619

    积分

    高级会员

    积分
    619
     楼主| 发表于 2024-1-26 11:13:35 | 显示全部楼层
    本帖最后由 grstory 于 2024-1-26 11:17 编辑

    再开一个Timer3定时器来处理业务流程,控制闪烁用is_show_dot变量,每隔500ms将会在1,0间变动,每隔1000ms调用一次AddSec函数,用SetSeg4Bit函数来将需要显示的数据写入具体变量,以供Timer4进行循环显示
    1. #define Mode_Show_1 minute
    2. #define Mode_Show_2 second
    3. void SetSeg4Bit()
    4. {
    5.         SetSeg4BitData_1(Mode_Show_1,is_show_dot);
    6.         SetSeg4BitData_2(Mode_Show_2);
    7. }
    8. //100毫秒@6.000MHz
    9. void Timer3_Isr(void) interrupt 19
    10. {
    11.     ++t3_iter;
    12.     if(t3_iter == 5)
    13.     {
    14.         is_show_dot = !is_show_dot;
    15.         SetSeg4Bit();
    16.     }
    17.     else if(t3_iter == 10)
    18.     {
    19.         AddSec();
    20.         is_show_dot = !is_show_dot;
    21.         SetSeg4Bit();
    22.         t3_iter = 0;
    23.     }
    24. }
    复制代码


    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    19 小时前
  • 签到天数: 108 天

    [LV.6]常住居民II

    13

    主题

    199

    回帖

    619

    积分

    高级会员

    积分
    619
     楼主| 发表于 2024-1-26 11:20:06 | 显示全部楼层
    直接用母对母的插线太不稳定了,经常线就掉了,多掉几根,还需要找对应的接口,于是决定将数码管焊到电路板上,本来想把单片机也焊上去,但是为了以后方便拆卸单片机,就焊了几根带母口的插线到数码管上了,单片机转接板上也焊上了排插
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    19 小时前
  • 签到天数: 108 天

    [LV.6]常住居民II

    13

    主题

    199

    回帖

    619

    积分

    高级会员

    积分
    619
     楼主| 发表于 2024-1-26 11:21:06 | 显示全部楼层
    为了方便调试,正常应该是显示小时,分钟的现在改为显示分钟,秒钟,用了2个宏定义,方便后期修改
    1. #define Mode_Show_1 minute
    2. #define Mode_Show_2 second
    复制代码
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    19 小时前
  • 签到天数: 108 天

    [LV.6]常住居民II

    13

    主题

    199

    回帖

    619

    积分

    高级会员

    积分
    619
     楼主| 发表于 2024-1-26 11:23:54 | 显示全部楼层
    本帖最后由 grstory 于 2024-1-26 11:25 编辑

    烧录程序,接上自制的简易电源,测试,能正常的显示时间流逝,并且冒号闪烁正常了!

    VID_20240125_223153~1.mp4

    1.09 MB, 下载次数: 8

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    19 小时前
  • 签到天数: 108 天

    [LV.6]常住居民II

    13

    主题

    199

    回帖

    619

    积分

    高级会员

    积分
    619
     楼主| 发表于 2024-1-26 11:28:27 | 显示全部楼层
    接下来就是添加按钮,然后实现调整时间的功能了,对了,请问下大佬们,按钮一端接IO口,另一端是接地还是接VCC?中间需要加电阻吗?
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    无聊
    11 小时前
  • 签到天数: 128 天

    [LV.7]常住居民III

    5

    主题

    76

    回帖

    220

    积分

    中级会员

    积分
    220
    发表于 2024-1-26 15:09:43 | 显示全部楼层
    你好这个代码能分享下吗,我做出来的乱码
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-6-12 19:17 , Processed in 0.076885 second(s), 66 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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