搜索
bottom↓
回复: 15

IAR AVR 中延时函数的 __delay_cycles 错误,大家有没有碰到过

[复制链接]

出0入0汤圆

发表于 2007-5-26 17:01:56 | 显示全部楼层 |阅读模式
当x大于291时,延时时间就是错误的,但小于或等于291时,又是正确的。

真是差之毫离,矢之千里





#define CPU_F 7372800

#define delay_us(x) __delay_cycles(x*CPU_F/1000000)

#define delay_ms(x) __delay_cycles(x*CPU_F/1000)



当x大于291时,差之毫离,矢之千里

     70              delay_us(292); delay_us(250);



   \   00000004   E405               LDI     R16, 69

   \   00000006   EA19               LDI     R17, 169

   \   00000008   EA2A               LDI     R18, 170

   \   0000000A   E23A               LDI     R19, 42

   \   0000000C   5001               SUBI    R16, 1

   \   0000000E   4010               SBCI    R17, 0

   \   00000010   4020               SBCI    R18, 0

   \   00000012   4030               SBCI    R19, 0

   \   00000014   F7D9               BRNE    $-8

   \   00000016   0000               NOP

   \   00000018   EC0C               LDI     R16, 204

   \   0000001A   E011               LDI     R17, 1

   \   0000001C   5001               SUBI    R16, 1

   \   0000001E   4010               SBCI    R17, 0

   \   00000020   F7E9               BRNE    $-4



   \   00000022   C000               RJMP    $+2



当x小于或等于291时

     70              delay_us(291); delay_us(250);

   \   00000004   E108               LDI     R16, 24

   \   00000006   E012               LDI     R17, 2

   \   00000008   5001               SUBI    R16, 1

   \   0000000A   4010               SBCI    R17, 0

   \   0000000C   F7E9               BRNE    $-4

   \   0000000E   EC0C               LDI     R16, 204

   \   00000010   E011               LDI     R17, 1

   \   00000012   5001               SUBI    R16, 1

   \   00000014   4010               SBCI    R17, 0

   \   00000016   F7E9               BRNE    $-4



   \   00000018   C000               RJMP    $+2

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2007-5-26 20:56:24 | 显示全部楼层
__delay_cycles 的声明贴上来看看

出0入0汤圆

 楼主| 发表于 2007-5-28 15:12:10 | 显示全部楼层
__delay_cycles(long i);



我知到了

7372800x291=7FE1 8000

7372800x292=8052 0000



我改为这样就可以了

#define delay_us(x) __delay_cycles(x/1000000*CPU_F)

#define delay_ms(x) __delay_cycles(x/1000*CPU_F)

出0入0汤圆

发表于 2007-5-28 16:56:44 | 显示全部楼层
#define delay_us(x) __delay_cycles(x/1000000*CPU_F)  

#define delay_ms(x) __delay_cycles(x/1000*CPU_F)  

---------------------------------------------------------

这样就可以了? 传入 __delay_cycles 的实参都成0了!



问题出在表达式 x*CPU_F 身上.这个表达式的运算结果默认是long型,而long型最大能表示的

正数是0x7FFFFFFF.当x大于291时,这个表达式的值就变成了负数,再除以1000000还是负数



解决办法有两个:

1. 不让x的值大于291

2. 把 #define CPU_F 7372800 改为 #define CPU_F 7372800UL



delay_us(x) 和 delay_ms(x) 仍为:

#define delay_us(x) __delay_cycles(x*CPU_F/1000000)

#define delay_ms(x) __delay_cycles(x*CPU_F/1000)

出0入0汤圆

发表于 2007-5-28 17:28:34 | 显示全部楼层
#define delay_us(x) __delay_cycles(CPU_F/100*x/10000)

#define delay_ms(x) __delay_cycles(CPU_F/100*x/10)

我感觉这样才好

不然X/1000,太小会变成0了

出0入0汤圆

发表于 2007-5-29 01:09:20 | 显示全部楼层
/*--------------------------------------------------------------------------------------

系统运行时钟【单位:Hz】的字符化常数定义配置:

--------------------------------------------------------------------------------------*/

#define CPU_CLOCK             11059200        // 定义系统运行时钟【单位:Hz】



/*--------------------------------------------------------------------------------------

延时函数的字符化常数定义配置:

--------------------------------------------------------------------------------------*/

#define CPU_CLOCK_DELAY       110592          // 定义延时函数的运行时钟【去掉尾数0之后的数】



