某个寄存器地址,由三个参数决定:1、总线基地址(BUS_BASE_ADDR);2,外设基于总线基地址的偏移量(PERIPH_OFFSET);3,寄存器相对外设基地址的偏移量(REG_OFFSET)。可以表示为:
寄存器地址 = BUS_BASE_ADDR + PERIPH_OFFSET + REG_OFFSET
复位和时钟控制(RCC) 0x4002 1000 - 0x4002 13FF
偏移地址:0x18 ;其地址为0x4002 1018
复位值:0x0000 0000
控制GPIOx的0-7针脚
控制GPIO的8-15针脚
每个GPI/O端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH),两个32位数据寄存器(GPIOx_IDR和GPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。 根据数据手册中列出的每个I/O端口的特定硬件特征, GPIO端口的每个位可以由软件分别配置成多种模式。
//#define GPIOB_CRH_addr 0X40010C04
//#define GPIOB_IDR_addr 0X40010C08
//#define GPIOB_ODR_addr 0X40010C0C
//#define GPIOB_BSRR_addr 0X40010C10
//#define GPIOB_BRR_addr 0X40010C14
//#define GPIOB_LCKR_addr 0X40010C18
//#define RCC_APB2ENR_addr 0X4002 1018 //偏移0x18
//#define GPIOB_CRL (*(unsigned int *)(0X40010C00))
//#define GPIOB_CRH (*(unsigned int *)(0X40010C04))
//#define GPIOB_IDR (*(unsigned int *)(0X40010C08))
//#define GPIOB_ODR (*(unsigned int *)(0X40010C0C))
//#define GPIOB_BSRR (*(unsigned int *)(0X40010C10))
//#define GPIOB_BRR (*(unsigned int *)(0X40010C14))
//#define GPIOB_LCKR (*(unsigned int *)(0X40010C18))
#define RCC_APB2ENR (*(unsigned int *)(0X40021018))
#define GPIOB_BASE_addr 0X40010C00
typedef struct{
volatile unsigned int CRL;
volatile unsigned int CRH;
volatile unsigned int IDR;
volatile unsigned int ODR;
volatile unsigned int BSRR;
volatile unsigned int BRR;
volatile unsigned int LCKR;
}GPIO;
GPIO *GPIO_B=(GPIO*)(GPIOB_BASE_addr);
//由于结构体连续分配内存,并且GPIO配置寄存器也是连续的相隔4个字节,故寄存器地址能完整映射到结构体。
int main()
{
RCC_APB2ENR=8;
// GPIOB_CRL = 0XD00000;//00000000 10110000 00000000 0000000; // 配置PB5为复用推挽输出模式速度为50MHz
//GPIOB_ODR = 0X10; //
//GPIOB_ODR= 0; //
GPIO_B->CRH=0X0011;
GPIO_B->CRL=0Xd00000;
//GPIO_B->ODR|=(1<<5);//低电平驱动LED
GPIO_B->ODR|=(1<<8);//高电平驱动有源蜂鸣器
while(1);
}