#define MHZ *1000000l
#define MSEC /1000l
这是函数定义
unsigned int SysTick_Config(unsigned int ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk)
return (1); // Reload value impossible
STRELOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; // set reload register
return (0); // Function successful
}
如下所述调用函数
SysTick_Config(96MHZ * 2.5MSEC);
我的疑问是关于使用的宏。写96MHZ意味着它被(96 * 1000000l)取代? 96乘以1000000? 另外,#define FiEC / 1000l中的/ 1000l是什么意思?为什么是/ used。
我正在使用IAR嵌入式工作台
答案 0 :(得分:0)
在像这样的数字旁边使用宏时,数字和宏之间需要有空格。在这种情况下,您应该看到编译器错误。
/1000l
只是除以1000。
答案 1 :(得分:0)
您需要在文字和宏之间添加空格,否则编译器会将它们视为无效的整数和浮点常量:
SysTick_Config(96 MHZ * 2.5 MSEC);
预处理后,该行将扩展为
SysTick_Config(96 *1000000l * 2.5 /1000l); // trailing l makes the type
// of the constant a long
// int instead of a regular int
请注意,如果您编写类似
的内容,这种编程风格会导致问题SysTick_Config(a + b MHZ * c - d MSEC);
您需要确保明确地将事物分组,例如
SysTick_Config((a+b) MHZ * (c-d) MSEC);
我知道有些人喜欢用这种方式编写代码,认为它是自我记录的。我认为这是一个错误,不仅因为它可能导致优先问题。
更安全的方法是使用带有参数的类似函数的宏:
/**
* When creating macros for arithmetic expressions, it's a good
* idea to use parentheses around each macro argument and the
* entire macro expansion itself; this way you can avoid
* precedence issues if you pass an expression like a+b to
* the macro.
*/
#define TO_MHZ(x) ((x) * 1000000L) // use uppercase L to avoid confusion
#define TO_MSEC(x) ((x) / 1000L ) // with the digit 1
并将其用作
SysTick_Config( TO_MHZ(96) * TO_MSEC(2.5) );
扩展为
SysTick_Config( ((96) * 1000000L) * ((2.5) / 1000L) )
或
SysTick_Config( TO_MHZ(a+b) * TO_MSEC(c-d) );
扩展为
SysTick_Config( ((a+b) * 1000000L) * ((c-d) / 1000L) );
这种方式没有混淆,您可以避免任何优先级问题。