STM32F103学习日程记录

Posted InumakiToge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32F103学习日程记录相关的知识,希望对你有一定的参考价值。

目录

相关芯片的背景: 

选用学习模块:

使用固件库点亮LED:

1.首先打开官方给的相关板子的原理图,找到LED的电路原理图

2.代码设计

2.1编程要点

2.2 LED引脚宏定义

2.3 bsp板级支持包的编写


相关芯片的背景: 

学习STM32F103之前,我们需要了解相关芯片的背景:

STM32F系列属于中低端的32位ARM微控制器,该系列芯片是意法半导体(ST)公司出品,其内核是Cortex-M3 

系列芯片按片内Flash的大小可分为三大类:小容量(16K和32K)、中容量(64K和128K)、大容量(256K、384K和512K)

芯片集成定时器Timer,CAN,ADC,SPII2C,USB,UART等多种外设功能

选用学习模块:

1.使用市面上所有的学习板:例如野火STM32、正点原子STM32等

2.使用最小系统板,自主安装外设

3.自主设计PCB,焊接STM32芯片再接外设

4.使用仿真软件

在这里我选用野火官网STM32F103指南者(价格对比正点稍贵)以及正点原子STM32F103精英版,在学习中大多使用野火板

使用固件库点亮LED:

有了板子以后,就要开始编写相关代码来实现目的,今天是学会用固件库点亮LED灯,这里的话我就不对寄存器和固件库有更多的解释和记录了,需要花不少时间,本身也是小白,之后若有时间和自己有需求记录理解资料的话可能会再刷然后记录,那我现在就直接开始。

1.首先打开官方给的相关板子的原理图,找到LED的电路原理图

 这些 LED 灯的阴极都是连接到 STM32 GPIO 引脚,只要我们控制 GPIO 引脚的电平输出状态, 即可控制 LED 灯的亮灭。若您使用的实验板 LED 灯的连接方式或引脚不一样,只需根据我们的工程修改引脚即可,程序的控制原理相同。由此可以看到LED绿灯LEDG的引脚是PB0,我此次的目的就是简单的用固件库点亮LEDG。

2.代码设计

为了使工程更加有条理,我们把 LED 灯控制相关的代码独立分开存储,方便以后移植。在“工
程模板”中的User内新建一个LED文件夹,再其中新建“ bsp_led.c ”及“ bsp_led.h ”文件,其中的“ bsp ”即 Board Support Packet 的缩 写 ( 板级支持包 ) ,这些文件也可根据您的喜好命名,这些文件不属于 STM32 标准库的内容,是由我们自己根据应用需要编写的。

2.1编程要点

1. 使能 GPIO 端口时钟;
2. 初始化 GPIO 目标引脚为推挽输出模式;
3. 编写简单测试程序,控制 GPIO 引脚输出高、低电平。

2.2 LED引脚宏定义

在编写应用程序的过程中,要考虑更改硬件环境的情况,例如 LED 灯的控制引脚与当前的不一
样,我们希望程序只需要做最小的修改即可在新的环境正常运行。这个时候一般把硬件相关的部
分使用宏来封装,若更改了硬件环境,只修改这些硬件相关的宏即可,这些定义一般存储在头文
件,即本例子中的“ bsp_led.h ”文件中
bsp_led.h
//LED_G_GPIO的引脚为PB0
#ifndef _BSP_LED_H
#define _BSP_LED_H

#include "stm32f10x.h"

/*以下定义是为了封装,方便更改代码,例如若是要更改PB0为PB5直接在此将GPIO_Pin_0改为GPIO_Pin_5
不用在以后函数中的所有关键字进行更改 */

#define LED_G_GPIO_PIN         GPIO_Pin_0               //定义当前引脚为Pin0口
#define LED_G_GPIO_PORT        GPIOB                    //定义当前的GPIO口为GPIOB
#define LED_G_GPIO_CLK         RCC_APB2Periph_GPIOB     //定义当前外设使能GPIO口为GPIOB

//函数声明,此函数在bsp_led.c中定义
void LED_GPIO_Config(void);

#endif /* _BSP_LED_H */
以上代码分别把控制 LED 灯的 GPIO 端口、 GPIO 引脚号以及 GPIO 端口时钟封装起来了。在实
际控制的时候我们就直接用这些宏,以达到应用代码硬件无关的效果。

2.3 bsp板级支持包的编写

首先是要包含头文件"bsp_led.h",其次需要定义一个LED点亮函数在此我定义的是LED_GPIO_Config,所以开头是这样的 :

