2021-04-07 05:14 AM
Hello,
i try to implement a 40kHz frequency burst with my NULCEO STM32F411RE. Until now i toggle the GPIO continuously in the HAL_TIM_PWM_PulseFinishedCallback function. But now i have to implement a start Trigger to do a small 40kHz burst. In the attached picture where you can see the yellow start trigger which should start my burst signal. To be flexible with the amplitude, i used the external DAC MCP4921. But as you can see (green signal), sometimes the code is executed faster, which generates a phaseshift. Thats why i want to implement this burst with an GPIO, but i will lose the functionallity of an flexible amplitude. I tried to use the Status Register UIF bit (Update interrupt flag) , which generates an impluse when the counter has overflown. but the result is not 40kHz (scope_4 blue signal). I changed the prescaler of my timer but nothing changed. I guess i have to use a different method.
void PM(void)
{
GPIOA->BSRR = (1<<24);;
for(int p=0;p<=40;p++)
{
if(TIM2->SR & 0x01)
GPIOA->ODR ^= (1<<8); //Toggle output GPIOA PA8
}
GPIOA->BSRR = (1<<24);
}
This is the function right after i read the yellow trigger Signal with
if(HAL_GPIO_ReadPin(I_Trigger_GPIO_Port, I_Trigger_Pin)== GPIO_PIN_SET)
How i could use the 40kHz of TIM2 to toggle my GPIO
2021-04-07 05:28 AM
Use the search function! :face_with_tears_of_joy:
40KHz timer for manually toggling the IO is very inefficient.
2021-04-07 06:16 AM
Okay, the example looks good. But i need in the middle of the Burst a phaseshift like "0 1 0 1 0 1 1 0 1 0 1 0"
2021-04-07 06:56 AM
Then be more detailed in your questions.
For example, how long is the burst?
How many pulses?
Toggling an output at a fixed frequency is very easy, but changing it to random values is a very different thing.
40KHz is too slow, leaves out SPI and I2S interfaces.
I2C and UART have start bits, so neither.
I think the only option is PWM. Or refining your code.
Using DMA+PWM burst mode (described in the link provided) should work.
The only difference is that in the example I used fixed DMA memory address, it doesn't increase.
It's easy as going into the Cube Ide settings and ticking the memory address increase.
And setting the correct transfer size of the buffer in the DMA call.
For example, MCU running at 96MHZ, the divider for 40KHz is 2400.
Prescaler= 0, period=2399.
The bad part is that it will take 16 bits for each bit:
Send "1" = set PWM to 2399
Send "0 = set PWM to 0
If you want to send "0 1 0 1 0 1 1 0 1 0 1 0" it would be:
uint16_t PulseBits[12] = {
0, // 0
2400, // 1
0, // 0
2400, // 1
0, // 0
2400, // 1
2400, // 1
0, // 0
2400, // 1
0, // 0
2400, // 1
0, // 0
};
// Send 12 pulses. You must stop it when the interrupt triggers, the PWM won't stop itself.
HAL_TIM_DMABurst_MultiWriteStart(&htim4, TIM_DMABASE_CCR1, TIM_DMA_UPDATE, (uint32_t*)&PulseBits, TIM_DMABURSTLENGTH_1TRANSFER, 12);
I set 2400 because that way it's higher than the PWM max, you'll ensure the PWM output stays high until the end.
2021-04-07 07:35 AM
> Set the SPI frequency to 40KHz
This may be tricky, the SPI baudrate generator is notoriously limiting; but the same interface in I2S setting may have more degrees of freedom in frequency setting, thanks to a dedicated PLL.
Could be pulled out using timers, but not in a simple manner.
JW
2021-04-07 07:43 AM
Yes, I know, I quickly noticed and edited it! You replied while I was editing... :beaming_face_with_smiling_eyes:
SPI has simple dividers like /2 / 4 /8 /16.... not ok.
And i2S has a PLL but won't go that slow.
2021-04-07 08:29 AM
@Walter Nazarenus maybe this helps you?
https://www.hackster.io/javier-munoz-saez/face-your-neopixels-baremetally-yeea-stm32-b6b4d0
Pwm+DMA i develop a neopixel controller but can be tweaked for your needs
2021-04-07 12:28 PM
> And i2S has a PLL but won't go that slow.
The minimum PLLI2S VCO output frequency is 100MHz, maximum RCC_PLLI2SCFGR.PLLR=7, SPI_I2SPR.I2SDIV is 8 bit i.e. max. is 255.
If MCKOE=0, bit (BCK) frequency is I2SxCLK/((2*I2SDIV)+ODD) so the minimum is 100MHz/7/(2*255+1) = 27.96kHz.
If MCKOE=0 and 16-bit transfer is used, bit frequency is I2SxCLK/(((2*I2SDIV)+ODD)*8) so the minimum is 27.96kHz/8=3.495kHz
JW
2021-04-08 01:04 AM