打印
[应用方案]

【NuMaker-M471测评】+bit band功能的讨论

[复制链接]
2167|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
bit band功能,相信大家都比较熟悉了。因为在CM3时,我们就有这个功能,CM4当然也继承了。
下面,我们谈谈M471对应的CM4核的bit band。在规格书里面,新唐并未对其做很多的说明,
仅仅是一带而过。具体感兴趣的,可以去看《Cortex M3与M4权威指南.pdf》,l里面很多CM4
内核相关的,都说的比较清楚~
流程示意:

用BITBANG与不用的区别:

给出的具体转换方法:


有2除寄存器位置可以用bitband:

官方给的例子是操作SRAM的,但是这个现象不是很明显,我们这里操作外设-->GPIO来试一下:
获取GPIO的读写寄存器地址:

我们或得各个PORT对应的读写寄存器地址后,就可以着手程序了:
程序:
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))

//IO口地址映射

//#define GPIOA_BASE             (AHBPERIPH_BASE + 0x04000UL)
//#define GPIOB_BASE             (AHBPERIPH_BASE + 0x04040UL)
//#define GPIOC_BASE             (AHBPERIPH_BASE + 0x04080UL)
//#define GPIOD_BASE             (AHBPERIPH_BASE + 0x040C0UL)
//#define GPIOE_BASE             (AHBPERIPH_BASE + 0x04100UL)
//#define GPIOF_BASE             (AHBPERIPH_BASE + 0x04140UL)
//#define GPIOG_BASE             (AHBPERIPH_BASE + 0x04180UL)
//#define GPIOH_BASE             (AHBPERIPH_BASE + 0x041C0UL)
//#define GPIOI_BASE             (AHBPERIPH_BASE + 0x04200UL)

//写寄存器
#define GPIOA_DOUT_Addr    (GPIOA_BASE+8) //0x40004008
#define GPIOB_DOUT_Addr    (GPIOB_BASE+8) //0x40004048
#define GPIOC_DOUT_Addr    (GPIOC_BASE+8) //0x40004088
#define GPIOD_DOUT_Addr    (GPIOD_BASE+8) //0x400040C8
#define GPIOE_DOUT_Addr    (GPIOE_BASE+8) //0x40004108
#define GPIOF_DOUT_Addr    (GPIOF_BASE+8) //0x40004148   
#define GPIOG_DOUT_Addr    (GPIOG_BASE+8) //0x40004188   
#define GPIOH_DOUT_Addr    (GPIOH_BASE+8) //0x400041C8   
#define GPIOI_DOUT_Addr    (GPIOI_BASE+8) //0x40004208     
//读寄存器
#define GPIOA_PIN_Addr    (GPIOA_BASE+16) //0x40004010
#define GPIOB_PIN_Addr    (GPIOB_BASE+16) //0x40004050
#define GPIOC_PIN_Addr    (GPIOC_BASE+16) //0x40004090
#define GPIOD_PIN_Addr    (GPIOD_BASE+16) //0x400040D0
#define GPIOE_PIN_Addr    (GPIOE_BASE+16) //0x40004110
#define GPIOF_PIN_Addr    (GPIOF_BASE+16) //0x40004150
#define GPIOG_PIN_Addr    (GPIOG_BASE+16) //0x40004190
#define GPIOH_PIN_Addr    (GPIOH_BASE+16) //0x400041D0  
#define GPIOI_PIN_Addr    (GPIOI_BASE+16) //0x40004210


//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_DOUT_Addr,n)  //输出
#define PAin(n)    BIT_ADDR(GPIOA_PIN_Addr,n)  //输入

#define PBout(n)   BIT_ADDR(GPIOB_DOUT_Addr,n)  //输出
#define PBin(n)    BIT_ADDR(GPIOB_PIN_Addr,n)  //输入

#define PCout(n)   BIT_ADDR(GPIOC_DOUT_Addr,n)  //输出
#define PCin(n)    BIT_ADDR(GPIOC_PIN_Addr,n)  //输入

#define PDout(n)   BIT_ADDR(GPIOD_DOUT_Addr,n)  //输出
#define PDin(n)    BIT_ADDR(GPIOD_PIN_Addr,n)  //输入

#define PEout(n)   BIT_ADDR(GPIOE_DOUT_Addr,n)  //输出
#define PEin(n)    BIT_ADDR(GPIOE_PIN_Addr,n)  //输入

#define PFout(n)   BIT_ADDR(GPIOF_DOUT_Addr,n)  //输出
#define PFin(n)    BIT_ADDR(GPIOF_PIN_Addr,n)  //输入

#define PGout(n)   BIT_ADDR(GPIOG_DOUT_Addr,n)  //输出
#define PGin(n)    BIT_ADDR(GPIOG_PIN_Addr,n)  //输入

#define PHout(n)   BIT_ADDR(GPIOH_DOUT_Addr,n)  //输出
#define PHin(n)    BIT_ADDR(GPIOH_PIN_Addr,n)  //输入

