唐宋404 2023-05-22 18:09 采纳率: 22.2%
浏览 54
已结题

STM32定时器问题

写STM32代码时遇到的问题

PWM** PWM::initTim(unsigned int tim,unsigned int psc,unsigned int arr,const char* choice){
    TIM_HandleTypeDef *htim = new TIM_HandleTypeDef;
    unsigned int channel_num=0;

    switch(tim){
        case 1:{__HAL_RCC_TIM1_CLK_ENABLE();break;}
        case 2:{__HAL_RCC_TIM2_CLK_ENABLE();break;}
        case 3:{__HAL_RCC_TIM3_CLK_ENABLE();break;}
        default:{__HAL_RCC_TIM1_CLK_ENABLE();break;}
    }

  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

  htim->Instance = TIMS[tim-1];
  htim->Init.Prescaler = psc;
  htim->Init.CounterMode = TIM_COUNTERMODE_UP;
  htim->Init.Period = arr;
  htim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim->Init.RepetitionCounter = 0;
  htim->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(htim)!= HAL_OK)
    Error_Handler();
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(htim, &sMasterConfig) != HAL_OK)
    Error_Handler();
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = arr+1;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    for(int i=0;i<4;i++)
        if(choice[i]=='1'){
            if(HAL_TIM_PWM_ConfigChannel(htim, &sConfigOC, CHANNELS[i]) != HAL_OK)
                Error_Handler();
            channel_num++;
        }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(htim, &sBreakDeadTimeConfig) != HAL_OK)
    Error_Handler();
  GPIO_Init(tim,choice);
    PWM** pwm_arr = new PWM *[channel_num];
    int p=0;
    for(int i=0;i<4;i++)
        if(choice[i]=='1'){
            pwm_arr[p++]= new PWM(htim,CHANNELS[i]);
        }
    return pwm_arr;
    
}

经过尝试发现问题出现在以下代码中,但不知道原因

    PWM** pwm_arr = new PWM *[channel_num];
    int p=0;
    for(int i=0;i<4;i++)
        if(choice[i]=='1'){
            pwm_arr[p++]= new PWM(htim,CHANNELS[i]);
        }
    return pwm_arr;

该代码的作用在于用类似于PWM** motor= PWM::initTim(2,71,999,"1111");的形式获取一个可供操纵的motor数组,
其中参数1代表TIM2,参数2代表psc=71,参数3代表arr=999,参数4代表四个通道都获取。
已经验证单个定时器没有问题
我理想的情况是无论开启多少个定时器都能使用,而现实是
PWM** motor= PWM::initTim(2,71,999,"1111");
PWM** motor= PWM::initTim(3,71,999,"1111");
此时两个定时器都没有反应了
我想知道原因与修改办法

  • 写回答

4条回答 默认 最新

  • xiaok-cpp C/C++领域新星创作者 2023-05-22 18:41
    关注

    经过分析,您的代码存在内存泄漏问题。在函数initTim中,为了返回可供操纵的motor数组,使用了new关键字动态创建了PWM对象(即pwm_arr[p++]= new PWM(htim,CHANNELS[i]);),却没有显式地去delete这些对象,导致内存泄漏。
    因此,当您连续两次调用PWM::initTim函数时,会创建新的PWM对象并返回一个新的指针数组,而旧的指针数组及其对象仍然存在于内存中,未能被正确释放,导致内存占用增加,并可能干扰系统的运行。解决办法是在使用完毕后,显式地调用delete关键字释放资源,并赋空值。例如可以写一个类似如下的析构函数:

    PWM::~PWM(){
      if (htim){
        HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_1);
        HAL_TIM_Base_Stop(&htim1);
        HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_1);
        HAL_TIM_Base_Stop(&htim2);
        HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1);
        HAL_TIM_Base_Stop(&htim3);
        HAL_TIM_PWM_Stop(&htim4,TIM_CHANNEL_1);
        HAL_TIM_Base_Stop(&htim4);
        delete htim;
        htim=nullptr;
      }
    }
    

    在需要释放资源的情况下,用delete进行释放,将指针清空,避免出现野指针,同时防止二次释放。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 5月23日
  • 已采纳回答 5月22日
  • 创建了问题 5月22日

悬赏问题

  • ¥50 Delphi 非客户区窗口阴影?
  • ¥15 cv2 morphologyEx函数报错
  • ¥15 有没有知道鸿蒙OS高级开发者新题答案的
  • ¥15 有没有人能帮我一下android
  • ¥20 做一个干部信息管理系统 软件
  • ¥15 通过4G模块EC600N向阿里云物联网平台物模型上面发送字符串,现在发送int数据是成功的,发送字符串就是不成功
  • ¥15 IDA反编译,代码识别失败
  • ¥70 matlab代码修改
  • ¥15 有没有下面符合以下条件的电子时钟的代码
  • ¥15 LMV844QMAX/NOPB(IS)问题判定