1. 查原理图看LED是哪个GPIO控制
这个原理图看不出来LED是哪个GPIO控制的,在知乎上查找资料得到了结果。
这里是控制LED0(DS1),是接在GPIOF9上的,灯是红色的。
2. 点亮LED灯的几个步骤
1.使能GPIOF口的时钟,配置RCC AHB1 外设时钟使能寄存器 RCC_AHB1ENR
2.配置GPIO端口模式寄存器GPIOx_MODER(设置其为通用输出状态)
3.配置GPIO 端口输出速度寄存器GPIOx_OSPEEDR(50 MHz)
4.配置GPIO 端口输出类型寄存器GPIOx_OTYPER(设置为推挽输出)
5.配置GPIO 端口上拉/下拉寄存器GPIOx_PUPDR(设置为上拉)
6.配置GPIO 端口输出数据寄存器GPIOx_ODR
3. 查找对应寄存器的绝对地址
3.1 寄存器 RCC_AHB1ENR地址
找到RCC的基地址:0x40023800
找到RCC_AHB1ENR的地址:0x40023830(基地址+偏移地址)
使能GPIOF口的时钟:*( unsigned int * )0x40023830 |= 1<<5;(引脚5置1,就是使能了GPIOF口的时钟)
3.2 寄存器GPIOF_MODER地址
找到GPIOF的基地址:0x40021400
找到GPIOF_MODER的地址:0x40021400(基地址+偏移地址)
设置GPIO端口模式寄存器GPIOF_MODER为通用输出状态:
*( unsigned int * )0x40021400 &=~(3<<2*9); //把第18和19位取0, 3的二进制是11(置0)
*( unsigned int * )0x40021400 |= 1<<(2*9); //18位变成1,这样18和19位就是01(取1)
3.3 寄存器GPIOF_OSPEEDR地址
这里和下面寄存器的基地址都是GPIOF的基地址:0x40021400
找到GPIOF_OSPEEDR的地址:0x40021408(基地址+偏移地址)
设置GPIO 端口输出速度寄存器GPIOx_OSPEEDR为50 MHz:
*( unsigned int * )0x40021408 &=~(3<<2*9); //把第18和19位取0,3的二进制是11
*( unsigned int * )0x40021408 |= 2<<(2*9); //18位变成1,这样18和19位就是10
3.4 寄存器GPIOF_OTYPER地址
找到GPIOF_OTYPER的地址:0x40021404(基地址+偏移地址)
配置GPIO 端口输出类型寄存器GPIOF_OTYPER为推挽输出:
*( unsigned int *)0x40021404 &=~(1<<9);(置0)
3.5 寄存器GPIOF_PUPDR地址
找到GPIOF_PUPDR的地址:0x4002140C(基地址+偏移地址)
配置GPIO 端口上拉/下拉寄存器GPIOF_PUPDR为上拉:
*( unsigned int * )0x4002140C &=~(3<<2*9); //把第18和19位取0, 3的二进制是11
*( unsigned int * )0x4002140C |= 1<<(2*9); //18位变成1,这样18和19位就是01
3.6 寄存器GPIOF_ODR地址
找到GPIOF_ODR的地址:0x40021414(基地址+偏移地址)
配置GPIO 端口输出数据寄存器GPIOx_ODR:
*( unsigned int * )0x40021414 &= ~(1<<9);
4. main函数代码
int main(void)
{
while(1){
/* */
//1.使能时钟,打开GPIOF端口的时钟 ,AHB1,RCC ,这里不考虑是PF9,就是开的F端口的
*( unsigned int * )0x40023830 |= 1<<5;
//2.通用输出寄存器,配置IO口为输出(通用输出模式)
*( unsigned int * )0x40021400 &= ~(3<<2*9); //把第18和19位取0, 3的二进制是11
*( unsigned int * )0x40021400 |= 1<<(2*9); //18位变成1,这样18和19位就是01
//3.端口输出速度寄存器,配置端口输出速度寄存器 10是50MHZ
*( unsigned int * )0x40021408 &= ~(3<<2*9); //把第18和19位取0,3的二进制是11
*( unsigned int * )0x40021408 |= 2<<(2*9); //18位变成1,这样18和19位就是10 50MHZ
//4.推挽输出设置,配置IO口为输出(推挽输出模式,第9位置0
*( unsigned int * )0x40021404 &= ~(1<<9);
//5.上拉设置 01
*( unsigned int * )0x4002140C &= ~(3<<2*9); //把第18和19位取0, 3的二进制是11
*( unsigned int * )0x4002140C |= 1<<(2*9); //18位变成1,这样18和19位就是01
//6.ODR寄存器位取0
*( unsigned int * )0x40021414 &= ~(1<<9);
}
}
5. 结果显示(红色的灯亮了)