我有一个 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 相同。非常感谢任何帮助!
TIM15/16/17 具有互补输出(带中断),这意味着您必须设置 TIMx_BDTR.MOE 才能使输出正常工作。