cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 is not fast enough

parisa
Senior

Hello,

Here is my code,

#include <stdio.h>
#include <string.h>
 
 
void GPIOSYS(void){
		GPIO_InitTypeDef GPIOSt;
	
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
		//GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
		GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
		GPIOSt.GPIO_Mode=GPIO_Mode_Out_PP;
		GPIOSt.GPIO_Pin=GPIO_Pin_7|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_0|GPIO_Pin_1;
		GPIOSt.GPIO_Speed=GPIO_Speed_50MHz;
		GPIO_Init(GPIOB,&GPIOSt);	
	
	
	
		GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
		GPIOSt.GPIO_Mode=GPIO_Mode_Out_PP;
		GPIOSt.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3;
		GPIOSt.GPIO_Speed=GPIO_Speed_50MHz;
		GPIO_Init(GPIOA,&GPIOSt);	
	
}
 
void CLOCK(void){
	RCC_HSEConfig(RCC_HSE_ON);
	while(RCC_WaitForHSEStartUp()==ERROR);
	
	RCC_PLLConfig(RCC_PLLSource_HSE_Div1,9);
	RCC_PLLCmd(ENABLE);
	
	while(RCC_GetFlagStatus( RCC_FLAG_PLLRDY)!=SET);
	
	RCC_ClockSecuritySystemCmd(ENABLE);
	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
	RCC_HCLKConfig(RCC_SYSCLK_Div1);
	
	while (RCC_GetSYSCLKSource() != 0x08);
	
}
 
void Delay(){
	int i,j;
	for(i=0;i<10000;i++)
	for(j=0;j<250;j++);
}
 
int main(void){
	CLOCK();
	GPIOSYS();
	
	while(1){
			GPIO_ResetBits(GPIOB,GPIO_Pin_6);
			GPIO_ResetBits(GPIOB,GPIO_Pin_7);
		
			GPIO_ResetBits(GPIOA,GPIO_Pin_2);
			GPIO_ResetBits(GPIOA,GPIO_Pin_3);
		
			//Delay();		
			GPIO_SetBits(GPIOB,GPIO_Pin_6);
			GPIO_SetBits(GPIOB,GPIO_Pin_7);			
		
			GPIO_SetBits(GPIOA,GPIO_Pin_2);
			GPIO_SetBits(GPIOA,GPIO_Pin_3);
			//Delay();
	}
	
}
 

I see a 500Khz pulse train on my oscilloscope which is below my expectations( for a 72Mhz MCU). Did I make a mistake or it is usual?

Thanks

14 REPLIES 14
Ozone
Lead

> while(1){

> GPIO_ResetBits(GPIOB,GPIO_Pin_6);

> GPIO_ResetBits(GPIOB,GPIO_Pin_7);

>

> GPIO_ResetBits(GPIOA,GPIO_Pin_2);

> GPIO_ResetBits(GPIOA,GPIO_Pin_3);

>

> //Delay();

> GPIO_SetBits(GPIOB,GPIO_Pin_6);

> GPIO_SetBits(GPIOB,GPIO_Pin_7);

>

> GPIO_SetBits(GPIOA,GPIO_Pin_2);

> GPIO_SetBits(GPIOA,GPIO_Pin_3);

> //Delay();

> }

What do you want to achieve with that ???

Use a timer, and set it up for PWM.

Honestly, all Cortex M have semi-autonomous peripherals, the 8051/PIC18 busy-looping-pin-toggle code is not a use case they are designed for.

> I see a 500Khz pulse train on my oscilloscope which is below my expectations( for a 72Mhz MCU)

Peripheral clock is not core clock. Read the datasheet/reference manual.

Enable full compiler optimization, or code in assembler.

parisa
Senior

Thank you so much for your comment.

I need to do bit-bang in order to send/receive bits from another source(Speed 1Mhz up to 2Mhz). I tried to do it with a timer but for 1us delay timers are not a good choice. By using a PWM source, I can't count the input/output bits correctly. what do you suggest?

What's the protocol? A USART might help. Or SPI. And what's the necessary speed?

If it's a more-complicated but bursty protocol, you can use DMA driven off a timer either to read a GPIO IDR or write to a GPIO BSRR. ST have given examples for emulating a UART on GPIO pins. You then just use your processor to set up or analyse what the DMA handles.

Hope this helps,

Danish

berendi
Principal

What kind of protocol is that? It might be possible to trick SPI into receiving, or use a timer DMA channel to read from GPIO.

parisa
Senior

I really thank you for your comment and help.

I send data(20bits) bit by bit (MSB first) (such as a pulse train). In receiver (my stm32f103) I need to read them correctly(such as SPI I send clock and then read input bits). My problems by using the popular protocol are

1)For using USART/UART, data is between start and stop bits and is divided into 8-16 bits which interruptions for start/stop bits and also this separation is not acceptable in my transmission.

2)For SPI, data is divided into one or two bytes and between each bytes we have another delay(another interruption). Clock stay at a specific value for small amount of time.

So, in this transmission, I need to send a clock for reading each bit each 1us. A 1us timer paralyzed the CPU. DMA is a good way if it can do this scenario.

> 2)For SPI, data is divided into one or two bytes and between each bytes we have another delay(another interruption). Clock stay at a specific value for small amount of time.

Most STM32 devices do not allow SPI transfer sizes which are not multiples of 8 (8, 16, 24).

Short of looking at other Cortex M families (outside the ST world ;-O) ), you might consider external hardware (standard logic / shift registers).

parisa
Senior

Thank you for your comment.

I need to implement this kind of shift register under STM32 because I think that STM32 are a good choice to have this communication and also do some other functions

Piranha
Chief II

20 bits without pauses can be sent and received with SAI peripheral, which is present on F4, L4, G4 and higher series. 🙂

The F103 is a relatively old M3 core.

You migth check newer STM32s, they use to have more flexible peripherals, perhaps you find one that can be tailored for your protocol (supposedly similar to SPI or I2S). More core performance included.

I lost track of the very latest cores, I stick to those one supported by the abandoned SPL lib, and ignore the ... Cube stuff.

> ...because I think that STM32 are a good choice to have this communication and also do some other functions

You can't really say unless you know alternatives.

My company uses whatever MCU is convenient for the purpose.

So do I for my private projects.