天九接收機信號 ppm pwm 學習過程

ppm和pcm是信號傳輸的一種編碼格式。
pwm是對負載進行平均功率控制的一種方式(電子設計的都應該知道電機pwm的控制原理)。

那麼模型遙控接收機輸出的脈衝信號是pwm信號嗎?很多人都認爲是pwm信號。其實不然。如果簡單的看確實是pwm。但你要是把這個信號當作pwm信號來設計個電調或舵機等模型外設,就有可能出現兼容問題。因爲模型接收機輸出的信號嚴謹的部分是脈衝的寬度,而週期是不嚴謹的,各個廠家的信號週期都有差別,甚至對於一個接收機在操作時週期是變化的。也就是說週期不確定的,去談佔空比就會有問題了。(這也是我自己寫了stm32pwm輸入捕捉的程序結果測試自己產生的pwm週期佔空比都對 都是測試天9時就週期啊佔空比啊一直在邊的原因)。

所以不提倡把模型接收機輸出信號說成pwm信號。以免造成誤解。

這裏把自己調試 固定佔空比pwm的輸入捕捉理解寫下來,害怕以後再做時又不知道這次怎麼搞的了。
捕獲原理:

1. 每個定時器有四個輸入捕獲通道IC1、IC2、IC3、IC4。且IC1 IC2一組,IC3 IC4一組。並且可是設置管腳和寄存器的對應關係。

2. 同一個TIx輸入映射了兩個ICx信號。

3. 這兩個ICx信號分別在相反的極性邊沿有效。

4. 兩個邊沿信號中的一個被選爲觸發信號,並且從模式控制器被設置成復位模式。

5. 當觸發信號來臨時,被設置成觸發輸入信號的捕獲寄存器,捕獲“一個PWM週期(即連續的兩個上升沿或下降沿)”,它等於包含TIM時鐘週期的個數(即捕獲寄存器中捕獲的爲TIM的計數個數n)。

6. 同樣另一個捕獲通道捕獲觸發信號和下一個相反極性的邊沿信號的計數個數m,即(即高電平的週期或低電平的週期)

7. 由此可以計算出PWM的時鐘週期和佔空比了

    frequency=f(TIM時鐘頻率)/n。

    duty cycle=(高電平計數個數/n),

    若m爲高電平計數個數,則duty cycle=m/n

    若m爲低電平計數個數,則duty cycle=(n-m)/n

注:因爲計數器爲16位,所以一個週期最多計數65535個,所以測得的 最小頻率= TIM時鐘頻率/65535。

 



在寫輸入捕捉時要注意輸入捕獲的TIMER的基準時鐘和最大計數,和中斷函數裏的計算公式就可以了。
基準時鐘跟計算週期有關,最大計數和你能捕捉的最低頻率有關。
void Timer2_Input(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
         NVIC_InitTypeDef NVIC_InitStructure;
         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_ICInitTypeDef  TIM_ICInitStructure;

SystemInit();
  /* TIM2 clock enable */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  /* GPIOA clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  TIM_TimeBaseStructure.TIM_Period = 0xffff;                                  //最大計數爲65535,週期最長65535us即頻率最低15hz               
  TIM_TimeBaseStructure.TIM_Prescaler = (72000000/1000000)-1; //基準時鐘爲1000000hz,也就是說你的計數週期是1us
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;   //
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//

  /* Enable the TIM2 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  /* NVIC configuration */
 
  /* TIM2 channel 2 pin (PA.01) configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;


  GPIO_Init(GPIOA, &GPIO_InitStructure);


  /* TIM2 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM2 CH2 pin (PA.01), 
     The Rising edge is used as active edge,
     The TIM2 CCR2 is used to compute the frequency value 
     The TIM2 CCR1 is used to compute the duty cycle value
  ------------------------------------------------------------ */


  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICFilter = 0x0;
  TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);


  /* Select the TIM2 Input Trigger: TI2FP2 */
  TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
  /* Enable the Master/Slave Mode */
  TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
 /* TIM enable counter */
  TIM_Cmd(TIM2, ENABLE);


  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
}



中斷函數如下
void TIM2_IRQHandler(void)
{
  // Clear TIM2 Capture compare interrupt pending bit //
  TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
  // Get the Input Capture value //
  IC2Value = TIM_GetCapture2(TIM2);         
  
  if (IC2Value != 0)
  {
    // Duty cycle computation //
    DutyCycle = (TIM_GetCapture1(TIM2) * 100) / IC2Value; 
    // Frequency computation //
    Frequency = 1000000/ IC2Value;           //這裏1000000就要和上邊保持一致就可以
  }
  else
  {
    DutyCycle = 0;
    Frequency = 0;
  }
}
發佈了28 篇原創文章 · 獲贊 15 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章