#define PIout(n)   BIT_ADDR(GPIOI_DOUT_Addr,n)  //输出
#define PIin(n)    BIT_ADDR(GPIOI_PIN_Addr,n)  //输入
我们知道PH4对应KEY,PB14对应LED,在正常的GPIO初始化后,我们开始用BITBAND的模式来读取控制:
  while(1)
  {  
    if(PHin(4)==0)
    {
      while(PHin(4)==0){};
      PBout(14)=~PBout(14);
    }
如果按键被按下,等待按键释放后,LED切换状态。
编译,下载,查看:

新唐和其他家的不一样,它的库里面,直接就可以对GPIO PIN 单独操作,如PA5=0 类似的。
这个例子在其他家结合BITBAND 会比较简单些。
我们看看它是具体怎实现的:
先看一个例子:
#define PA0             GPIO_PIN_DATA(0, 0 )
展开定义:
#define GPIO_PIN_DATA(port, pin)    (*((volatile uint32_t *)((GPIO_PIN_DATA_BASE+(0x40*(port))) + ((pin)<<2)))) /*!< Pin Data Input/Output \hideinitializer */
再展开:
#define GPIO_PIN_DATA_BASE     (AHBPERIPH_BASE + 0x04800UL)
再展开:
#define PERIPH_BASE          ((uint32_t)0x40000000)      /*!< Peripheral Base Address */
#define AHBPERIPH_BASE       PERIPH_BASE

好,现在我们重新从下往上推:
#define GPIO_PIN_DATA_BASE     ((uint32_t)0x40000000+ 0x04800UL)
我们查看:


可见 GPIO_PIN_DATA_BASE      对应的是GPIO PA.n Pin Data Input/Output Register
根据表格得,每一个PORT的GPIO_PIN_DATA_BASE  地址相差0x40
对应某一个PORT 的GPIO_PIN_DATA_BASE其内部的0~15 引脚地址关系:在这个地址上再加上0x04*n (n=0~15)
那也就是 ((pin)<<2)) (pin:0~15)
那么:#define PA0             GPIO_PIN_DATA(0, 0 )
这个宏,其实就是定义到对应PORT 对应pin的 PAn_PDIO寄存器上面,我们查看PDIO寄存器:

我去,这个寄存器太好了,直接能读,又能写,比我们之前分开的那个好多了~
ST是没有这个,NXP的有类似的~
好了,bitband就到这了,谢谢观看~


使用特权

评论回复
沙发
tail066| | 2021-8-20 15:26 | 只看该作者
楼主你的帖子,看了很多,每个都能有一些新的小东西。
很值得学习~
真心感谢!

使用特权

评论回复
板凳
tail066| | 2021-8-20 15:28 | 只看该作者
说实话,之前根本不知道bitband是啥,

使用特权

评论回复
地板
gaoyang9992006| | 2021-8-20 22:11 | 只看该作者
 在51系列的单片机中可以通过P1.1=1这样的用法来设置P1口编号为1的引脚的电平,但是在STM32系列的单片机中不能直接设置某一个I/O口的电平,只能对某一个PORT口进行统一赋值,即遵循读--改--写的顺序进行,但是在这个操作的过程中容易出现异常情况。
  于是就有个BitBand,即将某一个字节中一位与别名区的一个字相对应,这样可以通过直接给这个字赋值来直接修改与其对应的bit,提高修改的效率和准确性。
新唐好多系列有这个功能。

使用特权

评论回复
5
uptown| | 2021-9-4 17:46 | 只看该作者
位段/位带            

使用特权

评论回复
6
cehuafan| | 2021-9-4 17:46 | 只看该作者
寄存器配置的吗   

使用特权

评论回复
7
sesefadou| | 2021-9-4 17:46 | 只看该作者
bit band功能还是比较好的。   

使用特权

评论回复
8
earlmax| | 2021-9-4 17:47 | 只看该作者
一般都是宏定义的。   

使用特权

评论回复
9
alvpeg| | 2021-9-4 17:47 | 只看该作者
Cortex M3与M4权威指南哪里下载的   

使用特权

评论回复
10
primojones| | 2021-9-4 17:47 | 只看该作者
bit band有什么定义   

使用特权

评论回复
11
10299823| | 2021-9-4 17:48 | 只看该作者
可以用bitband的   

使用特权

评论回复
12
lihuami| | 2021-9-4 17:48 | 只看该作者
这个寄存器的地址在哪里   

使用特权

评论回复
13
xiaoyaozt| | 2021-9-4 17:48 | 只看该作者
stm32用的是bit操作   

使用特权

评论回复
14
jimmhu| | 2021-9-4 17:48 | 只看该作者
CM4可以吗?     

使用特权

评论回复
15
alvpeg| | 2021-9-4 17:49 | 只看该作者
      

使用特权

评论回复
16
qjp1988113|  楼主 | 2021-9-4 18:49 | 只看该作者

可以,CM3,CM4,CM7均有,CM0 目前没有~

使用特权

评论回复
17
qjp1988113|  楼主 | 2021-9-4 18:50 | 只看该作者
lihuami 发表于 2021-9-4 17:48
这个寄存器的地址在哪里

MCU的头文件,或在datasheet里面有更详细的说明~

使用特权

评论回复
18
qjp1988113|  楼主 | 2021-9-4 18:57 | 只看该作者
alvpeg 发表于 2021-9-4 17:47
Cortex M3与M4权威指南哪里下载的

链接:https://pan.baidu.com/s/1Uc0UKIOG6040qTRqkPvZ5A
提取码:t7mk
--来自百度网盘超级会员V4的分享

使用特权

评论回复
19
两只袜子| | 2021-9-8 10:23 | 只看该作者
好帖,支持一下

使用特权

评论回复
20
两只袜子| | 2021-9-8 10:23 | 只看该作者
好帖,支持一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

111

主题

627

帖子

2

粉丝