STM32F407初学

简单开始学习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”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值