OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7966|回复: 6

STM32F103RCT6 定时器2和定时器5做主从模式,控制输出固定数量的PWM,定时器5使能中断程序就死机

[复制链接]

9

主题

61

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2015-12-3
在线时间
29 小时
发表于 2019-7-27 10:26:42 | 显示全部楼层 |阅读模式
20金钱
本帖最后由 石头0218 于 2019-7-27 10:26 编辑

使用的KEIL5编译,程序是在RT_THREAD中使用的,不过我把RT_THEAD系统代码屏蔽单独测试只要打开TIM5中断还是会死机。
相同的代码使用定时器3和定时器4就没问题。
如果把TIM5中断使能HAL_NVIC_EnableIRQ(TIM5_IRQn);屏蔽掉,程序不会死机,可以持续输出PWM波,不过因为无法进入中断所以不会停止输出,也就不能实现输出指定数量PWM的功能了。有遇到这样的问题吗?敬请指教,不胜感激
123.png

代码如下:

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);                                  //关闭从定时器的计数
        }  
    }
}





走不一样的路,让别人看吧
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

61

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2015-12-3
在线时间
29 小时
 楼主| 发表于 2019-7-27 10:36:39 | 显示全部楼层
设置输出10个PWM

void TIM2_PWM_Set(void)
{
    __HAL_TIM_SET_AUTORELOAD(&shtim5,10-1);    //ARR装载要输出的PWM脉冲数

    HAL_TIM_Base_Start_IT(&shtim5);                   //从定时器计数开启

    HAL_TIM_PWM_Start_IT(&shtim2, TIM_CHANNEL_2);
}


void TIM3_PWM_Set(void)
{
    __HAL_TIM_SET_AUTORELOAD(&htim4,10-1);    //ARR装载要输出的PWM脉冲数

    HAL_TIM_Base_Start_IT(&htim4);                   //从定时器计数开启

    HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_2);
}
走不一样的路,让别人看吧
回复

使用道具 举报

9

主题

61

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2015-12-3
在线时间
29 小时
 楼主| 发表于 2019-7-27 13:19:06 | 显示全部楼层
我将定时器5改为定时器8,还是不行。完全不知道哪的问题
走不一样的路,让别人看吧
回复

使用道具 举报

9

主题

61

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2015-12-3
在线时间
29 小时
 楼主| 发表于 2019-7-27 17:32:46 | 显示全部楼层
3楼定时器5改为8是不行的,好像定时器8不能做从定时器,但是奇怪的是定时器8不开中断,定时器2居然有PWM输出。
走不一样的路,让别人看吧
回复

使用道具 举报

9

主题

61

帖子

0

精华

初级会员

Rank: 2

积分
194
金钱
194
注册时间
2015-12-3
在线时间
29 小时
 楼主| 发表于 2019-7-27 17:39:40 | 显示全部楼层
定时器2和定时器8组合,定时器8做主,定时器2做从,可以正常输出设定脉冲。但是为什么定时器2(主)和定时器5(从)就不行了呢?!看来非逼着改硬件啊。希望有大佬能帮忙解答一下,遇到问题不解决实在难受人啊。
这里,用到输出两路可控脉冲数的朋友也借鉴一下,硬件设计提前规避这个问题,或者提前搭硬件验证(说不好是我电路问题呢)。
走不一样的路,让别人看吧
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2019-7-28 02:32:11 | 显示全部楼层
帮顶
回复

使用道具 举报

2

主题

15

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2021-3-21
在线时间
4 小时
发表于 2021-5-18 16:59:40 | 显示全部楼层
楼主是否解决死机问题了?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-23 18:15

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表