嵌入式寄存器操作-----C语言位操作的学习

嵌入式C语言高效学习路径:一个月攻克指针、内存与实战项目 C语言作为底层编程的核心,以其高效的机器码生成和直接硬件操作能力,在资源受限的嵌入式系统中具有不可替代性。其原理在于通过编译器将代码转换为可直接在微控制器上执行的指令,无需虚拟机开销,从而实现对内存和寄存器的精准控制。这一技术价值体现在嵌入式开发对实时性、可靠性和资源利用率的极致追求上,广泛应用于物联网、工业控制、消费电子等场景。聚焦嵌入式C语言学习,关键在于掌握指针操作、内存管理和位运算等核心概念,并通过LED控制、命令解析等实战项目巩固技能。本文基于嵌入式开发高频需求,提供从环境配置到项目演练的速成路径 阅读详情


2015年4月1日总结。

a |= 1<<x         //第x位写1
a &=~(1<<x)        //第x位写0
(a &(1<<x)) == a       //判断1,等号左边括号不能省略
(a& (1<<x))==0        //判断0
a>>n              //除法a/ 2^n
a<<n              //乘法a*2^n


-----------------------------------------

学习嵌入式的过程中发现。C的位操作比较多,现根据资料整理如下。待以后查阅。


根据芯片手册配置寄存器的过程中,时常碰到要设置某一位或某几位的数据,根据情况置0或者置1。而对于该寄存器其他的位,我们不关心也不应该关心(谁知道其他位会不会有其他用途)。

这个时候,位操作是非常方便的。


寄存器的位操作主要是将特定位置0或者置1。一般情况是先擦除相应的位(就是置0),然后再置1。

1,如果只置为其中某一位为1

a &= ~(1<<x)               //将x位置0

b | = (1<<x)                 //将x位置1


2,如果一下置位多个位,下面的方法可以用

a &=~0001 1100        //第2-4置0

b | =0001 1100            //第2-4位置1

3,但是这个多位的用法犯了上面说过的问题,我们关心了其他位,因此,推荐的用法应该如下。

a &=~((1<<2) | (1<<3) | (1<<4))//将2-4置0

a|=(1<<2) | (1<<3) | (1<<4)//将2-4置1

这个代码初看起来比较上面的复杂和不便于阅读,但是实际情况不是如此,因为我们通常将(1<<2)这种代码定义为宏操作。具体可以看下面我贴出的代码。


4,如何判断寄存器某一位是0还是1。寄存器底层操作中,时常用到判断某个寄存器的状态,即读入某个寄存器的值。

a & (1<<x) //与操作,如果相应位是0,则结果是0,如果相应位是1,则结果是1.

b | (0<<x) //或操作,如果相应位是0,则结果是0,如果相应位是1,则结果是1.

这两个应该是没有区别的。

下面就是我根据TQ2440改写的按键LED程序,位操作使用宏定义。


----------------------------------------------------

/*按键控制LED灯*/
/*观察原理图得到,GPB5,6,7,8分别连接led1,2,3,4;低电平点亮*/
/*按键1,2,3,4分别对应EINT1,4,2,0外部中断,低电平按下*/
/*这里我们不用中断,EINT0-4对应GPF0-4*/
/*思路:不断扫描GPF0-4(引脚输入使能),相应输出GPB5-8,各对应关系如下*/
/*GPB	LED		KEY		EINI	GPF*/
/*5		1		1		1		1*/
/*6		2		2		4		4*/
/*7		3		3		2		2*/
/*8		4		4		0		0*/
/*这里主要注意下学习位操作*/
#include<stdio.h>

/*配置寄存器地址*/
/*GPBCON地址为(unsigned long*)0x56000010*/
/*所以GPBCON数据为(*(unsigned long*)0x56000010)*/
#define GPBCON   (*(volatile unsigned long*)0x56000010)
#define GPBDAT   (*(volatile unsigned long*)0x56000014)

#define GPFCON   (*(volatile unsigned long*)0x56000050)
#define GPFDAT   (*(volatile unsigned long*)0x56000054)

/*寄存器擦除某一位为0*/
/*这是16位寄存器,每一设置有2个二进制数位,因此一次擦除2位,3=0b11*/
#define GPB5_MSK	(3<<(5*2))		//位左移10位,[10.9]位为1,其余为0
#define GPB6_MSK	(3<<(6*2))
#define GPB7_MSK	(3<<(7*2))
#define GPB8_MSK	(3<<(8*2))

