AHB1ENR|= 1<<5;//使能RCC的AHB1时钟 //PF9 的GPIO配置 //将(1 1)左移..._gpioe->odr&=~(1<<13)">
赞
踩
第一种:指针形式
- led.c文件:
-
- #include "led.h"
- #include "stm32f4xx.h"
- void LED_Init(void)
- {
- //1左移五位既是将第五位置为1,查寄存器可知1是使能0失能
- RCC->AHB1ENR|= 1<<5;//使能RCC的AHB1时钟
-
-
- //PF9 的GPIO配置
- //将(1 1)左移18位再取反清零:2代表两位控制一IO,因为IO是F9,所以最后是~(3<<2*9),达到清零效果
-
- GPIOF->MODER &= ~(3<<2*9);//配置为0用&,配置为1用 |
- GPIOF->MODER |= 1<<(2*9);//1既是0 1,代表输出模式(查寄存器)
-
- GPIOF->OSPEEDR &= ~(3<<2*9);//同理,清零
- GPIOF->OSPEEDR |= 2<<(2*9);//2是1 0,将F9设置为50MHZ的速度
-
- GPIOF->PUPDR &= ~(3<<2*9);//清零
- GPIOF->PUPDR |=1<<(2*9);//上拉
-
- GPIOF->OTYPER &= ~(1<<9);//清零,该寄存器是低16位有效,1位控制1个IO
- GPIOF->OTYPER |=0<<9;//置0,既是输出推挽(复位)
-
- GPIOF->ODR|= 1<<9;//1 控制高低电平
- //GPIOF->ODR&=~(1<<9);//
-
- //PF10 同理配置PF10
- GPIOF->MODER &= ~(3<<2*10);
- GPIOF->MODER |= 1<<(2*10);
-
- GPIOF->OSPEEDR &= ~(3<<2*10);
- GPIOF->OSPEEDR |= 2<<(2*10);
-
- GPIOF->PUPDR &= ~(3<<2*10);
- GPIOF->PUPDR |=1<<(2*10);
-
- GPIOF->OTYPER &= ~(1<<10);
- GPIOF->OTYPER |=0<<10;
-
- GPIOF->ODR|= 1<<10;
- }
- ///
- led.h文件:
- #ifndef __LED_H
- #define __LED_H
-
- void LED_Init(void);
-
- #endif
- ///
-
- main.c文件:
-
- #include "stm32f4xx.h"
- #include "led.h"
- #include "delay.h"
-
- int main(void)
- {
- delay_init(168);
-
- LED_Init();
-
- while(1)
- {
-
- GPIOF->ODR&=~(1<<9);
- GPIOF->ODR&=~(1<<10);
- delay_ms(500);
-
- GPIOF->ODR |= 1<<9;
- GPIOF->ODR |=1<<10;
- delay_ms(500);
- }
- }
------------------------------------------------------------------------------------------------------------------
第二种方法:配置基地址开始
- // 设置寄存器宏定义
- //1、时钟线
- #define RCC_AHB1ENR *(volatile unsigned long *)(0x40023800 + 0x30) // volatile 防止编译器优化 AHB1外设使能时钟线
-
- #define GPIOF_MODER *(volatile unsigned long *)(0x40021400 + 0x00) // GPIOF的模式寄存器
- #define GPIOF_OTYPER *(volatile unsigned long *)(0x40021400 + 0x04) // GPIOF的输出类型寄存器
- #define GPIOF_OSPEEDR *(volatile unsigned long *)(0x40021400 + 0x08) // GPIOF的输出速度寄存器PUPDR
- #define GPIOF_PUPDR *(volatile unsigned long *)(0x40021400 + 0x0c) // GPIOF的上下拉寄存器
- #define GPIOF_ODR *(volatile unsigned long *)(0x40021400 + 0x14) // GPIOF的输出数据寄存器
- #define GPIOF_BSRR *(volatile unsigned long *)(0x40021400 + 0x18) // GPIOF的复位/置位寄存器
-
- #define GPIOE_MODER *(volatile unsigned long *)(0x40021000 + 0x00) // GPIOF的模式寄存器
- #define GPIOE_OTYPER *(volatile unsigned long *)(0x40021000 + 0x04) // GPIOF的输出类型寄存器
- #define GPIOE_OSPEEDR *(volatile unsigned long *)(0x40021000 + 0x08) // GPIOF的输出速度寄存器PUPDR
- #define GPIOE_PUPDR *(volatile unsigned long *)(0x40021000 + 0x0c) // GPIOF的上下拉寄存器
- #define GPIOE_ODR *(volatile unsigned long *)(0x40021000 + 0x14) // GPIOF的输出数据寄存器
- #define GPIOE_BSRR *(volatile unsigned long *)(0x40021000 + 0x18) // GPIOF的复位/置位寄存器
-
-
- // 大概时间的延时函数
- void delay(int n)
- {
- while(n--)
- {
- int i = 1000;
- while(i--);
- }
- }
-
- // 初始化LED
- int init_led(void)
- {
- // 2、初始化时钟、寄存器 第5位置1就是使能
- RCC_AHB1ENR |= 1<<5;
-
- //3、配置寄存器各种参数,LED只是输出,所以选择每个参数里面的输出模式
- // ①初始化GPIOF为输出模式
- //---------------模式--移动位数
- GPIOF_MODER &= ~(0x3<<18); // 清空第18位和19位 11
- GPIOF_MODER |= 1<<18; // 配置PF9
-
- //GPIOF_MODER &= ~(0xF<<18); // 清空第18位和19位、20位、21位 1111
- //GPIOF_MODER |= 0x5<<18; // 配置PF9、PF10
- GPIOF_MODER &= ~(0x3<<20); // 清空第20位、21位 11
- GPIOF_MODER |= 1<<20;//配置PF10
-
- // ②配置GPIOF的输出类型为推挽
- GPIOF_OTYPER &= ~(0x1<<9); // 清空第9位
- GPIOF_OTYPER &= ~(0x1<<10); // 清空第10位
-
- // ③配置GPIOF的输出速度
- GPIOF_OSPEEDR &= ~(0x3<<18); // 清空第18位和19位 11
- GPIOF_OSPEEDR &= ~(0x3<<20); // 清空第20 21 11
- GPIOF_OSPEEDR |= 0x2<<18; // 50M速度
- GPIOF_OSPEEDR |= 0x2<<20; // 50M速度
-
- // ④配置 GPIOF为上拉输出
- GPIOF_PUPDR &= ~(0x3<<18); // 清空第18位和19位 11
- GPIOF_PUPDR |= 1<<18; // 配置PF9为上拉输出
- GPIOF_PUPDR &= ~(0x3<<20); // 清空第20位和21位 11
- GPIOF_PUPDR |= 1<<20; // 配置PF10为上拉输出
-
- // ⑤输出数据:高电平 1 低电平 0
- GPIOF_ODR |= 1<<9; // PF的第9个引脚输出高电平
- GPIOF_ODR |= 1<<10; // PF的第10个引脚输出高电平
-
- /*********************************PE脚**************************************/
- // 初始化时钟 寄存器第4位置1就是使能
- RCC_AHB1ENR |= 1<<4; //PE脚
-
- // 初始化GPIOF为输出模式
- GPIOE_MODER &= ~(0x3<<26); // 清空第26位和27\28\29位 11
- GPIOE_MODER |= 1<<26; // 配置PF9, 1010即是5,可同时配置
-
- GPIOE_MODER &= ~(0x3<<28); // 清空第20位、21位 11
- GPIOE_MODER |= 1<<28;//配置PF10
-
- // 配置GPIOF的输出类型为推挽
- GPIOE_OTYPER &= ~(0x1<<13); // 清空第9位
- GPIOE_OTYPER &= ~(0x1<<14); // 清空第10位
-
- // 配置GPIOF的输出速度
- GPIOE_OSPEEDR &= ~(0x3<<26); // 清空第18位和19位 11
- GPIOE_OSPEEDR &= ~(0x3<<28); // 清空第20 21 11
- GPIOE_OSPEEDR |= 0x2<<26; // 50M速度
- GPIOE_OSPEEDR |= 0x2<<28; // 50M速度
-
- // 配置 GPIOF为上拉输出
- GPIOE_PUPDR &= ~(0x3<<26); // 清空第18位和19位 11
- GPIOE_PUPDR |= 1<<26; // 配置PF9为上拉输出
- GPIOE_PUPDR &= ~(0x3<<28); // 清空第20位和21位 11
- GPIOE_PUPDR |= 1<<28 ;// 配置PF10为上拉输出
-
- // 输出数据:高电平 1 低电平 0
- GPIOE_ODR |= 1<<13; // PF的第9个引脚输出高电平
- GPIOE_ODR |= 1<<14; // PF的第10个引脚输出高电平
- return 0;
- }
-
- int main(void)
- {
- // 初始化LED
- init_led();
-
- while (1)
- {
- // 点亮LED0
- GPIOF_ODR &= ~(1<<9); // PF的第9个引脚输出低电平
- delay(2000);
- GPIOF_ODR |= 1<<9;
- delay(2000);
-
- // 输出数据:高电平 1 低电平 0
- GPIOF_ODR &= ~(1<<10);
- delay(2000);
- GPIOF_ODR |= 1<<10; // PF的第9个引脚输出高电平
- delay(2000);
-
- GPIOE_ODR &= ~(1<<13);
- delay(2000);
- GPIOE_ODR |= 1<<13; // PE的第13、14个引脚输出高电平
- delay(2000);
-
- GPIOE_ODR &= ~(1<<14);
- delay(2000);
- GPIOE_ODR |= 1<<14;
- delay(2000);
- }
- }
两者的区别在于一个需要配置基地址,一个直接用指针对寄存器进行操作,那怎样配置基地址,下面解释一下:
1、根据STM32F4xx中文参考手册的2.3节存储器的映射找到对应总线、外设的边界基地址,我这里只截了部分图,仅供参考
2、找到对应寄存器的偏移地址,在STM32F4xx中文参考手册7.4节
配置后如下所示:
2、最后对应寄存器进行对其位移操作即可(寄存器映射),可参考上面的代码
总结:这里以一个简单的LED闪烁来了解对寄存器进行具体的操作,使自己能够用寄存器来进行项目的开发,其他的外设配置是一样的原理。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。