文档库 最新最全的文档下载
当前位置:文档库 › STM32Cube官方例程学习指南(Lu)

STM32Cube官方例程学习指南(Lu)

STM32Cube官方例程学习指南(Lu)
STM32Cube官方例程学习指南(Lu)

STM32Cube官方例程学习指南

STM32CubeMX是ST官方提供的一个代码生成工具。使用该工具,通过图形化的配置方法,就能快速生成STM32的各种片上外设的初始化代码。CubeMX生成的软件工程使用HAL库,HAL库是ST 以后主推的外设驱动库。另外CubeMX还提供了FATFS、FreeRTOS、LWIP、USB库等中间件的支持,配置之后生成软件工程,工程文件就包含了相应代码。

本文档以STM32F4系列为例,简要地分析官方提供的Cube例程。希望能够帮助CubeMX初学者快速掌握STM32的常用外设使用方法。文档不求全面,只讲常用的外设,对不常用的只进行概况性地描述。同时,文档只对例程进行直接分析,不对其他文件进行详述。

第一部分准备工作

首先是下载STM32CubeF4支持包,可以到与非网ST社区搜索STM32CubeF4,然后下载

当前版本已经更新到V1.13.0。点击附件中的STM32CubeF4,转到下载链接地址。附件大小300M左右。本人当前使用的是V1.9.0版本的,例程相差不大,后面就用V1.9.0版本的例程进行分析。

下载后解压,得到如下图的文件,其中例程放在Projects文件夹中:

打开Projects文件夹,可以看到前12个文件夹分别官方提供的12款评估板,后面我们仅以STM324xG_EVAL评估板的例程为讲解内容。

STM324xG_EVAL文件夹中,Examples文件夹存放的就是片上外设的使用例程。

(Applications文件夹是STM324xG_EVAL相关的一些高级应用例程,如FreeRTOS、FatFs、LwIP、USB等,有一定基础之后可以学习这里面的内容。本文不作分析。)

Examples文件夹提供了27个外设对应文件夹,每个文件夹包含若干个例程,后面将对常用的外设例程(不是全部)进行简要分析。

第二部分例程分析

下面将挑选常用外设的例程进行分析,顺序是从简单的到复杂的。

第一章:GPIO

GPIO共有两个例程:外部中断和IO翻转。

1.GPIO_IOToggle

打开…\GPIO_IOToggle\MDK-ARM文件夹下的MDK工程,打开main.c文件。

如main.c文件开头的描述,本例程描述如何配置GPIO和通过HAL API函数使用GPIO。

看main函数:

分析:从注释可以看出,GPIO的控制只需要3个步骤,使能GPIO时钟、配置GPIO模式、控制GPIO状态。前两个步骤的代码不需要用户手动输入,完全有STM32CubeMX生成,用户只需要在CubeMX 中用图形化界面进行配置。(详细操作步骤可参考本人编写的STM32Cube学习笔记,或者其他STM32Cube入门教程。)步骤3的重点在HAL_GPIO_TogglePin()函数,在控制GPIO反转的。其他控制GPIO输出状态的函数还有HAL_GPIO_WritePin()。

2.GPIO_EXTI

该例程演示如何使用GPIO的外部中断功能。

打开…\GPIO_EXTI\MDK-ARM文件夹下的MDK工程,打开main.c文件。先看main函数:

main函数只有个语句,分3个部分。第一部分是系统时钟配置。第二部分是板级支持配置,本例中是初始化两个LED控制口。第三部分是配置外部中断。这三个部分的代码功能都可以通过CubeMX 配置生成,不需要用户输入。

最后,要在回调函数中实现中断响应的功能代码。

HAL_GPIO_EXTI_Callback()函数是HAL库的外部中断回调函数,所有的外部中断都是使用该函数。然后在处理时,判断是哪个引脚号对应的中断。

第二章:UART

1.UART_Printf

打开…\UART_Printf\MDK-ARM文件夹下的MDK工程,打开main.c文件。

如main.c文件开头描述,本例演示了如何将printf()函数的输出功能映射到串口上。

看main函数:

main函数分为3部分。第一部分是系统初时钟配置。第二部分是初始化UART。第三部分是使用printf()函数输出一个语句。在126~133行,就是实现过程。

其中PUTCHAR_PROTOTYPE是一个宏,该宏已经在main文件开头给出。

因此,对于MDK-ARM使用的编译器,126~133的函数等效于。

实现该函数并包含stdio.h文件之后,程序中就可以用printf()通过UART输出字符串了。

2.UART_Hyperterminal_IT

打开…\ UART_Hyperterminal_IT\MDK-ARM文件夹下的MDK工程,打开main.c文件。