#if (CPU_CLOCK/CPU_CLOCK_DELAY == 1000000)

#define PER_US_STEP_NUM       (CPU_CLOCK_DELAY)       // 定义每微秒需运行的循环步数

#define PER_MS_STEP_NUM       (CPU_CLOCK_DELAY*1000)  // 定义每毫秒需运行的循环步数

#elif (CPU_CLOCK/CPU_CLOCK_DELAY == 100000)

#define PER_US_STEP_NUM       (CPU_CLOCK_DELAY/10)

#define PER_MS_STEP_NUM       (CPU_CLOCK_DELAY*100)

#elif (CPU_CLOCK/CPU_CLOCK_DELAY == 10000)

#define PER_US_STEP_NUM       (CPU_CLOCK_DELAY/100)

#define PER_MS_STEP_NUM       (CPU_CLOCK_DELAY*10)

#elif (CPU_CLOCK/CPU_CLOCK_DELAY == 1000)

#define PER_US_STEP_NUM       (CPU_CLOCK_DELAY/1000)

#define PER_MS_STEP_NUM       (CPU_CLOCK_DELAY)

#elif (CPU_CLOCK/CPU_CLOCK_DELAY == 100)

#define PER_US_STEP_NUM       (CPU_CLOCK_DELAY/10000)

#define PER_MS_STEP_NUM       (CPU_CLOCK_DELAY/10)

#elif (CPU_CLOCK/CPU_CLOCK_DELAY == 10)

#define PER_US_STEP_NUM       (CPU_CLOCK_DELAY/100000)

#define PER_MS_STEP_NUM       (CPU_CLOCK_DELAY/100)

#elif (CPU_CLOCK/CPU_CLOCK_DELAY == 1)

#define PER_US_STEP_NUM       (CPU_CLOCK_DELAY/1000000)

#define PER_MS_STEP_NUM       (CPU_CLOCK_DELAY/1000)

#else

#error 延时函数错误!没有定义 " CPU_CLOCK " 或 " CPU_CLOCK_DELAY " ,或 \

" CPU_CLOCK÷CPU_CLOCK_DELAY "的结果不是 1、10、100、1000、10000、100000、1000000 这几个数值。

#endif





__delay_cycles((unsigned long int)n*PER_US_STEP_NUM)



__delay_cycles((unsigned long int)n*PER_MS_STEP_NUM)

出0入0汤圆

发表于 2009-3-5 14:33:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-4-27 12:06:28 | 显示全部楼层
是默认类型转换的错误

出0入0汤圆

发表于 2009-4-27 12:10:45 | 显示全部楼层
用浮点是最安全的办法。最小程度防止溢出。

#define _delay_loop_1(A) __delay_cycles(3*(A))
#define _delay_loop_2(A) __delay_cycles(4*(A))

#define _delay_us(A)\
  __delay_cycles( (uint32) ( (double)(F_CPU) *((A)/1000000.0) + 0.5))

#define _delay_ms(A)\
  __delay_cycles( (uint32) ( (double)(F_CPU)*((A)/1000.0) + 0.5))

#define _delay_s(A)\
  __delay_cycles( (uint32) ( (double)(F_CPU)*((A)/1.0) + 0.5))

出0入0汤圆

发表于 2009-12-5 09:30:52 | 显示全部楼层
这个函数是什么意思啊??

出0入0汤圆

发表于 2009-12-30 21:52:10 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-2 08:50:25 | 显示全部楼层
#define delay_us(us)   __delay_cycles((F_CPU/1000000UL) * us)

出0入0汤圆

发表于 2012-4-7 10:43:45 | 显示全部楼层
6楼 那些 是那个 文件里的

出0入0汤圆

发表于 2012-4-7 11:31:30 | 显示全部楼层

  1. #define _delay_us(A)\
  2.   __delay_cycles( (uint32) ( (double)(F_CPU) *((A)/1000000.0) + 0.5))

  3. #define _delay_ms(A)\
  4.   __delay_cycles( (uint32) ( (double)(F_CPU)*((A)/1000.0) + 0.5))

  5. #define _delay_s(A)\
  6.   __delay_cycles( (uint32) ( (double)(F_CPU)*((A)/1.0) + 0.5))
复制代码

出0入0汤圆

发表于 2013-6-30 09:04:24 | 显示全部楼层
正在研究IAR-AVR,标记。

出0入0汤圆

发表于 2015-3-19 22:04:19 | 显示全部楼层
先顶起!我的主频率是16Mhz。貌似目前无用。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 12:28

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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