C语言基础笔记——位操作
基础知识
1. 位运算概述
2. 位运算概览
3. 按位与运算符(&)
4. 按位或运算符(|)
5. 异或运算符(^)
6. 取反运算符(~)
7. 左移运算符(<<)
8. 右移运算符(>>)
9. 复合赋值运算符
位运算示例:
假设有定义uint8_t a = 3,b = 5;
则
a&b = 1; a|b = 7; a^b =6; ~a=0b 1111 1100; a>>1 == 1; b<<2 = 20;
在单片机中的应用
在单片机软件开发中,位操作是硬件寄存器控制和资源优化的核心手段。
一、常用位操作
1.基本位操作
2. 多比特操作
3. 移位操作
二、在寄存器中的运用
寄存器配置要点:
对寄存器进行配置时,通常有两种方式:
- 先将带设置的位清0,然后再设置对应的值
- 先将寄存器的值读出来,修改完成后,再写回去
三、代码技巧
1. 使用宏定义寄存器地址和位掩码
// 定义寄存器地址(假设PORTB地址为0x25)
#define PORTB (*(volatile uint8_t*)0x25)
// 定义位掩码
#define LED_PIN (1 << 5) // PB5
#define BUTTON_PIN (1 << 2) // PB2// 使用示例
PORTB |= LED_PIN; // 点亮LED
if (PORTB & BUTTON_PIN) { /* 按钮按下 */ }
2. 位域结构体(用于寄存器映射)
typedef struct {uint8_t mode : 2; // 低2位:模式配置uint8_t enable : 1; // 第2位:使能位uint8_t : 3; // 匿名位域填充(保留未用)uint8_t error : 2; // 高2位:错误码
} ControlReg;volatile ControlReg* pReg = (volatile ControlReg*)0x4000;
pReg->enable = 1; // 直接操作寄存器位
3. 联合体(Union)与位操作
结合联合体和结构体,实现灵活的数据访问:
typedef union {uint16_t value; // 整体值struct {uint8_t low; // 低字节uint8_t high; // 高字节};struct {uint8_t bit0 : 1; // 按位访问// ... 其他位定义};
} DataReg;DataReg reg;
reg.value = 0x1234;
reg.high = 0xAB; // 修改高字节
if (reg.bit0) { // 检查第0位// ...
}
4. 内联函数或宏封装常用操作
// 宏封装置位和清零
#define SET_BIT(reg, bit) ((reg) |= (1 << (bit)))
#define CLEAR_BIT(reg, bit) ((reg) &= ~(1 << (bit)))// 内联函数判断位状态
static inline bool IsBitSet(volatile uint8_t* reg, uint8_t bit) {return (*reg & (1 << bit)) != 0;
}
四、注意事项
五、典型应用场景
合理使用位操作可显著提升单片机代码的效率和可维护性,但需结合硬件手册和实际场景谨慎设计。
练习题链接:位操作练习
参考链接:
菜鸟编程:位运算
C语言基本笔记(6)—— 位操作
参考视频:
1.2STM32入门_寄存器配置中的位运算