stm32位带操作中对内存的浅显理解

发布者:美丽花朵最新更新时间:2022-04-19 来源: eefocus关键字:stm32  位带操作  内存 手机看文章 扫描二维码
随时随地手机看文章

基础知识

进制

  计算机以二进制代码储存信息,每个二进制数表示一位 (bit),每8个二进制数表示一个字节 (Byte) , 而再往上的KB,就是210倍的字节,总结有以下进制关系。


1 Byte = 8 bit

1 KB = 1024Byte(210=1024)

1 MB = 1024KB

1 GB = 1024MB

1 GB = 230Byte


内存地址

  内存地址使用16进制数表示,内存地址只是一个编号表示,一个内存空间,计算机以字节存储数据,所以一个内存地址对应的应该是一个字节(8 bit)的大小,这个之后会详细解释。

这里用32位机的内存做一个图例。32位机的内存地址用8位16进制数表示。


0x00000000----->[8bit];

0x00000001----->[8bit];

0x00000002----->[8bit];

0x00000003----->[8bit];


32位机

  32位表示CPU一次可以处理32位数据or一次可以寻址32位,就是4个字节的数据。也就是CPU一次可以读取的数据可以有 232种不同的数,从0000 0000 到1111 1111,这一共232个不同的数。这 232个数就是232个地址,每个地址对应8个实际的二进制位,也就是一个地址管理一个字节的数据。

  这也就是CPU寻址能力的来由,32位机的最大寻址能力就是 232Byte = 4GB;

  对于32位机,高于4GB的内存将无法一次性寻得,所以32位机理论最大内存是 4GB。


内存的理解

下面的图将说明计算机的内存地址,实际存储样式和人所看到的表现。

现在我们向内存中写入“A” “B”"C"看看实际的存储是怎样的关系。

在这里插入图片描述

注:这里的数据是编造的。


第一行的ABC是用户输入的数据,第二行是计算机实际储存的数据

而第三行就是内存地址,可见一个内存地址对应一个字节,而计算机就靠这个地址来找到储存的信息。


对STM32的理解

寄存器地址

首先我们看一下STM32的参考手册

在这里插入图片描述

可以看到,这里的内存地址使用8位16进制储存的。一个地址对应一个字节的二进制数。

再以GPIO的寄存器为例

在这里插入图片描述

每个寄存器首地址以4个字节递增,每个寄存器占4个字节,对于BSRR寄存器可以画出这样的图

在这里插入图片描述

由此我们可以理解:

 每个GPIO端口有16个IO口,


 而每个 GPIO端口 有7个寄存器对这16个 IO 口进行各种设置,如:输入,输出,模式,速度等等,


 每个寄存器占4个字节(Byte),32位(bit)。所以用这个32位就可以对16个 IO 口进行设置。一般这32位有以下集中分配方式:


一·每两位对应一个 IO 口,如 CRL,CRH

在这里插入图片描述

二·每一位对应一个IO,但只使用低16位进行设置,高16位保留,如 IDR, ODR, BRR, LCKR

在这里插入图片描述

三·每一位对应一个IO,低16位对应一种操作,高十六位对应另一种操作,如 BSRR

在这里插入图片描述

位带操作

 位带操作是对STM32寄存器的位进行直接操作,有如51单片机中的“sbit”关键字。且只有GPIO 和 SRAW 中的低 1Mb 空间可以被位带操作。

 其中寄存器的每一位数据在别名膨胀成4个字节,但只有最后一位有效。如此膨胀的原因是stm32为32位机,一次处理32位数据效率最高。

由以上的分析,位带别名区的转化公式也就很好理解了。


计算公式

如GPIO的计算公式:


AliasAddr = 0x42000000 + (A-0x40000000)*8*4+n*4


  首先要明白,这个公式是计算字节的也就是内存地址


  A为寄存器地址, 0x40000000 外设基地址是,A-0x40000000 就可以算出寄存器相对外设基地址的偏移了多少个字节(地址),又一个字节有8个位,每个位又膨胀为4个字节,所以先乘8再乘4。


  算完寄存器的偏移就要计算位的偏移了,前面算出的其实是每个寄存器0位的偏移量,而 n 表示位号,每位膨胀为4个字节,所以乘4。


  最后加上GPIO对应别名区的首地址 0x42000000 ,就可以算出寄存器某位对应别名区的地址了。

同理,SRAM的计算公式只是把对应别名区首地址修改


AliasAddr = 0x22000000 + (A-0x40000000)*8*4+n*4


统一公式

( (addr & 0xF0000000) +0x02000000+ ( (addr & 0x00FFFFFF)<<5 ) + bitnum<<2 )


