C_位运算符及其在单片机寄存器的操作
C语言的位运算符用于直接操作二进制位,本篇简单结束各个位运算符的作业及其在操作寄存器的应用场景。
一、位运算符的简单说明
1、按位与运算符(&)
- 功能:按位与运算符对两个操作数的每一位执行与操作。如果两个对应的二进制位都是1,则结果为1,否则为0。(有0为0,全1为1)
- 示例:
int a = 5; // 0101 int b = 3; // 0011 int result = a & b; // 0001 -> 1
2、按位或运算符(|)
- 功能:按位或运算符对两个操作数的每一位执行或操作。如果两个对应的二进制位中至少有一个是1,则结果为1,否则为0。(有1为1,全0为0)
- 示例:
int a = 5; // 0101 int b = 3; // 0011 int result = a | b; // 0111 -> 7
3、按位异或运算符(^)
- 功能:按位异或运算符对两个操作数的每一位执行异或操作。如果两个对应的二进制位相同,则结果为0;如果不同,则结果为1。(相同为1,不同为0)
- 示例:
int a = 5; // 0101 int b = 3; // 0011 int result = a ^ b; // 0110 -> 6 - 补充: 按位异或运算符也可以用来交换2个变量的数值。交换2个变量1的数值我们常用的方法是定义一个临时变量来暂时存储一个变量的值,当如果不想多定义一个变量就可以采用按位异或运算符来操作,具体方法如下:

4、按位取反运算符(~)
- 功能:按位取反运算符对操作数的每一位执行取反操作,即将0变为1,将1变为0。(0变1,1变0)
- 示例:
int a = 5; // 0101 int result = ~a; // 1010 -> -6(在补码表示下)
5、左移运算符(<<)
- 功能:左移运算符将操作数的二进制位向左移动指定的位数。左移时,空出的低位用0填充。(整体左移,低位补0,高位不一定舍弃)
- 说明: 整体左移后结果取决于赋值给什么类型的变量,从低到高截位,并不是简单的高位舍弃如果高位没有舍弃,数据左移一位就扩大一倍。如图:

- 示例:
int a = 5; // 0101 int result = a << 1; // 1010 -> 10
6、右移运算符(>>)
- 功能:右移运算符将操作数的二进制位向右移动指定的位数。对于无符号数,空出的高位用0填充;对于有符号数,空出的高位根据符号位填充(算术右移)。(整体右移,低位舍弃,有符号数高位补最高位的数字)
- 说明:无符号数高位补0,有符号数高位补最高位的数字,数据右移一位就缩小一倍(除以2并舍去余数)。如图:

