air32f103-template icon indicating copy to clipboard operation
air32f103-template copied to clipboard

Changing the system clock

Open mabartibin opened this issue 2 years ago • 4 comments

While setting the system clock with #define SYSCLK_HSE HSE(200) is just fine usually, I wonder how I can change the frequency later. I’ve tried the code over here, i.e. copied void RCC_ClkConfiguration(void) and call it at the beginning of main(), but that doesn’t work.

Any ideas?

mabartibin avatar Apr 23 '23 20:04 mabartibin

You can use AIR_RCC_PLLConfig() to change the system clock in the code. I just added a demo.

There is a problem in the demo that PLL >=17 will enable the fast PLL, then the system clock will be always above 136MHz. I didn't figure out how to turn the fast PLL off.

IOsetting avatar Apr 24 '23 17:04 IOsetting

Thanks for the example, works!

There’s another weirdness, apart from the the fast PLL: if I start out with 200MHz in the _conf file, upon reaching 256MHz, it sometimes does what it should, sometimes halts, sometimes resets itself. I have not had problems when starting from 72MHz. No problems either if I stop at a lower frequency like 240MHz.

mabartibin avatar Apr 25 '23 06:04 mabartibin

I just did some tests on both AIR32F103CBT6 and AIR32F103CCT6, but I cannot reproduce the halts and resets. Are there any additional configurations in your code?

The code I am using is

air32f10x_conf.h

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __AIR32F10x_CONF_H
#define __AIR32F10x_CONF_H

/* Set system clock speed in MHZ
*  It will revert to HSI mode if not defined.
*  Otherwise, will calculate the PLL multiplier (SYSCLK / HSE_VAL).
*  If the multiplier is 1, then the PLL won't be used.
*/
#define SYSCLK_HSE      HSE(200)

/* Includes ------------------------------------------------------------------*/
/* Uncomment/Comment the line below to enable/disable peripheral header file inclusion */
#include "air32f10x_adc.h"
#include "air32f10x_bkp.h"
#include "air32f10x_can.h"
#include "air32f10x_cec.h"
#include "air32f10x_crc.h"
#include "air32f10x_dac.h"
#include "air32f10x_dbgmcu.h"
#include "air32f10x_dma.h"
#include "air32f10x_exti.h"
#include "air32f10x_flash.h"
#include "air32f10x_fsmc.h"
#include "air32f10x_gpio.h"
#include "air32f10x_i2c.h"
#include "air32f10x_iwdg.h"
#include "air32f10x_pwr.h"
#include "air32f10x_rcc.h"
#include "air32f10x_rtc.h"
#include "air32f10x_sdio.h"
#include "air32f10x_spi.h"
#include "air32f10x_tim.h"
#include "air32f10x_usart.h"
#include "air32f10x_wwdg.h"
#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Uncomment the line below to expanse the "assert_param" macro in the 
   Standard Peripheral Library drivers code */
/* #define USE_FULL_ASSERT    1 */

/* Exported macro ------------------------------------------------------------*/
#ifdef  USE_FULL_ASSERT

/**
  * @brief  The assert_param macro is used for function's parameters check.
  * @param  expr: If expr is false, it calls assert_failed function which reports 
  *         the name of the source file and the source line number of the call 
  *         that failed. If expr is true, it returns no value.
  * @retval None
  */
  #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
  void assert_failed(uint8_t* file, uint32_t line);
#else
  #define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */

#endif /* __AIR32F10x_CONF_H */

main.c

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "air32f10x.h"
#include "debug.h"

void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    // PC13
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}

/**
 * Change system clock
*/
void RCC_ClkConfiguration(uint32_t RCC_PLLMul)
{
    RCC_DeInit();
    RCC_HSEConfig(RCC_HSE_ON);
    while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);

    RCC_PLLCmd(DISABLE);
    AIR_RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul, 1);
    RCC_PLLCmd(ENABLE);
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    RCC_HCLKConfig(RCC_SYSCLK_Div1);
    RCC_PCLK1Config(RCC_HCLK_Div2);
    RCC_PCLK2Config(RCC_HCLK_Div1);
    SystemCoreClockUpdate();
}

int main(void)
{
    RCC_ClocksTypeDef clocks;
    Delay_Init();
    RCC_GetClocksFreq(&clocks);
    GPIO_Configuration();

    USART_Printf_Init(115200);
    printf("\nSYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhz\n",
           (float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000,
           (float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, 
		   (float)clocks.ADCCLK_Frequency / 1000000);
    printf("AIR32F103 Clock Config Test\n");
    Delay_Ms(1000);
    printf("SystemClk:%ld\r\n", SystemCoreClock);
    Delay_Ms(1000);

    printf("SystemClk: switch to 256MHz\n");
    RCC_ClkConfiguration(RCC_PLLMul_32);
    Delay_Init();
    USART_Cmd(USART1, DISABLE);
    USART_Printf_Init(115200);
    printf("SystemClk:%ld\r\n", SystemCoreClock);
    Delay_Ms(500);
    printf("SystemClk:%ld\r\n", SystemCoreClock);
    Delay_Ms(500);

    while (1)
    {
        printf("SystemClk:%ld\r\n", SystemCoreClock);
        GPIO_SetBits(GPIOC, GPIO_Pin_13);
        Delay_Ms(500);
        GPIO_ResetBits(GPIOC, GPIO_Pin_13);
        Delay_Ms(500);
    }
}

IOsetting avatar Apr 30 '23 15:04 IOsetting

I think I the only bit I changed from your demo code was to toggle PB10 instead of PC13. I can check tonight or tomorrow and see if I can reproduce it.

Anyway, 256MHz is far beyond what little specs there are. We can’t really expect it to work 100% with all specimens.

mabartibin avatar May 02 '23 08:05 mabartibin