找回密码
 立即注册
查看: 1431|回复: 8

SDCC 计算延迟的问题

[复制链接]

5

主题

12

回帖

95

积分

注册会员

积分
95
发表于 2023-7-17 11:11:06 | 显示全部楼层 |阅读模式
我是用 SDCC 编译器,使用官方stc-isp生成的延迟函数时间不精准,如何根据晶振的频率计算出精准延迟,并在sdcc编译环境中。
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:38
  • 最近打卡:2025-04-30 14:38:57

25

主题

977

回帖

3599

积分

超级版主

积分
3599
发表于 2023-7-17 18:27:05 | 显示全部楼层
STC下载软件提供的软件延时都是基于Keil的
SDCC的代码优化相比Keil要差一些,同样的延时代码,sdcc编译后执行时间要长一些

如果要在SDCC环境下定义很精准的代码延时,你只能先编译,然后再看反汇编,通过数指令周期数对循环次数进行调整
回复 支持 1 反对 0

使用道具 举报 送花

11

主题

340

回帖

929

积分

荣誉版主

积分
929
发表于 2023-7-17 20:06:29 | 显示全部楼层
本帖最后由 熊仔 于 2023-7-17 21:06 编辑

keil C51编译,优化等级8. 可以看看翻译汇编,计算下用了多少个指令周期
  1. //keil代码
  2. void delay_ms(uint16_t ms)
  3. {
  4.         uint16_t i;
  5.         do{
  6.                 i = MAIN_Fosc / 10000;  //10T
  7.                 while(--i);
  8.         }while(--ms);
  9. }
复制代码



keil编译 i--循环一次大概10T。
所以 i = MAIN_Fosc / 10000;  //10T




回复 支持 反对

使用道具 举报 送花

11

主题

340

回帖

929

积分

荣誉版主

积分
929
发表于 2023-7-17 20:15:38 | 显示全部楼层
本帖最后由 熊仔 于 2023-7-17 20:48 编辑

如果使用sdcc编译,large模式,汇编代码真的很长
  1. _delay_ms:
  2.         mov        r7,dph
  3.         mov        a,dpl
  4.         mov        dptr,#_delay_ms_ms_65536_18
  5.         movx        @dptr,a
  6.         mov        a,r7
  7.         inc        dptr
  8.         movx        @dptr,a
  9. ;        src\main.c:30: do{
  10.         mov        dptr,#_delay_ms_ms_65536_18
  11.         movx        a,@dptr
  12.         mov        r6,a
  13.         inc        dptr
  14.         movx        a,@dptr
  15.         mov        r7,a
  16. ;        src\main.c:32: while(--i);
  17. 00109$:
  18.         mov        r4,#0x60
  19.         mov        r5,#0x09
  20. 00101$:
  21.         dec        r4
  22.         cjne        r4,#0xff,00126$
  23.         dec        r5
  24. 00126$:
  25.         mov        a,r4
  26.         orl        a,r5
  27.         jnz        00101$
  28. ;        src\main.c:33: }while(--ms);
  29.         dec        r6
  30.         cjne        r6,#0xff,00128$
  31.         dec        r7
  32. 00128$:
  33.         mov        dptr,#_delay_ms_ms_65536_18
  34.         mov        a,r6
  35.         movx        @dptr,a
  36.         mov        a,r7
  37.         inc        dptr
  38.         movx        @dptr,a
  39.         mov        a,r6
  40.         orl        a,r7
  41.         jnz        00109$
  42.         mov        dptr,#_delay_ms_ms_65536_18
  43.         mov        a,r6
  44.         movx        @dptr,a
  45.         mov        a,r7
  46.         inc        dptr
  47.         movx        @dptr,a
  48. ;        src\main.c:34: }
  49.         ret
复制代码
执行的代码确实很多,主要看中间 i-- 部分代码
  1. 00101$:
  2.         dec        r4
  3.         cjne        r4,#0xff,00126$
  4.         dec        r5
  5. 00126$:
  6.         mov        a,r4
  7.         orl        a,r5
  8.         jnz        00101$
复制代码
这里共需要9T,比keil生成的汇编少了1T。
所以 i = MAIN_Fosc / 9000;  //9T

最终延时函数修改成下面:
  1. void delay_ms(uint16_t ms)
  2. {
  3.         uint16_t i;
  4.         do{
  5.                 i = MAIN_Fosc / 9000;  //9T
  6.                 while(--i);
  7.         }while(--ms);
  8. }
复制代码

改9000后,汇编r4,r5 的值变了,24000000/9000=2666=0x0A6A
  1. 00109$:
  2.         mov        r4,#0x6a
  3.         mov        r5,#0x0a
复制代码


当然因为参数ms保存在xdata空间,导致外循环时间稍微有点长。导致延时稍微加长。



  1. void main(void)
  2. {   
  3.         
  4.     while (1)
  5.     {        
  6.                 P3 = ~P3;
  7.                 delay_ms(10);
  8.     }
  9.    
  10. }