bsp_led.c

//bsp:board support package 板级支持包
#include "bsp_led.h"                       //头文件

void LED_GPIO_Config(void)                 //LED点亮函数
{

}

在学习过库函数以及固件库相关知识后,在库中找到相关定义结构体,在工程文件中打开FWLIB,点进stm32f10x_gpio.h中,找到配置GPIO的结构体GPIO_InitTypeDef,在此中有对GPIO的引脚控制、输出输入模式以及速度定义。

stm32f10x_gpio.h中的GPIO_InitTypeDef结构体定义

typedef struct
{
  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.
                                      This parameter can be any value of @ref GPIO_pins_define */

  GPiospeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.
                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.
                                      This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;

好的,让我们回到bsp_led.c中继续代码,此刻我们需要LED点亮函数中用GPIO_InitTypeDef结构体定义一个变量名GPIO_InitStruct用来存放引脚定义,然后对其进行模式定义,点亮LED灯需定义LED_G_GPIO_PIN引脚、输出输入模式定义为推挽输出也就是GPIO_Mode_Out_PP,速度定义为50MHz,GPIO_Speed_50MHz(该结构体所有范围以及在stm32f10x_gpio.h中有枚举定义,可以对其按F12查看相关地方),所以代码为

bsp_led.c

//bsp : board support package 板级支持包
#include "bsp_led.h"

void LED_GPIO_Config(void)
{
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
}

然后,我们需要打开外设的使能时钟,观察官方给的参考资料

 我们可以知道复位和时钟控制RCC中,GPIOB的时钟是挂在APB2上的,所以我们找到APB2的RCC时钟去使能

 通过手册我们可以知道,APB2时钟使能寄存器是RCC_APB2ENR,观察前四位,我们需要将IOPBEN至1,使其使能,所以我们打开工程目录中的FWLIB中找到stm3210x_rcc.h,然后在其库中找到对应的APB2的外设时钟使能函数是RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState),对其按F12,就知道其函数两个变量名一个为外设定义引脚,在此是RCC_APB2Periph_GPIOB(这个在bsp_led.h中定义过),另一个就是引脚直接使能或失能ENABLE与DISABLE,所以在此的使能函数定义为RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK,ENABLE);所以现在的代码为

bsp_led.c

//bsp : board support package 板级支持包
#include "bsp_led.h"

void LED_GPIO_Config(void)
{
	
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK,DISABLE);
	GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
}

使能完毕后,想想还需要什么才能是PB0定义出来,没错,现在就差一个定义GPIOB了,也就是bsp_led.h中定义的接口LED_G_GPIO_PORT,所以现在在stm3210x_gpio.h中找到GPIO引脚的定义也就是GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct),对其F12可知其函数的相关定义,通过相关代码可知,第一个需定义为GPIOB也就是LED_G_GPIO_PORT,第二个变量是强转结构体的指针而我们在bsp_led.c中已经定义了GPIO_InitTyDef的 GPIO_InitStruct了,所以直接对GPIO_InitStruct取地址,就可以定义相关引脚状态了,在此也就是GPIO_Init(LED_G_GPIO_PORT,&GPIO_InitStruct),所以完整代码为:

bsp_led.c

//bsp : board support package 板级支持包
#include "bsp_led.h"

void LED_GPIO_Config(void)
{
	
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK,DISABLE);
	GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);

}

编写好了板级支持包后,直接在main函数中调用函数就可以了

main.c

#include "stm32f10x.h"  //相当于51单片机中的 #include<reg51.h>
#include "bsp_led.h"

int main(void)
{
   
	LED_GPIO_Config();
	
}

编译,然后烧入代码,板子的绿色灯就亮起了。

本人还是初学者,写这篇文章只是记录自己的学习历程,并且加入一些自己的见解,方便自己在复习的时候可以知道这时是怎么想的,很多地方讲解不清还请见谅~~

以上是关于STM32F103学习日程记录的主要内容,如果未能解决你的问题,请参考以下文章

GD32F103学习笔记——在GD32F103移植STM32F103代码

STM32F103X datasheet学习笔记---RCC(reset and clock control)

STM32学习笔记 二基于STM32F103C8T6和STM32CubeMX实现UART串口通信数据收发

STM32F103(二十)DAC(贼详细)

STM32F103(十八)ADC总结(贼详细)

STM32学习笔记 二基于STM32F103C8T6和STM32CubeMX实现UART串口通信数据收发