初级会员

- 积分
- 194
- 金钱
- 194
- 注册时间
- 2015-12-3
- 在线时间
- 29 小时
|
20金钱
本帖最后由 石头0218 于 2019-7-27 10:26 编辑
使用的KEIL5编译,程序是在RT_THREAD中使用的,不过我把RT_THEAD系统代码屏蔽单独测试只要打开TIM5中断还是会死机。
相同的代码使用定时器3和定时器4就没问题。
如果把TIM5中断使能HAL_NVIC_EnableIRQ(TIM5_IRQn);屏蔽掉,程序不会死机,可以持续输出PWM波,不过因为无法进入中断所以不会停止输出,也就不能实现输出指定数量PWM的功能了。有遇到这样的问题吗?敬请指教,不胜感激
代码如下:
TIM_HandleTypeDef shtim2;
TIM_HandleTypeDef shtim5;
/* TIM2 init function */
void MX_TIM2_Init(void)
{
// TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_TIM2_CLK_ENABLE();
shtim2.Instance = TIM2; //设置主定时器为TIM2
shtim2.Init.Prescaler = 720-1; //设置PWM频率
shtim2.Init.CounterMode = TIM_COUNTERMODE_UP; //设置计数模式为向上计数
shtim2.Init.Period = 5000-1; //设置占空比
shtim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置为无分频
HAL_TIM_PWM_Init(&shtim2);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; //更新事件被选为触发输入
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE; //开启主从模式
HAL_TIMEx_MasterConfigSynchronization(&shtim2, &sMasterConfig);
sConfigOC.OCMode = TIM_OCMODE_PWM1; //设置PWM模式为PWM1
sConfigOC.Pulse = 2500; //设置PWM占空比为50%(50/100)
sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW; //设置PWM空闲状态引脚拉低
HAL_TIM_PWM_ConfigChannel(&shtim2, &sConfigOC, TIM_CHANNEL_2);
__HAL_AFIO_REMAP_TIM2_PARTIAL_1();//部分重映射
/**TIM2 GPIO Configuration
PB3 ------> TIM2_CH2
*/
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_TIM_Base_Stop(&shtim2);
}
void MX_TIM5_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
__HAL_RCC_TIM5_CLK_ENABLE();
shtim5.Instance = TIM5; //设置从定时器为TIM5
shtim5.Init.Prescaler =0; //设置从定时器频率为0
shtim5.Init.CounterMode = TIM_COUNTERMODE_UP; //设置计数模式为向上计数
shtim5.Init.Period =0xffff; //这个大于0就行
shtim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //设置为无分频
HAL_TIM_Base_Init(&shtim5);
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; //设置为内部时钟触发,即为TIM2
HAL_TIM_ConfigClockSource(&shtim5, &sClockSourceConfig);
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED; //设置为门触发
sSlaveConfig.InputTrigger = TIM_TS_ITR0; //设置ITR0(tim2)为输入源
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; //设置触发模式为上升沿
sSlaveConfig.TriggerPrescaler = TIM_TRIGGERPRESCALER_DIV1; //设置无预分频
sSlaveConfig.TriggerFilter = 0x0; //设置无滤波
HAL_TIM_SlaveConfigSynchronization(&shtim5, &sSlaveConfig);
//开启ITM5中断
HAL_TIM_Base_Stop_IT(&shtim5);
HAL_NVIC_SetPriority(TIM5_IRQn,0,2); //设置中断优先级,抢占优先级0,子优先级2
HAL_NVIC_EnableIRQ(TIM5_IRQn);
}
void TIM5_IRQHandler(void)
{
HAL_TIM_IRQHandler(&shtim5);
}
//回调函数,定时器中断服务函数调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim==(&htim4))
{
if(__HAL_TIM_GET_FLAG(&htim4, TIM_FLAG_CC1) != RESET) //判断是否触发中断
{
__HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_CC1); //清除中断标志位
HAL_TIM_PWM_Stop_IT(&htim3, TIM_CHANNEL_2); //关闭主定时器的PWM输出
HAL_TIM_Base_Stop_IT(&htim4); //关闭从定时器的计数
}
}
if(htim==(&shtim5))
{
if(__HAL_TIM_GET_FLAG(&shtim5, TIM_FLAG_CC1) != RESET) //判断是否触发中断
{
__HAL_TIM_CLEAR_FLAG(&shtim5, TIM_FLAG_CC1); //清除中断标志位
HAL_TIM_PWM_Stop_IT(&shtim2, TIM_CHANNEL_2); //关闭主定时器的PWM输出
HAL_TIM_Base_Stop_IT(&shtim5); //关闭从定时器的计数
}
}
}
|
|