你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F1位带操作(寄存器、标准库、HAL库)

[复制链接]
STMCU小助手 发布时间:2021-11-30 21:00
位带操作也叫原子操作,也称别名。起作用直接进行位带操作,即直接读取寄存器的X位,或直接写寄存器的X位。
       STM32的寄存器为32位的,在写入寄存器的x位中,通常操作为;排除寄存器除x外的其它位,在进行赋值。而位带操作可直接写寄存器的x位,使位操作更为便捷。

1. 实验内容及步骤:
实验内容:

       通过位带操作实现LED灯的翻转,和按键的读取。

       按键按下时,LED亮,松开按键时,LED灭;

步骤:

       根据原寄存器地址定位位带地址;

2. 硬件说明

20210617101338928.png


20210617101343678.png



       按键与PE4相连接,按下时低电平(所以GPIOE4应该配置为上拉输入,按下:低电平;松开:高电平)

       LED与PB5相连,另一端接VCC,(所以GPIOB5应该配置为推挽输出,亮:低电平;灭:高电平)

3. 位带操作原理
       STM32F1内部是有两个位带区的,如下图所示。

20210617105544116.png


     位带操作分别有片上外设和片上SRAM。我们用的比较多的通常是片上外设的位带操作,一般用来控制GPIO的反转和读取。



其膨胀对应关系图如下图所示,以SRAM位带操作位例,0x2000 0000地址的第一位,映射到0x2200 0000地址。其用法如下所示:

       当0x2200 0000的内容=1时 => 0x2000 0000的内容=0x01

       当0x2200 0000的内容=0时 => 0x2000 0000的内容=0x00

       ……………

       当0x2200 0018的内容=1时 => 0x2000 0000的内容=0x40=(二进制)0100 0000

       当0x2200 0018的内容=0时 => 0x2000 0000的内容=0x00

20210617140221772.png


4. 寄存器说明
       位带映射地址如下图所示。(中文STM32参考手册P29)

20210617101442958.png


       位带操作的例子如下图所示(CM3权威指南CnR2)

20210617101509429.png


       根据例子可写成通用的式子。

       bit_word_addr = (IN_ADDR_BASR&0xF0000000|0x02000000)+ (IN_ADDR_BASR&0x000FFFFF)*32+Bit*4

       =>

       bit_word_addr = (IN_ADDR_BASR&0xF0000000|0x02000000)+ ((IN_ADDR_BASR&0x000FFFFF)<<5)+(Bit<<2)

       如要控制LED灯(PB5)

       IN_ADDR_BASR = GPIOB的输出寄存器 = 0X4001 0C00 + 0x0C;

       Bit = 5

5. 程序设计
       代码班的通用位带操作地址转换宏定义如下:
  1. #define BIT_WORD_ADDR(IN_ADDR,BIT) *(__IO uint32_t*)((IN_ADDR&0xF0000000|0x02000000) +((IN_ADDR&0x000FFFFF)<<5) + (BIT<<2))
复制代码

       GPIO的输出位带宏定义如下定义
  1.         #define BPB_OUT(BIT)  BIT_WORD_ADDR((GPIOA_BASE+0x0C),BIT)   
复制代码
BIT为要操作的位。
       在本实验中要操作LED(PB5),因此BIT=5;

       GPIO的输入位带宏定义如下定义

        #define BPE_IN(BIT)  BIT_WORD_ADDR((GPIOE_BASE+0x08),BIT)
       BIT为要操作的位。

在本实验中要读取按键(PE4)的值,因此BIT=4;



位带操作源码:

源码筛选了关键部分,详细看源码。

  1. #define BIT_WORD_ADDR(IN_ADDR,BIT)      *(__IO uint32_t*)((IN_ADDR&0xF0000000|0x02000000) +\
  2.                                                             ((IN_ADDR&0x000FFFFF)<<5) +\
  3.                                                              (BIT<<2))

  4. //GPIO_OUT
  5. #define BPA_OUT(BIT)  BIT_WORD_ADDR((GPIOA_BASE+0x0C),BIT)
  6. #define BPB_OUT(BIT)  BIT_WORD_ADDR((GPIOB_BASE+0x0C),BIT)
  7. #define BPC_OUT(BIT)  BIT_WORD_ADDR((GPIOC_BASE+0x0C),BIT)
  8. #define BPD_OUT(BIT)  BIT_WORD_ADDR((GPIOD_BASE+0x0C),BIT)
  9. #define BPE_OUT(BIT)  BIT_WORD_ADDR((GPIOE_BASE+0x0C),BIT)
  10. #define BPF_OUT(BIT)  BIT_WORD_ADDR((GPIOF_BASE+0x0C),BIT)
  11. #define BPG_OUT(BIT)  BIT_WORD_ADDR((GPIOG_BASE+0x0C),BIT)
  12. //GPIO_IN
  13. #define BPA_IN(BIT)  BIT_WORD_ADDR((GPIOA_BASE+0x08),BIT)
  14. #define BPB_IN(BIT)  BIT_WORD_ADDR((GPIOB_BASE+0x08),BIT)
  15. #define BPC_IN(BIT)  BIT_WORD_ADDR((GPIOC_BASE+0x08),BIT)
  16. #define BPD_IN(BIT)  BIT_WORD_ADDR((GPIOD_BASE+0x08),BIT)
  17. #define BPE_IN(BIT)  BIT_WORD_ADDR((GPIOE_BASE+0x08),BIT)
  18. #define BPF_IN(BIT)  BIT_WORD_ADDR((GPIOF_BASE+0x08),BIT)
  19. #define BPG_IN(BIT)  BIT_WORD_ADDR((GPIOG_BASE+0x08),BIT)
复制代码

6. 实验结果
       按键按下后,LED灯亮;

       按键松开后,LED灯灭。




收藏 评论0 发布时间:2021-11-30 21:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版