addr 是要操作的为所在寄存器的地址

bitnum 位号,在寄存器的第几位。


公式解释:

addr & 0xF0000000 留下最高位的数字,再加上0x02000000 就可以得到二者分别公式中的第一项。


addr & 0x00FFFFFF 去除最高的两位,算出寄存器地址和基地址的偏移, <<5 左移5位即为乘32。


bitnum<<2 左移2位即为乘4。


开始编程

使用位带操作,完成按下按键LED点亮和熄灭的操作。电路图如下。


  首先,检测按键,要用到GPIO的输入功能,先配置端口输入模式,再读取寄存器 IDR 就可以知道IO端口电平变化。

  点亮led灯必须先配置IO输出模式,再对ODR或BRR,BSRR操作即可置位和清零。


第一,制作一个计算器,可以帮对上面位带操作的公式计算


#define SetBit(addr,n)     *(unsigned int*)

((addr & 0xF0000000) +0x02000000+

( (addr & 0x00FFFFFF)<<5 ) + (n<<2))


  使用一个带参宏就可以完成这个工作。传入 addr 为寄存器的地址, n 为位在寄存器中的位置。


  为了检测代码可行性,先尝试对IDR寄存器的读取,以便判断按键是否按下,和对 ODR 的置位,以便点亮LED灯。而对GPIO输入输出的配置沿用之前固件库编程的代码。


一下为检测按键按下的代码


#define GPIOA_IDR           GPIOA_BASE + 0x08

#define SetBit(addr,n)     *(unsigned int*)((addr & 0xF0000000) +0x02000000+ ( (addr & 0x00FFFFFF)<<5 ) + (n<<2))

int main(void)

{

while(1)

{

if(SetBit(GPIOA_IDR,0) == 1)

{

while(SetBit(GPIOA_IDR,0) == 1);

LED_G_TOGGLE;

}

}

}


  GPIOA_BASE 是固件库中GPIOA 的基地址,0x08 是参考手册中的地址偏移,二者相加就是 GPIOA 的 IDR 寄存器的基地址。


  if语句检测按下,while语句检测松手。要注意的是,要读取的位是 0 位,这点要注意。最后用一个宏定义 LED_G_TOGGLE 完成led灯的反转。


LED_G_TOGGLE的宏定义如下:


#define GPIOB_ODR           GPIOB_BASE + 0x0C

#define SetBit(addr,n)     *(unsigned int*)((addr & 0xF0000000) +0x02000000+ ( (addr & 0x00FFFFFF)<<5 ) + (n<<2))


#define LED_G_TOGGLE  {SetBit(GPIOB_ODR,0) ^= 1;}


使用异或运算完成对这一位的反转。


完整的代码如下:


#define GPIOA_IDR           GPIOA_BASE + 0x08

#define GPIOB_ODR           GPIOB_BASE + 0x0C

#define SetBit(addr,n)     *(unsigned int*)((addr & 0xF0000000) +0x02000000+ ( (addr & 0x00FFFFFF)<<5 ) + (n<<2))


#define LED_G_TOGGLE       {SetBit(GPIOB_ODR,0) ^= 1;}


int main(void)

{

KEY_GPIO_Config();//配置输入端口为浮空,50M,Pin0

LED_GPIO_Config();//配置输出端口为推挽,50M,Pin0

while(1)

{

if(SetBit(GPIOA_IDR,0) == KEY_ON)

{

while(SetBit(GPIOA_IDR,0) ==KEY_ON);

LED_G_TOGGLE;

}

}

}


其中使用固件库配置端口输入输出模式的

KEY_GPIO_Config() 和LED_GPIO_Config() 代码这里不再展示。

关键字:stm32  位带操作  内存 引用地址:stm32位带操作中对内存的浅显理解

上一篇:STM32固件库的小结
下一篇:STM32 SysTick小结

推荐阅读最新更新时间:2024-11-11 11:49

