STM32无法使用某些定时器生成PWM

问题描述 投票:0回答:1

我有一个 arduino Giga (STM32H7),我正在尝试生成 PWM。我成功地使用了 PA7(数字引脚 5)的备用功能 AF9,该功能使用 TIM14_CH1。现在,使用完全相同的代码(据我所知),但使用 PA2/PA3(数字引脚 3 和 2)和备用功能 AF4(使用 TIM15_CH1/2),我没有得到这些引脚的任何输出。不过,TIM15 确实会打开,即它开始计数并在适当的时间重新启动。

int VolRepTime = 11000;     // Time to acquire one volume, in microseconds.
int Laser1UpTime = 8000;    // Time Laser1 trigger should stay up, in microseconds.
int Laser2UpTime = 5000;    // Time Laser2 trigger should stay up, in microseconds.
int Laser3UpTime = 4000;    // Time Laser3 trigger should stay up, in microseconds.

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  
  initTimers();
  initPins();

  Trigger1(Laser1UpTime, VolRepTime);
  Trigger2(Laser2UpTime, VolRepTime);  
  Trigger3(Laser3UpTime, VolRepTime);

}


void initTimers(){

  RCC->APB1LENR |= RCC_APB1LENR_TIM14EN;    // Enable use of TIM14
  RCC->APB2ENR  |= RCC_APB2ENR_TIM15EN;     // Enable use of TIM15

  // Set PWM mode.
  TIM14->CCMR1 |= ( 0x6UL << TIM_CCMR1_OC1M_Pos );    //  PWM mode 1 - Channel 1 is active as long as TIMx_CNT < TIMx_CCR1 else inactive.
  TIM15->CCMR1 |= ( 0x6UL << TIM_CCMR1_OC1M_Pos );    //  PWM mode 1 - Channel 1 is active as long as TIMx_CNT < TIMx_CCR1 else inactive.
  TIM15->CCMR1 |= ( 0x6UL << TIM_CCMR1_OC2M_Pos );    //  PWM mode 1 - Channel 2 is active as long as TIMx_CNT < TIMx_CCR1 else inactive.
  

  TIM14->CCER |= TIM_CCER_CC1E;  // Enables Capture/Compare for Channel 1.
  TIM15->CCER |= TIM_CCER_CC1E;  // Enables Capture/Compare for Channel 1.
  TIM15->CCER |= TIM_CCER_CC2E;  // Enables Capture/Compare for Channel 2.

  TIM14->DIER |= ( TIM_DIER_CC1IE | TIM_DIER_UIE );    // Update and Capture/Compare interrupts enabled
  TIM14->SR &= ~( TIM_SR_CC1IF | TIM_SR_UIF );         // Clear the interrupts

  TIM15->DIER |= ( TIM_DIER_CC1IE | TIM_DIER_UIE );    
  TIM15->SR &= ~( TIM_SR_CC1IF | TIM_SR_UIF );         
  TIM15->DIER |= ( TIM_DIER_CC2IE | TIM_DIER_UIE );  
  TIM15->SR &= ~( TIM_SR_CC2IF | TIM_SR_UIF );         

}



void initPins(){
  // Enables GPIOA. Gives access to digital pins 2, 3 and 5.
  RCC->AHB4ENR |= RCC_AHB4ENR_GPIOAEN;

  // Digital port = microcontroller port - [ModeRegisterBits]:
  // D2 = PA3 - [6 7]
  // D3 = PA2 - [4 5]
  // D5 = PA7 - [14 15]
  
  // For  Alternate function mode set bits to 10.
  // Set bits manually for now... (FIX ME)

  GPIOA->MODER = 0b10101011111111111011111110101111;
  


  // See page 89 of Datasheet.
  // Digital port = microcontroller port -> Alternate function - Corresponding timer
  // D2 = PA3-> AF4 - TIM15_CH2;
  // D3 = PA2-> AF4 - TIM15_CH1;
  // D5 = PA7-> AF9 - TIM14_CH1;

  // Set which alternate function each port should use.
  GPIOA->AFR[0] |= ( 0x4UL << 12);  // AF4 at AFR3
  GPIOA->AFR[0] |= ( 0x4UL << 8);   // AF4 at AFR2
  GPIOA->AFR[0] |= ( 0x9UL << 28);  // AF9 at AFR7

}


void Trigger1(int UpTime, int VolRepTime){
  TIM14->PSC = 240-1;             // Prescaler set so that 1 tick is 1 microsecond.
  TIM14->ARR = VolRepTime-1;      // Counter resets after reaching this value.
  TIM14->CCR1 = UpTime;           // Compare Register: Signal goes down after this time.        
}

void Trigger2(int UpTime, int VolRepTime){
  TIM15->PSC = 240-1;             
  TIM15->ARR = VolRepTime-1;      
  TIM15->CCR1 = UpTime;        
}

void Trigger3(int UpTime, int VolRepTime){
  TIM15->PSC = 240-1;             
  TIM15->ARR = VolRepTime-1;      
  TIM15->CCR2 = UpTime;        
}



void onoff(){
  // Turns TIM14/TIM15 on and off.
  TIM14->CR1 ^= TIM_CR1_CEN; 
  TIM15->CR1 ^= TIM_CR1_CEN;

}


void loop()
{
  delay(1000);
  
  if(Serial.read()!=-1){
    onoff();
  }
  Serial.println(TIM15->CNT);
}

即使将 TIMx_CCMR1_OCxM 设置为 0x5UL(“强制有效电平 - OC1REF 强制为高电平。”)对于 TIM15 也不起作用。我还尝试过使用 TIM16(使用 GPIOB),但我也无法工作,这很奇怪,因为功能与 TIM14 相同。非常感谢任何帮助!

timer arduino stm32 pwm mbed
1个回答
0
投票

TIM15/16/17 具有互补输出(带中断),这意味着您必须设置 TIMx_BDTR.MOE 才能使输出正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.