与51单片机对比
STM32F103的位带操作相当于51单片机的sbit。因为STM32F103每次操作都是4个字节(32位),所以我们要把一个位变成32位,其中膨胀后的最后一位就是原来的位。
这样之后,通过赋值0或1,就能控制最后一位(即原来的位)。
STM32F103的位带区
位带区和位带别名区地址转换
一个位膨胀成四个字节,这样便于STM32以4个字节的方式操作。
1.外设位带别名区地址
所在字节的地址为 A,位序号为 n(0<=n<=7)
AliasAddr= =0x42000000+ ((A-0x40000000)x8+n)*4
其中 (A-0x40000000)代表着地址偏移,(A-0x40000000)*8之后代表着位偏移,最后,一个地址里有8位,((A-0x40000000)x8+n)代表着总的位偏移,一个位要膨胀成四个字节,最后位偏移要×4代表着地址偏移的数。
2.SRAM位带别名区地址
所在字节的地址为 A,位序号为 n(0<=n<=7)
AliasAddr= =0x22000000+ (A-0x20000000)x8x4 +n*4
分析同上
3.统一公式
((addr & 0xF0000000)+0x02000000+((addr & 0x00FFFFFF)<<5)+(bitnum<<2))
统一公式就是给计算机理解用的,记住公式就行,上述分析已经让你知道了位带是怎么实现的,如果想具体了解这个公式,可以自行百度了解。
所以C语言的宏实现如下:
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr&0x00FFFFFF)<<5)+(bitnum<<2))
举个例子:(控制GPIOC第二个IO口)
找到GPIOC的基地址:0x4001 1000
GPIOC_ODR的地址: 0x4001100C(基地址+地址偏移)
我们要控制第二个IO口,所以bitnum数值为2
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x02000000+((addr&0x00FFFFFF)<<5)+(bitnum<<2))
BIATAND(0x4001100C,2) //为位带别名区的地址
地址强制转化成指针,
赋值1表示最后一位为1,原来的位是1,GPIOC第二个IO口输出高电平
赋值0表示最后一位为0,原来的位是0,GPIOC第二个IO口输出低电平
关键字:STM32F103 固件库编程 位带操作
引用地址:
STM32F103固件库编程(2)—位带操作
推荐阅读最新更新时间:2024-11-10 13:38
对STM32的GPIO位带操作的理解
支持了位带操作后,便可以使用普通的加载/储存指令来对单一的比特进行读写操作了。简单而言,就是可以单独的对一个比特位读和写。在F103中,有两个地方实现了位带操作, 其中一个是SRAM 区的最低 1MB 范围,第二个则是片内外设区的最低 1MB 范围。这两个区中的地址除了可以像普通的 RAM 一样使用外,它们还都有自己的“位带别名区”,位带别名区把每个比特膨胀成一个 32位的字。当你通过位带别名区访问这些字时,就可以达到访问原始比特的目的。 图1.1 位带区与位带别名区的膨胀对应关系图 支持位带操作的两个内存区的范围是:0x2000_0000‐0x200F_FFFF( SRAM 区中的最低1MB); 0x4000_000
[单片机]
STM32F103 CAN总线配置总结
stm32的can总线的配置如下: CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式 CAN_InitStructure.CAN_ABOM=DISABLE; CAN_InitStructure.CAN_AWUM=DISABLE; CAN_InitStructure.CAN_NART=DISABLE;//CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失) CAN_InitStructure.CAN_RFLM=DISABLE; CAN_InitStructure.CAN_TXFP=DISABLE; CAN_InitStruct
[单片机]
STM32f103xxxxz中断理解笔记
中断:在程序执行过程中产生了一个必须执行的外部因素时,程序就去执行外部因素对应的中断服务函数,完了再回到正常程序,这就是简单的理解中断。 但是当程序在处理中断服务函数时又产生另一个中断时就需要一个机制来调解:NVIC. NVIC 即嵌套向量中断控制器(Nested Vectored Interrupt Controller)。在stm32f103中总共有70个中断源,包括10个内核中断和60个可屏蔽中断,具有16级的可编程的中断优先级,我们通常使用这60个可屏蔽中断,在配置中断的时候我们一般只用 ISER、ICER 和 IP 这三个寄存器,ISER 用来使能中断,ICER 用来失能中断,IP 用来设置中断优先级。 一、
[单片机]
STM32F103和STM32F105在串口初始化的区别
问题描述:使用STM32F105RB芯片进行串口编程,宏定义为STM32F10X_HD,串口正常,能够收发数据,如果宏定义为STM32F10X_CL,则发送数据混乱,跟波特率不一致的现象很相似。STM32F105为互联型产品,应该进行STM32F10X_CL的宏定义。后续解决后会发上来。 解决方案: 1、原因,由于在谁stm32f10x.h中有这样一段话 #if !defined HSE_VALUE #ifdef STM32F10X_CL #define HSE_VALUE ((uint32_t)25000000) /*! Value of the External oscillator in Hz */
[单片机]
STM32F103ZET6 时钟(2)—— 代码篇
基于特定的开发板上的时钟策略: 倍频/分频系数需要在使能 PLL 之前进行配置,所以需要在 Open PLL 之前将所有系统的时钟分频器系数以及PLL的倍频系数配置好。整个时钟的配置流程如下所示: (1) 开启HSE,等待HSE稳定 (2) 设置APB2、APB1、AHB分频系数 (3) 设置PLL的时钟来源和PLL的倍频系数 (4) 开启PLL,等待PLL稳定 (5) 设置SYSCLK源为 PLL 的输出,读取时钟切换状态,确保PLLCLK被选为系统时钟 (1) OSC_IN/OSC_OUT 上外接 8M 晶振。要使用外接晶振,上电后(默认使用 8M 的HSI),首先需要使能 HSE,位于RCC_CR寄存器的 bi
[单片机]
Proteus8.8版本+ STM32F103驱动LCD1602显示程序+按键+ADC+串口
STM32F103仿真驱动点亮LCD1602 一、开发环境介绍 proteus 8.8 版本+ STM32CubeMX 4.18.0 程序基于keil集成开发环境编写,基于ST官方的HAL库。 STM32CubeMX pack版本 STM32CubeMX的版本 二、项目功能介绍 该项目程序中实现了 1、程序实现了LCD1602的点亮显示 2、程序中实现了STM32的AD采样 3、程序中实现了串口通信 4、程序中实现了按键控制操作 通过滑动变阻器加放大器改变输入值。后边加上lcd1602,初始化显示“光节点检测系统” 然后加个按键按下开始 显示“光功率值:(多少)dbm 这里的范围就0-100 通过调节前边电位器每次只变化一
[单片机]
STM32f103C8T6 bootloader设计
使用的是STM32f103C8T6:64Kflash,在应用程序中通过CAN把接受到的bin写到外置 flash的指定地址处。在bootloader中判断一个单独的标志位看程序是否需要升级,如果需要升级,则复制外置flash处的内容到STM32的内置flash的指定地址处。 如: bootloader地址:0x08000000UL 大小:10K——0x2800——STM32的内置flash 应用程序地址:0x08002800UL 大小:45K——0xB400——STM32的内置flash 升级信息表:0x720000UL 大小:8K——0x2000——外置flash 升级的bin文件地址:0x080124
[单片机]
STM32F103学习笔记(二) 创建工程模板+点亮LED+蜂鸣器
捣鼓了几天,终于点亮led了,那个欣慰啊。。。 至于建立工程模板,对于我这种小白来说确实不容易上手,捣鼓了好久,不是忘记添加.c文件,就是忘记加入头文件的路径(头文件的路径千万要是英文)。其实模板建立好之后,只需要编写两个文件夹(1)USER,用来编辑主函数的。(2)HADEWARE(硬件)用来配置相关硬件的,eg:包含led.c led.h 后面要用的话,直接在这里边调用就行了。 接下来就是led的点亮和蜂鸣器发出响声了。 对于led,首先上个电路图: 板子上有两个led,DS0和DS1分别接了PB5,PE5,. 重要的是对init(初始化)的配置: span style= font-size:1
[单片机]