单片机_rom_ram,程序容量之迷
引言 单片机的内存有大小之分,内存大的相对较贵,如何选择大小,是个头疼问题,此文是自己在编程过程中遇到和ram,rom大小有关的问题。 1.单片机中xdata 和data xdata是指片外的ram数据,data是指内部的ram数据。 而STC15中会有逻辑在外,实际在内的ram。如下图: 图1 上图摘自stc15的手册中,如果你的单片机ram只有128个字节,所以选择Memory Model时乖乖选择:Small。如下图: 图2 因为Large 模式,会选择外部ram存放和读取数据,你只有内部ram,所以程序会死(实践中我的串口通讯失效)。 所以官方建议: Memory Model : Speci
[单片机]
单片机_<font color='red'>rom</font>_<font color='red'>ram</font>,程序容量之迷
STM32串口USART配置、发送与接收
一、配置时钟:GPIO时钟、串口时钟、复用引脚时钟 二、配置GPIO结构体 三、配置串口结构体 //串口初始化示例 void usart_init(void) { //创建结构体 GPIO_InitTypeDef gpioinitStructure; USART_InitTypeDef usartinitStructure; NVIC_InitTypeDef NVICinitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //设置时钟 RCC_APB2PeriphClockCmd(RCC_APB2Pe
[单片机]
<font color='red'>STM32</font>串口USART配置、发送与接收
STM32printf函数实现方法
这几天学习stm32发现利用keil不能正常使用printf函数,所以我去网上找了一下,这是一个网易博主的解决办法,亲测有效: STM32串口通信中使用printf发送数据配置方法(开发环境 Keil RVMDK) 在STM32串口通信程序中使用printf发送数据,非常的方便。可在刚开始使用的时候总是遇到问题,常见的是硬件访真时无法进入main主函数,其实只要简单的配置一下就可以了。 下面就说一下使用printf需要做哪些配置。 有两种配置方法: 一、对工程属性进行配置,详细步骤如下 1、首先要在你的main 文件中 包含“stdio.h” (标准输入输出头文件)。 2、在main文件中重定义 /
[单片机]
基于STM32的智能电机保护器设计
0 引言 电机是工业生产领域中最主要的驱动源,如何有效地监控电机的运行状态,保护电机回路,提高电机的运行时间,减少电机故障,对工厂整体电网的运行十分关键。 电动机保护装置有很多种,目前使用得比较普遍的还是基于金属片机械式的热继电器,它结构简单,在保护电动机过载方面具有反时限特性。但它的保护功能少,无断相保护,对电机发生通风不畅、扫膛、堵转、长期过载、频繁启动等故障也不能起保护作用。此外,热继电器还存在重复性能差、大电流过载或短路故障后不能再次使用、调整误差大、易受环境温度影响而误动或拒动、功耗大、耗材多、性能指标落后等缺陷。 为响应国家节能减排的要求,采用基于微控制器的电子式电机保护器替代现有热继电器,具有广大的市场。
[单片机]
基于<font color='red'>STM32</font>的智能电机保护器设计
stm32systick知识
systick又叫滴答定时器,是STM32内核的一个24位简单定时器,常用作延时以及系统心跳等功能。 systick总共有4个寄存器CTRL、 LOAD、 VAL、CALIB SysTick- CTRL 的各位定义如图 5.1.2.1 所示: SysTick- LOAD 的定义如图 5.1.2.2 所示: SysTick- VAL 的定义如图 5.1.2.3 所示: SysTick- CALIB 不常用,在这里我们也用不到,故不介绍了。 从上面可以看出它的确是最简单的定时器,用作延时正合适。
[单片机]
stm32systick知识
一文解析STM32、GD32、ESP32差异
前言 STM32:意法半导体在 2007 年 6 月 11 日发布的产品,32位单片机。 GD32:兆易创新 2013 年发布的产品,在芯片开发、配置、命名上基本模仿 STM32,甚至 GPIO 和 STM32 都是 pin to pin 的,封装不改焊上去直接用。有时候 STM32 的源码不修改,重新编译烧写到 GD32 上就可以跑。当然也有很多不同,比如串口驱动、USB 、库文件等。 ESP32:乐鑫公司 2017 年开发的产品,和 STM32、GD32 不同,ESP32 主要面向物联网领域,支持功能很多,但引出 GPIO pin 脚很少,因此大多数 GPIO 都有很多复用功能。出厂就集成蓝牙、WiFi 等物联网必备功能
[单片机]
一文解析<font color='red'>STM32</font>、GD32、ESP32差异
STM32开发笔记77: 内部看门狗长延时的产生
单片机型号:STM32L053R8T6 开发笔记STM32开发笔记45:看门狗驱动程序的移植介绍了看门狗驱动程序的基本设计方法。今天项目中看门狗的延时时间达到10秒,则实际运行效果只有3秒。 以下是看门狗最大延时时间的设置函数: void CIwdg::SetMaxRefreshInterval(uint8_t u8_second) { this- hIwdg.Instance = IWDG; this- hIwdg.Init.Prescaler = IWDG_PRESCALER_64; this- hIwdg.Init.Window = 4095; #if defined STM32F091xC || defi
[单片机]
一例使用STM32外设库设置串口速度与实际不一样的解决
最近手上有了块金牛的stm32实验板,兴致勃勃的测试各种功能,但是碰到一个问题,用stm32 的外设库写串口程序,发现串口速度与实际不一样。一度怀疑是外设库的问题,但是用mdk的外设监控查看后,发现实际的串口速度为自定义的3倍,如图 很疑惑,本人有一种钻牛角尖的精神,因此一度debug下去,发现这个设置是在如下关键语句 (位于 外设库 中的 USART_Init定义语句,在stm32f10x_usart.c中) USART_Init初始化函数 RCC_GetClocksFreq(&RCC_ClocksStatus); if (usartxbase == USART1_BASE) { apbclock = RCC_ClocksSt
[单片机]

推荐帖子

疑惑,关于触摸板在控制windows媒体播放器
今天刚拿到触摸板,就迫不及待的去用一下什么效果,在操作windows媒体播放器时(默认的媒体播放器),用触控操作怎么不能操作windows媒体播放器,反倒把酷狗播放器打开了,对酷狗进行的触摸操作疑惑,关于触摸板在控制windows媒体播放器原帖由yunhaiking于2011-10-917:12发表今天刚拿到触摸板,就迫不及待的去用一下什么效果,在操作windows媒体播放器时(默认的媒体播放器),用触控操作怎么不能操作windows媒体播放器,反倒把酷狗播放器打开了,对酷狗
yunhaiking 微控制器 MCU
加法器为什么不能通过编译呢
用DSPBuilder设计16阶FIR滤波器,4个4阶级联一起的,结果最后16阶的加法器就出现下面错误,而4阶的加法器是正确的,谁知道怎么解决啊,我输入数据时9位,输出时20位。提示错误信息:ErrorreportedbyS-function\'sGeneric\'in\'fir16/ParallelAdderSubtractor\':Couldnotinferatypeforportfir16/ParallelAdderSubtractor:d
eeleader FPGA/CPLD
avr应用开发实例
avr应用开发实例avr应用开发实例谢谢,正在学习谢谢啦学习中,谢谢楼主分享了!十分感谢顶楼主,谢谢了。看看后在评论谢谢楼主了!!!!!!!!!对应的书能发上来就好了收藏了。正在复习,AVR,谢谢你。谢谢。多谢了板子虽然用不上,但是感谢楼主共享!~板子虽然用不上,但是感谢楼主共享!~板子虽然用不上,但是感谢楼主共享!~谢谢分享谢谢楼主的贡献谢谢非常感谢学习中是不是说明一下大体内容啊正在学习avr谢谢分享哟西把错吧错,学习学习谢谢,看看
ahshan Microchip MCU
#以拆会友#-拆解一多功能台灯及简易的改造
#以拆会友#-拆解一多功能台灯及简易的改造1这是九十年代后期集疝离子灯照明和吹出清新高压负离子微风的造型和收纳适宜的一款台灯,疝离子灯管一坏便遭淘汰;其外观和机身尚好,可將现有先进技术等替换集成其内,必不可练练手还有新的收获。拆解一番,看其内脏,其内由220伏电源转疝离子灯电源、负离子电源及负离子放电装置、清新风扇、转换开关等组装,电路还是较为简单(待续)#以拆会友#
bjwl_6338 以拆会友
请教:SP485REN-L/TR频繁损坏原因
大家好,请教一个关于485的问题。整个设备是金属外壳,用于船用发电机组发电机状态的监控。金属外壳外壳链接一根保护地线经由主设备PCB上的连接器连接到外部,与电源地和信号地没有电气连接。该485网络有五个节点,其中两个节点配置了120欧姆的终端电阻,每个节点上的A都加1K下拉电阻,B都连接1K上拉电阻。每个485节点的布线都很短,不超过50厘米(由于节点都在金属外壳内,因此没有使用隔离方案),四个从设备的电源均来自主设备。请教:SP485REN-L/T
chenzhouyu 模拟电子
电感分裂式推挽换向软开关技术的研究
摘要:提出一种电感分裂式推挽换向软开关电路,分析该电路的工作原理及实现软开关的条件,仿真结果表明该电路控制简单、性能可靠,特别适用于中、小功率场合。关键词:电感分裂式推挽换向软开关仿真推挽电路因控制简单、无直通现象等优点,在中、低电压输入变换器中得到广泛应用,但推挽电路中两个开关管处于硬开关状况,随着开关频率的增高,开通功耗较大。桥臂换向软开关在桥式变换器(包括半桥变换器)中得到广泛应用,如移相全桥软开关电路,但桥臂换向软开关无法在推挽电路中应用,虽然文献,对推挽软开关作过探讨,
zbz0529 PCB设计
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved