STM32 微控制器类型转换

Ore*_*reo 3 c casting stm32

我有一个关于 STM32 微控制器的 C 语言类型转换的问题。现在我正在尝试编写自己的库来控制微控制器的外围设备。但我不明白为什么以及何时应该使用像 (uint32_t) 这样的类型转换。

例如,对于 GPIO 配置寄存器,我看到了下一个示例:

#define INPUT_ANALOG    ((uint32_t) 0x00)
#define INPUT_FLOATING  ((uint32_t) 0x01)
#define INPUT_PUP_PDOWN ((uint32_t) 0x02)
Run Code Online (Sandbox Code Playgroud)

此信息来自数据表(下面附有打印屏幕)。在这里我不明白为什么使用 typecast (uint32_t) 而不仅仅是 0x00 或 0。

我可以将下一个代码用于相同的目的吗?

typedef enum{
    INPUT_ANALOG = 0,
    IN_FLOATING,
    IN_PULL_UP_DOWN,
}PinConfInput_t;
Run Code Online (Sandbox Code Playgroud)

我应该对此代码进行类型转换吗?你能给我推荐一些关于 typecast 的学习资料吗?谢谢

在此处输入图片说明

Ant*_*ala 6

类型转换到unsigned int 后缀u/U需要使用的值0x000x01以及0x02在许多情况下。0x00,0x01并且0x02它们本身是类型的常量int,并且有一些在ints上工作可疑的小东西,例如将它们位移到符号位置时!

如果您取值 0x02 (int) 并将其左移到位 31:30,就会发生这种情况!所以,

0x02 << 30
Run Code Online (Sandbox Code Playgroud)

在整数为 32 位宽的机器上有未定义的行为,而

0x02U << 30 
Run Code Online (Sandbox Code Playgroud)

或者

((uint32_t)0x02) << 30
Run Code Online (Sandbox Code Playgroud)

不会。

枚举列表的标识符声明为 ( C11 6.7.2.2p3 )

具有 int 类型的常量,并且可以出现在任何允许的地方。

即是的,他们也需要这些位移位的演员表。


请注意,C 中枚举常量的类型不必是枚举本身的类型:

#include <stdio.h>


enum foo {
    bar = 42
};


int main(void) {
    printf("An enumeration constant is an %s\n",
           _Generic(bar,
                    int: "int",
                    unsigned int: "unsigned int",
                    default: "something else"));


    printf("On this implementation the enum foo is %s\n",
           _Generic((enum foo) 0,
                    int: "int",
                    unsigned int: "unsigned int",
                    default: "something else"));
}
Run Code Online (Sandbox Code Playgroud)

在GCC会打印出int的枚举常量类型,unsigned int为的类型enum foo。即常量具有与实际枚举不同的类型。

此外,使用超出整数范围的枚举常量是违反约束的;由于0x80000000不能表示为int32 位系统,因此它不能可移植地用作枚举常量:

% gcc enumtest.c -std=c11 -pedantic
enumtest.c:5:11: warning: ISO C restricts enumerator values to range of ‘int’
        [-Wpedantic]
    5 |     bar = 0x80000000
      |           ^~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

最后,正如 C 标准所说,枚举本身的类型由编译器决定,一些编译器可能会使用unsigned char短枚举。好吧,即使在那里你也可能需要一个演员表,因为unsigned char将被提升为 a signed int,而不是unsigned int在算术之前。