cancel
Showing results for 
Search instead for 
Did you mean: 

APB1 prescaler issue STM32F3DISCOVERY

andreaspiezia9
Associate III
Posted on January 11, 2016 at 08:25

Hi all,

I've some problem with APB1, APB low speed prescaler setting. File stm32f30x.h of STM32F3-Discovery_FW_V1.1.0\Libraries, reports the below PPRE1 meaningin according with DM00043574 pg. 142:

#define RCC_CFGR_PPRE1_DIV1 ((uint32_t)0x00000000) /*!< HCLK not divided */
#define RCC_CFGR_PPRE1_DIV2 ((uint32_t)0x00000400) /*!< HCLK divided by 2 */
#define RCC_CFGR_PPRE1_DIV4 ((uint32_t)0x00000500) /*!< HCLK divided by 4 */
#define RCC_CFGR_PPRE1_DIV8 ((uint32_t)0x00000600) /*!< HCLK divided by 8 */
#define RCC_CFGR_PPRE1_DIV16 ((uint32_t)0x00000700) /*!< HCLK divided by 16 */

I've tried to set all the PPRE1 values in SetSysClock() and measured with my scope, and I see that: RCC_CFGR_PPRE1_DIV1 HCLK not divided RCC_CFGR_PPRE1_DIV2 HCLK not divided RCC_CFGR_PPRE1_DIV4 HCLK divided by 2 RCC_CFGR_PPRE1_DIV8 HCLK divided by 4 RCC_CFGR_PPRE1_DIV16 HCLK divided by 8 Have you aver seen the same behavior? #setsysclock #stm32-mco-clock-output
9 REPLIES 9
Radosław
Senior
Posted on January 11, 2016 at 10:40

How your measurment look?

Probably you are doing something wrong.

andreaspiezia9
Associate III
Posted on January 11, 2016 at 13:27

I'll post the code ASAP.

andreaspiezia9
Associate III
Posted on January 12, 2016 at 08:32

Here below the code, thanks for helping:

#include ''stm32f30x.h''
#include ''main.h''
void
RCC_Configuration(
void
)
{
RCC_ClockSecuritySystemCmd(ENABLE);
/* Enable GPIO clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); 
//see DM00068049 pg. 235
/* Enable MCO */
RCC_MCOConfig(RCC_MCOSource_SYSCLK);
}
/**************************************************************************************/
void
GPIO_Configuration(
void
)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_DeInit(GPIOA); 
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_0); 
// MCO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
int
main(
void
)
{
/* TIM3_CLK = PCLK1 (APB1_PRESC = 1) = 8Mhz //it seems that APB1_PRESC: any value assigned to RCC_PPRE1 as the same effect of RCC_PPRE1 = RCC_CFGR_PPRE1_DIV1 (no div) 
PCLK1 = SYSCLK/1 (AHB_PRESC = 0) = 8Mhz
SYSCLK = PLLCLK = 8Mhz
PLLCLK = PLL_IN * 2 = 8Mhz
PLL_IN = HSE/2 = 4MHz (RCC_CFGR_PLLXTPRE_PREDIV1_Div2 clock divided by 2 for PLL entry)
HSE = 8Mhz USE CLOCK FROM MCO OF ST-LINK*/
RCC_Configuration();
GPIO_Configuration();
while
(1){
}
}

static
void
SetSysClock(
void
)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/* HSE oscillator bypassed with external clock */
RCC->CR |= (uint32_t)(RCC_CR_HSEON | RCC_CR_HSEBYP);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++; 
} 
while
((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if
((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
} 
if
(HSEStatus == (uint32_t)0x01)
{
/* Enable Prefetch Buffer and set Flash Latency */
FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_1;
/* HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV4;
/* PLL configuration: PLLCLK = HSE * RCC_CFGR_PLLMULLx */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL2); 
/* Enable PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till PLL is ready */
while
((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; 
/* Wait till PLL is used as system clock source */
while
((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
{
}
}
else
{ 
/* If HSE fails to start-up, the application will have wrong clock 
configuration. User can add here some code to deal with this error */
} 
}

Radosław
Senior
Posted on January 12, 2016 at 08:54

This code is abstraction to your problem.

 

How you measure APB clock? By MCO is imposible.
andreaspiezia9
Associate III
Posted on January 12, 2016 at 10:24

Thanks, You are rigth! I've simplified the code. I measure the PWM period of TIM3, and I see the same period with:

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;

or 

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

but I see double period with

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV4;

quadruple with

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV8;

Radosław
Senior
Posted on January 12, 2016 at 11:04

Look to RM on picture with RCC structure.

If APB presc > 1 then TIM clk is multiply by 2.
andreaspiezia9
Associate III
Posted on January 12, 2016 at 11:32

Here below the picture from DM00058181 pg 18:

as you said ''if (APB1 presc. = 1) x1 else x2. but this is in contrast with what I see:

APB1 presc = 1 or APB1 presc = 2 , TIM3_CLK is the same!

if APB1 presc = 4, TIM3_CLK double

0690X00000603MJQAY.jpg

Any way if you see RM0316 pg 142 it says different. What I'm doing wrong?

0690X00000603M4QAI.jpg

Radosław
Senior
Posted on January 12, 2016 at 11:49

Consider AHB clk = 16Mhz

APB2_div = 1 -> TIM CLK = 16MHz

APB2_div = 2 -> TIM CLK = 16MHz

APB2_div = 4 -> TIM CLK = 8MHz

APB2_div = 8 -> TIM CLK = 4MHz.
andreaspiezia9
Associate III
Posted on January 12, 2016 at 13:21

Thanks dembek, now it's clear!

 

Consider AHB clk = 16Mhz

APB1_div = 1 -> TIM CLK = (AHB/1)x1 = 16MHz

APB1_div = 2 -> TIM CLK = (AHB/2)x2 = 16MHz

APB1_div = 4 -> TIM CLK = (AHB/4)x2 = 8MHz

APB1_div = 8 -> TIM CLK = (AHB/8)x2 =  4MHz.