原理了解
高级定时器中有一个重复计数器,本实验输出指定个数PWM就是利用了重复计数器的特性,先来看看重复计数器的特性是什么:
计数器每次上溢或下溢都能使重复计数器减1,减到0时,再发生一次溢出就会产生更新事件
这是什么意思呢,这里举个例子比如说我设定重复计数器的值为3,则计数器上溢一次则重复计数器的值变为2,再继续上溢知道重复计数器的值变为0,此时在溢出一次,则产生更新中断,即如果重复计数器的值为3,则计数器需要溢出4次才会产生更新事件,那么结合本实验输出指定数量的PWM波,通过将N-1写入重复计数器中,则可以产生N个PWM波。
从上图来看,当RCR为0时,计数器每溢出一次就会产生更新事件;当RCR为1时,计数器每溢出两次就会产生更新事件,以此类推;那么这里着重看一下最后一个是怎么产生更新事件,当由软件产生一次更新事件后,计数器的值会回到初始状态即0或最大值,然后再溢出4次再次产生更新事件,即软件产生了更新事件后,将会把RCR的值装载进影子寄存器中,重新开始计数。
STM32CubeMx配置
定时器及通道配置
这里使用定时器8通道一作为我们的PWM输出,配置如下:
选择内部时钟源,通道一配置为PWM输出,然后设置PWM周期的频率,这里以2KHz设置,根据公式:
Tout= ((arr+1)*(psc+1))/Tclk
先代入PSC为7200-1,Tclk为72M(系统时钟源),则可算出arr为5000-1。
配置PWM为模式一,pulse为设置占空比,设置为arr一半则占空比为50%,输出极性为高。
打开定时器8更新中断,设置抢占优先级及相应优先级(根据用户自身需求)
GPIO口选择
查看数据手册
PC6为定时器八通道一的复用口,同时查看硬件原理图:
选择PE5作为输入验证程序输出指定数量PWM,通过生成N个PWM使LED亮N次;选择PB5作为输出,控制LED亮灭证明程序烧写成功。
添加PE4按键,通过按键更改生成的PWM数量。
STM32CubeMx配置如下:
配置完成后就可生成工程了。
工程生成及代码编写
工程文件
生成工程后,可以看到左边已经有了相关代码:
在输出指定数量PWM波中有如下几个比较重要的函数:
void MX_TIM8_Init(void); //定时器八初始化函数
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle); //相关时钟使能、中断开启函数
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel); //使能PWM输出
HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource); //产生指定事件
void TIM8_UP_IRQHandler(void); //定时器8中断处理服务函数
void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim); //定时器中断公共处理函数
HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); //更新中断回调函数,需要用户重写该函数
__HAL_TIM_ENABLE_IT(__HANDLE__, __INTERRUPT__); //这是一个宏定义,使能中断
__HAL_TIM_ENABLE(__HANDLE__); //这是一个宏定义,使能计数器
代码编写
tim.c编写
首先打开tim.c文件:
可以看到里面已经帮我们完成了STM32CubeMx配置的初始化,需要完成输出指定数量PWM波功能我们需要开启PWM输出及使能更新中断,即在用户代码区中添加如下函数:
__HAL_TIM_ENABLE_IT(&htim8, TIM_IT_UPDATE);
HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1);
中断相关函数
打开stm32f1xx_it.c文件可以看到中断的处理函数已经写好了:
需要做的则是编写中断回调函数,即:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
实现功能函数
首先为了实现输出指定PWM波实验,这里新添一个atimp.c文件方便管理:
atim.c及atim.h编写
#include "atimp.h"
static uint8_t g_npwm_set = 0; //pwm设置输出数量
//输出pwm个数配置函数
void atim_timx_npwm_chy_set(uint8_t npwm)
{
if(0 == npwm)
return;
g_npwm_set = npwm;
HAL_TIM_GenerateEvent(&htim8, TIM_EVENTSOURCE_UPDATE); //通过软件启动更新中断
__HAL_TIM_ENABLE(&htim8); //使能计数器
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM8)
{
if(g_npwm_set) //判断设置的pwm数量
{
TIM8->RCR = g_npwm_set-1; //要想产生N个pwm将N-1放入RCR寄存器中
HAL_TIM_GenerateEvent(&htim8, TIM_EVENTSOURCE_UPDATE); //通过软件启动更新中断将设定值放入影子寄存器中
__HAL_TIM_ENABLE(&htim8); //使能计数器产生进行PWM输出
g_npwm_set = 0;
}
else
{
TIM8->CR1 &= ~(1 << 0); //关闭计数器
}
}
}
#ifndef __ATIMP_H__
#define __ATIMP_H__
#include "main.h"
#include "tim.h"
void atim_timx_npwm_chy_set(uint8_t npwm);
#endif
用到按键,再添加一个key.c文件文章来源:https://www.toymoban.com/news/detail-784530.html
key.c及key.h编写
#include "key.h"
uint8_t key_scan()
{
static uint8_t key_sta = 1;
uint8_t key_value = 0;
if(key_sta && (KEY0 == 0))
{
HAL_Delay(10);
key_sta = 0;
if(KEY0 == 0)
key_value = KEY0_PRESS;
}
else if(KEY0)
{
key_sta = 1;
}
return key_value;
}
#ifndef __KEY_H
#define __KEY_H
#include "main.h"
#define KEY0_PRESS 1 //PE4按下状态
#define KEY0 HAL_GPIO_ReadPin(GPIOE, KEY0_Pin) //读取当前PE4状态
uint8_t key_scan(void);
#endif
main.c编写
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_TIM8_Init();
/* USER CODE BEGIN 2 */
uint8_t key = 0; //记录键值
uint8_t t =0;
atim_timx_npwm_chy_set(5); //设置PWM输出5次
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
key = key_scan();
if(key == KEY0_PRESS)
{
atim_timx_npwm_chy_set(3); //设置PWM输出3次
}
/*LED翻转证明程序正常工作*/
t++;
if(t > 20)
{
t = 0;
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
}
HAL_Delay(10);
}
/* USER CODE END 3 */
}
至此,代码就编写完成啦。文章来源地址https://www.toymoban.com/news/detail-784530.html
到了这里,关于STM32高级定时器输出指定数量PWM(STM32CubeMx配置)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!