Timer for generating 1us tick
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-07-20 05:03 AM
I'm using STM32F108RG on 48MHz clock configuration.
I need to generate a 1 micrososeconds timer tick on it, for driving an output pin interfaced with a 3rd party device. Using PWM is not an option available.
I tried configuring TIM3 with following parameters:
Clock: Internal (48MHz)
Prescaler: 47 (48 - 1)
Counter Mode: Up
Counter Period (Auto-Reload Register -16 bit): 1
Internal Clock Division: No Division
Auto-reload preload: Disabled
With these settings, the closest I can reach is 6.8us.
I was able to generate 10us with the above settings with Counter Period set to 10,
but it doesn't seem to go below 6.8us.
I also tried TIM1 for the same purpose, but got the same observations.
Is that a limitation of the device, or do I need to perform any additional steps?
- Labels:
-
STM32F1 Series
-
TIM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-07-20 05:10 AM
Don't interrupt at these speeds you will saturate the processor.
​
Have a TIM count at 1 MHz, and spin on TIM->CNT advancing a required amount.
​
Consider also DWT_CYCCNT​
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-07-20 06:12 AM
You could use SPI with a 1MHz clock to output an arbitrary signal. Calling an interrupt at 1MHz isn't going to pan out well. It'll take more than 48 ticks for the ISR to complete.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-07-20 08:08 AM
Thanks for the response, clive1
I'm a complete noob on STM32 platform (otherwise wouldn't have had posted such queries)
So what exactly do you mean by "spin on TIM->CNT"?
Also, what is 'DWT_CYCCNT'?
I gave it a search in the HAL library thinking that it's some sort of peripheral register,
but couldn't find it.
Apologies for asking for more help on this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-07-20 08:09 AM
That would have been a great idea.
Thanks for the response, TDK; but I don't think I have enough SPI peripherals left on my application.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-07-20 08:47 AM
If terms are unfamiliar stick them into Google or the search here, should be preexisting examples and postings.
With TIM3, prescale 47, period 0xFFFF (maximal)
void delay_us(uint16_t us)
{
uint16_t start = TIM3->CNT;
while((TIM3->CNT - start) < us) {};
}
For finer granularity, let the TIM clock faster, use a 32-bit TIM where available
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-07-20 08:54 AM
//****************************************************************************
volatile unsigned int *DWT_CYCCNT = (volatile unsigned int *)0xE0001004; //address of the register
volatile unsigned int *DWT_CONTROL = (volatile unsigned int *)0xE0001000; //address of the register
volatile unsigned int *DWT_LAR = (volatile unsigned int *)0xE0001FB0; //address of the register
volatile unsigned int *SCB_DEMCR = (volatile unsigned int *)0xE000EDFC; //address of the register
//****************************************************************************
void EnableTiming(void)
{
*SCB_DEMCR |= 0x01000000;
*DWT_LAR = 0xC5ACCE55; // enable access (required on Cortex-M7)
*DWT_CYCCNT = 0; // reset the counter
*DWT_CONTROL |= 1 ; // enable the counter
}
//****************************************************************************
void Delay(uint32_t cycles) // Based on SystemCoreClock, at 48 MHz, 48 cycles is 1us, 48000 cycles is 1ms
{
uint32_t start = *DWT_CYCCNT;
while((*DWT_CYCCNT - start) < cycles);
} // sourcer32@gmail.com
//****************************************************************************
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-07-20 09:08 AM
interrupts at 10kHz or higher is the symptom of danger. use hw assist as much as possible. if you have a spare timer pin channel or spi mosi, short it with the one you want to send a pulse pattern by dma if needed. no spare pin? new board design?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-07-20 09:56 AM
Indeed modulating patterns with fixed timing requirements can be done with TIM+DMA+GPIO more effectively than using timing loops eating all processor resources.
Consider also logic or CPLDs for hardware orientated problems.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-07-20 09:57 AM
With hard software timing loops you're going to run out of bandwidth for your application pretty quickly
Up vote any posts that you find helpful, it shows what's working..
