找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

单片机DS1302驱动与转换数据以及时序观察问题

查看数: 4297 | 评论数: 44 | 收藏 1
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2022-12-23 15:06

正文摘要:

录像只写了读取秒钟

回复

ID:401564 发表于 2023-2-1 11:48
xianfajushi 发表于 2023-1-31 11:00
为了验证程序员的价值和水平可以做到降低产品成本,我修改了程序抛开时钟芯片用定时期替代秒计时,运行十几 ...

自己回复自己的帖子有意思吗?
一个DS1302再怎么搞,它也就那样,并不能体现一个程序员的代码水平
你搞个无刷电机FOC试一下,你就会知道,DS1302是多么的低端
再说,你整几个月,都还没有搞明白,DS1302的精度跟程序一点关系都没有
"我修改了程序抛开时钟芯片用定时期替代秒计时,运行十几个小时结果和电脑时钟一样精准"
自以为是找到新世界的大门,实际上是连DS1302的门都没有找到
DS1302的精度取决晶振,如果你用的无源晶振,那就得用晶振机(或者叫石英精度测试仪之类的)不断的调试,更改匹配电容来达到高精度的效果如果用的是有源晶振,DS1302的精度主取决有源晶振的误差了,但这一点意义都没有,因为一个有源晶振的价格可以买一个RX8025T了,如果你不知道什么叫RX8025T,那就先去百度一下吧
ID:213173 发表于 2023-1-31 14:42
xianfajushi 发表于 2023-1-31 11:00
为了验证程序员的价值和水平可以做到降低产品成本,我修改了程序抛开时钟芯片用定时期替代秒计时,运行十几 ...

就单纯做时钟而言本来就是用单片机远比1302精准。理论精度达10ns级。采用计时专用芯片的好处是掉电不停止走时,做万年历还可省去繁琐的大小月、润月、闰年、世纪年的计算。如果算成本,批量定制电子钟专用的邦定封装芯片比单片机成本还低。
ID:332444 发表于 2023-1-31 11:14
对了有一点需要补充就是程序里面写的定时期频率仿真电路芯片的时钟频率需要保持一致否则会偏差,比如程序写11.0592Mhz那么仿真电路图中的单片机属性里面的时钟频率也要修改为11.0592Mhz保持相同,如果是12Mhz则走快了,反过来如果程序写12Mhz而仿真是11.0592Mhz则会走慢。
ID:332444 发表于 2023-1-29 15:43
突发奇想,用数码管显示每周的值:一二三四五六日。64,64,9,9,73,73,63,63,9,61,81,69,121,79
ID:332444 发表于 2023-1-29 08:55
wulin 发表于 2023-1-28 20:56
所谓合理是相对的,在不影响其它功能的前提下频繁读1302也并无不可,单片机也累不死。只能说在现有硬件条 ...

如果能够把程序打造得轻便即可用计时器中断实现比较精准的计时抛却时钟芯片目标,毕竟兆赫兹的精度比千赫兹提高了一个数量级别。
ID:332444 发表于 2023-1-29 08:50
wulin 发表于 2023-1-28 20:56
所谓合理是相对的,在不影响其它功能的前提下频繁读1302也并无不可,单片机也累不死。只能说在现有硬件条 ...

只有了然于胸才能驾轻就熟
ID:332444 发表于 2023-1-29 08:29
wulin 发表于 2023-1-28 20:56
所谓合理是相对的,在不影响其它功能的前提下频繁读1302也并无不可,单片机也累不死。只能说在现有硬件条 ...

不断优化就是对逻辑思维的验证,从而实现卖油翁的过程.
其实不然我认为频繁读取对精度有所影响,就好比开定时器中断应该说没什么影响,然而实践告诉人们,轻便的程序对定时器计时精度没多大影响,而复杂的程序对定时器计时精度就有影响,中断也要获得响应时间的,电路也是一样的总要拨点时间去处理其他事件.
ID:213173 发表于 2023-1-28 20:56
xianfajushi 发表于 2023-1-28 17:08
那么怎样才合理?之上已经说了,寻求合理的安排,目前把读秒压缩在每秒4次左右,在不开定时期情况下;若开定时 ...

