Input (STM32)是否可以仅使用定时器1、CH1和CH2捕获两个不同的信号?

Input (STM32)是否可以仅使用定时器1、CH1和CH2捕获两个不同的信号?,input,embedded,stm32,capture,pwm,Input,Embedded,Stm32,Capture,Pwm,我目前正在从事一个项目,我正在尝试测量连接到定时器1(通道1和通道2)的两个不同信号的占空比和频率 PE9----->TIM1\U CH1 PE11----->TIM1\U CH2 我的计划是每100ms在CH1和CH2之间切换一次,调用一个名为PwmInput_SwitchChannels(BOOL)的函数,该函数包含每个通道的正确配置。在中断函数中,我希望捕获值并将它们存储在一个由两个pwm_捕获类型元素组成的数组中 typedef struct { __IO UInt1

我目前正在从事一个项目,我正在尝试测量连接到定时器1(通道1和通道2)的两个不同信号的占空比和频率 PE9----->TIM1\U CH1 PE11----->TIM1\U CH2

我的计划是每100ms在CH1和CH2之间切换一次,调用一个名为PwmInput_SwitchChannels(BOOL)的函数,该函数包含每个通道的正确配置。在中断函数中,我希望捕获值并将它们存储在一个由两个pwm_捕获类型元素组成的数组中

typedef struct
       {
   __IO UInt16            uhIC2Value;
   __IO UInt16            uhDutyCycle;
   __IO UInt32            uwFrequency;
        }
        pwm_capture;
pwm_capture input_capture[2];
问题是1个通道的捕获值​​与真实的不匹配,这似乎是PwmInput_开关通道中的问题。 当我独立测试这两个通道时,代码运行得非常好,中断功能正在发挥作用

            #define PIN18_PWM_A ((BOOL)  0)
            #define PIN19_PWM_B ((BOOL)  1)

            typedef struct
                    {
               __IO UInt16            uhIC2Value;
               __IO UInt16            uhDutyCycle;
               __IO UInt32            uwFrequency;
                    }
                    pwm_capture;

             pwm_capture input_capture[2];
             BOOL Tim1_Channels = 0;
             UInt16 counter_pwm = 0;


            void HalTim_MainFunction(void)
            {
                if ( FALSE != rb_InitStatus )
                {
                    counter_pwm++;
                    if(counter_pwm % 100 == 0)
                    {
                        Tim1_Channels = ! Tim1_Channels;
                        PwmInput_SwitchChannels(Tim1_Channels);
                    }
                }
                else {
                    ;
                }
            }





            void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
            {
                if(htim->Instance == TIM1)
                {
                switch(Tim1_Channels){
                  case PIN18_PWM_A:
                  {
                    if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
                    {
                        /* Get the Input Capture value */
                        input_capture[0].uhIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);

                        if (input_capture[0].uhIC2Value != 0)
                        {
                            /* Duty cycle computation */
                            input_capture[0].uhDutyCycle = ((HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1)) * 100) / input_capture[0].uhIC2Value;

                            /* uwFrequency computation
                  TIM1 counter clock = (RCC_Clocks.HCLK_Frequency)/2 */
                            input_capture[0].uwFrequency = (HAL_RCC_GetHCLKFreq()) / input_capture[0].uhIC2Value;
                        }
                        else
                        {
                            input_capture[0].uhDutyCycle = 0;
                            input_capture[0].uwFrequency = 0;
                        }

                    }
                  break;
                  }
                  case PIN19_PWM_B:
                  {
                      if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
                      {
                          /* Get the Input Capture value */
                          input_capture[1].uhIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);

                          if (input_capture[1].uhIC2Value != 0)
                          {
                              /* Duty cycle computation */
                              input_capture[1].uhDutyCycle = ((HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2)) * 100) / input_capture[1].uhIC2Value;

                              /* uwFrequency computation
                               TIM1 counter clock = (RCC_Clocks.HCLK_Frequency)/2 */
                              input_capture[1].uwFrequency = (HAL_RCC_GetHCLKFreq()) / input_capture[1].uhIC2Value;
                          }
                          else
                          {
                              input_capture[1].uhDutyCycle = 0;
                              input_capture[1].uwFrequency = 0;
                          }

                      }
                  break;
                  }
                  default:
                          Error_Handler();

                }
              }
            }





            void PwmInput_SwitchChannels(BOOL aux)
            {
                TIM_SlaveConfigTypeDef sSlaveConfig_aux = {0};
                TIM_MasterConfigTypeDef sMasterConfig_aux = {0};
                TIM_IC_InitTypeDef sConfigIC_aux = {0};

                /*##-4- Stop the Input Capture in interrupt mode ##########################*/
                 if (HAL_TIM_IC_Stop_IT(&htim1, TIM_CHANNEL_2) != HAL_OK)
                {
                 /* Starting Error */
                 Error_Handler();
                }

                 /*##-5- Stop the Input Capture in interrupt mode ##########################*/
                if (HAL_TIM_IC_Stop_IT(&htim1, TIM_CHANNEL_1) != HAL_OK)
                {
                 /* Starting Error */
                 Error_Handler();
                }

               switch (aux){
               case PIN18_PWM_A:
               {
                        sSlaveConfig_aux.SlaveMode = TIM_SLAVEMODE_RESET;
                        sSlaveConfig_aux.InputTrigger = TIM_TS_TI2FP2;
                        sSlaveConfig_aux.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
                        sSlaveConfig_aux.TriggerFilter = 0;
                        if (HAL_TIM_SlaveConfigSynchronization(&htim1, &sSlaveConfig_aux) != HAL_OK)
                        {
                           Error_Handler();
                         }
                        sMasterConfig_aux.MasterOutputTrigger = TIM_TRGO_RESET;
                        sMasterConfig_aux.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
                        if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig_aux) != HAL_OK)
                         {
                            Error_Handler();
                         }
                         sConfigIC_aux.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
                         sConfigIC_aux.ICSelection = TIM_ICSELECTION_INDIRECTTI;
                         sConfigIC_aux.ICPrescaler = TIM_ICPSC_DIV1;
                         sConfigIC_aux.ICFilter = 0;
                         if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC_aux, TIM_CHANNEL_1) != HAL_OK)
                         {
                            Error_Handler();
                         }
                         sConfigIC_aux.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
                         sConfigIC_aux.ICSelection = TIM_ICSELECTION_DIRECTTI;
                         if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC_aux, TIM_CHANNEL_2) != HAL_OK)
                         {
                            Error_Handler();
                         }
                        break;
               }
               case PIN19_PWM_B:
               {
                        sSlaveConfig_aux.SlaveMode = TIM_SLAVEMODE_RESET;
                        sSlaveConfig_aux.InputTrigger = TIM_TS_TI1FP1;
                        sSlaveConfig_aux.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
                        sSlaveConfig_aux.TriggerFilter = 0;
                        if (HAL_TIM_SlaveConfigSynchronization(&htim1, &sSlaveConfig_aux) != HAL_OK)
                        {
                           Error_Handler();
                         }
                        sMasterConfig_aux.MasterOutputTrigger = TIM_TRGO_RESET;
                        sMasterConfig_aux.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
                        if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig_aux) != HAL_OK)
                         {
                            Error_Handler();
                         }
                         sConfigIC_aux.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
                         sConfigIC_aux.ICSelection = TIM_ICSELECTION_INDIRECTTI;
                         sConfigIC_aux.ICPrescaler = TIM_ICPSC_DIV1;
                         sConfigIC_aux.ICFilter = 0;
                         if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC_aux, TIM_CHANNEL_2) != HAL_OK)
                         {
                            Error_Handler();
                         }
                         sConfigIC_aux.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
                         sConfigIC_aux.ICSelection = TIM_ICSELECTION_DIRECTTI;
                         if (HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC_aux, TIM_CHANNEL_1) != HAL_OK)
                         {
                            Error_Handler();
                         }
                        break;
                }
                default:
                      Error_Handler();

                 /*##-4- Start the Input Capture in interrupt mode ##########################*/
                if (HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2) != HAL_OK)
                {
                  /* Starting Error */
                  Error_Handler();
                }

                 /*##-5- Start the Input Capture in interrupt mode ##########################*/
                if (HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1) != HAL_OK)
                {
                  /* Starting Error */
                  Error_Handler();
                }
            }
            }

