单片机 - 位运算详解(``、`|`、`~`、`^`、`>>`、`<<`)

news2025/3/29 19:19:02

单片机中的位运算详解(&|~^>><<

位运算是单片机编程(C/C++)中经常使用的技巧,用于高效地操作寄存器、I/O 端口和数据。以下是各位运算符的详细解析,并结合单片机实际应用举例。

1. 按位与(&):用于位清零、检测某个位是否为 1

特点:

  • 两个二进制位都为 1,结果才为 1,否则为 0

单片机应用场景:

  • 用于屏蔽特定位(清零特定位)。
  • 检测某个位是否为 1

示例:
假设 P1 代表某个 I/O 端口,我们想要清除 P1 端口的第 3 位(保留其他位不变)。

P1 = P1 & 0b11110111; // 清除 P1 端口的第 3 位(从 0 开始编号)

示例:检测某个位是否为 1

if (P1 & (1 << 3)) {  
    // 第 3 位为 1,执行某些操作
}

2. 按位或(|):用于位设为 1

特点:

  • 只要有一个二进制位为 1,结果就是 1

单片机应用场景:

  • 用于设置某个位为 1(打开某个功能)。

示例:
假设 P2 端口连接了 LED,我们要点亮 LED(假设 LED 连接在 P2 的第 2 位)。

P2 = P2 | 0b00000100; // 设置 P2 端口的第 2 位为 1

或使用移位操作

P2 |= (1 << 2);

3. 按位取反(~):对所有位取反

特点:

  • 0 变 1,1 变 0。

单片机应用场景:

  • 用于翻转数据,例如按键检测、反向输出。

示例:
如果 P3 端口是某个设备的控制信号,我们想要翻转它:

P3 = ~P3; // 让所有位取反

示例:只翻转 P3 端口的第 5 位

P3 ^= (1 << 5);

4. 按位异或(^):用于翻转某个位

特点:

  • 1 ^ 1 = 0
  • 0 ^ 1 = 1
  • 1 ^ 0 = 1
  • 0 ^ 0 = 0

单片机应用场景:

  • 用于翻转(取反)某一位。

示例:
如果 P4 端口的第 1 位用于指示 LED,我们想要让它每次调用时反转:

P4 ^= (1 << 1); // 让 P4 端口的第 1 位取反

5. 取反再异或(~^):等价于按位 XNOR(同或)

特点:

  • ~(a ^ b),即两个相同位为 1,不同位为 0

单片机应用场景:

  • 用于比较两位是否相等。

示例:
判断 AB 是否相等(所有位均相同)。

if (~(A ^ B) == 0xFF) {  
    // A 和 B 完全相同
}

6. 左移运算(<<):用于乘 2 的幂次方

特点:

  • a << n 相当于 a × (2^n)

单片机应用场景:

  • 快速计算 2 的倍数。
  • 控制某个位的移位。

示例:
假设 P5 连接了一个 8 段 LED,我们希望轮流点亮 LED:

for (int i = 0; i < 8; i++) {
    P5 = 1 << i; // 依次点亮 LED
}

7. 右移运算(>>):用于除 2 的幂次方

特点:

  • a >> n 相当于 a / (2^n)

单片机应用场景:

  • 用于快速除法。
  • 数据解码时提取某几位。

示例:
假设 sensorData 是一个 16 位的传感器数据,我们想提取高 8 位:

uint8_t highByte = sensorData >> 8;

举例应用:按键消抖

单片机中按键输入可能会因机械抖动导致错误读取,我们可以结合位运算实现按键消抖:

#define KEY_PIN P3_0  // 假设按键连接 P3.0 端口

void delay() {
    for (volatile int i = 0; i < 5000; i++);  // 简单延时
}

uint8_t readKey() {
    if ((P3 & (1 << 0)) == 0) {  // 检测按键是否按下
        delay();
        if ((P3 & (1 << 0)) == 0) {  // 再次检测,确认消抖
            return 1;  // 按键按下
        }
    }
    return 0;  // 按键未按下
}

总结

运算符作用单片机应用
& (按位与)清零某个位,检测某个位读取 I/O 端口状态
按位或设置某个位为 1控制 LED、使能外设
~ (按位取反)取反所有位翻转 I/O 信号
^ (按位异或)仅翻转某个位翻转 LED 状态
~^ (XNOR)比较两数据是否相同数据校验
<< (左移)乘 2 的幂快速计算、移位
>> (右移)除 2 的幂提取高位数据

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2322136.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(二)手眼标定——概述+原理+常用方法汇总+代码实战(C++)

一、手眼标定简述 手眼标定的目的&#xff1a;让机械臂和相机关联&#xff0c;相机充当机械臂的”眼睛“&#xff0c;最终实现指哪打哪 相机的使用前提首先需要进行相机标定&#xff0c;可以参考博文&#xff1a;&#xff08;一&#xff09;相机标定——四大坐标系的介绍、对…

【Linux网络-NAT、代理服务、内网穿透】

一、NAT技术 1.NAT技术背景 之前我们讨论了&#xff0c;IPV4协议中&#xff0c;IP地址数量不充足的问题 NAT技术当前解决IP地址不够用的主要手段&#xff0c;是路由器的一个重要功能 NAT&#xff08;网络地址转换&#xff0c;Network Address Translation&#xff09;是一种…

新手村:逻辑回归-理解02:逻辑回归中的伯努利分布

新手村&#xff1a;逻辑回归-理解02&#xff1a;逻辑回归中的伯努利分布 伯努利分布在逻辑回归中的潜在含义及其与后续推导的因果关系 1. 伯努利分布作为逻辑回归的理论基础 ⭐️ 逻辑回归的核心目标是: 建模二分类问题中 目标变量 y y y 的概率分布。 伯努利分布&#xff08…

golang Error的一些坑

golang Error的一些坑 golang error的设计可能是被人吐槽最多的golang设计了。 最经典的err!nil只影响代码风格设计&#xff0c;而有一些坑会导致我们的程序发生一些与我们预期不符的问题&#xff0c;开发过程中需要注意。 ​​ errors.Is​判断error是否Wrap不符合预期 ​…

【STM32】知识点介绍二:GPIO引脚介绍

文章目录 一、概述二、GPIO的工作模式三、寄存器编程 一、概述 GPIO&#xff08;英语&#xff1a;General-purpose input/output&#xff09;,即通用I/O(输入/输出)端口&#xff0c;是STM32可控制的引脚。STM32芯片的GPIO引脚与外部设备连接起来&#xff0c;可实现与外部通讯、…

【AI】NLP

不定期更新&#xff0c;建议关注收藏点赞。 目录 transformer大语言模型Google Gemma疫情网民情绪识别 整体框架 baseline构建 模型调参、模型优化、其他模型 数据trick、指标优化、magic feature 数据增强、伪标签、迁移学习 模型融合sklearn中TFIDF参数详解 频率阈值可以去掉…

Go 代理爬虫

现在注册&#xff0c;还送15美金注册奖励金 --- 亮数据-网络IP代理及全网数据一站式服务商 使用代理服务器&#xff0c;通过 Colly、Goquery、Selenium 进行网络爬虫的基础示例程序 本仓库包含两个分支&#xff1a; basic 分支包含供 Go Proxy Servers 这篇文章改动的基础代码…

【NLP 43、大模型技术发展】

目录 一、ELMo 2018 训练目标 二、GPT-1 2018 训练目标 三、BERT 2018 训练目标 四、Ernie —— baidu 2019 五、Ernie —— Tsinghua 2019 六、GPT-2 2019 七、UNILM 2019 八、Transformer - XL & XLNet 2019 1.模型结构 Ⅰ、循环机制 Recurrence Mechanism Ⅱ、相对位置…

在普通用户下修改root用户密码

1 从普通用户切换到root用户 sudo -s 再输入密码。 2 输入passwd ,会提醒你输入当前用户密码&#xff0c;验证后会提醒你输入root用户密码。 3 切换到root用户&#xff0c;使用修改过的密码登陆。 4 成功进入root用户。

SPPAS安装及问题汇总

SPPAS下载地址 文件找不到&#xff0c;可能是MAC的自动化操作问题&#xff0c;解决方案有二&#xff1a; 方案一&#xff1a; 直接查看SPPAS中的readme&#xff0c;运行sppas.command 方案二&#xff1a; 在自动化脚本中添加 export PATH/usr/local/bin:$PATH

LINUX基础 [三] - 进程创建

目录 前言 进程创建的初次了解&#xff08;创建进程的原理&#xff09; 什么是fork函数&#xff1f; 初识fork函数 写时拷贝 fork函数存在的意义 fork调用失败的原因 进程终止 运行完毕结果不正确 main函数返回 库函数函数exit 系统调用接口_exit 进程异常终止 进…

【day1】数据结构刷题 链表

一 反转链表 206. 反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]…

