基于STM32F429和Cube的主从定时器多通道输出固定个数的PWM波形
主从定时器的原理已在上篇博文:
基于STM32F429+HAL库编写的定时器主从门控模式级联输出固定个数PWM脉冲的程序
讲解了,这篇重点就讲如何实现多通道的PWM级联输出。
1.软件环境
Keil5,Cube5.21
2.Cube配置
选择定时器3,打开通道1和通道2的PWM输出,然后开启主从模式,触发方式为上升沿触发。
频率和占空比的设置请看上篇博文。

生成的代码 如下
void MX_TIM3_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig = {};
TIM_OC_InitTypeDef sConfigOC = {}; htim3.Instance = TIM3;
htim3.Init.Prescaler = ;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = -;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = ;
sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_MspPostInit(&htim3); }
选择定时器4,从模式为门控模式,触发时钟为TIM3,即ITR2,内部时钟触发


生成的代码如下:
/* TIM4 init function */
void MX_TIM4_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {};
TIM_SlaveConfigTypeDef sSlaveConfig = {};
TIM_MasterConfigTypeDef sMasterConfig = {}; htim4.Instance = TIM4;
htim4.Init.Prescaler = ;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 0xffff;
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED;
sSlaveConfig.InputTrigger = TIM_TS_ITR2;
if (HAL_TIM_SlaveConfigSynchro(&htim4, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
{
Error_Handler();
} }
STM32F429的定时器3通道1,2的PWM复用口

PA6 ------> TIM3_CH1
PA7 ------> TIM3_CH2
3,程序介绍
(1)在主函数里开启定时器的中断功能和PWM输出
TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING) ; // 捕获比较1中断使能
TIM_SET_CAPTUREPOLARITY(&htim3,TIM_CHANNEL_2,TIM_ICPOLARITY_RISING) ; // 捕获比较2中断使能 __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,) ; // 输入通道1的捕获比较值CCR1 ,PWM个数为6400个
__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,) ; // 输入通道2的捕获比较值CCR2 HAL_TIM_OC_Start_IT(&htim4,TIM_CHANNEL_1) ; //开启定时器4通道1的输入捕获中断
HAL_TIM_OC_Start_IT(&htim4,TIM_CHANNEL_2) ; //开启定时器4通道2的输入捕获中断 PostInit(); //这个是为了控制通道2的复用GPIO口PA7,可忽略 HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_1); //开启定时器3通道1的PWM输出中断
HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_2); //开启定时器3通道2的PWM输出中断
(2)在PWM中断轮询函数关闭定时器的中断功能和PWM输出
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) //重写PWM中断轮询弱函数
{ if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET) //判断是否生成中断标志位SR
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET) //定时器中断使能是否开启
{ __HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_CC1); //清除中断标志位SR
if(HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_1)==HAL_OK) //关闭定时器3的通道1的PWM输出
{
HAL_TIM_OC_Stop_IT(&htim4,TIM_CHANNEL_1) ; //关闭定时器4的通道1的输入中断捕获
FLAG1_OK = ; //关闭标志置1 } }
} //下面的通道2同理如此
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) !=RESET)
{ __HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_CC2); //清除标志位 PostDeInit(); //这个是为了控制通道2的复用GPIO口PA7,可忽略 if(HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_2)==HAL_OK)
{
HAL_TIM_OC_Stop_IT(&htim4,TIM_CHANNEL_2) ; FLAG2_OK = ;
} } } if( FLAG1_OK == &&FLAG2_OK == )
{
FLAG1_OK = ;
FLAG2_OK = ;
FLAG1_Static =; __HAL_TIM_SET_COUNTER(&htim4,); //如果两个通道都关闭好了,就把计数装载值CNT清零 TIM_CCxChannelCmd(TIM3,TIM_CHANNEL_2,TIM_CCx_ENABLE); //这个是为了控制通道2的复用GPIO口PA7,可忽略 //
//Delay100ms();
} }
重头戏来了!!!如果你发现以上代码,通道1,2的GPIO口只能输出通道1的波形,说明你的中断只是进了通道1的,但通道2也触发了
原因就是两者的中断标志位都被清零了,而且是HAL库自动清零的。