- 示例:
int a = 5; // 0101 int result = a >> 1; // 0010 -> 2
7. 复合赋值运算符
运算符也可以与赋值运算符组合,形成复合赋值运算符:
- 按位与赋值:
&= - 按位或赋值:
|= - 按位异或赋值:
^= - 左移赋值:
<<= - 右移赋值:
>>=
二、位运算符的运用
1、用按位与运算符(&)将变量的某位置0
有一个变量char a = 0b1111 1111,要将其的第n位置0(最右一位为第0位),只需要将其按位与上一个第n位为0,其余为都为1的数据。
char a = 0b11111111
char b = 0b11110111
a &= b;
这样a的第3位就会被置0;
2、用按位或运算符(|)将变量的某位置1
有一个变量char a = 0b0000 0000,要将其的第n位置1(最右一位为第0位),只需要将其按位或上一个第n位为1,其余为都为0的数据。
char a = 0b00000000
char b = 0b00001000
a |= b;
这样a的第3位就会被置1;
3、用左移运算符(<<)和按位或运算符(|)进行数据合成
①将两个8位数据合成一个16位数据
将第一个数据左移8位后按位或上第二个数据
#include <stdio.h>int main() {unsigned char a = 0x34; // 8位数据,十六进制:34unsigned char b = 0x12; // 8位数据,十六进制:12unsigned short result = (a << 8) | b; // 左移a并与b按位或,合成16位数据printf("合成的16位数据: 0x%0X\n", result); // 输出:0x3412return 0;
}
②将两个16数据合成一个32位数据
将第一个数据左移16位后按位或上第二个数据
#include <stdio.h>int main() {unsigned short x = 0x1234; // 16位数据,十六进制:1234unsigned short y = 0xABCD; // 16位数据,十六进制:ABCDunsigned int result = (x << 16) | y; // 左移x并与y按位或,合成32位数据printf("合成的32位数据: 0x%0X\n", result); // 输出:0x1234ABCDreturn 0;
}
③将一个8位数据和一个16位数据合成一个32位数据
#include <stdio.h>int main() {unsigned char a = 0x12; // 8位数据,十六进制:12unsigned short b = 0xABCD; // 16位数据,十六进制:ABCDunsigned int result = (a << 16) | b; // 左移a和b并合成32位数据printf("合成的32位数据: 0x%0X\n", result); // 输出:0x12ABCDreturn 0;
}
4、截取一个数据的某部分字节
①截取一个数据的低字节
截取低字节可以用赋值运算符或者强制转换。
例如:截取0xABCD中的0xCD
#include <stdio.h>int main() {unsigned short a = 0xABCD; // 16位数据,十六进制:ABCDunsigned char b = a; // 将16位数据a赋值给8位数据bprintf("%0X\n", (unsigned char)a); // 强制转换为8位,并输出低字节printf("%0X\n", b); // 输出b的值return 0;
}
②截取一个数据的高字节或中间字节
截取高字节或中间字节可以将数据右移后再用赋值运算符或者强制转换
#include <stdio.h>int main() {unsigned short a = 0xABCD; // 16位数据,十六进制:ABCDunsigned int b = 0x1234ABCD; // 32位数据,十六进制:1234ABCD// 第一个 printf:将 a 右移8位,得到高字节,然后转换为 unsigned charprintf("%0X\n", (unsigned char)(a >> 8));// 第二个 printf:将 b 右移12位,得到高字节部分的前两位,然后转换为 unsigned charprintf("%0X\n", (unsigned char)(b >> 12));return 0;
}
③分别截取一个数据的低字节,中间字节和高字节合成一个新数据
#include<stdio.h>int main(void)
{unsigned short a = 0xaabb;unsigned short b = 0xccdd;unsigned short c = 0xeeff;unsigned int d = (a & 0x00ff) | (b & 0x0ff0)<<4 | (c & 0xff00)<<8 ;printf("%x",d);
}
5、对寄存器进行操作
假设你有一个 u32 类型的变量 temp,表示一个 32 位的寄存器。
①对寄存器的某一位写0
将temp变量的第n位置0,其他位不变
规律:temp &= ~(1 << n)
②对寄存器的某一位写1
将temp变量的第n位置1,其他位不变
规律:temp |= (1 << n)
③对寄存器的某连续两位操作
1.将temp变量的第n和第n+1位置0,其他位不变
规律:temp &= ~(3 << n)
2. 将temp变量的第n和第n+1位置1,其他位不变
规律:temp |= (3 << n)
3.将temp变量的第n和第n+1位置01或10,其他位不变
先将第n和第n+1位清0: temp &= ~(1 << n)
01:temp |= (1 << n)
10:temp |= (2 << n)
4.将temp的第2位第4位第5位置0,其他位保持不变
temp &= ~ (1<<2|1<<4|1<<5);
5.将temp的第n位进行翻转,其他位保持不变
temp ^ = (1<<n);
三、位运算操作GPIO寄存器_LED
本篇示例所用的芯片型号为STM32F103,先创建好keil工程并配置好环境。
要操作LED灯的亮灭,我们要将对于GPIO端口设置为通用推挽输出模式。
这是一个已经创建好的keil工程,目前只有一个延时函数和基本的框架,接下来我们通过查找芯片手册配置寄存器来点亮LED灯。

通过原理图我们可以看出LED0接在PB5端口上,LED1接在PE5端口上。 因此要点亮LED0和LED1,我们就需要对PB5和PE5端口进行操作,端口输出低电平灯亮,输出高电平灯灭。
我们翻看芯片手册的目录,找到系统架构 。

