Weird HardwareTimer behavior
Posted: Fri Dec 20, 2019 8:46 am
Hello there,
I've had problem with HardwareTimer, it wont make me trigger interrupt for more than 500KHz, like it was capped.
Here is my code
Theoritically with prescaleFactor of 18 and overflow of 4 the timer will fire each 1uS, but in fact i get 2.5uS confirmed by ms5 that is printing 2500, since ms1 reset each 1000 tick, it gives 2.5uS. i've tried a lot of combination like prescale 72 and overflow 1, prescale 36 and overflow 2, prescaler 18 and overflow 4, but all of them will keep firing at 2.5uS, and weirdly at 2uS when i swapped prescale and overflow value (eg prescale 1 and overflow 72, prescale 2 and overflow 36), My thought it should be the same if we swapped prescaler and overflow, but whatt?????.
Then i thought it was timer clock problem (it was not the same as F_CPU), but when i set prescaleFactor to 2 and overflow to 36000, i get exact correct 1000uS period, same with overflow of 3600 (prescale still 2) i get 100uS period, and overflow of 360 i get 10uS period, but when i set the overflow to 36, i get 2uS again.
And also when i set it fast like prescale 1 and overflow 1 the Serial will stopped working, it will not print anything to Serial monitor, and since i dont have any logic analyzer or oscilloscope to knew exactly what is the interrupt reload frequency is, i dont know exactly what happened on that prescale and overflow value (1), but by looking at led blinking frequency, im pretty sure that it was still 2uS (the led blinking frequency is same as prescale 2 overflow 36).
I use rogerclark core, STM32F103C8T6 china clone (the IC label is TF-A2, but it was indeed C8T6) from some DMD LED Controller (TF-A2 Led Controller), i dont think the ic was the problem, and i upload via Serial.
Did i do something wrong, or the HardwareTimer is buggy?
I've had problem with HardwareTimer, it wont make me trigger interrupt for more than 500KHz, like it was capped.
Here is my code
Code: Select all
#define G2_LOW() GPIOB->regs->ODR &= ~(1 << 5)
#define G2_HIGH() GPIOB->regs->ODR |= (1 << 5)
unsigned long ms1 = 0;
unsigned long ms2 = 0;
unsigned long ms3 = 0;
unsigned long ms4 = 0;
unsigned long ms5 = 0;
unsigned long ms6 = 0;
bool ledState = 0;
void handler_led(){
ms1++;
if(ms1 % 1000 == 0){
ms5 = micros()-ms6;
ms6 = micros();
ms1 = 0;
ms3++;
}
if(ms3 >= 200){
ms3 = 0;
ledState = !ledState;
if(ledState) G2_HIGH(); else G2_LOW();
}
}
//HardwareTimer timerx(3);
void setup() {
pinMode(PB5,OUTPUT);
pinMode(PA8,OUTPUT);
digitalWrite(PA8,LOW);
Serial.begin(115200);
ms2 = 5000000;
Timer2.setMode(TIMER_CH1, TIMER_OUTPUTCOMPARE);
Timer2.setPrescaleFactor(18);
Timer2.setOverflow(4);
Timer2.setCompare(TIMER_CH1, 1);
Timer2.attachInterrupt(TIMER_CH1, handler_led);
}
void loop() {
Serial.println(ms5);
delay(500);
}
Then i thought it was timer clock problem (it was not the same as F_CPU), but when i set prescaleFactor to 2 and overflow to 36000, i get exact correct 1000uS period, same with overflow of 3600 (prescale still 2) i get 100uS period, and overflow of 360 i get 10uS period, but when i set the overflow to 36, i get 2uS again.
And also when i set it fast like prescale 1 and overflow 1 the Serial will stopped working, it will not print anything to Serial monitor, and since i dont have any logic analyzer or oscilloscope to knew exactly what is the interrupt reload frequency is, i dont know exactly what happened on that prescale and overflow value (1), but by looking at led blinking frequency, im pretty sure that it was still 2uS (the led blinking frequency is same as prescale 2 overflow 36).
I use rogerclark core, STM32F103C8T6 china clone (the IC label is TF-A2, but it was indeed C8T6) from some DMD LED Controller (TF-A2 Led Controller), i dont think the ic was the problem, and i upload via Serial.
Did i do something wrong, or the HardwareTimer is buggy?