鼠标在客户区内按下左键和双击右键

书籍&#xff1a;《Visual C 2017从入门到精通》的2.6鼠标 环境&#xff1a;visual studio 2022 内容&#xff1a;【例2.44】鼠标在客户区内按下左键和双击右键 1.创建一个单文档程序 一个简单的单文档程序-CSDN博客https://blog.csdn.net/qq_20725221/article/details/1463…

c++ map和vector模板类

在这一章中C语法之模板函数和模板类-CSDN博客 我们学习了怎样写模板函数和模板类&#xff0c;接下来我们来学习系统给我们写好的两个模板类:map和vector。 我相信有了上文的基础&#xff0c;能帮助我们更好的理解这些模板类。 map和vector 是C STL(标准模板库) 中的一部分&a…

hn航空app hnairSign unidbg 整合Springboot

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向分析 学习unidbg补环境。先弄一个…

Arm Linux ceres库编译

由于工作需要&#xff0c;需在国产化系统上编译ceres库&#xff0c;手上有一块树莓派&#xff0c;就在树莓派上面进行测试编译ceres库&#xff0c;总体来说比较顺利。只出现了一点小问题 参考链接&#xff1a; Ceres中文教程-安装 Ceres官方网站&#xff08;英文&#xff09; …

矩阵补充,最近邻查找