可以看到 GPIOB和GPIOE都是挂载在APB2总线上的,因此我们首先需要对APB2进行时钟使能。

翻看目录,找到APB2 外设时钟使能寄存器(RCC_APB2ENR)。
要开启IO端口B和IO端口的时钟,我们需要将寄存器RCC_APB2ENR的位3和位6置1。
具体操作如下:

接着翻看目录,找到端口配置寄存器。
我们需要将PB5和PE5设置为通用推挽输出模式 ,PB5和PE5的配置方法是一样的,需要将寄存器GPIOx_CRL的位21和位20置01,位23和位22置00。
具体操作如下:
最后找到端口输出数据寄存器(GPIOx_ODR) (x=A..E)
将寄存器GPIOB_ODR/GPIOE_ODR的位5置1则端口PB5/PE5输出高电平,置0则输出低电平。
具体操作如下:
烧录后效果如下:
LED
相关文章:
C_位运算符及其在单片机寄存器的操作
C语言的位运算符用于直接操作二进制位,本篇简单结束各个位运算符的作业及其在操作寄存器的应用场景。 一、位运算符的简单说明 1、按位与运算符(&) 功能:按位与运算符对两个操作数的每一位执行与操作。如果两个对应的二进制…...
Java面试题集合篇5:10道基础面试题
文章目录 前言41、多线程使用 ArrayList42、List 和 Set 区别43、HashSet 实现原理44、HashSet检查重复和保证数据不可重复45、BlockingQueue46、Map接口46.1、HashMap实现原理46.2、HashMap在JDK1.7和JDK1.8中不同点46.3、JDK1.7 VS JDK1.8 比较 47、HashMap的put方法流程48、…...
汽车加气站操作工试题及答案
1.天然气的主要成分是( ) A. 乙烷 B. 乙烯 C. 甲烷 D. 乙炔 答案:C 2.加气站中,用来储存天然气的设备是( ) A. 加气机 B. 压缩机 C. 储气井 D. 脱水装置 答案:C 3.以下哪…...
Rust错误处理:从灭火器到核按钮的生存指南
开篇:错误处理的生存哲学 在Rust的平行宇宙里,错误分为两种人格: panic! → 核按钮💣(不可恢复,全系统警报)Result → 灭火器🧯(可控制,局部处理࿰…...
企业四要素如何用PHP进行调用
一、什么是企业四要素? 企业四要素接口是在企业三要素(企业名称、统一社会信用代码、法定代表人姓名)的基础上,增加了一个关键要素,通常是企业注册号或企业银行账户信息。这种接口主要用于更全面的企业信息验证&#x…...
【大数据技术】搭建完全分布式高可用大数据集群(Hadoop+MapReduce+Yarn)
搭建完全分布式高可用大数据集群(Hadoop+MapReduce+Yarn) jdk-8u361-linux-x64.tarhadoop-3.3.6.tar.gz注:请在阅读本篇文章前,将以上资源下载下来。 写在前面 本文主要介绍搭建完全分布式高可用集群Hadoop+MapReduce+Yarn的详细步骤。 注意: 统一约定将软件安装包存放…...
【MySQL】MySQL经典面试题深度解析
文章目录 一、MySQL与C的深度结合1.1 为什么C项目需要MySQL?1.2 典型应用场景 二、基础概念面试题精讲2.1 存储引擎对比2.2 索引原理 三、C专项面试题解析3.1 连接池实现3.2 预处理语句3.3 批量操作优化 四、高级应用面试题剖析4.1 事务隔离级别4.2 锁机制详解4.3 查…...
GitHub Copilot 越狱漏洞
研究人员发现了两种操控 GitHub 的人工智能(AI)编码助手 Copilot 的新方法,这使得人们能够绕过安全限制和订阅费用、训练恶意模型等。 第一种技巧是将聊天交互嵌入 Copilot 代码中,利用 AI 的问答能力,使其产生恶意输…...
React组件开发技巧:如何优雅地传递Props?
React组件开发技巧:如何优雅地传递Props? 一、重复Props传递的痛点二、JSX展开语法的优雅解决方案语法解析适用场景 三、使用展开语法的注意事项1. **可读性风险**2. **Props冲突问题**3. **过度使用展开语法** 四、实际项目中的最佳实践五、总结六、扩展…...
Flask+gevent 实现异步请求处理
Flaskgevent 实现异步请求处理 使用flaskgevent实现异步请求处理,首先gevent库要使用猴子布丁,使底层I/O支持异步处理。 1 使用猴子补丁 from gevent import monkey monkey.patch_all()使用猴子补丁后, 内建函数time.sleep()已经魔改成gev…...
Python利用VideoCapture和FFmpeg读取多个rtsp流性能的比较
最近一个项目,要用python读取30个海康摄像头的rtsp流,一开始直接用cv2.VideoCapture(video_path),结果运行一段时间后发现读出来的frame经常出现花屏的现象。所以通过两种方式对程序进行了修改。 1、我先是通过cap.set(cv2.CAP_PROP_BUFFERS…...
Selenium 浏览器操作与使用技巧——详细解析(Java版)
目录 一、浏览器及窗口操作 二、键盘与鼠标操作 三、勾选复选框 四、多层框架/窗口定位 五、操作下拉框 六、上传文件操作 七、处理弹窗与 alert 八、处理动态元素 九、使用 Selenium 进行网站监控 前言 Selenium 是一款非常强大的 Web 自动化测试工具,能够…...
git 项目的更新
更新项目 当自己的本地项目与 远程的github 的仓库已经建立远程连接时, 则直接按照下面的步骤, 将本地的项目代码更新到远程仓库。 # Stage the resolved file git add README.md <file1> <file2># To stage all changes: git add .# Comm…...
UE虚幻引擎No Google Play Store Key:No OBB found报错如何处理
UE虚幻引擎No Google Play Store Key:No OBB found报错如何处理? 问题描述: UE成功打包APK并安装过后,启动应用时提示: No Google Play Store KeyNo OBB found and no store key to try to download. Please setone …...
吴恩达深度学习——卷积神经网络实例分析
内容来自https://www.bilibili.com/video/BV1FT4y1E74V,仅为本人学习所用。 文章目录 LeNet-5AlexNetVGG-16ResNets残差块 1*1卷积 LeNet-5 输入层:输入为一张尺寸是 32 32 1 32321 32321的图像,其中 32 32 3232 3232是图像的长和宽&…...
LabVIEW的智能电源远程监控系统开发
在工业自动化与测试领域,电源设备的精准控制与远程管理是保障系统稳定运行的核心需求。传统电源管理依赖本地手动操作,存在响应滞后、参数调节效率低、无法实时监控等问题。通过集成工业物联网(IIoT)技术,实现电源设备…...
【自动化办公】批量图片PDF自定义指定多个区域识别重命名,批量识别铁路货物运单区域内容改名,基于WPF和飞桨ocr深度学习模型的解决方案
项目背景介绍 铁路货运企业需要对物流单进行长期存档,以便后续查询和审计。不同的物流单可能包含不同的关键信息,通过自定义指定多个区域进行识别重命名,可以使存档的图片文件名具有统一的规范和明确的含义。比如,将包含货物运单…...
neo4j-在Linux中安装neo4j
目录 切换jdk 安装neo4j 配置neo4j以便其他电脑可以访问 切换jdk 因为我安装的jdk是1.8版本的,而我安装的neo4j版本为5.15,Neo4j Community 5.15.0 不支持 Java 1.8,它要求 Java 17 或更高版本。 所以我需要升级Java到17 安装 OpenJDK 17 sudo yu…...
专业学习|通过案例了解蒙特卡罗模拟实操步骤与含义
一、蒙特卡罗模拟介绍 蒙特卡罗模拟(Monte Carlo Simulation)是一种基于随机采样的数值计算方法,用于解决具有不确定性或复杂概率分布的问题。其核心思想是通过多次随机抽样来逼近系统的行为或目标函数的真实值,进而对系统进行评估…...
数据结构【链栈】
基于 C 实现链表栈:原理、代码与应用 一、引言 栈就是一个容器,可以当场一个盒子,只能一个一个拿,一个一个放,而且是从上面放入。 有序顺序栈操作比较容易【会了链栈之后顺序栈自然明白】,所以我们这里只…...
《数据可视化新高度:Graphy的AI协作变革》
在数据洪流奔涌的时代,企业面临的挑战不再仅仅是数据的收集,更在于如何高效地将数据转化为洞察,助力决策。Graphy作为一款前沿的数据可视化工具,凭借AI赋能的团队协作功能,为企业打开了数据协作新局面,重新…...
rust安装笔记
安装笔记 安装加速cargo 国内源nightly版本安装其他目标将现有项目迁移到新版本升级 安装加速 export RUSTUP_UPDATE_ROOT"https://mirrors.ustc.edu.cn/rust-static/rustup" export RUSTUP_DIST_SERVERhttps://mirrors.tuna.tsinghua.edu.cn/rustup curl --proto h…...
人工智能|本地部署|ollama+chatbox快速Windows10下部署(初级篇)
一、 前言: 其实早一个月我已经使用过deepseek,并且也在自己的机器上通过ollama部署过,但一直没有太多动力,现在感觉还是的记录一下,省的自己给忘掉了 本文只是简单记录一下ollamaopen-webuichatbox部署通过网盘分享…...
Android Studio 下载安装教程(2024 更新版),附详细图文
今天,为大家带来的是Android Studio 2024更新版的下载安装教程,包含详细图文步骤。 随着 Android Studio 的不断更新,自从引入 Koala 系列后,其版本号的命名规则也发生了变化。以本次更新为例,版本号为 2024.2.1&#…...
【人工智能】通用人工智能 AGI
AGI 是 Artificial General Intelligence 的缩写,中文翻译为通用人工智能。与我们常见的**特定人工智能(Narrow AI)**不同,AGI 是一个更高深、更具野心的目标。 AGI(人工通用智能)的定义 通用人工智能&am…...
Android车机DIY开发之软件篇(九) NXP AutomotiveOS编译
Android车机DIY开发之软件篇(十一) NXP AutomotiveOS编译 Google 在汽车上也提供了用于汽车的 Google 汽车服务(GAS,Google Automotive Service),包含有 Google 地图、应用市场、Google 汽车助理等等。Google 汽车服务同样没有开…...
6.【BUUCTF】[SUCTF 2019]CheckIn
打开题目页面如下 看样子是一道有关文件上传的题 上传一句话木马 显示:非法后缀! 看来.php后缀被过滤了 上传一张带有木马的照片 在文件地址处输入cmd 输入以下代码执行 copy 1.jpg/b4.php/a 5.jpg 最后一行有一句话木马 上传带有木马的图片 但其实…...
在线教程丨YOLO系列10年更新11个版本,最新模型在目标检测多项任务中达SOTA
YOLO (You Only Look Once) 是计算机视觉领域中最具影响力的实时目标检测算法之一,以其高精度与高效性深受业界青睐,广泛应用于自动驾驶、安防监控、医疗影像等领域。 该模型最早于 2015 年由华盛顿大学研究生 Joseph Redmon 发布,开创了将目…...
ES6 变量解构赋值总结
1. 数组的解构赋值 1.1 基本用法 // 基本数组解构 const [a, b, c] [1, 2, 3]; console.log(a); // 1 console.log(b); // 2 console.log(c); // 3// 跳过某些值 const [x, , y] [1, 2, 3]; console.log(x); // 1 console.log(y); // 3// 解构剩余元素 const [first, ...re…...
FreeRTOS学习 --- 中断管理
什么是中断? 让CPU打断正常运行的程序,转而去处理紧急的事件(程序),就叫中断 中断执行机制,可简单概括为三步: 1,中断请求 外设产生中断请求(GPIO外部中断、定时器中断…...
