8

我正在为微处理器编写一些代码。
它有几个大的、关键的常数。

#define F_CPU 16000000UL

在这种情况下,这是 CPU 频率。在赫兹。

事实上,如果不手动在数字上使用光标,很难判断这是 1,600,000、160,000,000 还是 16,000,000。

如果我把逗号放在数字#define F_CPU 16,000,000UL中,它会截断常数。

我使用过一些具有特定数字分隔符的深奥语言,旨在使大量数字更具可读性(例如16_000_000,主要用于 MCU 的语言)。大的“幻数”在嵌入式东西中相当普遍,因为需要它们来描述 MCU 如何与现实世界对话的各个方面。

C中有这样的东西吗?

4

8 回答 8

11

是的,C 确实有预处理器分隔符:##

所以你可以写

#define F_CPU 16##000##000UL

其含义与 16000000UL完全相同。(与 16*1000*1000 等其他结构不同,您需要小心不要将它们放在乘法可能导致问题的地方。)

于 2012-06-11T09:22:27.133 回答
6

也许是这样的?

#define MHz(x) (1000000 * (x))
...
#define F_CPU MHz(16)

另外,我不喜欢#defines。通常最好有enums 或常量:

static const long MHz = 1000*1000;
static const long F_CPU = 16 * MHz;
于 2012-06-11T09:19:33.300 回答
5

一种可能性是这样写:

#define F_CPU (16 * 1000 * 1000)

或者

#define MHz (1000*1000)
#define F_CPU (16 * MHz)

编辑:其他人建议的 MHz(x) 可能会更好

于 2012-06-11T09:20:44.470 回答
4

您可以将常量写为计算的结果(16*1000*1000例如)。更好的是,您可以定义另一个宏 ,MHZ(x)并将您的常量定义为MHZ(16),这将使代码更具自我记录性 - 以创建名称空间冲突概率为代价。

于 2012-06-11T09:19:17.963 回答
1
// constants.h
#define Hz   1u              // 16 bits
#define kHz  (1000u  *  Hz)  // 16 bits
#define MHz  (1000ul * kHz)  // 32 bits

// somecode.h
#define F_CPU (16ul * MHz)   // 32 bits

笔记:

  • int在 8 位 MCU 上是 16 位。
  • 16 位文字将尽可能优化为 8 位文字(使用 8 位指令)。
  • 有符号整数文字是危险的,特别是在与位运算符混合时,这在嵌入式系统中很常见。默认情况下使所有内容都未签名。
  • 考虑使用变量表示法或注释来指示常量是 32 位,因为 32 位变量在大多数 8 位上非常非常慢。
于 2012-06-12T14:40:48.810 回答
1

另一种方法是在更通用的宏中使用 ## 预处理器运算符

#define NUM_GROUPED_4ARGS(a,b,c,d) (##a##b##c##d)
#define NUM_GROUPED_3ARGS(a,b,c)   (##a##b##c)

#define F_CPU NUM_GROUPED_3ARGS(16,000,000UL)

int num = NUM_GROUPED_4ARGS(-2,123,456,789); //int num = (-2123456789);
int fcpu = F_CPU; //int fcpu = (16000000UL);

这在某种程度上是所见即所得,但不能免于误用。例如。你可能会抱怨编译器

int num = NUM_GROUPED_4ARGS(-2,/123,456,789);  //int num = (-2/123456789); 

但它不会。

于 2018-05-29T09:15:04.833 回答
0

您可以使用科学计数法:

#define F_CPU 1.6e+007

或者:

#define K 1000

#define F_CPU (1.6*K*K)
于 2012-06-11T09:24:57.047 回答
0

将常量定义为:

#define F_CPU_HZ 16000000UL

这样你就知道里面有什么类型的数据。在我们的软件中,我们有一些外围设备需要设置各种预分频器,所以我们有#defines这样的:

#define SYS_CLK_MHZ    (48)
#define SYS_CLK_KHZ    (SYS_CLK_MHZ * 1000)
#define SYS_CLK_HZ     (SYS_CLK_KHZ * 1000)
于 2012-06-22T17:45:22.920 回答