两个被注释掉的函数就是HAL库帮你清零的语句,你手动注释掉就行了。
4.注意事项
(1)小心使用延迟函数,定时器可能和延迟函数有冲突;
(2)如果你发现你不能输出超过255个波形,那就在初始化哪里加个__HAL_TIM_SET_AUTORELOAD(&htim4, 0xffff) ,
既往ARR装载0xffff。
(3)下图的3个函数是用来调控PA7这个PWM复用口的,如果你发现你的PWM波形神奇的自动下降沿计数的话,就用来试下吧。
void PostDeInit(void)
{ GPIO_InitTypeDef GPIO_InitStruct = {}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin =GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
// GPIO_InitStruct.Alternate = 0x00;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } void PostInit(void)
{ GPIO_InitTypeDef GPIO_InitStruct = {}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin =GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = 0x02; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } TIM_CCxChannelCmd(TIM3,TIM_CHANNEL_2,TIM_CCx_ENABLE);
基于STM32F429和Cube的主从定时器多通道输出固定个数的PWM波形的更多相关文章
- 基于STM32F429+HAL库编写的定时器主从门控模式级联输出固定个数PWM脉冲的程序
硬件设备 42步进电机,步进电机驱动器,正点原子F429开发板 开发软件 keil5,Cube 综述 一般要精准的控制电机,就要控制单片机的引脚输出指定个数的PWM波,有多种可实现的方法 ...
- 基于STM32F429和Cube的ov2640程序
1.ov2640和DCMI介绍 OV2640 是 OV(OmniVision)公司生产的一颗 1/4 寸的 CMOS UXGA(1632*1232)图 像传感器.该传感器体积小.工作电压低,提供单片 ...
- 基于Camera Link和PCIe DMA的多通道视频采集和显示系统
基于Camera Link和PCIe DMA的多通道视频采集和显示系统 在主机端PCIe驱动的控制和调度下,视频采集与显示系统可以同时完成对多个Camera Link接口视频采集以及Camera Li ...
- STM32F103ZET6 用定时器级联方式输出特定数目的PWM(转载)
STM32F103ZET6里共有8个定时器,其中高级定时器有TIM1-TIM5.TIM8,共6个.这里需要使用定时器的级联功能,ST的RM0008 REV12的P388和P399页上有说明对于特定的定 ...
- PHP 定时器 边输出边刷新网页
使用定时器的时候当然想网页能够看到输出,不希望网页直接卡住,定时器结束输出一片. 要做到定时器不卡住输出,只需要两个函数就行了,看下面代码 <?php //定时器测试代码 demo //跟踪定时 ...
- STM32F103ZET6 用定时器级联方式输出特定数目的PWM
STM32F103ZET6 用定时器级联方式输出特定数目的PWM STM32F103ZET6里共有8个定时器,其中高级定时器有TIM1-TIM5.TIM8,共6个. 这里需要使用定时器的级联功能,ST ...
- 基于STM32F030F4P9和STM32 CUBEMX 输出PWM波形
STM32F030F4P9定时器功能比较丰富,在此记录项目中使用其自动输出PWM波形(频率:50HZ).CubeMX配置定时器如下图说明. 在此定时器基础时钟为48MHZ,配置中不做分频处理,预分频系 ...
- STM32 TIM 多通道互补PWM波形输出配置快速入门
platform:stm32f10xxx lib:STM32F10x_StdPeriph_Lib_V3.5.0 前言 在做三相逆变的时候,需要软件生成SVPWM波形,具体的算法需要产生三对互补的PWM ...
- AMQ学习笔记 - 14. 实践方案:基于ZooKeeper + ActiveMQ + replicatedLevelDB的主从部署
概述 基于ZooKeeper + ActiveMQ + replicatedLevelDB,在Windows平台的主从部署方案. 主从部署可以提供数据备份.容错[1]的功能,但是不能提供负载均衡的功能 ...
随机推荐
- 自定义WPF 窗口样式
原文:自定义WPF 窗口样式 Normal 0 false 7.8 pt 0 2 false false false EN-US ZH-CN X-NONE 自定义 Window 在客户端程序中,经常需 ...
- EasyUI学习之menu and button(菜单和按钮)
前言 今天下午的天气感觉格外的气闷,整个人有一种黏糊糊的感觉,格外的不舒服.加之立即要放假了了,感觉自己全然坐不住呢(节前综合症么).只是学习还是的继续的. 原定计划这篇文章本来应该是关于search ...
- uwp - 上滑隐藏导航栏下滑显示
原文:uwp - 上滑隐藏导航栏下滑显示 好久没写博客了,因为忙着工作.昨天周末填坑需要做一个上滑列表数据时隐藏导航栏下滑时显示的效果,下面分享一下我的做法,希望能给你带来帮助. 思路是通过判断滚动条 ...
- 在efcore 中创建类 通过实现IEntityTypeConfiguration<T>接口 实现实体类的伙伴类 实现FluentApi
1 创建实体类: public partial class NewsCategory : IAggregationRoot { public NewsCategory() { } public Gui ...
- 在WPF中制作正圆形公章
原文:在WPF中制作正圆形公章 之前,我利用C#与GDI+程序制作过正圆形公章(利用C#制作公章 ,C#制作公章[续])并将它集成到一个小软件中(个性印章及公章的画法及实现),今天我们来探讨一下WPF ...
- arcserver开发小结(三)
一.关于网络数据集的制作 由于要做实现网络分析的功能,而手中却没有网络数据集,关于网络数据集的制作,网上也有不少的资料.我参考的是ESRI为我们提供的帮助文档(Network_Analyst_Tuto ...
- VC6下深入理解new[]和delete[](在多线程下new和delete的时候,必须选择上多线程库,不然可能造成进程崩溃)
多少年了,一直处于C与C++混用的状态,申请空间一直用malloc,释放空间一直用free,为什么?因为他们好理解易操作,就如同输出一直用printf而不用<<,输入一直用scanf而不用 ...
- Android 百度地图 SDK v3.0.0 (四) 离线地图功能介绍
转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/37758097 一直认为地图应用支持离线地图非常重要啊.我等移动2G屌丝,流量不易 ...
- 搭建本地yum源和局域网yum源
搭建本地yum源和局域网yum源 由于很多客户环境是专网,不允许连网,无法使用网上的各种yum源,来回拷贝rpm包安装麻烦,还得解决依赖问题.所以想着搭建个本地/局域网YUM源,方便安装软件. 1 ...
- VS发布到IIS Express外网Debug(如微信开发)
主要效果是本机调试网站,将网站发布到某域名(如m16758r728.iok.la),可以进入VS断点,不必再用远程调试!!! 环境 VS2015windows 10操作系统花生壳(可以用其他内网穿透的 ...