刘凯stm32教程第13-14讲总结——位绑定

stm32是32位微控制器,每次操作都必须一次处理32个位,若想对其进行一个为处理,那么如要对GPIOA的输出寄存器ODR的第3位进行置1,则操作语句为GPIOA->ORD=GPIOA->ORD|0X08,要经历读出、或运算、写入操作,操作繁琐,而若能单独对其进行一个位进行操作,会大大提高运算速度。这里有两种方法,一种是对GPIOx的寄存器BRR和BSRR进行赋值,还有一种就是位绑定。stm32不是允许所以位都可进行位绑定,只要求两个区域SRAM区0x2000 0000~0x200f ffff范围(1M空间),片上外设区0x4000 0000~0x400f ffff范围(1M空间),这两个区称为bit_band region,每个位都相对应其他区域的32位,对这32位进行操作来控制所对应的位为0或1,控制原理是1或0又32位最低位的1或0控制,而其他高31位无作用。在stm32中,一个地址(一位)对应8位存储单元,即一个字节。所指向32位单元的区域称为Alias region,因为stm32中每个寄存器都占32个字节,所以相邻寄存器的起始地址相差4。位绑定公式为
bit_word_addr = Alias_region_base + (byte_offset*32) + (bit_number*4)

其中
bit_word_addr在Alias region,为地址指向32位存储空间,而这32位为计算机实际要操作的数,并映射到对应的位。
Alias_region_base:Alias region基址
byte_offset:bit_band region偏移地址(因为bit_band region基址与Alias region基址对应)。
bit_number:寄存器中的第几位。
要说明的是,有的人把bit_number限制在0~7,这是因为bit_band region的每个地址(一位)对应bit_band region8位,所以相当于把一个寄存器分成4份,每份配一个首地址,但这样相对麻烦,还不如把bit_number的范围规定为0~31,只需要知道一个寄存器的首地址即可。
编程可为:

#include "stm32f10x.h"
#define GPIO_ODR_A (GPIOA_BASE + 0x0C)
#define GPIO_IDR_A (GPIOA_BASE + 0x08)
#define GPIO_ODR_B (GPIOB_BASE + 0x0C)
#define GPIO_IDR_B (GPIOB_BASE + 0x08)
#define GPIO_ODR_C (GPIOC_BASE + 0x0C)
#define GPIO_IDR_C (GPIOC_BASE + 0x08)
#define GPIO_ODR_D (GPIOD_BASE + 0x0C)
#define GPIO_IDR_D (GPIOD_BASE + 0x08)
#define GPIO_ODR_E (GPIOE_BASE + 0x0C)
#define GPIO_IDR_E (GPIOE_BASE + 0x08)
#define BitBand(Addr,BitNum) *((volatile unsigned long *)((Addr & 0xF0000000) + 0x2000000 + ((Addr & 0xFFFFF)*32) + (BitNum*4)))
#define PAOut(n) BitBand(GPIO_ODR_A,n)
#define PAIn(n) BitBand(GPIO_IDR_A,n)
#define PBOut(n) BitBand(GPIO_ODR_B,n)
#define PBIn(n) BitBand(GPIO_IDR_B,n)
#define PCOut(n) BitBand(GPIO_ODR_C,n)
#define PCIn(n) BitBand(GPIO_IDR_C,n)
#define PDOut(n) BitBand(GPIO_ODR_D,n)
#define PDIn(n) BitBand(GPIO_IDR_D,n)
#define PEOut(n) BitBand(GPIO_ODR_E,n)
#define PEIn(n) BitBand(GPIO_IDR_E,n)
#define BitBand(Addr,BitNum)  *((volatile unsigned long *)((Addr&0xF0000000)+0x02000000+((Addr&0xfffff)*32)+(BitNum*4)))

#define PAout(n)   BitBand(GPIOA_ODR_A,n) 
#define PAin(n)   BitBand(GPIOA_IDR_A,n) 
#define PBout(n)   BitBand(GPIOB_ODR_B,n) 
#define PBin(n)   BitBand(GPIOB_IDR_B,n)
#define PCout(n)   BitBand(GPIOC_ODR_C,n) 
#define PCin(n)   BitBand(GPIOC_IDR_C,n)
#define PDout(n)   BitBand(GPIOD_ODR_D,n) 
#define PDin(n)   BitBand(GPIOD_IDR_D,n)
#define PEout(n)   BitBand(GPIOE_ODR_E,n) 
#define PEin(n)   BitBand(GPIOE_IDR_E,n)
int  main(void)
{
    GPIOA->CRL=0X33333333;
    GPIOA->CRH=0X44444444;
    while(1)
    {
    if(PAin(8)==1) PAout(0)=1;
    else           PAout(0)=0;  
    if(PAin(9)==1) PAout(1)=1;
    else           PAout(1)=0;
    if(PAin(10)==1) PAout(2)=1;
    else           PAout(2)=0;
    if(PAin(11)==1) PAout(3)=1;
    else           PAout(3)=0;
    if(PAin(12)==1) PAout(4)=1;
    else           PAout(4)=0;
    if(PAin(13)==1) PAout(5)=1;
    else           PAout(5)=0;
    if(PAin(14)==1) PAout(6)=1;
    else           PAout(6)=0;
    if(PAin(15)==1) PAout(7)=1;
    else           PAout(7)=0;


    }

    return(1);
}

妈的,因为一点小错误,调错耽误了一下午时间,以后一定要小心啊!仔细慢慢写,可能速度会慢一些,但实际上并不慢,不疾而速!

#define BitBand(Addr,BitNum)  *((volatile unsigned long *)((Addr&0xF0000000)+0x02000000+(Addr&0xfffff)*32+BitNum*4))

#define PAout(n)   BitBand(GPIOA_ODR_A,n) 

函数还可以这样定义,开了眼界。由前面的调用函数提供必要的变量。其中PAout(n)为指针。
参考http://m.doczj.com/doc/83d303b2c850ad02df80416f.html

猜你喜欢

转载自blog.csdn.net/a_z666666/article/details/54427453