P0=0xFE;
sbit LED1 =P0^0;
LED1=0;
参考资料:《Cortex-M3权威指南》第五章的位带操作 理解比特的膨胀对应关系。
外设位带区与外设位带别名区的地址转换: AliasAddr=0x4200 0000+(A-0x4000 0000)32+n4; SRAM位带区与SRAM位带别名区的地址转换: AliasAddr=0x2200 0000+(A-0x2000 0000)32+n4;
A:表示我们要操作的那个位所在的寄存器的地址; n:位号
每一个字节都膨胀为一个字(4个字节)
((addr&0xF000 0000)+0x0200 0000+((addr&0x00FF FFFF)<<5)+(bitnum)<<2) addr:要操作的位所在寄存器的地址 bitnum:位号,即在寄存器的第几位
key.h
#ifndef __KEY_H
#define __KEY_H
#include "stm32f10x.h"
#include "delay.h"
#define KEY_0_GPIO_PIN GPIO_Pin_4
#define KEY_0_GPIO_PORT GPIOE
#define KEY_0_GPIO_CLK RCC_APB2Periph_GPIOE
#define KEY_1_GPIO_PIN GPIO_Pin_3
#define KEY_1_GPIO_PORT GPIOE
#define KEY_1_GPIO_CLK RCC_APB2Periph_GPIOE
#define KEY_UP_GPIO_PIN GPIO_Pin_0
#define KEY_UP_GPIO_PORT GPIOA
#define KEY_UP_GPIO_CLK RCC_APB2Periph_GPIOA
#define KEY0 PEin(4)
#define KEY1 PEin(3)
#define KEY_UP PAin(0)
#define KEY0_PRES 1
#define KEY1_PRES 2
#define KEY_UP_PRES 3
#define GPIOE_ODR_Addr (GPIOE_BASE+0x08)
#define PEin(n) *(u32 *)((GPIOE_ODR_Addr&0xF0000000)+0x02000000+((GPIOE_ODR_Addr&0x00FFFFFF)<<5)+(n<<2))
#define GPIOA_ODR_Addr (GPIOA_BASE+0x08)
#define PAin(n) *(u32 *)((GPIOA_ODR_Addr&0xF0000000)+0x02000000+((GPIOA_ODR_Addr&0x00FFFFFF)<<5)+(n<<2))
void Key_GPIO_Config(void);
uint8_t Key_Scan(void);
#endif
GPIO输入:
#define GPIOE_ODR_Addr (GPIOE_BASE+0x08)
#define PEin(n) *(u32 *)((GPIOE_ODR_Addr&0xF0000000)+0x02000000+((GPIOE_ODR_Addr&0x00FFFFFF)<<5)+(n<<2))
是参考((addr&0xF000 0000)+0x0200 0000+((addr&0x00FF FFFF)<<5)+(bitnum)<<2)得到的。
#define KEY0 PEin(4)
是GPIO输入的位带操作的应用,可以通过判断KEY0的值来得到按键的状态。
main.c
#include "stm32f10x.h"
#include "bsp_led.h"
#include "key.h"
#include "delay.h"
#define GPIOB_ODR_Addr (GPIOB_BASE+0x0c)
#define PBout(n) *(u32 *)((GPIOB_ODR_Addr&0xF0000000)+0x02000000+((GPIOB_ODR_Addr&0x00FFFFFF)<<5)+(n<<2))
int main(void)
{
uint8_t a;
LED_GPIO_Config();
Key_GPIO_Config();
delay_init();
LED_0(OFF);
LED_1(OFF);
#if 0
while(1)
{
PBout(5)=0;
delay_ms(500);
PBout(5)=1;
delay_ms(500);
}
#else
while(1)
{
a=Key_Scan();
if(a!=0)
{
if(a==1){LED_0_TOGGLE;}
else if(a==2){LED_1_TOGGLE;}
else if(a==3){LED_0_TOGGLE;LED_1_TOGGLE;}
}
}
#endif
}
GPIO输出:
#define GPIOB_ODR_Addr (GPIOB_BASE+0x0c)
#define PBout(n) *(u32 *)((GPIOB_ODR_Addr&0xF0000000)+0x02000000+((GPIOB_ODR_Addr&0x00FFFFFF)<<5)+(n<<2))
PBout(5)=0;
是GPIO输出的位带操作的应用,可以直接通过它来赋值。
|