#define GPF0_MSK	(3<<(0*2))
#define GPF1_MSK	(3<<(1*2))
#define GPF2_MSK	(3<<(2*2))
#define	GPF4_MSK	(3<<(4*2))

/*设置引脚为输入功能,相应位置00*/
#define GPF0_IN		(0<<(0*2))
#define GPF1_IN		(0<<(1*2))
#define GPF2_IN		(0<<(2*2))
#define GPF4_IN		(0<<(4*2))

/*设置引脚为输出功能,相应位置01*/
#define GPB5_OUT	(1<<(5*2))
#define GPB6_OUT	(1<<(6*2))
#define GPB7_OUT	(1<<(7*2))
#define GPB8_OUT	(1<<(8*2))




int main(void)
{
	/*配置引脚功能,GPB[5,8]为输出,GPF[0,3]为输入*/
	GPBCON &=~(GPB5_MSK | GPB6_MSK | GPB7_MSK | GPB8_MSK);
	GPBCON |=GPB5_OUT | GPB6_OUT | GPB7_OUT | GPB8_OUT;
	GPFCON &=~(GPF0_MSK | GPF1_MSK | GPF2_MSK | GPF4_MSK);
	GPFCON |=GPF0_IN | GPF1_IN | GPF2_IN | GPF4_IN;
	
	unsigned long key_date;

	/*低电平表示按键按下*/
	while(1)
	{
		key_date=GPFDAT;

		if(key_date & (1<<0))		//判断第0位是否为1,对应按键4,GPB8
			GPBDAT |=(1<<8);		//是1,按键未按下,相应LED置1,不点亮
		else
			GPBDAT &=~(1<<8);		//是0,按键按下,相应LED低电平,点亮
		

		if(key_date & (1<<1))     //GPF1,KEY1,LED1,GPB5
			GPBDAT |=(1<<5);      
	    else
			GPBDAT &=~(1<<5);
			
		if(key_date & (1<<2))     //GPF2,KEY3,LED3,GPB57
			GPBDAT |=(1<<7);        
		else
			GPBDAT &=~(1<<7);
		
		if(key_date & (1<<4))     //GPF4,KE21,LED2,GPB6
			GPBDAT |=(1<<6);        
		else
			GPBDAT &=~(1<<6);
	}
}

嵌入式-ARM寄存器基本概念 嵌入式-ARM寄存器基本概念   无论是学习哪一种处理器,首先需要明确的就是这种处理器的寄存器以及工作模式。   ARM有37个寄存器,其中31个通用寄存器,6个状态寄存器。   这里尤其要注意区别的是ARM自身寄存器和它的一些外设的寄存器的区别。   ARM自身是统一架构的,也就意味着37个寄存器无论在哪个公司的芯片里面都会出现。但是各家公司会对ARM进行外设的扩展,所以就出现了好多外设 阅读详情

相关推荐

对寄存器的理解

前言 在进行嵌入式开发过程中,寄存器可以说是与嵌入式工程师打交道最多的东西,因为偏向底层的驱动开发,几乎都是利用寄存器完成的。那么,寄存器到底是什么呢?下面为自己的一些理解,如有错误之处,还望海涵与纠正,谢谢! 内存映射 在正式进入寄存器的知识之前,首先对内存映射进行简单的介绍。此处以TI公司的DSP28335芯片为例。通过查询该芯片的官方数据手册,可获知该芯片的内存分配图。由于该图比较大,即使贴...

IssacMi的博客 4983

嵌入式 寄存器某一位置位或清零

应用一:将寄存器中的某一位置1或则清0,保持其他位不变。 int l_data; void SetBit(int pos)//将某一位置位的操作 { if((pos >= 0) && (pos <= 31)) { l_data |= BIT_MASK(pos);//BIT_MASK是 掩码。就是除了这一位其余位均为0 } } void ClrBit(int pos)//将某一位清0的操作 { i

skdkjxy的专栏 5266

嵌入式C语言学习路线:1个月从零到项目实战

C语言作为嵌入式开发的核心编程语言,其价值在于能够直接操作硬件寄存器、管理内存资源,实现底层控制。从技术原理看,通过指针和位操作可以直接访问内存映射的硬件寄存器,而结构体和联合体则用于组织复杂的外设数据结构。在嵌入式系统中,这种底层编程能力对于实现GPIO控制、中断处理和通信协议等关键功能至关重要。应用场景广泛覆盖智能家居、工业控制、物联网设备等领域。本路线针对嵌入式C语言学习,重点涵盖指针操作、内存管理和硬件接口编程等热词内容,通过实际项目案例帮助开发者快速掌握嵌入式开发必备技能。

