This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem with frequency on STM32F103C8T6

Hello!
Found a very strange problem with STM32F103C8T6. When executing this program, if you remove the CountDigit () function, then the delay function works correctly, i.e. Delay (1000) makes a delay of about 1 second. But if you execute the CountDigit () function, then after that the Delay (1000) function makes a delay of about 0.7 seconds.
In this function, by an exception method, I found that the line "while (x! = 0)" causes a failure in the delay function. I tried to replace it with the "if" and "for" commands, but this did not fix the problem.
In general, it is very likely that the frequency of the microcontroller is increasing. Because the transmission on the I2C bus ceases to work normally, you have to reduce the speed of the I2C bus, instead of ClockSpeed ​​= 100000, set it to about 70,000 then it starts to work properly.
I’ve been on different boards, the malfunction is always preserved.
I also tried to implement the delay procedure in different ways, removed the InitDelay () function, removed the CPU_CLK variable definition, set it to "#define CPU_CLK 72000000". I even used timers, but the problem did not resolve.
Can anyone tell me how to solve this problem and what is my mistake?

#include "stm32f10x.h"

#define DiagLED_GPIOx GPIOC
#define DiagLED_Pin_x GPIO_Pin_13
#define DiagLED_ON GPIO_ResetBits(DiagLED_GPIOx, DiagLED_Pin_x)
#define DiagLED_OFF GPIO_SetBits(DiagLED_GPIOx, DiagLED_Pin_x)

unsigned int CPU_CLK;

void InitDelay(void)
{
	RCC_ClocksTypeDef RCC_Clocks;
	
  RCC_GetClocksFreq(&RCC_Clocks);
	CPU_CLK=RCC_Clocks.HCLK_Frequency;
}
#pragma push
#pragma O0
void Delay(unsigned int ms)
{
volatile unsigned int i;
	i=(CPU_CLK/10000)*ms;
	for (; i!=0; i--);
}
#pragma pop

unsigned char CountDigit(signed int Number)
{
unsigned char result=0;
signed int x=Number;  

  while (x != 0) 
	{
    x /= 10;
    result++;
	}
	return(result);
}

void GPIO_InitPIN(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin_x, GPIOMode_TypeDef GPIO_Mode_x)
{
	GPIO_InitTypeDef GPIO_Init_ALL;
	
	if (GPIOx==((GPIO_TypeDef *) GPIOA_BASE)) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);}
	if (GPIOx==((GPIO_TypeDef *) GPIOB_BASE)) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);}
	if (GPIOx==((GPIO_TypeDef *) GPIOC_BASE)) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);}
	if (GPIOx==((GPIO_TypeDef *) GPIOD_BASE)) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);}
	
  GPIO_Init_ALL.GPIO_Mode = GPIO_Mode_x;							
  GPIO_Init_ALL.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init_ALL.GPIO_Pin = GPIO_Pin_x;
  GPIO_Init(GPIOx,&GPIO_Init_ALL);
}

void Init(void)
{
InitDelay();
GPIO_InitPIN(DiagLED_GPIOx, DiagLED_Pin_x ,GPIO_Mode_Out_PP);		// LED on board
DiagLED_OFF;
}

int main(void)
{
unsigned int ii=1000;

ii=CountDigit(ii);
Init();
while(1)
{
DiagLED_OFF;
Delay(1000);
DiagLED_ON;
Delay(1000);
}
}