1,什么是位带操作?
位带操作就是一种对GPIOx(x=ABCDEFG...)某个位进行操作,
2,为什么进行位带操作?
为了更方便,没了。(我也不清楚位带操作会不会使GPIO口翻转变得更快,我认为是不行)
3,位带操作原理
3.1位带区和位带别名区:略
外设位带区地址为:0x40000000~0x40100000,大小为1MB,(这一部分包含了F1系列所有的片上外设寄存器)
外设位带别名区地址:0x42000000~0x43FFFFFF,大小为32MB
位带别名区是位带区的地址进行膨胀形成的,每一位变大为32位(因为stm32的系统总线是32位的,所以膨胀为32位处理速度最快,最高效)
虽然stm32上所有寄存器都可以实现位操作,大部分情况我们只会对IO口进行位带操作
4,STM32F103 GPIO位带操作实验
#include "stm32f10x.h" // Device header
#define BITBAND(addr,bitnum) ((addr & 0xF0000000) + 0x02000000+ ((addr & 0x00FFFFFF) <<5 )+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))
#define GPIOA_ODR_Addr (GPIOA_BASE+12)
#define GPIOB_ODR_Addr (GPIOB_BASE+12)
#define GPIOC_ODR_Addr (GPIOC_BASE+12)
#define GPIOD_ODR_Addr (GPIOD_BASE+12)
#define GPIOE_ODR_Addr (GPIOE_BASE+12)
#define GPIOF_ODR_Addr (GPIOF_BASE+12)
#define GPIOG_ODR_Addr (GPIOG_BASE+12)
#define GPIOA_IDR_Addr (GPIOA_BASE+8)
#define GPIOB_IDR_Addr (GPIOB_BASE+8)
#define GPIOC_IDR_Addr (GPIOC_BASE+8)
#define GPIOD_IDR_Addr (GPIOD_BASE+8)
#define GPIOE_IDR_Addr (GPIOE_BASE+8)
#define GPIOF_IDR_Addr (GPIOF_BASE+8)
#define GPIOG_IDR_Addr (GPIOG_BASE+8)
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n)
#define PAin(n) BIT_ADDR(GPIOA_ODR_Addr,n)
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n)
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n)
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n)
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n)
void delay(void)
{
int i;
for(i=720;i>0;i--)
{
for(i=720;i>0;i--);
}
}
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
while (1)
{
PCout(13)=1;
delay();
PCout(13)=0;
delay();
}
}
软件延时可能写的有点问题,数据好像溢出了,但是懒得改了
#define BITBAND(addr,bitnum) ((addr & 0xF0000000) + 0x02000000+ ((addr & 0x00FFFFFF) <<5 )+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))
这三行是公式