一、查看原理图:

由图可知,该开发板的
LED0和LED1分别接PA8和PD2,且欲点亮LED0和LED1,需要让PA8和PD2输出低电平
二、查看参考手册:
1、外设时钟使能:


由以上信息可知:
RCC寄存器的起始地址为0x40021000,APB2 外设时钟使能寄存器RCC_APB2ENR的偏移地址为0x18,即绝对地址为 0x40021000+0x18=0x40021018,把RCC_APB2ENR寄存器的bit5和bit2置1即可使能GPIOA和GPIOD的时钟
2、端口配置:



由以上信息可知:
GPIOA寄存器和GPIOD寄存器的起始地址分别为0x40010800和0x40011400,端口配置高寄存器GPIOx_CRH的偏移地址为0x04,端口配置低寄存器GPIOx_CRL的偏移地址为0x00,所以PA8口:应配置地址0x40010804的bit3~0为0001,PD2口:应配置地址0x40011400的bit11~8为0001(此处我们配置通用推挽输出模式和输出模式,最大速度10MHZ)
3、端口输出:

GPIOA寄存器和GPIOD寄存器的起始地址分别为0x40010800和0x40011400,端口输出数据寄存器GPIOx_ODR的地址偏移为0x0C,所以PA8口:应配置地址0x4001080C的bit8置0,PD2口:应配置地址0x4001140C的bit2置0
三、参考程序:
!!逐步优化代码,不断接近库函数,从而实现 “寄存器版本” 向 “库函数版本” 的转变
1、直接操作寄存器:
void LED0_Init(void);
void LED1_Init(void);
int main(void)
{
LED0_Init();
LED1_Init();
*(unsigned int *)0x4001080C &= ~(1<<8); // PA8输出低电平
*(unsigned int *)0x4001140C &= ~(1<<2); // PD2输出低电平
}
void LED0_Init(void)
{
*(unsigned int *)0x40021018 |= (1<<2); // 开启GPIOA时钟
*(unsigned int *)0x40010804 &= ~((0x0f)<<(4*0)); // 配置 PA8
*(unsigned int *)0x40010804 |= ((1)<<(4*0));
}
void LED1_Init(void)
{
*(unsigned int *)0x40021018 |= (1<<5); // 开启GPIOD时钟
*(unsigned int *)0x40011400 &= ~((0x0f)<<(4*2)); // 配置PD2
*(unsigned int *)0x40011400 |= ((1)<<(4*2));
}
2、寄存器映射:
#define PERIPH_BASE ((unsigned int)0x40000000)
#define APB1PERIPH_BASE (PERIPH_BASE)
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
#define GPIOA_BASE (APB2PERIPH_BASE + 0x800)
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
#define RCC_APB2ENR *(unsigned int *)(RCC_BASE + 0x18)
#define GPIOA_CRH *(unsigned int *)(GPIOA_BASE +

最低0.47元/天 解锁文章
1703

被折叠的 条评论
为什么被折叠?



