简单开始学习STM32F4,上学期巩固一遍51单片机,单片机实现外设ADC采集及数据传输。这学期开始学习STM32并完成毕业设计。
学习32确实得从寄存器开始,因为51其实都已经分装好自己的寄存器,你去完成一些很简单的东西确实不需要寄存器,但是对于上面提到的完成外设ADC的话,对AD芯片手册的学习,就会发现寄存器真的太烦人了。听了好几天STM32的课,现总结初识STM32寄存器部分,完成点亮LED。(新建项目、文主函数、h函数就不必写了)。
1.首先,编写stm32f4xx.h文件,也就是寄存器映射函数,这一部分可以很好的把寄存器部分理解清楚,你需要什么寄存器,那你需要这个寄存器的哪一位,需要用什么寄存器打开。
/*用来存放寄存器映射相关代码*/
//GPIOF寄存器的基值,找到第一个位置,方便后面增加偏移地址
#define GPIOF_BASE ((unsigned int) 0x40021400) //基值,找到第一个位置,方便后面增加偏移地址
//分别写出GPIOF对应的MODRE OTYPER ODR 寄存器的地址
#define GPIOF_MODER *(unsigned int *)(GPIOF_BASE + 0x00) //控制GPIOF端口输出模式的寄存器
#define GPIOF_OTYPER *(unsigned int *)(GPIOF_BASE + 0x04)
#define GPIOF_ODR *(unsigned int *)(GPIOF_BASE + 0x14) //一个GPIOF端口对应16个IO,ODR寄存器可以对16个IO进行赋值
//RCC寄存器的基值。 因为GPIOF寄存器挂在AHB1总线上,要能使GPIOF用作IO口
//就需要打开RCC_AHB1寄存器上对应GPIOF的使能。1为使能IO端口F时钟,0为禁止。
#define RCC_BASE ((unsigned int) 0x40023800)
#define RCC_AHB1ENR *(unsigned int *)(RCC_BASE + 0x30)
通过C语言中对地址访问,对寄存器地址进行简单定义,方便在主函数中调用。
2.其次,是主函数编写。也就是对.h中定义的寄存器进行赋值。我的理解就是,比如现在需要PF9引脚输出低电平(正点原子开发板PF9接了LED方便观察),那整体思路是:
PF9属于哪个GPIO----------------------------------------------------GPIOF
这个GPIOF是控制16位的IO,怎么找到PF9------------------------数据手册,找到第几位控制PF9
如何让这个口输出呢?------------------------------------------------GPIOF_MODER寄存器,一共有四个模式,需要选择输出模式,才能达到预期效果。
如何对PF9赋值------------------------------------------------------用ODR或BSRR寄存器
如何让这个口输出呢-------------------------------------------------打开对应时钟使能:RCC寄存器
PF9对应的时钟使能是哪个?----------------------------------------GPIOF是搭载在AHB1总线上的,所以需要打开AHB1EN。
#include "stm32f4xx.h"
int main (void)
{
/*添加程序*/
/*第一步 打开GPIOF端口时钟:RCC寄存器控制GPIOF端口时钟
RCC_AHB1寄存器一共32位,第五位为GPIOFEN,使其为1即可*/
RCC_AHB1ENR |= (1<<5);
/*第二步 配置GPIO为输出:MODER寄存器 先清零,再置位!*/
GPIOF_MODER &= ~((0x03)<<(2*10));// 清0:用“与非”实现
GPIOF_MODER |= ((0x01)<<(2*10));// 置1:用“或”实现
/*第三步 让GPIOF输出具体数值:ODR寄存器*/
GPIOF_ODR |= ((0x01) << 10); //先将GPIOF10赋值为1
GPIOF_ODR &= ~((0x01) << 10); //再将GPIOF10赋值为0
}
void SystemInit (void)
{
}
最后,加上官方的启动文件就可以了。
那有人会问为什么上面这块会有SystemInit()这个函数,如图:
在启动文件中,需要包括SystemInit()函数。不过也可以直接在启动文件把这句话注释掉(启动文件是汇编语言,需要用;注释),注释掉之后就不需要在主函数中加SystemInit()函数了。
最后!强调一下 对寄存器赋值过程中,清0用“与非1”;置1用“或1”。