英文网站的建设意义,网站开发维护计入什么费用,wordpress企业主题免费下载,wordpress slider插件下载概述
上一篇的实验中#xff0c;分别正确地配置了 TIM16 和 TIM1#xff0c;TIM16 的中断服务程序中每隔 500ms 翻转板载 LED 一次#xff1b;TIM1 的 CHANNEL_1 用于输出一个固定占空比的 PWM 信号。这一次我们进一小步#xff1a;使用 TIM16 的中断设置 TIM1 CHANNEL_1 …概述
上一篇的实验中分别正确地配置了 TIM16 和 TIM1TIM16 的中断服务程序中每隔 500ms 翻转板载 LED 一次TIM1 的 CHANNEL_1 用于输出一个固定占空比的 PWM 信号。这一次我们进一小步使用 TIM16 的中断设置 TIM1 CHANNEL_1 的 PWM 输出呈现从小到大再从大到小的循环即实现呼吸灯效果。
为此PWM 输出改用千分之一精度的调节TIM16 的定时周期设置为 8 毫秒PWM 从 0% 到 100%耗时 8秒。
对于 TIM1PWM_PERIOD 定义为 2400PWM 调节步长设置为 2.4F和 1000 步调节到位相对应。PWM_PERIOD 参数用于 TIM1 的 ARR 装填PWM 输出频率为 10KHz。
实现代码
修改 main.h 文件
将 PWM 分频参数 PWM_PERIOD 搬到 mian.h 中
新增一个千分之一 PWM 输出的函数
void TIM1_PWM_Output_Permill(const uint16_t duty_permill);
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H#ifdef __cplusplus
extern C
{
#endif#ifndef PWM_PERIOD
#define PWM_PERIOD 2400
#endif/* Includes ------------------------------------------------------------------*/
#include py32f0xx_hal.h
#include py32f003xx_Start_Kit.h
#include stdbool.h/* Exported functions prototypes ---------------------------------------------*/
HAL_StatusTypeDef SystemClock_Config(void);
HAL_StatusTypeDef GPIO_Config(void);
HAL_StatusTypeDef USART_Config(void);
HAL_StatusTypeDef DBG_UART_Start(void);
HAL_StatusTypeDef TIM16_Config(void);
HAL_StatusTypeDef TIM16_Start(void);HAL_StatusTypeDef TIM1_PWM_Config(void);
HAL_StatusTypeDef TIM1_PWM_Start(uint32_t duty);
HAL_StatusTypeDef TIM1_PWM_Stop(void);
void TIM1_PWM_Output(const uint8_t duty_percent);
void TIM1_PWM_Output_Permill(const uint16_t duty_permill);void Debug_Info(const char* msg);...
...在 app_pwm.c 中实现 TIM1_PWM_Output_Permill 函数
void TIM1_PWM_Output_Permill(const uint16_t duty_permill)
{uint16_t tmp_duty 0;uint32_t duty 0;tmp_duty duty_permill;if(duty_permill 1000) tmp_duty 999;duty (uint32_t)(tmp_duty * PWM_PERIOD / 1000.0F 0.5F) 1;TIM1_PWM_Start(duty);
}计算 duty 时加的那个 0.5F 是处理四舍五入用的。
修改 app_timer.c 文件
在原有代码上增加三个全局变量
#include main.hTIM_HandleTypeDef htim16;#define gPwmStep 2.4F
uint16_t gCurrentDutyPermill 0;
int8_t gPwmDir 1;...
...
初始化代码修改如下Period 和 Prescaler 的设定值使 TIM16 的定时周期为 0.008s 即8毫秒。
HAL_StatusTypeDef TIM16_Config(void)
{HAL_StatusTypeDef conf_res HAL_OK;htim16.Instance TIM16; // 选择 TIM16htim16.Init.Period 12000 - 1; // 自动重装载值 500ushtim16.Init.Prescaler 16 - 1; // 预分频为 2-1两者确定定时器中断周期为1mshtim16.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; // 时钟不分频htim16.Init.CounterMode TIM_COUNTERMODE_UP; // 向上计数htim16.Init.RepetitionCounter 1 - 1; // 不重复计数htim16.Init.AutoReloadPreload TIM_AUTORELOAD_PRELOAD_ENABLE; // TIMx ARR 缓冲conf_res HAL_TIM_Base_Init(htim16); // TIMx 初始化if ( conf_res ! HAL_OK) return conf_res;return HAL_OK;
}
在 HAL_TIM_PeriodElapsedCallback 函数中计算出呼吸灯的调节量并调用 TIM1_PWM_Output_Permill 函数执行 PWM 输出。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim-Instance ! TIM16) return;TIM1_PWM_Output_Permill(gCurrentDutyPermill);gCurrentDutyPermill (uint16_t)(gCurrentDutyPermill gPwmDir * gPwmStep);if(gPwmDir 1){if(gCurrentDutyPermill 1000){gPwmDir -1;gCurrentDutyPermill 1000;}}else {if(gCurrentDutyPermill (uint16_t)(gPwmStep 0.5)){gPwmDir 1;gCurrentDutyPermill 0;}}
}代码中原有的翻转 LED 灯的那一句去掉了闪烁频率太高看着不舒服了。
稍微修改一下 main() 函数
注意要将 TIM16 的初始化函数放到 TIM1_PWM 初始化函数前面。
int main(void)
{HAL_Init(); // systick初始化SystemClock_Config(); // 配置系统时钟if(USART_Config() ! HAL_OK) Error_Handler(); printf([SYS_INIT] Debug port initilaized.\r\n);if(GPIO_Config() ! HAL_OK) Error_Handler(); printf([SYS_INIT] Board LED initilaized.\r\n);if(TIM16_Config() ! HAL_OK) Error_Handler();printf([SYS_INIT] Timer initialized.\r\n);if(TIM1_PWM_Config() ! HAL_OK) Error_Handler();printf([SYS_INIT] PWM initialized.\r\n);if (TIM16_Start() ! HAL_OK) Error_Handler();printf([SYS_INIT] Timer started.\r\n);printf(\r\n---------------------------------------\r\n| PY32F003 MCU is ready. |\r\n---------------------------------------\r\n);if (DBG_UART_Start() ! HAL_OK) Error_Handler();// TIM1_PWM_Output_Permill(250);while (1) { }
}
总结
示波器的输出波形已通过视频上传达到设计预期。
视频链接PY32F003 的呼吸灯效果-CSDN直播
要点
根据 PWM 输出精度的要求设置 TIM1 对应通道 PWM 的频率例如要实现千分之一的逐级调节PWM_PERIOD 就要设置得大于1000才好。根据 PWM 调节时长限制确定 TIM16 的定时周期例如要实现 8秒完成一轮调节每一轮调节需要 1000 次递增/递减则需要将 TIM16 的定时周期设置为 8 毫秒。TIM16 的初始化和启动应放在 TIM1 的初始化之后。在 TIM16 的中断服务程序中以最少的时间代价完成 TIM1 PWM 通道的输出。
问题点在 PWM 波形变化过程中会出现少许凹陷的毛刺还没有找到原因。