找回密码
 立即注册
楼主: challis

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

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

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

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 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. }
复制代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 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的内容
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 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来实现增加一秒,以及自动增加分钟和小时
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 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. }
复制代码


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

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

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

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

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

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

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

VID_20240125_223153~1.mp4

1.09 MB, 下载次数: 55

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

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

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:396
  • 最近打卡:2025-05-01 16:33:56

6

主题

101

回帖

411

积分

中级会员

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

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 04:36 , Processed in 0.171431 second(s), 104 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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