一、位运算
在C语言中,取位操作通常指的是从整数中提取特定位的操作。这可以通过位掩码(bit masks)和位操作符来实现。下面是一些常用的位操作符及其用法:
位与操作符(&):用于提取特定位。
位或操作符(|):用于设置特定位。
位非操作符(~):用于反转特定位。
位异或操作符(^):用于切换特定位。
左移操作符(<<):用于将位向左移动,常用于设置或清除位。
右移操作符(>>):用于将位向右移动。
示例
假设我们要处理一个字节(8位),并想提取、设置或清除其中的特定位。
- 提取特定位
假设我们想提取一个字节的第3位(从0开始计数),可以这样做,下面用二进制直观表示一下:
unsigned char byte = 0b10101010; // 示例字节值,用二进制表示
unsigned char mask = 0b00000100; // 创建掩码,第3位为1,其余为0
unsigned char result = byte & mask; // 使用位与操作提取第3位
result = result >> 2; // 将结果右移2位以获取第3位的值(因为是从左边开始计数的)
上面用二进制表示的,下面我们用16进制表示一下
2. 设置特定位
假设我们想设置第3位为1:
unsigned char byte = 0b10101010; // 示例字节值
unsigned char mask = 0b00000100; // 第3位掩码
byte = byte | mask; // 使用位或操作设置第3位为1
- 清除特定位
假设我们想清除第3位:
unsigned char byte = 0b10101010; // 示例字节值
unsigned char mask = ~(0b00000100); // 创建掩码并取反,第3位为0,其余为1
byte = byte & mask; // 使用位与操作清除第3位
- 切换特定位
假设我们想切换第3位的值:
unsigned char byte = 0b10101010; // 示例字节值
unsigned char mask = 0b00000100; // 第3位掩码
byte = byte ^ mask; // 使用位异或操作切换第3位的值
二、获取高8位和低8位
在32位系统上,int通常是4字节,在stm32上就是这样
实验:
- 定义了一个32位整数,使用16进制表示
int num = 0x12345678; // 十六进制表示,总共4个字节
- 访问低8位和高8位
低8位通常指的是最低的有效字节(在大多数现代架构中,这是最低的地址字节)。在32位整数中,我们可以使用按位与操作和位移操作来获取低8位。
unsigned char low_byte = num & 0xFF; // 使用0xFF掩码来获取低8位
高8位指的是最高有效字节。为了获取高8位,我们可以先右移8位,然后再次应用掩码。
unsigned char high_byte = (num >> 8) & 0xFF; // 先右移8位以对齐高位,再使用掩码获取高8位
- 修改低8位和高8位
如果我们想修改这些位的值,可以使用按位或操作和掩码。
修改低8位
num = (num & ~0xFF) | new_low_byte; // 清除低8位然后或上新的值
修改高8位
num = (num & ~(0xFF << 8)) | (new_high_byte << 8); // 清除高8位然后左移新值并或上
- 程序示例
#include <stdio.h>
int main() {
int num = 0x12345678; // 初始值
unsigned char low_byte, high_byte;
unsigned char new_low_byte = 0xAB; // 新低8位值
unsigned char new_high_byte = 0xCD; // 新高8位值
// 获取低8位和高8位
low_byte = num & 0xFF; //取低8位
high_byte = (num >> 8) & 0xFF; //取高8位
printf("Original: num = 0x%X, low_byte = 0x%X, high_byte = 0x%X\n", num, low_byte, high_byte);
// 修改低8位和高8位
num = (num & ~0xFF) | new_low_byte; // 修改低8位
num = (num & ~(0xFF << 8)) | (new_high_byte << 8); // 修改高8位
low_byte = num & 0xFF; // 重新获取修改后的低8位
high_byte = (num >> 8) & 0xFF; // 重新获取修改后的高8位
printf("Modified: num = 0x%X, low_byte = 0x%X, high_byte = 0x%X\n", num, low_byte, high_byte);
return 0;
}
二、高低位合并
- 合并两个独立的8位值
#include <stdio.h>
#include <stdint.h>
uint16_t merge_8bit_values(uint8_t low, uint8_t high) {
// 将高8位左移8位,然后与低8位进行或操作
return (high << 8) | low;
}
int main() {
uint8_t low = 0x12; // 二进制 00010010
uint8_t high = 0x34; // 二进制 00110100
uint16_t result = merge_8bit_values(low, high);
printf("Result: 0x%X\n", result); // 输出合并后的结果
return 0;
}
- 合并一个大整数的低8位和高8位
如果你有一个较大的整数(例如uint16_t或uint32_t),并且想将它的低8位和高8位合并到另一个整数中,你可以这样操作:
#include <stdio.h>
#include <stdint.h>
uint16_t merge_low_high_bits(uint16_t value) {
// 获取高8位,然后左移8位,与低8位进行或操作
return ((value & 0xFF00) >> 8) | (value & 0x00FF);
}
int main() {
uint16_t value = 0x1234; // 二进制 00010010 00110100
uint16_t result = merge_low_high_bits(value);
printf("Result: 0x%X\n", result); // 输出合并后的结果,应为 0x3412
return 0;
}