weixin_29164091的博客 259

计算机并口地址定义,电脑并口(LPT)引脚定义

概述:电脑并行口与串行口的区别是交换信息的方式不同,并行口能同时通过8条数据线传输信息,一次传输一个字节;而串行口只能用1条线传输一位数据,每次传输一个字节的一位。并行口由于同时传输更多的信息,速度明显高于串行口,但串行口可以用于比并行口更远距离的数据传输。引脚含义:1 选通 (STROBE低电平) 10 确认 (ACKNLG低电平)2 数据位0 (DATAO) 11...

weixin_39787792的博客 3085

从零开始手搓STM32标准库:用C语言结构体玩转GPIO寄存器映射

本文详细介绍了如何从零开始构建STM32标准库,通过C语言结构体和指针实现GPIO寄存器映射。从内存映射原理到GPIO初始化函数设计,再到位操作技巧,全面解析了硬件抽象层的实现方法。适合STM32初学者和嵌入式开发者深入理解GPIO操作与寄存器映射技术。

weixin_30444105的博客 469

嵌入式入门学习路径:从寄存器操作到项目实战

嵌入式系统开发是软硬件结合的工程实践,其核心在于通过C语言直接操作寄存器来控制芯片行为。理解寄存器地址映射、指针与位操作,是打通单片机开发底层逻辑的关键;而中断与调试能力则决定了能否从“点灯”走向复杂系统。随着物联网与智能硬件场景普及,嵌入式开发岗位需求持续增长,掌握从原理图阅读、时钟树配置到串口打印、故障定位的完整方法论,是高效入门的正确路径。本文梳理了从基础外设驱动到三个项目闭环的嵌入式学习路线,覆盖开发环境选择、工程结构理解以及HardFault排查等实战技能,帮助初学者绕过“只会复制例程”的陷阱,真

weixin_30110543的博客 235

嵌入式按键c语言,嵌入式寄存器操作-----C语言位操作的学习

