cancel
Showing results for 
Search instead for 
Did you mean: 

Clock settings in STM32l152 (startup/stability issues)

fifi_22
Associate III

Hello.

I'm playing with my stm32l152 discovery board. I've got lcd, buttons, leds working. I wanted to change my clock speed to 16Mhz HSI (default 2Mhz MSI) and problem started.

To write my code I use RM - and I'm missing something. How this configuration should be done?

There is my clocks setting code: (If nedded I can upload whole project)

	RCC->CR |= (RCC_CR_HSION);					//enable high-speed internal oscillator
	while(!(RCC->CR & RCC_CR_HSIRDY));			//wait until oscillator starts
 
	RCC->CFGR |= RCC_CFGR_SW_HSI;				//set hsi as systemclk
	while((RCC->CR & RCC_CFGR_SWS_HSI)!= RCC_CFGR_SWS_HSI);
 
	RCC->CFGR |= (RCC_CFGR_MCOSEL_SYSCLK);		//set mco output to sysclk
 
	RCC->AHBENR |= (RCC_AHBENR_GPIOAEN);		//enable clock for PORTA peripheral
	RCC->AHBENR |= (RCC_AHBENR_GPIOBEN);		//enable clock for PORTB peripheral
	RCC->AHBENR |= (RCC_AHBENR_GPIOCEN);		//enable clock for PORTC peripheral

This is just after main(). Is this correct way to do it?

What actually happens:

After reset processor doesn't always start up (led doesn't blink). When it sometimes starts - the signal on MCO output is not present every time(2/10 times?) And moreover - the led sometimes flashes as on 2Mhz and sometimes as on 16Mhz clocks (somehow returning to default?) .

Any help really appreciated!

1 ACCEPTED SOLUTION

Accepted Solutions

Have you set RCC_APB1ENR.PWREN before changing PWR registers?

JW

View solution in original post

11 REPLIES 11

After reset, the power regulator is set to Range 2 (VCORE=1.5V), and that allows only 8MHz at the default 0 waitstate FLASH latency - see Relation between CPU clock frequency and Flash memory read time subchapter of FLASH chapter in RM, PWR_CR.VOS and the whole PWR chapter.

So either increase VCORE voltage, or increase FLASH latency.

JW

I tried what You say, but that didn't solved the problem. It does startup more times, but still not 100% Something else is wrong...

while((PWR->CSR & PWR_CSR_VOSF));			//poll for voltage stabilization
	PWR->CR |= PWR_CR_VOS_0;					//change vcore to 1.8
	while((PWR->CSR & PWR_CSR_VOSF));			//poll for voltage stabilization
 
	RCC->CR |= (RCC_CR_HSION);					//enable high-speed internal oscillator
	while(!(RCC->CR & RCC_CR_HSIRDY));			//wait until oscillator starts
 
	RCC->CFGR |= RCC_CFGR_SW_HSI;				//set hsi as systemclk
	while((RCC->CR & RCC_CFGR_SWS_HSI)!= RCC_CFGR_SWS_HSI);
 
	RCC->CFGR |= (RCC_CFGR_MCOSEL_SYSCLK);		//set mco output to sysclk
 
	RCC->AHBENR |= (RCC_AHBENR_GPIOAEN);		//enable clock for PORTA peripheral
	RCC->AHBENR |= (RCC_AHBENR_GPIOBEN);		//enable clock for PORTB peripheral
	RCC->AHBENR |= (RCC_AHBENR_GPIOCEN);		//enable clock for PORTC peripheral

TDK
Guru

> PWR->CR |= PWR_CR_VOS_0;

There are 2 bits that define this field. You're only changing one of them. The other defaults to 1, so you will need to clear it. You should read, modify and write this to avoid intermediate states.

If you feel a post has answered your question, please click "Accept as Solution".
fifi_22
Associate III

Stiupid me! Now those bits are set correctly, but this didn't help either.

while((PWR->CSR & PWR_CSR_VOSF));			//poll for voltage stabilization
	PWR->CR &= ~(PWR_CR_VOS);
	PWR->CR |= PWR_CR_VOS_0;					//change vcore to 1.8
	while((PWR->CSR & PWR_CSR_VOSF));			//poll for voltage stabilization

Here is the project, I will upload wideo of the issue in 1/2 of hour

There is the video: (when I use MSI clock source - everything is nice and stable)

TDK
Guru

> PWR->CR &= ~(PWR_CR_VOS);

What setting does it have directly after this line is executed? Step through and inspect the registers and you'll spot the problem. Read the description of this field in the reference manual.

If you feel a post has answered your question, please click "Accept as Solution".

> PWR->CR &= ~(PWR_CR_VOS);

This is exactly what TDK said you should not do - see RM, 0b00 is forbidden.

PWR->CR = (PWR->CR & ~(PWR_CR_VOS)) | PWR_CR_VOS_0;

JW

Oh! I saw this text, and didn't thought about it! Unforunetly still no change...

	while((PWR->CSR & PWR_CSR_VOSF));			//poll for voltage stabilization
	PWR->CR = (PWR->CR & ~(PWR_CR_VOS)) | PWR_CR_VOS_0;					//change vcore to 1.8
	while((PWR->CSR & PWR_CSR_VOSF));			//poll for voltage stabilization

When I do this (exactly the same I think)

	while((PWR->CSR & PWR_CSR_VOSF));			//poll for voltage stabilization
	PWR->CR |= (PWR_CR_VOS_1);
	PWR->CR |= (PWR_CR_VOS_0);
	PWR->CR &= ~(PWR_CR_VOS_1);
	while((PWR->CSR & PWR_CSR_VOSF));			//poll for voltage stabilization

I have got 9/10 startups, so better, but still might me somethig else.

Have you set RCC_APB1ENR.PWREN before changing PWR registers?

JW