STM32之寄存器访问

一般的寄存器访问需要通过读-改-写三步曲位运算的清0置1来实现,但在stm32的编程中,通过利用它的一些优秀的特性如端口位设置/复位寄存BSRR、位绑定等,我们可以大大提升寄存器的访问速度和简化寄存器的操作。

GPIO->ODR |= 0x10;  //Pin4置1
GPIO->ODR &= ~0x10; //Pin4清0

BSRR/BRR寄存器
这里写图片描述
这里写图片描述

GPIO->BSRR //对BSRR的低16位写1置位,对BSRR的高16位写1清零
GPIO->BRR //对BRR的低16位写1清零,BRR的高16位保留

由此可见,通过BSRR/BRR寄存器来操作ODR寄存器, 不需要 读-改-写三步曲, 仅通过 就可一步到位,方便不少。

位绑定
当然了,stm32还有一个更牛X的特性–位绑定,仅仅只要1个时钟周期就能实现单独的位操作。位绑定,是通过简单的地址变换将寄存器中的某一个位映射到内存中的某一个存储单元。这样通过对一个内存单元的读写就能间接访问相应寄存器的某个位了,当然此时该32位的内存单元也只有最低位是有效的啦!

但是整个M3内核并没有全部允许位绑定,只有两个区有,分别是

SARM:0x20000000~0x2000FFFF 1M大小 

这个区绑定的地址是从0x22000000开始的;

PERIPHERALS:0x40000000~0x4000FFFFF 1M大小

这个区绑定的地址是从0x42000000开始的;

对应的位绑定公式为:

SRAM:AliasADDr = 0x22000000+((A-0x20000000)*32+n*4)

其中A:0x20000000~0x2000FFFF n:0~31

PERIPHERALS: AliasADDr = 0x42000000+((A-0x40000000)*32+n*4)

其中A:0x40000000~0x4000FFFFF n:0~31

下面就可以通过位绑定来快速实现位操作

#define GPIOA_ODR_ADDR (GPIOA_BASE + 0x0C)
#define GPIOA_IDR_ADDR (GPIOA_BASE + 0x08)
#define BitBind(Addr, bitNum) (*(volatile unsigned long *)((Addr&0xF0000000)+0x2000000+((Addr&0xFFFFF)<<5)+(bitNum<<2)))
//Addr&0xF0000000是为了区分SRAM还是PERIPHERALS
//Addr&0xFFFFF相当于(A-0x20000000)或者(A-0x40000000)
//左移是为了实现快速的乘法操作:左移n位相当于乘以2^n
#define PAout(n) BitBind(GPIOA_ODR_ADDR, n)
#define PAin(n) BitBind(GPIOA_IDR_ADDR, n)

这样就实现了类似51单片机访问I/O的操作方式

sbit P10 = P1^0
P10 = 0; 或 P10 = 1;
PAout(3) = 1; 或 PAout(3) = 0;

版权声明:著作权归作者所有。

相关推荐

Nginx禁止直接使用IP访问

默认情况下,使用IP就可以访问到主机的默认页面。为了防止别人恶意将域名解析到自己的IP上,可以修改Nginx配置禁止直接使用ip访问。添加server如下:server {  listen 80 default;  server_name _;  return 403;}如果要禁止使用https访问,添加server如下:server { listen 443 d

Nginx禁用ip访问

在Nginx配置禁用ip访问有两种方法:方法一、新增一个server,设置为默认的虚拟主机,如下:server { listen 80 default; server_name _; return 403;}方法二、只允许指定域名进入:listen 80;server_name www.example.com;if ($host != 'ww

使用awk分析nginx访问日志access.log的ip

access.log为nginx的访问日志,默认路径在/var/log/nginx/access.log 分析access.log的ip命令如下:awk '{print $1}' access.log |sort|uniq -c|sort -n 命令里使用awk过滤出访问的ip使用sort对ip排序对排序后的ip进行统计,统计每一个ip访

Kotlin:流程控制之条件语句 if 和 when

在Kotlin有两种用于判断条件的语句if 和when。if在Kotlin,if既可以是条件语句,仅仅用作条件判断,还可以是条件表达式,表达式会返回一个值。传统的条件判断if语句var max = a  if (a < b) max = b if-elsevar max:&

TypeScript:变量声明之解构赋值

解构(Destructuring)是ES6新增的特性。数组和对象(Object)的一个作用是把一些值组合打包在一起。与之相对,解构就类似把数组里的值或对象的属性解包。使用解构赋值语法可以很简便地把数组的值或对象的属性赋值给单独的变量。语法var a, b, rest; [a, b] = [10, 20]; console.log