矩阵补充&#xff0c;最近邻查找 矩阵补充是向量召回最简单的一种方法&#xff0c;现在不常用&#xff0c;学习矩阵补充是为了更好的理解后面学到的双塔模型 下图&#xff0c;输入用户ID和物品ID后从Eebedding层拿到对应的向量做内积&#xff0c;内积的结果就是矩阵补充 模型…

gradio调用多个CSS的HTML页

很多博客介绍的gradio读取html和css比较简单&#xff0c;如果要做很细致的前端页面优化&#xff0c;比如丰富的响应式的cssjs&#xff0c;至少要有html多个css&#xff0c;是暂不能实现的。bootstrap、font-awesome、jquery等 方案一当然是直接更换htmlcss为主的部署方式&#…

NVIDIA NeMo 全面教程:从入门到精通

NVIDIA NeMo 全面教程&#xff1a;从入门到精通 文章目录 NVIDIA NeMo 全面教程&#xff1a;从入门到精通目录框架介绍NeMo的核心特点NeMo的架构NeMo与其他框架的比较NeMo的模型集合NeMo的工作流程NeMo 2.0的新特性 安装指南系统要求使用Docker容器安装步骤1&#xff1a;安装Do…

Thales靶机攻略

1.下载导入VBox&#xff0c;并启动靶机 靶机地址&#xff1a;https://download.vulnhub.com/thales/Thales.zip 解压后&#xff0c;在VBox中导入虚拟电脑。包含所有网卡的MAC地址。 导入完成&#xff0c;设置网卡模式为仅主机网络。开启靶机。 kali网卡更改为桥接模式。点击工…