lgl_debug 发表于 2007-5-26 17:01:56

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

当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

ywhbn 发表于 2007-5-26 20:56:24

__delay_cycles 的声明贴上来看看

lgl_debug 发表于 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)

ywhbn 发表于 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)

gaozhi1111 发表于 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了

LYStudio 发表于 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)

hibond 发表于 2009-3-5 14:33:40

mark

hermes 发表于 2009-4-27 12:06:28

是默认类型转换的错误

void_c 发表于 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))

chen0610 发表于 2009-12-5 09:30:52

这个函数是什么意思啊??

rubinrubin 发表于 2009-12-30 21:52:10

mark

luoyiming1984 发表于 2010-2-2 08:50:25

#define delay_us(us)   __delay_cycles((F_CPU/1000000UL) * us)

ziran902 发表于 2012-4-7 10:43:45

6楼 那些 是那个 文件里的{:shy:}

uc_cpp 发表于 2012-4-7 11:31:30


#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))

MICO_CHEN 发表于 2013-6-30 09:04:24

正在研究IAR-AVR,标记。

jack267 发表于 2015-3-19 22:04:19

先顶起!我的主频率是16Mhz。貌似目前无用。。
页: [1]
查看完整版本: IAR AVR 中延时函数的 __delay_cycles 错误,大家有没有碰到过