所谓合理是相对的,在不影响其它功能的前提下频繁读1302也并无不可,单片机也累不死。只能说在现有硬件条件下,满足所有功能预期,互相不发生冲突是需要一定的编程技巧。刻意追求主函数周期减小到十几微秒又有多少实际意义。
ID:213173 发表于 2023-1-28 20:39
xianfajushi 发表于 2023-1-28 10:27
频繁读取1302全部数据是否会影响其计时精度?目前猜测而已没什么证据。

频繁读取1302全部数据不会影响其计时精度,但对于你刻意精打细算主循环时间肯定有影响。比如蜂鸣器音调会不稳。
ID:332444 发表于 2023-1-28 17:08
wulin 发表于 2023-1-28 09:13
这个限制条件不完善,在Mbcd=0的1秒时间内会多次读1302,如果是跨年的那1秒内,则重复多次读全部数据。当 ...

那么怎样才合理?之上已经说了,寻求合理的安排,目前把读秒压缩在每秒4次左右,在不开定时期情况下;若开定时器按每秒读取然而定时器未必就能精确每秒夜有不精确时候就会造成漏读秒的情况发生.
ID:332444 发表于 2023-1-28 10:27
wulin 发表于 2023-1-28 09:13
这个限制条件不完善,在Mbcd=0的1秒时间内会多次读1302,如果是跨年的那1秒内,则重复多次读全部数据。当 ...

频繁读取1302全部数据是否会影响其计时精度?目前猜测而已没什么证据。
ID:213173 发表于 2023-1-28 09:13
xianfajushi 发表于 2023-1-10 17:13
限制条件的读是最合理的时间安排
Mbcd=Du_1302(0x81);
if(Mbcd==0)Fbcd=Du_1302(0x83);

这个限制条件不完善,在Mbcd=0的1秒时间内会多次读1302,如果是跨年的那1秒内,则重复多次读全部数据。当然这属吹毛求疵,未必影响其它程序正常运行。何况是在半夜,谁还会去计较。
ID:332444 发表于 2023-1-27 07:29
wulin 发表于 2023-1-9 17:17
用定时器的目的是控制主函数循环周期,以便轻松处理按键消抖和按键长短按计数以及数码管动态扫描。如果在 ...

中断+计数的1毫秒间隔或200微妙能做多少事还真的没什么案例,本案例旨在说明询问式计数延时相比独占计数延时的优越且灵活调节和设置,属于高级分析思维模式,而非入门级别独占计数延时一直套用引发种种疑难。
ID:332444 发表于 2023-1-18 10:14
经过几次试验目前把读秒信号压缩到每秒4次左右基本察觉不到太大差别可以接受的程度,调整后蜂鸣器音调频率也发生变化能听出区别来。
ID:332444 发表于 2023-1-15 12:52
人中狼 发表于 2023-1-12 08:39
这个就是纯粹的强调所谓的效率两个字而已,但实际应用中效率到底又指什么呢

其它都不用说,有好的程序拿来看看。
我家一台旭日红外热水器无线控制器每周都快1小时多,比如时间是6点看它屏幕走时已经是7点多了,每次都要去调整时间,否则计算峰谷的时间就不准确了!非常麻烦,是很差劲的产品质量,可以断定是很差劲的程序代码,所以莫要小看简单的程序提高效率问题,所谓见微知著,简单的功能都不能注重效率的话,可知复杂功能是很有问题的。
ID:384109 发表于 2023-1-12 08:39
这个就是纯粹的强调所谓的效率两个字而已,但实际应用中效率到底又指什么呢
ID:401564 发表于 2023-1-11 13:22
188610329 发表于 2023-1-11 00:20
ds1302来说,你真要节约宝贵的系统资源,就用硬件读写。不管用spi读写,还是串口1读写,都比你IO读写,占 ...

从主程序中看到,这就是一个1302时钟,其它什么事都没干,压根就不需要节约什么时间,效率什么的都是没有什么意义的
1秒钟读取一次,延时直接用delay();
按键一样的直接延时去抖动,没必要折腾那么多东西
或者是说用读取的时间来作为数码管的延时,都比楼主折腾这个好
我也不知道,把单片机时间节约成这样子,是为了什么?
是怕单片机累坏了?还是怕单片机长时间延时会闹情绪
我看了半天,都不知道“独占时间”是个什么玩意
ID:624769 发表于 2023-1-11 00:20
xianfajushi 发表于 2023-1-10 16:50
优化的读取是秒=0则读分,分=0则读时,不需要频繁读分和时信息,这样就可以节省很多宝贵的时间资源.

