上位机知识篇---与、或、移位操作(、|、>><<)
文章目录
- 前言
- 第一部分:与操作(&)
- 简介
- 语法
- 示例
- 在代码中的应用
- 1.提取某一位
- 2.屏蔽某些位(清零)
- 3.判断某一位是否为 1
- 在 DS18B20 和 AT24C02 代码中的应用
- 1.DS18B20 代码
- 2.AT24C02 代码
- 第二部分:移位操作(<< 和 >>)
- 语法
- 1.左移操作
- 2.右移操作
- 示例
- 在代码中的应用
- 1.逐位发送数据
- 2.逐位接收数据
- 3.合并数据
- 在 DS18B20 和 AT24C02 代码中的应用
- 1.DS18B20 代码
- 2.AT24C02 代码
- 综合示例
- 总结
- 1.与操作(&)
- 2.移位操作(<< 和 >>)
- 第三部分:或操作(|)
- 或操作(|)的基本作用
- 1.合并数据
- 2.设置特定位
- 3.组合标志位
- 语法
- 在 DS18B20 代码中的或操作
- 在 AT24C02 代码中的或操作
- 其他常见应用场景
- 1:设置寄存器的特定位
- 2:组合多个标志位
- 或操作与移位操作的结合
- 或操作与逻辑或(||)的区别
- 总结
- 1.合并数据
- 2.设置标定位
- 典型应用场景
- 1.设备地址模式切换
- 2.寄存器配置
- 3.多标志位组合
- 4.与移位操作结合
- 总结
前言
本文仅仅简单介绍了&(与操作)、|(或操作)、<<>>(左移与右移操作),以及在DS18B20与AT24C02中的示例代码。
第一部分:与操作(&)
简介
与操作是一种位运算,用于逐位比较两个操作数。只有当两个操作数的对应位都为 1 时,结果的对应位才为 1,否则为 0。
语法
result = operand1 & operand2;
示例
uchar a = 0b11001100;
uchar b = 0b10101010;
uchar result = a & b; // result = 0b10001000
在代码中的应用
1.提取某一位
通过与操作可以提取某一位的值。
例如,提取 byte 的最低位:
uchar bit = byte & 0x01; // 提取最低位
2.屏蔽某些位(清零)
通过与操作可以将某些位清零。
例如,清零 byte 的高 4 位:
byte = byte & 0x0F; // 清零高 4 位
3.判断某一位是否为 1
通过与操作可以判断某一位是否为 1。
例如,判断 byte 的第 3 位是否为 1:
if (byte & 0x04) {
// 第 3 位为 1
}
在 DS18B20 和 AT24C02 代码中的应用
1.DS18B20 代码
DQ = byte & 0x01; // 提取 byte 的最低位并赋值给 DQ
这里通过与操作提取 byte 的最低位,用于单总线通信中逐位发送数据。
2.AT24C02 代码
if (SDA) byte |= 0x80; // 如果 SDA 为高电平,将 byte 的最高位设置为 1
这里通过与操作判断 SDA 的状态,并根据状态设置 byte 的最高位。
第二部分:移位操作(<< 和 >>)
移位操作是将二进制数的位向左或向右移动。左移操作(<<)将位向左移动,右移操作(>>)将位向右移动。
语法
1.左移操作
result = operand << n; // 将 operand 的位向左移动 n 位
2.右移操作
result = operand >> n; // 将 operand 的位向右移动 n 位
示例
uchar a = 0b00001111;
uchar b = a << 2; // b = 0b00111100(左移 2 位)
uchar c = a >> 2; // c = 0b00000011(右移 2 位)
在代码中的应用
1.逐位发送数据
通过左移操作可以逐位发送数据。
例如,发送 byte 的每一位:
for (i = 0; i < 8; i++) {
bit = (byte >> i) & 0x01; // 提取第 i 位
// 发送 bit
}
2.逐位接收数据
通过左移操作可以逐位接收数据并合并为一个字节。
例如,接收 8 位数据:
for (i = 0; i < 8; i++) {
byte = (byte << 1) | bit; // 将 bit 合并到 byte 中
}
3.合并数据
通过移位操作可以将多个字节合并为一个更大的数据。
例如,将两个 8 位数据合并为一个 16 位数据:
uint data = (highByte << 8) | lowByte;
在 DS18B20 和 AT24C02 代码中的应用
1.DS18B20 代码
byte = (byte << 1) | DQ; // 将 DQ 的状态合并到 byte 中
这里通过左移操作逐位接收数据,并将接收到的位合并为一个字节。
2.AT24C02 代码
temp = (tempH << 8) | tempL; // 将高字节和低字节合并为 16 位数据
这里通过左移操作将两个 8 位数据合并为一个 16 位数据。
综合示例
以下是一个综合示例,展示如何通过 与操作 和 移位操作 实现数据的逐位发送和接收。
示例:逐位发送和接收数据
#include <reg52.h>
sbit DQ = P2^0; // 单总线数据线
// 发送一个字节
void SendByte(uchar byte) {
uchar i;
for (i = 0; i < 8; i++) {
DQ = (byte >> i) & 0x01; // 提取第 i 位并发送
Delay(10); // 延时
}
}
// 接收一个字节
uchar ReceiveByte() {
uchar i, byte = 0;
for (i = 0; i < 8; i++) {
byte = (byte << 1) | DQ; // 将接收到的位合并到 byte 中
Delay(10); // 延时
}
return byte;
}
void main() {
uchar data = 0x55; // 要发送的数据
uchar receivedData;
SendByte(data); // 发送数据
receivedData = ReceiveByte(); // 接收数据
while (1);
}
总结
1.与操作(&)
-
用于提取某一位、屏蔽某些位或判断某一位的状态。
-
在 DS18B20 和 AT24C02 代码中用于逐位发送和接收数据。
2.移位操作(<< 和 >>)
-
用于逐位发送或接收数据,以及合并数据。
-
在 DS18B20 和 AT24C02 代码中用于逐位操作和数据处理。
-
通过合理使用与操作和移位操作,可以实现高效的数据处理和通信功能。
第三部分:或操作(|)
或操作(|)的基本作用
或操作是一种位运算,逐位比较两个操作数,只要某一位为 1,结果对应位即为 1。其核心作用包括:
1.合并数据
合并数据:将多个位或字节组合成一个完整的数据。
2.设置特定位
设置特定位:在不影响其他位的前提下,将某些位设为 1。
3.组合标志位
组合标志位:将多个标志位合并到一个字节中。
语法
result = operand1 | operand2;
示例:
uchar a = 0b11000011;
uchar b = 0b00111100;
uchar result = a | b; // result = 0b11111111
在 DS18B20 代码中的或操作
在 DS18B20 的温度读取代码中,或操作主要用于 合并高低字节的温度数据。
示例代码片段:
// 从 DS18B20 读取温度数据
tempL = DS18B20_ReadByte(); // 读取温度低字节(例如 0x50)
tempH = DS18B20_ReadByte(); // 读取温度高字节(例如 0x01)
temp = (tempH << 8) | tempL; // 合并为 16 位数据(0x0150)
分析:
移位操作:tempH << 8 将高字节左移 8 位,得到 0x0100。
或操作:通过 | 将高字节和低字节合并:
0x0100 | 0x50 = 0x0150。
结果:合并后的 16 位数据表示原始温度值。
意义:
DS18B20 的温度数据以 16 位补码形式 存储,需合并高低字节才能正确解析温度值。
在 AT24C02 代码中的或操作
在 AT24C02 的代码中,或操作主要用于 设置设备地址的读/写模式。
示例代码片段:
// AT24C02 的读操作
I2C_Start();
I2C_SendByte(AT24C02_ADDR); // 发送设备地址(写模式,0xA0)
I2C_WaitAck();
I2C_SendByte(addr); // 发送内存地址
I2C_WaitAck();
I2C_Start();
I2C_SendByte(AT24C02_ADDR | 0x01); // 发送设备地址(读模式,0xA1)
I2C_WaitAck();
data = I2C_ReadByte();
分析:
设备地址格式:
AT24C02 的写模式地址为 0xA0(二进制 10100000)。
读模式地址为 0xA1(二进制 10100001)。
或操作的作用:
AT24C02_ADDR | 0x01 将最低位设为 1,实现从写模式切换到读模式。
例如:0xA0 | 0x01 = 0xA1。
意义:
I2C 协议中,设备地址的最低位表示读/写模式:
0:写模式。
1:读模式。
通过或操作动态切换读/写模式。
其他常见应用场景
1:设置寄存器的特定位
在配置寄存器时,或操作用于保留其他位的同时设置某些位。
// 假设控制寄存器 CTRL_REG 的地址为 0x80
// 需要启用中断(设置第 3 位)
CTRL_REG = CTRL_REG | 0x08; // 0x08 = 0b00001000
2:组合多个标志位
将多个标志位合并到一个字节中。
#define FLAG_A 0x01 // 00000001
#define FLAG_B 0x02 // 00000010
#define FLAG_C 0x04 // 00000100
uchar flags = FLAG_A | FLAG_C; // flags = 0x05 (00000101)
或操作与移位操作的结合
在嵌入式开发中,或操作常与移位操作结合使用,例如:
示例:合并高低字节
uchar highByte = 0x12;
uchar lowByte = 0x34;
uint combinedData = (highByte << 8) | lowByte; // combinedData = 0x1234
分析:
highByte << 8 将 0x12 左移 8 位,得到 0x1200。
0x1200 | 0x34 合并后得到 0x1234。
或操作与逻辑或(||)的区别
| 特性 | 或操作(|) | 逻辑或(||) |
| 运算类型 | 位运算 | 逻辑运算 |
| 操作数 | 整数类型(如 uchar) | 布尔类型(0 或非 0) |
| 结果 | 整数 | 布尔值(0 或 1) |
| 示例 | 0xA0 | 0x01 = 0xA1 | (a > 0) || (b < 0) |
总结
或操作(|) 在 DS18B20 和 AT24C02 代码中的核心作用:
1.合并数据
合并数据:如将高低字节温度数据合并为 16 位。
2.设置标定位
设置特定位:如切换 AT24C02 的读/写模式。
典型应用场景
1.设备地址模式切换
设备地址模式切换。
2.寄存器配置
寄存器配置。
3.多标志位组合
多标志位组合。
4.与移位操作结合
与移位操作结合:用于高效处理多字节数据。
通过合理使用或操作,可以简化代码逻辑并提高硬件控制效率。
总结
以上就是今天要讲的内容,本文仅仅简单介绍了&(与操作)、|(或操作)、<<>>(左移与右移操作),以及在DS18B20与AT24C02中的示例代码。