我的目的是在不影响结果和性能的情况下在两个通道之间正确切换(由于硬件限制,仅使用Tim1_CH1和Tim1_CH2)。

一个可能的原因是
Tim1_通道
未声明
volatile
。它在主函数中写入,并在中断处理程序中访问。由于缺少
volatile
限定符,优化器无法将值保存在寄存器中,也无法将其写回内存。据优化器所知,值为accessd的中断处理程序从未从主程序调用。

一个可能的原因是
Tim1\u通道
未声明
volatile
。它在主函数中写入,并在中断处理程序中访问。由于缺少
volatile
限定符,优化器无法将值保存在寄存器中,也无法将其写回内存。据优化器所知,值为accessd的中断处理程序从未从主程序调用。

我通过将以下变量声明为volatile并修改中断函数中的代码来解决问题

 __IO pwm_capture input_capture[2] = {{0}, {0}};
 __IO BOOL Tim1_Channels = 0;
 __IO UInt16 counter_pwm = 0;


 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
 {
    if(htim->Instance == TIM1)
     {
    switch(Tim1_Channels){
    case PIN18_PWM_A:
     {
    if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
    {
        /* Get the Input Capture value */
        input_capture[0].uhIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);

        if (input_capture[0].uhIC2Value != 0)
        {
            /* Duty cycle computation */
            input_capture[0].uhDutyCycle = ((HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2)) * 100) / input_capture[0].uhIC2Value;

            /* uwFrequency computation
  TIM1 counter clock = (RCC_Clocks.HCLK_Frequency)/2 */
            input_capture[0].uwFrequency = (HAL_RCC_GetHCLKFreq()) / input_capture[0].uhIC2Value;
        }
        else
        {
            input_capture[0].uhDutyCycle = 0;
            input_capture[0].uwFrequency = 0;
        }

    }
     break;
  }
  case PIN19_PWM_B:
  {
      if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
      {
          /* Get the Input Capture value */
          input_capture[1].uhIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);

          if (input_capture[1].uhIC2Value != 0)
          {
              /* Duty cycle computation */
              input_capture[1].uhDutyCycle = ((HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2)) * 100) / input_capture[1].uhIC2Value;

              /* uwFrequency computation
    TIM1 counter clock = (RCC_Clocks.HCLK_Frequency)/2 */
              input_capture[1].uwFrequency = (HAL_RCC_GetHCLKFreq()) / input_capture[1].uhIC2Value;
          }
          else
          {
              input_capture[1].uhDutyCycle = 0;
              input_capture[1].uwFrequency = 0;
          }

      }
      break;
    }
  default:
      Error_Handler();

   }
  }

}

