前言
在C51单片机中,有P1.1=1 和 P1.1=0的位操作方式,也支持bit型变量;在STM32中,也有个位带区。
那么,在C语言中,有没有对应的位带操作方式呢?
答案是肯定的,而且有很多种方法。
宏定义方式
#define BitSet(var,m) (var | (1U << (uint8_t)m))
#define BitReset(var,m) (var & ~(1U << (uint8_t)m))
这种方式简单、直观,却有不足之处:复位与置位的定义不同。
我们希望的是能实现Flag = 1和 Flag = 0 这样的简便操作。
位域结构体
【依靠编译器实现】把一个整型变量的指针强制转化为位域结构体指针,再取地址上结构体元素。
位域联合体
【直接定义】以位域联合体数据类型定义一个联合体,直接调用联合体元素
/* Private typedef -----------------------------------------------------------*/
//位域结合体 类型定义
typedef struct
{
//小端排序
uint8_t B0 : 1;
uint8_t B1 : 1;
uint8_t B2 : 1;
uint8_t B3 : 1;
uint8_t B4 : 1;
uint8_t B5 : 1;
uint8_t B6 : 1;
uint8_t B7 : 1;
} u8_bitband_st;
//位域联合体 类型定义
typedef struct
{
uint8_t BYTE;
struct{
//小端排序
uint8_t B0 : 1;
uint8_t B1 : 1;
uint8_t B2 : 1;
uint8_t B3 : 1;
uint8_t B4 : 1;
uint8_t B5 : 1;
uint8_t B6 : 1;
uint8_t B7 : 1;
}BIT;
} u8_bitband_ut;
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
//初始化时的赋值
uint8_t u8_data1 = 0x03; //整形变量,初始化时赋值
u8_bitband_st u8st_data2 = {1,1,0,}; //结构体型,初始化时要对每个元素依次赋值
u8_bitband_ut u8ut_data3 = {0x03,}; //联合体型,初始化时要对最宽元素赋值
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void main(void)
{
//0x03 --> 0x01
(*(u8_bitband_st *)(&u8_data1)).B1 = 0; //整形地址转换,左值太长,不推荐用宏定义代替左值
u8st_data2.B1 = 0; //结构体型,必须逐一赋值个元素,不能赋值整体
u8ut_data3.BIT.B1 = 0; //联合体型,可赋值元素
//0x01 --> 0x04
u8ut_data3.BYTE = 0x04; //联合体型,可赋值整体
}