ds1302来说,你真要节约宝贵的系统资源,就用硬件读写。不管用spi读写,还是串口1读写,都比你IO读写,占用系统时钟少。
ID:332444 发表于 2023-1-10 23:01
在不开定时器情况下也可以比较精准控制只读一次秒信息精度控制在毫秒以下,因为上述说过了的6毫秒和40毫秒周期,因此可以比较精准控制去读秒信息一次足够,而不需要无谓的多次读取,同样道理读天月年也可以按条件读取,只是不开定时器情况下按我的思路是实现所有功能代码后再进行比较精准的控制读秒信息,因为不同功能的程序周期也不同,就比如6毫秒和40毫秒周期一般道理。
ID:332444 发表于 2023-1-10 17:13
wulin 发表于 2023-1-9 17:17
用定时器的目的是控制主函数循环周期,以便轻松处理按键消抖和按键长短按计数以及数码管动态扫描。如果在 ...

限制条件的读是最合理的时间安排
Mbcd=Du_1302(0x81);
if(Mbcd==0)Fbcd=Du_1302(0x83);
if(Mbcd==0&&Fbcd==0)Sbcd=Du_1302(0x85);
ID:332444 发表于 2023-1-10 16:59
wulin 发表于 2023-1-9 17:17
用定时器的目的是控制主函数循环周期,以便轻松处理按键消抖和按键长短按计数以及数码管动态扫描。如果在 ...

之前代码是秒分时频繁都去读取,其实没必要,因此修改后的代码就是按条件限制的读取
Mbcd=Du_1302(0x81);
if(Mbcd==0)Fbcd=Du_1302(0x83);
if(Fbcd==0)Sbcd=Du_1302(0x85);
ID:332444 发表于 2023-1-10 16:50
wulin 发表于 2023-1-9 17:17
用定时器的目的是控制主函数循环周期,以便轻松处理按键消抖和按键长短按计数以及数码管动态扫描。如果在 ...

优化的读取是秒=0则读分,分=0则读时,不需要频繁读分和时信息,这样就可以节省很多宝贵的时间资源.
ID:213173 发表于 2023-1-9 17:17
xianfajushi 发表于 2023-1-5 07:29
今早想起来要补充说明不开定时器的情况下,就用简单的功能来测试,蜂鸣器一定要的,若要其它功能不是不会 ...

用定时器的目的是控制主函数循环周期,以便轻松处理按键消抖和按键长短按计数以及数码管动态扫描。如果在主函数中加无源蜂鸣器驱动就得缩短定时周期也就是主函数循环周期。大约200us。因为无源蜂鸣器有特定的驱动频率要求,常见的廉价无源蜂鸣器约2KHz声压最大。若主函数循环周期不稳定蜂鸣器音量声调也不会稳定。这不是仿真就可以搞定的。通常情况下200us可以干很多很多事。对于某些在一个主循环周期内做不完的事可以拆分。单片机玩的就是时间和逻辑。说白了就是在什么时间点干什么事。
ID:332444 发表于 2023-1-9 16:05
通过我提供的测试图片一看就知道单片机的时间都到哪去了,也就知道优化该从何处下手了,我之所以说我的程序还能进一步优化,指的是读取芯片的频次可以进一步减少而不会明显影响显示精度,按目前图片的时间约50毫秒的频次显然有很多次去读取是不必要的,因此是可以继续优化的,至于多少次或说多少时间去读取一次合理,就值得探讨了,各位高手不妨畅言高论。
ID:332444 发表于 2023-1-5 07:29
wulin 发表于 2023-1-4 20:42
这种要求的程序很简单,也用不着138、573,给你一个示例参考,另加闹钟也是轻而易举的事。黑币你就自己留 ...

今早想起来要补充说明不开定时器的情况下,就用简单的功能来测试,蜂鸣器一定要的,若要其它功能不是不会提出来,我自己代码也是不开定时器,不使用额外循环计数延时,我的测试周期还可以优化再减小。
ID:332444 发表于 2023-1-5 07:05
wulin 发表于 2023-1-4 20:42
这种要求的程序很简单,也用不着138、573,给你一个示例参考,另加闹钟也是轻而易举的事。黑币你就自己留 ...