该例程演示如何使用串口发送和接收中断。

看main函数:

在main函数中已经标注了各个步骤的序号。步骤1就是初始化串口,和上一个例子形式差不多。步骤2是演示HAL_UART_Transmit_IT()函数的用法,该函数的功能是将aTxStartMessage[]数组的TXSTARTMESSAGESIZE个字节数据发送出去,并使能发送完成中断,当发送完成后会调用一次HAL_UART_TxCpltCallback()回调函数。步骤3是演示HAL_UART_Receive_IT ()函数的用法,用法和发送函数类似。功能是使能UART接收中断,接收的数据存入缓冲数组aRxBuffer[],在接收数据量达到RXBUFFERSIZE字节时调用一次HAL_UART_RxCpltCallback()回调函数。用户可以在回调函数中添加数据

步骤4是等待串口空闲。步骤5是再次发送数据。

步骤6、7、8,过程和前面类似,注释已经说明清楚。

本例中回调函数的内容很简单,就是点亮LED。

3.UART_Hyperterminal_DMA

该例程演示如何使用串口DMA发送和接收及中断,和UART_Hyperterminal_IT结构完全相同,只是把函数的后缀都改成了_DMA。而且回调函数都是一样的。

第三章:TIM

TIM共有18个例程。定时器是STM32中用途最多变的外设。下面分析几个典型应用例程。

1.TIM_TimeBase

打开…\TIM_TimeBase\MDK-ARM文件夹下的MDK工程,打开main.c文件。

该例程是定时器最基本的应用,即定时中断功能。

看main函数:

一共只有两个步骤。步骤1是配置定时器,步骤2是启动定时器并使能中断。步骤1是通过CubeMX

HAL_TIM_PeriodElapsedCallback()是定时器Update中断回调函数。所有定时器的更新中断都使用该回调函数接口。因此,如果开启了多个定时器更新中断时,应该对中断源进行判断,如下图:

2.TIM_PWMOutput

打开…\TIM_PWMOutput\MDK-ARM文件夹下的MDK工程,打开main.c文件。

该例程演示怎么使用定时器的PWM模式产生4路PWM信号。

看main函数:

步骤1是配置TIM外设。步骤2是配置PWM通道。这两步骤的代码可由CubeMX配置生。

步骤3是启动各个PWM通道,就是调用HAL_TIM_PWM_Start()函数。该步骤的代码要用户添加。经过上述3个步骤,就可以在相应引脚输出PWM信号了。

3.TIM_InputCapture

打开…\ TIM_InputCapture \MDK-ARM文件夹下的MDK工程,打开main.c文件。

该例程演示TIM的输入捕获功能,用该功能测量信号的频率或周期。

看main函数:

步骤1配置TIM外设,步骤2配置输入捕获通道。

步骤3启动输入捕获功能,并使能相应中断。

对捕获值的处理在中断回调函数中进行。一共捕获两次,两次捕获值的差值就是乘以定时器时钟周期,就得到信号的周期,其倒数就是信号频率。

4.TIM_PWMInput

该例程演示用TIM的输入捕获功能能测量PWM信号的占空比。

打开…\ TIM_PWMInput \MDK-ARM文件夹下的MDK工程。

关键步骤就是同一个定时器开启了两个输入捕获通道,一个捕获上升沿,另一个捕获下降沿。

在捕获中断回调函数中进行数据处理。两次相邻的上升沿的时间差就是PWM信号周期,这两次上升沿之间有个下降沿,该下降沿和第一次上升沿的时间差就是PWM信号的占空比。

5.TIM_OCActive

该例程演示用TIM的比较匹配功能输出4路PWM信号。

打开…\ TIM_OCActive \MDK-ARM文件夹下的MDK工程。

步骤1配置TIM外设。

步骤3点亮LED1,这一步无关紧要。

步骤4启动各通道比较匹配输出功能。

6.TIM_OCInactive

该例程和TIM_OCActive的步骤完全相同,只是PWM输出信号的进行了取反,并且在步骤4中启动个通道时使能了比较匹配中断。最后在中断函数中分别控制LED的熄灭。

7.TIM_OCToggle

该例程演示如何用TIM的比较输出功能的翻转模式,输出4路频率不同的50%占空比的方波信号。

打开…\ TIM_OCToggle \MDK-ARM文件夹下的MDK工程。

步骤2配置输出比较通道参数,包括输出模式、极性、比较值等。

步骤3启动各通道的输出比较功能,并使能中断。

关键的步骤是中断回调函数中。因为其实TIM硬件并不能同时输出多路不同频率的PWM信号,这里是通过不断修正各个通道的比较值,才实现了4路不同频率的方波信号。