2015年4月1日总结。a |= 1<a &=~(1<(a &(1<(a& (1<a>>n //除法a/ 2^na<-----------------------------------------学习嵌入式的过程中发现。C的位操作比较多,现根据资料整理如下。待以后查阅。根据芯片手册配置寄存器的过程中,时常...

weixin_39622521的博客 317

嵌入式C语言学习路线与STM32开发实战

C语言作为嵌入式开发的核心编程语言,因其高效性和直接硬件操作能力被广泛应用。在嵌入式系统中,开发者需要掌握指针、内存管理等核心概念,特别是在STM32等平台上,硬件寄存器操作和实时性要求更为严格。嵌入式C编程涉及裸机编程、直接硬件操作和严格的内存管理,这些技术在实际项目中尤为重要。通过深入理解多级指针、函数指针和内存区域管理,开发者可以更好地应对资源受限系统的挑战。此外,位操作和volatile关键字的使用是嵌入式开发中的常见技巧,能有效提升代码的稳定性和性能。本文结合工程实践,探讨了嵌入式C语言的学习路线

weixin_42639246的博客 96

《C语言内核深度解析》笔记(2):c语言位操作

《嵌入式Linux与物联网开发——C语言内核深度解析》这本书很适合新人嵌入式工程师学习,这本书有两个推荐的点:第一个是以嵌入式的视角重新解读C语言,在实际硬件和应用场景下重新讲解相关概念;第二个是补充了很多关于嵌入式c语言的细节,这些细节在工作中常见,但在课堂上不会讲。接下来一段时间我会把之前做的笔记陆续整理发出来,当作个人一次复习的小结。 第02章 C语言位操作 2.2 常用位运算符 按位取反(~)与非的区别:~10 = 5; !10 = 0 左移位(<<): x <<

wangxiaobeia的博客 3602

从C语言到单片机实战:51与STM32嵌入式开发全路径解析

C语言作为嵌入式开发的核心编程语言,因其高效率、可移植性和直接操作硬件的能力,在资源受限的微控制器领域占据主导地位。其原理在于通过指针和位操作直接访问内存映射的硬件寄存器,实现对LED、串口、定时器等外设的精确控制。这种底层硬件操作能力赋予了嵌入式系统实时响应和高可靠性的技术价值,广泛应用于智能家居、工业控制、物联网设备等场景。本文聚焦于51单片机与STM32的实战开发,通过寄存器操作、中断服务程序等核心概念,结合Keil开发环境搭建与HAL库应用,系统梳理了从C语言基础到嵌入式项目框架的完整学习路径,并提

weixin_30706691的博客 352

C语言 | 嵌入式位操作精华技巧汇总

分享关于位操作一些笔记: 一、位操作简单介绍 首先,以下是按位运算符: 在嵌入式编程中,常常需要对一些寄存器进行配置,有的情况下需要改变一个字节中的某一位或者几位,但是又不想改变其它位原有的值,这时就可以使用按位运算符进行操作。下面进行举例说明,假如有一个8位的TEST寄存器: 当我们要设置第0位bit0的值为1时,可能会这样进行设置: TEST = 0x01; 但是,这样设置是不够准确的,...

嵌入式大杂烩 2780

STM32 嵌入式学习入门(0)——C语言基础复习

掌握了这六种操作否的用法,C语言的位操作就差不多了。2.|按位或:两个相应的二进制位中只要有一个为1,该位的结果值为1。3.^按位异或: 若参加运算的两个二进制位值相同则为0,否则为1。4.!取反: 对一个二进制数按位取反,即将0变1,将1变0。// 1!= 0 0!= 15.右移:将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0。

2401_85012481的博客 1198

从零编写linux0.11 - 第二章 内核初始化

编程环境:Ubuntu Kylin 16.04 代码仓库:https://gitee.com/AprilSloan/linux0.11-project linux0.11源码下载(不能直接编译,需进行修改) 1.添加内核 进入内核后也不是马上进入main函数,上一章只是暂时设置gdt,此外还要设置idt和其他的一些初始化操作,这些内容也要使用汇编进行编写,此处采用AT&T格式的汇编。 以下为head.s的内容,为了简单起见,内容还是一个死循环。 .globl startup_32 startup_3

皓空Fly的博客 1264

嵌入式开发入门:从C语言到单片机实战的保姆级学习路径

嵌入式系统作为以应用为中心、软硬件可裁剪的专用计算机系统,其核心在于对硬件资源的直接、高效控制。这一特性决定了C语言成为其开发的首选,因为C语言兼具高效性、可移植性及贴近硬件的操作能力,尤其是指针和位操作等核心概念,是直接读写硬件寄存器、实现底层驱动的关键。掌握这些技术,对于开发智能穿戴、工业控制、物联网终端等对成本、功耗和可靠性有严格要求的设备具有重要价值。本文聚焦于嵌入式开发中最经典的入门实践——单片机开发,通过剖析C语言在嵌入式视角下的重点(如指针操作硬件、位控制及静态内存管理),并结合具体的单片机(

weixin_30621711的博客 608

‌NTRU算法详细教程 | 2025年最新版(基于NIST后量子密码标准更新)

‌:NTRU是当前抗量子加密的黄金标准,‌。

blns_yxl的博客 1802

长短期记忆网络(Long Short-Term Memory networks, LSTM)

如何简单的理解LSTM——其实没有那么复杂:

weixin_39910711的博客 2万+

嵌入式C语言实战:30天从零基础到项目开发

C语言作为嵌入式开发的核心编程语言,其价值在于能够直接操作硬件资源。通过理解内存管理、指针操作等基础概念,开发者可以掌握寄存器访问、中断处理等底层原理。这种硬件交互能力在STM32等微控制器开发中尤为重要,能够实现外设驱动、实时控制等关键技术。结合嵌入式系统特有的volatile关键字、位操作等编程技巧,可以构建稳定可靠的数据采集、通信协议等应用场景。本文基于嵌入式开发实战需求,提供从GPIO控制到串口通信的完整学习路径,帮助零基础学习者快速掌握硬件编程能力。

weixin_32349093的博客 245

01 高等数学 上下册知识点总结

极限与连续 8个等价无穷小 8个常用泰勒公式 高数复习——多元函数微分学 一、概念 一元函数: 可微<=>可导 △y=A△x+o(△x)dy=AdxA=f′(x)\triangle y=A\triangle x+o(\triangle x)\\dy=Adx\\A=f'(x)△y=A△x+o(△x)dy=AdxA=f′(x) 多元函数: 可微=>可导(可导指两个偏导数存在,反之不成立) 可微=>连续(反之不成立) △z=A△x+B△y+o(p)dz=Adx+BdyA=δzδxdx

qq_44292038的博客 1万+

单片机入门不必先学C语言:寄存器驱动法高效上手

单片机开发本质是硬件操控,核心在于理解寄存器配置、时序图读取与物理信号控制,而非掌握完整C语言体系。C语言在此场景中仅作为描述寄存器操作的轻量工具,其真实工程阈值极低——熟练使用赋值、位运算、宏定义及中断声明即可覆盖90%裸机开发需求。技术价值体现在大幅压缩学习路径,让新手跳过语法迷宫,直击LED控制、定时器配置、串口通信等真实功能模块。典型应用场景包括51/STM32开发板快速验证、可控硅相位控制、一键开关机状态机实现及TF卡扇区级数据存储。本文聚焦‘寄存器驱动法’,以芯片手册为唯一权威,将学习重心从语言

weixin_29168813的博客 240

QT实现HTTP文件(夹)下载的完整流程与实战技巧

本文详细介绍了使用QT框架实现HTTP文件和文件夹下载的完整流程与实战技巧。通过QNetworkAccessManager等核心类,讲解了从单文件下载、大文件处理、进度显示、暂停/取消功能,到复杂的文件夹下载策略。文章重点剖析了断点续传、错误处理与网络健壮性等关键问题,为C++桌面应用集成稳定高效的下载功能提供了专业指导。

weixin_29239279的博客 277

ADS电路仿真方法综述:原理与应用

在射频与微波电路设计中,精确的仿真技术是验证性能的关键。ADS(Advanced Design System)作为行业标准工具,集成了多种仿真方法,适用于不同场景。本文将系统解析瞬态分析、谐波平衡(HB)、交流分析(AC)、直流分析(DC)、S参数、大信号SP(LSSP)及包络分析的原理、实现机制与应用场景。

u014344410的博客 480

自动化转ROS2先学C语言:C99与嵌入式开发核心学习路线

在机器人开发中,C语言是连接底层硬件与上层算法的关键桥梁,也是学习ROS2与C++的重要前置基础。许多自动化、机电背景的开发者从PLC或Simulink转向ROS2时,常因缺少C语言功底而难以理解指针、内存、回调等核心机制。C99标准作为嵌入式领域广泛采用的编程规范,通过定长整数、指定初始化器等特性,为跨平台开发与硬件驱动编写提供了可靠保障。理解C语言中的函数指针、结构体与内存管理,有助于掌握ROS2中的订阅发布模型与智能指针;而链表、环形队列等数据结构,则是传感器数据缓冲和导航算法的基础。结合寄存器操作与

weixin_30315435的博客 335

19、利用PostGIS进行空间分析:更高效的矢量分析方法

本文介绍了如何利用PostGIS进行高效灵活的矢量空间分析,重点探讨了在选址安静住宅场景中使用缓冲区和距离测量两种方法的实现与优化。通过QGIS与PostGIS结合,演示了数据上传、CTE应用、ST_Intersects与ST_Distance函数对比,并深入分析了横向子查询在提升查询性能和代码可读性方面的优势。文章还比较了不同方法的适用场景,并以房地产开发选址为例展示了完整分析流程,最后总结了PostGIS在空间分析中的强大能力与未来应用前景。

d3e4f的博客 92

嵌入式C语言与C51单片机实战:从语法到工程思维的跨越

C语言作为嵌入式开发的核心编程语言,其价值远不止于基础语法。理解其内存管理、指针深度应用及位操作等原理,是直接与硬件寄存器对话、实现高效控制的关键。这些底层技术能力支撑着嵌入式系统在资源受限环境下稳定运行,广泛应用于工业控制、物联网设备和消费电子等领域。本文聚焦于嵌入式C的实战应用,特别是结合C51单片机平台,探讨如何将语言知识转化为解决实际硬件问题的工程能力,例如通过内存分区优化提升性能,利用函数指针构建灵活架构,从而帮助学习者避开从理论到实践的常见陷阱,真正对标企业级开发需求。

weixin_34121282的博客 284

信奥赛csp初赛高频考点【位运算】(详细解析)

信奥赛csp初赛高频考点【位运算】(详细解析)

王老师青少年编程 368

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: 嵌入式C语言的杂七杂八
下一篇: ANSI,ASCII,Unicode,UTF-8的区别。自认为写得最好的一篇
ZeroSkyrim
博客等级 码龄16年 34粉丝 10原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值