不错,通篇没用到计数延时。
ID:332444 发表于 2023-1-5 07:02
wulin 发表于 2023-1-4 20:42
这种要求的程序很简单,也用不着138、573,给你一个示例参考,另加闹钟也是轻而易举的事。黑币你就自己留 ...

实在是抱歉,我忘记了说明是不开定时器的情况下,就用简单的功能做测试,不要看表面功能简单,练就的是功夫。
ID:213173 发表于 2023-1-4 20:42
xianfajushi 发表于 2023-1-4 07:12
可以这样说,以贴出来的电路和只读取1302的时分秒送8位数码管显示,并有整点4响半点2响为功能,并在主函数w ...

这种要求的程序很简单,也用不着138、573,给你一个示例参考,另加闹钟也是轻而易举的事。黑币你就自己留着吧。


  1. #include <reg51.H>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. #define key_S 8                                        //宏定义短按(约20ms)
  6. #define key_L key_S*30                        //宏定义长按(约600ms)
  7. #define key_I key_S*20                        //宏定义长按连+间隔(约200ms)
  8. //DS1302引脚连接定义
  9. sbit DSIO = P3^2;
  10. sbit REST = P3^0;
  11. sbit SCLK = P3^1;
  12. sbit key1 = P3^3;
  13. uchar code table[]={//共阴数码管段码"0~f-."
  14. 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x80};
  15. uchar dis_buf[8]={0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00};                //数码管显示缓存数组
  16. //DS1302读取和写入时分秒日月周年的地址
  17. uchar code READ_RTC_ADDR[7]=  {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; //读出地址
  18. uchar code WRITE_RTC_ADDR[7]= {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; //写入地址
  19. //              秒    分    时    日    月    周    年
  20. uchar TIME[7]={0x00, 0x00, 0x12, 0x04, 0x01, 0x03, 0x23};//读取Ds1302 存储顺序是秒分时日月周年
  21. //---全局变量声明---
  22. uint  Cnt2ms;                //2.5ms计数变量
  23. uint  num;                    //计数变量
  24. uchar KeySec;                 //键值变量
  25. bit   flashing;               //闪烁标志
  26. //---本地函数声明---//
  27. void Ds1302Init();            //DS1302初始化
  28. void Ds1302Write(uchar addr, uchar dat);//向1302芯片写入地址和数据
  29. uchar Ds1302Read(uchar addr); //从1302读数据
  30. void Ds1302ReadTime();        //读取秒分时日月周年信息
  31. uchar BCD_D(uchar bcd);       //BCD码转十进制函数
  32. uchar D_BCD(uchar Dec);       //十进制转BCD码函数
  33. void Timer0Init(void);        //定时器T0初始化
  34. //==============DS1302驱动部分=====================
  35. //写1302时钟数据
  36. void Ds1302Write(uchar addr, uchar dat)
  37. {
  38.         uchar i;
  39.         REST= 0;
  40.         SCLK= 0;
  41.         REST= 1;
  42.         for(i=0;i<8;i++)       // 写地址
  43.         {
  44.                 DSIO=addr & 0x01;  //数据从低位开始传送
  45.                 addr>>=1;
  46.                 SCLK = 1;          //数据在上升沿时,DS1302读取数据
  47.                 SCLK = 0;
  48.         }
  49.         for(i=0;i<8;i++)       //写数据
  50.         {
  51.                 DSIO=dat & 0x01;
  52.                 dat>>= 1;
  53.                 SCLK = 1;           // 数据在上升沿时,DS1302读取数据
  54.                 SCLK = 0;       
  55.         }                 
  56.         REST = 0;                // 传送数据结束       
  57. }
  58. //读1302时钟数据
  59. uchar Ds1302Read(uchar addr)
  60. {
  61.         uchar i,dat,dat1;
  62.         REST = 0;
  63.         SCLK = 0;
  64.         REST = 1;
  65.         for(i=0; i<8; i++)      // 开始传送八位地址命令
  66.         {
  67.                 DSIO = addr & 0x01; // 数据从低位开始传送
  68.                 addr >>= 1;
  69.                 SCLK = 1;           // 上升沿有效,DS1302读取数据
  70.                 SCLK = 0;
  71.         }
  72.         for(i=0;i<8;i++)        // 读取8位数据
  73.         {
  74.                 dat1 = DSIO;        // 从最低位开始接收
  75.                 dat=(dat>>1)|(dat1<<7);
  76.                 SCLK = 1;           // 上升沿有效,DS1302读取数据
  77.                 SCLK = 0;
  78.         }
  79.         REST = 0;               // 以下为DS1302复位的稳定时间,必须的。                   
  80.         SCLK = 1;
  81.         DSIO = 0;
  82.         DSIO = 1;
  83.         return dat;       
  84. }
  85. //初始化DS1302
  86. void Ds1302Init()
  87. {
  88.         uchar i;
  89.         Ds1302Write(0x8E,0x00);   // 禁止写保护功能
  90.         for(i=0;i<3;i++)          // 写入3个字节的时钟信号:分秒时       
  91.                 Ds1302Write(WRITE_RTC_ADDR[i],TIME[i]);
  92.         Ds1302Write(0x8E,0x80);   // 打开写保护功能
  93. }
  94. //BCD码转十进制函数
  95. uchar BCD_D(uchar bcd)
  96. {
  97.         return ((bcd>>4)*10)+(bcd & 0x0f);
  98. }
  99. //十进制转BCD码函数,返回BCD码
  100. uchar D_BCD(uchar Dec)
  101. {
  102.         return (Dec/10*16+Dec%10);
  103. }

  104. //读取时钟信息
  105. void Ds1302ReadTime()
  106. {
  107.         uchar i;
  108.         for(i=0;i<3;i++)         //读取3个字节的时钟信号:秒分时
  109.                 TIME[i]=BCD_D(Ds1302Read(READ_RTC_ADDR[i]));//BCD转换成十进制保存
  110. }

  111. //按键服务函数
  112. void key_scan()
  113. {
  114.         static uint time=0;  //计数变量

  115.         if(!key1)       //按键按下
  116.         {
  117.                 time++;
  118.                 if(time>=key_L)  //长按
  119.                 {
  120.                         switch(KeySec)
  121.                         {
  122.                                 case 1: TIME[2]++;if(TIME[2]>23)TIME[2]=0;break;
  123.                                 case 2: TIME[1]++;if(TIME[1]>59)TIME[1]=0;TIME[0]=0;break;
  124.                         }
  125.                         time=key_I;  //连+间隔
  126.                         num=2000;     //自复位变量赋值(5秒)
  127.                 }
  128.         }
  129.         else                                //松手
  130.         {
  131.                 if(time>key_S && time<key_I)//短按
  132.                 {
  133.                         num=2000;    //自复位变量赋值(5秒)
  134.                         KeySec++;
  135.                         if(KeySec>2)
  136.                         {
  137. //                                KeySec=0;
  138.                                 num=1;
  139.                         }
  140.                 }
  141.                 time=0;
  142.         }
  143. }

  144. // 数码管显示函数
  145. void display()
  146. {
  147.         uchar i;
  148.         if(KeySec==0)           //常态显示
  149.         {
  150.                 dis_buf[0]=table[TIME[2]/10];
  151.                 dis_buf[1]=table[TIME[2]%10];
  152.                 dis_buf[3]=table[TIME[1]/10];
  153.                 dis_buf[4]=table[TIME[1]%10];
  154.                 dis_buf[6]=table[TIME[0]/10];
  155.                 dis_buf[7]=table[TIME[0]%10];
  156.         }
  157.         if(KeySec==1)           //调整时
  158.         {
  159.                 if(!key1)//持续不变表示键长按连加,时不闪烁
  160.                 {
  161.                         dis_buf[0]=table[TIME[2]/10];
  162.                         dis_buf[1]=table[TIME[2]%10];
  163.                 }
  164.                 else                //松手 时闪烁
  165.                 {
  166.                         if(flashing)
  167.                         {
  168.                                 dis_buf[0]=table[TIME[2]/10];
  169.                                 dis_buf[1]=table[TIME[2]%10];
  170.                         }
  171.                         else
  172.                         {
  173.                                 dis_buf[0]=0x00;
  174.                                 dis_buf[1]=0x00;
  175.                         }
  176.                 }
  177.                 dis_buf[3]=table[TIME[1]/10];
  178.                 dis_buf[4]=table[TIME[1]%10];
  179.                 dis_buf[6]=table[TIME[0]/10];
  180.                 dis_buf[7]=table[TIME[0]%10];

  181.         }
  182.         if(KeySec==2)           //调整分
  183.         {
  184.                 dis_buf[0]=table[TIME[2]/10];
  185.                 dis_buf[1]=table[TIME[2]%10];
  186.                 if(!key1)//持续不变表示键长按连加,分不闪烁
  187.                 {
  188.                         dis_buf[3]=table[TIME[1]/10];
  189.                         dis_buf[4]=table[TIME[1]%10];
  190.                 }
  191.                 else                //松手 分闪烁
  192.                 {
  193.                         if(flashing)
  194.                         {
  195.                                 dis_buf[3]=table[TIME[1]/10];
  196.                                 dis_buf[4]=table[TIME[1]%10];
  197.                         }
  198.                         else
  199.                         {
  200.                                 dis_buf[3]=0x00;
  201.                                 dis_buf[4]=0x00;
  202.                         }
  203.                 }
  204.                 dis_buf[6]=table[TIME[0]/10];
  205.                 dis_buf[7]=table[TIME[0]%10];
  206.         }
  207.         P2=0xff;
  208.         P0=dis_buf[i];
  209.         P2=~(0x01<<i);
  210.         i=++i%8;
  211. }
  212. //初始化定时器
  213. void Timer0Init(void)                //2500微秒@12.000MHz
  214. {
  215.         TMOD |= 0x01;                //设置定时器模式
  216.         TL0 = 0x3C;                //设置定时初始值
  217.         TH0 = 0xF6;                //设置定时初始值
  218.         TF0 = 0;                //清除TF0标志
  219.         TR0 = 1;                //定时器0开始计时
  220. }
  221. //主函数
  222. void main()
  223. {
  224.         uchar t;
  225.         Ds1302Init();
  226.         Timer0Init();   //初始化定时器
  227.         while(1)
  228.         {
  229.                 if(TF0)    //周期2.5ms
  230.                 {
  231.                         TF0=0;
  232.                         TL0 = 0x3C;                //设置定时初始值
  233.                         TH0 = 0xF6;                //设置定时初始值
  234.                         if(++Cnt2ms==400)Cnt2ms=0;
  235.                         key_scan();//按键扫描
  236.                         if(num!=0)
  237.                         {
  238.                                 if(Cnt2ms%80==0)//0.2s 设置状态时、分快闪
  239.                                         flashing=~flashing;
  240.                                 num--;
  241.                                 if(num==0)//按键停止操作5秒自动恢复正常显示
  242.                                 {
  243.                                         for(t=1;t<3;t++)//数据转码导入写入缓存
  244.                                                 TIME[t]=D_BCD(TIME[t]);//十进制转BCD码
  245.                                         Ds1302Init();//写入实时时间
  246.                                         KeySec=0;//键值清0
  247.                                 }
  248.                         }
  249.                         else //设置时间时 不读取DS1302实时时间
  250.                         {
  251.                                 Ds1302ReadTime();//读DS1302实时时间
  252.                         }
  253.                         display();// 数码管显示函数
  254.                 }
  255.         }
  256. }

复制代码



ID:401564 发表于 2023-1-4 20:03
xianfajushi 发表于 2023-1-4 07:12
可以这样说,以贴出来的电路和只读取1302的时分秒送8位数码管显示,并有整点4响半点2响为功能,并在主函数w ...

我这几年编程白学了?我怎么看了几次都看不明白这段文字表达了什么...........
ID:996773 发表于 2023-1-4 13:31
没看懂楼主的目的,楼主用的是138解码逐个点亮数码管的扫描方式,读取1302数据和bcd转换十进制再查表只需要在点亮一个数码管周期内完成,其余时间只能等待延时,不延时还能干嘛呢,还有啊,这程序太简单了,很多功能都没实现,操作不用按钮,使用旋转编码器,年月日和闹钟都没实现呢,这些都实现了,再找优化方案和程序精简

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

Powered by 单片机教程网

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