PWM not working on STM32F401CEU6
Posted: Sun Jan 26, 2025 12:58 pm
Hi, I am trying to make a project to drive ESCs for a drone, for the same I am trying to generate PWM pulses using the STM32 TIM2_CHx, but it does not seem to work as my ESCs are not responding.
My code is as below
===============================================================================================================================
#include <libmaple/scb.h>
uint32_t loop_timer,now, receiver_input1, receiver_input1_previous,systick_counter;;
uint8_t int_flag;
void setup() {
pinMode(PA5,PWM); //PA5 seems to be the PIN for TIM2_CH1 as per the datasheet.
//all the needed registers are initialized.
TIMER2_BASE->CR1 = TIMER_CR1_CEN|TIMER_CR1_ARPE;
TIMER2_BASE->CR2 = 0;
TIMER2_BASE->SMCR = 0;
TIMER2_BASE->DIER = 0;
TIMER2_BASE->EGR = 0;
TIMER2_BASE->CCMR1 = (0b110 << 4) | TIMER_CCMR1_OC1PE;
TIMER2_BASE->CCMR2 =0;
TIMER2_BASE->PSC = 84; // Pre-scaler is set to 84 as processor clock is 84Mhz, so I can get 84/84 = 1Mhz for the timer
TIMER2_BASE->ARR = 5000;
TIMER2_BASE->DCR = 0;
TIMER2_BASE->CCR1 = 1000;
Serial.begin(57600);
attachInterrupt(PB10, ch1, CHANGE); // interrupt routine for detecting the receiver input pulse (this part is working)
// put your setup code here, to run once:
}
void loop() {
loop_timer = micros()+4000; // software reset of the timer to keep program loop at 250Hz
TIMER2_BASE->CNT = 5000;
// Flight Controller Code Start
TIMER2_BASE->CCR1 = receiver_input1; //storing the receiver input in the Capture Compare Register 1
Serial.println(receiver_input1);
// Flight Controller Code End
while(loop_timer > micros());
}
void ch1(){
systick_counter = SYSTICK_BASE->VAL;
if (0b1 & SCB_BASE->ICSR >> 26){
int_flag =1;
systick_counter = SYSTICK_BASE->VAL;
}
else int_flag = 0;
now = (systick_uptime_millis * 1000) + (SYSTICK_RELOAD_VAL + 1 - systick_counter) / CYCLES_PER_MICROSECOND;
if (int_flag)now += 1000;
if(0B1 & GPIOB_BASE->IDR >> 10)receiver_input1_previous = now;
else receiver_input1 = now - receiver_input1_previous;
}
==============================================================================================================================
Maybe I am missing something, Do I have to enable the DTG register for output ?
PS: The code compiles without errors, and the ESCs are working with an Arduino.
Thank you for the help
My code is as below
===============================================================================================================================
#include <libmaple/scb.h>
uint32_t loop_timer,now, receiver_input1, receiver_input1_previous,systick_counter;;
uint8_t int_flag;
void setup() {
pinMode(PA5,PWM); //PA5 seems to be the PIN for TIM2_CH1 as per the datasheet.
//all the needed registers are initialized.
TIMER2_BASE->CR1 = TIMER_CR1_CEN|TIMER_CR1_ARPE;
TIMER2_BASE->CR2 = 0;
TIMER2_BASE->SMCR = 0;
TIMER2_BASE->DIER = 0;
TIMER2_BASE->EGR = 0;
TIMER2_BASE->CCMR1 = (0b110 << 4) | TIMER_CCMR1_OC1PE;
TIMER2_BASE->CCMR2 =0;
TIMER2_BASE->PSC = 84; // Pre-scaler is set to 84 as processor clock is 84Mhz, so I can get 84/84 = 1Mhz for the timer
TIMER2_BASE->ARR = 5000;
TIMER2_BASE->DCR = 0;
TIMER2_BASE->CCR1 = 1000;
Serial.begin(57600);
attachInterrupt(PB10, ch1, CHANGE); // interrupt routine for detecting the receiver input pulse (this part is working)
// put your setup code here, to run once:
}
void loop() {
loop_timer = micros()+4000; // software reset of the timer to keep program loop at 250Hz
TIMER2_BASE->CNT = 5000;
// Flight Controller Code Start
TIMER2_BASE->CCR1 = receiver_input1; //storing the receiver input in the Capture Compare Register 1
Serial.println(receiver_input1);
// Flight Controller Code End
while(loop_timer > micros());
}
void ch1(){
systick_counter = SYSTICK_BASE->VAL;
if (0b1 & SCB_BASE->ICSR >> 26){
int_flag =1;
systick_counter = SYSTICK_BASE->VAL;
}
else int_flag = 0;
now = (systick_uptime_millis * 1000) + (SYSTICK_RELOAD_VAL + 1 - systick_counter) / CYCLES_PER_MICROSECOND;
if (int_flag)now += 1000;
if(0B1 & GPIOB_BASE->IDR >> 10)receiver_input1_previous = now;
else receiver_input1 = now - receiver_input1_previous;
}
==============================================================================================================================
Maybe I am missing something, Do I have to enable the DTG register for output ?
PS: The code compiles without errors, and the ESCs are working with an Arduino.
Thank you for the help