8.TIM_OnePulse

该例程演示如何用TIM输出单脉冲信号。通过通道2输入信号,上升沿触发通道1产生脉冲信号。

看main函数:

步骤1配置TIM外设。

步骤2配置通道1为单脉冲模式,输入通道是通道2。

步骤3启动单脉冲通道2。

9.TIM_DMA

该例程演示通过TIM更新请求触发DMA更新TIM的输出比较值,以改变PWM的占空比。

打开…\TIM_DMA \MDK-ARM文件夹下的MDK工程。

看main函数:

步骤1配置TIM外设。在此RepetitionCounter是一个重要参数,等于3就是3个周期触发一次更新请求。

步骤2配置PWM通道参数,包括输出模式、极性、脉冲宽度。步骤3以DMA模式启动PWM输出,注意HAL_TIM_PWM_Start_DMA()函数的最后两个参数,一个是数据地址,一个是数据量。

程序运行的过程:TIM的定时周期由变量uhTimerPeriod确定,由于RepetitionCounter=3,TIM经过3个定时周期就触发一次DMA传输。DMA传输是将aCCValue_Buffer[]的数据传入TIM的CHANNEL_3的比较匹配寄存器中,即改变PWM的占空比。第一次DMA传输的是aCCValue_Buffer[0],第二次传输aCCValue_Buffer[1],第三次传输aCCValue_Buffer[2]。三次DMA传输就完成了整个循环周期。第四次又传输aCCValue_Buffer[0],如此往下循环。

10.TIM_DMABurst

该例程演示通过TIM更新请求触发DMA突发传输更新TIM的ARR、RCR、CCR1寄存器的值,以改变PWM的周期、占空比。

打开…\TIM_DMABurst \MDK-ARM文件夹下的MDK工程。

步骤1配置TIM外设。

步骤2配置PWM通道。步骤3启动PWM输出。步骤4启动DMA突发传输。

注意HAL_TIM_DMABurst_WriteStart()中几个被标注的参数,他们只有可用的有效取值,查看该函数在stm32f4xx_hal_tim.c的位置,有详细的说明。

该例程的运行过程,在…\TIM_DMABurst 文件夹的readme.txt文件有描述。

“每次更新的DMA请求,DMA就传输3个Half Word到定时器的寄存器,起始寄存器为ARR。

在DMA更新请求中,0x0FFF被传入ARR,0x0000传入RCR,0x0555传入CCR1。”

对比例程代码,传输3个Half Word,这是由HAL_TIM_DMABurst_WriteStart()的最后一个参数值TIM_DMABURSTLENGTH_3TRANSFERS确定的。传输的传输的三个值0x0FFF、0x0000、0x0555,就是数组aSRC_Buffer[3]的3个元素。对应的三个寄存器ARR、RCR、CCR1,它们的地址是连续的。触发事件是TIM更新,由参数TIM_DMA_UPDATE确定。

readme.txt的描述传输单位是“Half Word”,可能有误。因为HAL_TIM_DMABurst_WriteStart()的第四个参数的类型是(uint32_t*),而且TIM的所有寄存器占用空间是32bit(虽然都只使用了低16bit),即上面的ARR、RCR、CCR1实际地址间隔是4字节。所以可以判断,DMA传输的单位是Word而不是Half

11.TIM_ComplementarySignals

该例程演示使用TIM1产生3对互补PWM信号。

打开…\ TIM_ComplementarySignals \MDK-ARM文件夹下的MDK工程。

步骤1是TIM外设基本配置。

步骤2配置PWM通道占空比等参数,另外还设置了互补通道的死区时间、参数锁定等。

步骤3就是启动各个PWM通道和互补通道的输出。

12.另外7个例程只作简要说明

①TIM_6Steps例程:

演示如何用高级定时器输出6步PWM信号,这个在无刷电机控制中使用比较多。readme.txt文件给出了例程的说明,并给出了6步状态表,以及各通道的波形示意图。

②TIM_7PWMOutput例程:

演示如何用定时器输出7路PWM信号。它们的频率是相同的,且每一对互补输出引脚的占空比是联动的。

③TIM_Synchronization和④TIM_ParallelSynchro例程:

这两个例程是差不多的,都是演示定时器并行同步。它们的readme.txt都有一个TIM连接示意图。

两个例程都是用一个定时器触发TIM3和TIM4,使这两个定时器同步。

⑤TIM_CascadeSynchro例程:

演示如何将TIM串联使用,将一个TIM的事件输出作为另一个TIM的触发输入。

相关文档