GD32库中的位运算宏定义

/* enum definitions */
typedef enum {DISABLE = 0, ENABLE = !DISABLE} EventStatus, ControlStatus;
typedef enum {FALSE = 0, TRUE = !FALSE} bool;
typedef enum {RESET = 0, SET = !RESET} FlagStatus;
typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrStatus;

/* bit operations */
#define REG32(addr)                  (*(volatile uint32_t *)(uint32_t)(addr))
#define REG16(addr)                  (*(volatile uint16_t *)(uint32_t)(addr))
#define REG8(addr)                   (*(volatile uint8_t *)(uint32_t)(addr))
#define BIT(x)                       ((uint32_t)((uint32_t)0x01U<<(x)))
#define BITS(start, end)             ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) 
#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start))

REG32(addr)

该宏定义用来读写32位地址的值, (*(volatile uint32_t *)(uint32_t)(addr)) 首先将 addr 转换为 uint32_t,然后再将 uint32_t 转换为 (volatile uint32_t )指针,最后取出指针地址的值

REG16(addr) 和 REG8(addr)

功能和 REG32(addr) 类似。

BIT(X)

该宏定义的功能是生成一个 uint32_t 类型的值,该值中第 X 位为 1

BITS(start, end)

通过一个具体的例子来了解 BITS 的具体实现。

1
BITS(0, 3)

调用该宏会生成一个怎样的数字,把03带入到宏定义中如下:

1
#define BITS(start=0, end=3)             ((0xFFFFFFFFUL << (start=0)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end=3))))

首先 (0xFFFFFFFFUL << (start=0)) 的结果是 0xFFFFFFFFUL 不变;其次要计算(0xFFFFFFFFUL >> (31U - (uint32_t)(end=3))) 的结果,结果为 (0xFFFFFFFFUL >> 28) 等于15,也就是二级制的 1111。从这个例子中可以看到该宏的作用就是生成一个32位的无符号从 start 到 end 之间为 1 二进制的值。start 从 0 开始。

GET_BITS(regval, start, end)

从定义可以看出,该宏定义的作用就是把regval指定位范围二级制值置1然后移位到从0位开始的一个值。

这三个属于递进关系:BIT(X),将一个值的第x位置位;BITS(start, end),将一个值的从第start位到end位置1;GET_BITS(regval, start, end),将regval变量的第start位到end位置1,然后移位到第0位;

你可能感兴趣的:(单片机,嵌入式硬件)