2020-03-12 07:39 PM
I've used stm32F103VC before, so this time I changed my MCU to stm32F103RC.
I saw in the datasheet that the specifications of the two chips are almost equal.
However, I cannot properly set the timer in stm32F103RC.
Here's how I tested it:
I make a clock pulse by changing the value of pin at TIM_UP_IRQhandler using GPIO PIN.
And I measure this clock pulse with an oscilloscope.
I made 1 usec clock pulse using stm32F103VC.
However, I applied the same settings in the stm32F103RC, and i made 100 usec clocks pulse.
Please let me know how to set the values of Prescaler and Period.
Also, is the clock frequency of TIM1 in APB2 peripheral clock of stm32F103RC a 72MHz?
2020-03-12 09:38 PM
Interrupting at 1 MHz is impractical, the processor saturates.
Use the TIM to toggle the pin, use the TIM CNT register to mark time in 1 us ticks.
2020-03-12 10:31 PM
That's right, so I did pin control after counting 100 times at the interrupt. So I actually measured the 1msec waveform on an oscilloscope.
TIM_TimeBaseStructure.TIM_Prescaler = 72-1;
TIM_TimeBaseStructure.TIM_Period = 1;
When set as above, the period of pin toggle in stm32F103VC occurred in 1msec. (TIM1 period: 10usec)
However, in the stm32F103RC, the period of pin toggle occurs at 1.8 msec.
(TIM1 period: 18usec)
Despite the same settings, why is the period of the clock pulse different?
2020-03-12 11:30 PM
You have 72 MHz PCLK that clocks a /72 prescaler. That gives you 1 MHz timer clock => period is 1 us.
Now, if you have interrupt in every update event and your period is 1, it interrupts every 1 microseconds.
Rather, set the period to 100 - 1 and toggle the line in every interrupt. The result should be about 100 us on the scope.
With 72 MHz the clock cycle is about 14 ns, and ARM executes most instructions in one cycle. external accesses take more.
The best case is that the processor can execute 71 instructions in 1 us.
2020-03-13 12:44 AM
I don't know your intention.
I just wanted to use the interrupt of the timer when using my ultrasonic sensor.
When calculating TOD of my ultrasonic sensor, I need accurate time.
This exact time means that it can be measured in 1 usec unit.
So I wanted to make sure that the method I tested was appropriate.
period = 100 -1
I would recommend a method other than the above.
2020-03-13 04:42 AM
Interrupts are too slow for microsecond accuracy.
How does this sensor work? You send a pulse on pin 1, receive a pulse on pin 2, and measure the timing, right? Good news is that a timer can do most of this on its own.
You need one output channel, and one or two capture channels. Two if you want to measure both the rising and falling edges of the echo signal.
Depending on the frequency of the output signal and the required resolution, you might need two timers in a master-slave relation.
Read the timer functional description chapter in the reference manual, time base unit capture/compare channels, input capture mode, PWM input, PWM mode (output) in particular.
What are the parameters? Output pulse width, frequency, measurement range (min/max) and resolution?
2020-03-13 11:15 AM
That's to find out if your timer runs right.
For that usage, interrupts are far too slow.
You mau need a clock triggered ADC with DMA, if you get pressure info, or timer with input capture, if your sensor just signald about detection.
If you try to get 2-dimensional data (from two sensors), you'd need dual ADC mode to get a good sound "image".
2020-03-15 11:06 PM
Sorry for reading your post late.
I'm going to do sensor testing as your advice.
Is it difficult to generate 1usec interrupt through setting the timer of stm32F103RC?
Here is the pseudo code from my project.
/********************************************************************/
void Timer_Configuration(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 72MHz/72 = 1MHz
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
TIM_TimeBaseStructure.TIM_Period = 1; // 1 usec
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_ClearITPendingBit(TIM1,TIM_FLAG_Update);
TIM_ITConfig(TIM1,TIM_FLAG_Update,ENABLE);
TIM_Cmd(TIM1, ENABLE);
}
void TIM1_UP_IRQHandler(void) { //1us
/* Clear the TIM1 Update pending bit */
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
if((++Timer1msec) > _TIMER_1MS) { //1000 times(_TIMER_1MS)
Timer1msec = _CLR;
BitTimer1mSec = _SET;
}
}
void TIM1_1ms(void) {
if(GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_6) == 1 )
GPIO_ResetBits(GPIOC, GPIO_Pin_6);
else
GPIO_SetBits(GPIOC, GPIO_Pin_6);
}
/********************************************************************/
I have read the reference manuals provided by st and the articles on the internet.
So I thought the timer's 1usec setting would be possible.
TIM1_1ms () in Main () is waiting for the BitTimer1mSec set.
It is set when an interrupt occurs 1000 times.
I measure the clock pulse using an oscilloscope generated by a pin.
If there is something wrong with my configuration, please let me know.
2020-03-16 12:26 AM
Cortex-M3 TRM (for example, revision 'I') states that the interrupt latency on entry is 12 cycles and the latency on exit is also 12 cycles. This is a typographical error in the Cortex-M3 TRM. The Cortex-M3 has a latency on exit of ten cycles, just like the Cortex-M4.
In a 1 us your CPU has 72 clock cycles. Interrupt enter+exit takes at least 12+10 of them. Processing code in interrupt and waiting on memory accesses also takes at least few tenths of cycles. The result is that your CPU is fully loaded while waiting and probably even losing some interrupts and extending the delay by same number of microseconds. That is totally useless because you can do the same by simple polling of CNT register and it's even better, because will not lose microseconds. With smart coding it can be done even on polling SysTick in parallel to running typical system ticks.
2020-03-16 02:12 AM
Also note that these numbers are for the best case, when both the interrupt handler and the vector table are in 0 wait state memory. STM32F1 flash should have 2 wait states at 72 MHz.