我通过将以下变量声明为volatile并修改中断函数中的代码,解决了这个问题

 __IO pwm_capture input_capture[2] = {{0}, {0}};
 __IO BOOL Tim1_Channels = 0;
 __IO UInt16 counter_pwm = 0;


 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
 {
    if(htim->Instance == TIM1)
     {
    switch(Tim1_Channels){
    case PIN18_PWM_A:
     {
    if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
    {
        /* Get the Input Capture value */
        input_capture[0].uhIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);

        if (input_capture[0].uhIC2Value != 0)
        {
            /* Duty cycle computation */
            input_capture[0].uhDutyCycle = ((HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2)) * 100) / input_capture[0].uhIC2Value;

            /* uwFrequency computation
  TIM1 counter clock = (RCC_Clocks.HCLK_Frequency)/2 */
            input_capture[0].uwFrequency = (HAL_RCC_GetHCLKFreq()) / input_capture[0].uhIC2Value;
        }
        else
        {
            input_capture[0].uhDutyCycle = 0;
            input_capture[0].uwFrequency = 0;
        }

    }
     break;
  }
  case PIN19_PWM_B:
  {
      if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
      {
          /* Get the Input Capture value */
          input_capture[1].uhIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);

          if (input_capture[1].uhIC2Value != 0)
          {
              /* Duty cycle computation */
              input_capture[1].uhDutyCycle = ((HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2)) * 100) / input_capture[1].uhIC2Value;

              /* uwFrequency computation
    TIM1 counter clock = (RCC_Clocks.HCLK_Frequency)/2 */
              input_capture[1].uwFrequency = (HAL_RCC_GetHCLKFreq()) / input_capture[1].uhIC2Value;
          }
          else
          {
              input_capture[1].uhDutyCycle = 0;
              input_capture[1].uwFrequency = 0;
          }

      }
      break;
    }
  default:
      Error_Handler();

   }
  }

}

预期的频率范围是多少?你有哪款STM32单片机?时钟频率是多少?嗨,两个信号的范围都在10khz到50khz之间,时钟频率是48Mhz,没有计时器1的预分频器,我使用stm32f103vct6.TIM_SlaveConfigTypeDef sSlaveConfig={0};TIM_MasterConfigTypeDef sMasterConfig={0};TIM_IC_InitTypeDef sConfigIC={0};htim1.Instance=TIM1;htim1.Init.Prescaler=0;htim1.Init.CounterMode=TIM\u CounterMode\u UP;htim1.Init.Period=65535;htim1.Init.ClockDivision=TIM\u ClockDivision\u DIV1;htim1.Init.RepetitionCounter=0;htim1.Init.autoreloaddreload=TIM\u AUTORELOAD\u PRELOAD\u DISABLE;预期的频率范围是多少?你有哪款STM32单片机?时钟频率是多少?嗨,两个信号的范围都在10khz到50khz之间,时钟频率是48Mhz,没有计时器1的预分频器,我使用stm32f103vct6.TIM_SlaveConfigTypeDef sSlaveConfig={0};TIM_MasterConfigTypeDef sMasterConfig={0};TIM_IC_InitTypeDef sConfigIC={0};htim1.Instance=TIM1;htim1.Init.Prescaler=0;htim1.Init.CounterMode=TIM\u CounterMode\u UP;htim1.Init.Period=65535;htim1.Init.ClockDivision=TIM\u ClockDivision\u DIV1;htim1.Init.RepetitionCounter=0;htim1.Init.autoreloaddreload=TIM\u AUTORELOAD\u PRELOAD\u DISABLE;非常感谢,我通过修改中断函数解决了这个问题,正如你所说,我声明了Tim1_通道不稳定。非常感谢,我通过修改中断函数解决了这个问题,正如你所说,我声明了Tim1_通道不稳定。