cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F401 PLL from HSI

Stastny.Petr
Associate III
Posted on August 20, 2016 at 18:05

Hello,

I have a problem with PLL from HSI on STM32F401 (on Nucleo Board). I am not able to run PLL, if I read actual clock, it is always 16 MHz. The code without PLL set gives me always

System clock: 16 MHz, HCLK: 16 MHz, PCLK1: 16 MHz, PCLK2: 16 MHz

If I put PLL settings (as written bellow) USART output does not work at all or have a wrong baudrate. Can you help me what is wrong? Thank you

int
main(
void
)
{
RCC_ClocksTypeDef clocks;
RCC_DeInit();
RCC_HSICmd(ENABLE);
RCC_HCLKConfig(RCC_SYSCLK_Div1); 
/* HCLK = SYSCLK */
RCC_PCLK1Config(RCC_HCLK_Div2); 
/* PCLK1 = HCLK*/
RCC_PCLK2Config(RCC_HCLK_Div1); 
/* PCLK2 = HCLK*/
RCC_AdjustHSICalibrationValue(0x10);
RCC_PLLConfig(RCC_PLLSource_HSI, 16, 336, 4, 7);
RCC_PLLCmd(ENABLE);
// while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
SystemCoreClockUpdate();
COMInit();
RCC_GetClocksFreq(&clocks); 
printf(
''\nCLOCK READ:\n\r''
);
printf(
''System clock: %u MHz, HCLK: %u MHz, PCLK1: %u MHz, PCLK2: %u MHz\n''
, 
clocks.SYSCLK_Frequency/1000000, clocks.HCLK_Frequency/1000000, clocks.PCLK1_Frequency/1000000, clocks.PCLK2_Frequency/1000000);
while
(1)
{
}
}
void
COMInit(
void
)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); 
/* Configure USART Tx as alternate function */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect PXx to USARTx_Tx*/
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
/* Configure USART Rx as alternate function */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect PXx to USARTx_Rx*/
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
/* USART2 Config */
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* USART configuration */
USART_Init(USART2, &USART_InitStructure);
/* Enable USART */
USART_Cmd(USART2, ENABLE);
}
PUTCHAR_PROTOTYPE
{
while
(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); 
// Is it empty?
USART_SendData(USART2, (uint8_t) ch); 
// Ok, write it now
return
ch;
}

2 REPLIES 2
Posted on August 20, 2016 at 18:48

I don't use any of the ''libraries'' functions of which you might be calling: does any of them set the FLASH waitstates according to the changed system frequency?

JW

Posted on August 20, 2016 at 23:39

This stuff would normally be done in SystemInit() called prior to your main() function. Review the code in system_stm32f4xx.c to see how ST does this.

Specifically you'd need to make sure the PLL is not running before you attempt to change it, so an HSI or HSE must be clocking the system. You must wait for the PLL to lock, and you must also wait for the system clock to be selected. As Jan points out the wait states for the flash must be sufficient, and failure here would likely result in a Hard Fault.

If it is not working review the state of the RCC registers to understand what state it is in and why it might be in that state.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..