复制代码
实测效果还是挺准的。






回复 支持 1 反对 0

使用道具 举报 送花

11

主题

340

回帖

929

积分

荣誉版主

积分
929
发表于 2023-7-17 21:00:55 | 显示全部楼层
sdcc编译器,delay_ms函数形参加上 __data修饰符,ms变量就用寄存器保存。汇编代码和keil差不多。


C代码:

  1. #define MAIN_Fosc                24000000        //定义主时钟
  2. void delay_ms(uint16_t __data ms)
  3. {
  4.         uint16_t i;
  5.         // uint16_t _ms = ms;
  6.         do{
  7.                 i = MAIN_Fosc / 9000;  //9T
  8.                 while(--i);
  9.         }while(--ms);
  10. }
复制代码
汇编代码:
  1. _delay_ms:
  2.         mov        r6,dpl
  3.         mov        r7,dph
  4. ;        src\main.c:33: while(--i);
  5. 00109$:
  6.         mov        r4,#0x6a
  7.         mov        r5,#0x0a
  8. 00101$:
  9.         dec        r4
  10.         cjne        r4,#0xff,00123$
  11.         dec        r5
  12. 00123$:
  13.         mov        a,r4
  14.         orl        a,r5
  15.         jnz        00101$
  16. ;        src\main.c:34: }while(--ms);
  17.         dec        r6
  18.         cjne        r6,#0xff,00125$
  19.         dec        r7
  20. 00125$:
  21.         mov        a,r6
  22.         orl        a,r7
  23.         jnz        00109$
  24. ;        src\main.c:35: }
  25.         ret
复制代码
测量结果更准一点。




回复 支持 2 反对 0

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-02 07:55:56
已绑定手机

19

主题

3191

回帖

4872

积分

论坛元老

积分
4872
发表于 2024-3-13 11:50:52 | 显示全部楼层
本帖最后由 soma 于 2024-3-23 00:31 编辑

keil毕竟是代码优化最好的编译器
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:21
  • 最近打卡:2024-08-08 21:16:41

5

主题

14

回帖

28

积分

新手上路

积分
28
发表于 2024-3-22 07:57:22 | 显示全部楼层
sdcc更新后代码优化似乎更好了
  1. // sdcc --std-sdcc2x --model-large --opt-code-speed --code-size 0xffff --xram-size 0x2000 -c delay.c
  2. #include <stdint.h>
  3. #define CONFIG_FOSC 24000000
  4. void delay_ms(uint16_t __data ms) {
  5.     uint16_t i;
  6.     do {
  7.         i = CONFIG_FOSC / 9000; // 9T
  8.         while (--i)
  9.             ;
  10.     } while (--ms);
  11. }
复制代码

4.0编译的结果:
  1. ;        delay.c:7: while (--i)
  2. 00109$:
  3.         mov        r4,#0x6a
  4.         mov        r5,#0x0a
  5. 00101$:
  6.         dec        r4
  7.         cjne        r4,#0xff,00122$
  8.         dec        r5
  9. 00122$:
  10.         mov        a,r4
  11.         orl        a,r5
  12.         jnz        00101$
  13. ;        delay.c:9: } while (--ms);
  14.         mov        a,r6
  15.         add        a,#0xff
  16.         mov        r4,a
  17.         mov        a,r7
  18.         addc        a,#0xff
  19.         mov        r5,a
  20.         mov        ar6,r4
  21.         mov        ar7,r5
  22.         mov        a,r4
  23.         orl        a,r5
  24.         jnz        00109$
  25. ;        delay.c:10: }
  26.         ret
复制代码

4.4编译的结果:
  1. ;        delay.c:7: while (--i)
  2. 00109$:
  3.         mov        r4,#0x6a
  4.         mov        r5,#0x0a
  5. 00101$:
  6.         dec        r4
  7.         cjne        r4,#0xff,00129$
  8.         dec        r5
  9. 00129$:
  10.         mov        a,r4
  11.         orl        a,r5
  12.         jnz        00101$
  13. ;        delay.c:9: } while (--ms);
  14.         dec        r6
  15.         cjne        r6,#0xff,00131$
  16.         dec        r7
  17. 00131$:
  18.         mov        a,r6
  19.         orl        a,r7
  20.         jnz        00109$
  21. ;        delay.c:10: }
  22.         ret
复制代码

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:21
  • 最近打卡:2024-08-08 21:16:41

5

主题

14

回帖

28

积分

新手上路

积分
28
发表于 2024-3-22 07:58:50 | 显示全部楼层
不知道对之前的代码影响大不大{:5_351:}
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-02 07:55:56
已绑定手机

19

主题

3191

回帖

4872

积分

论坛元老

积分
4872
发表于 2024-3-22 12:14:30 来自手机 | 显示全部楼层
sdcc还有很大进步空间啊
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 21:47 , Processed in 0.162314 second(s), 105 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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