Estaba haciendo la configuración PLL para ejecutar mi STM32F103RCT6 a 72MHz. Estoy usando la biblioteca CMSIS y, por lo tanto, tomé la ayuda de la biblioteca periférica estándar para escribir este código. Tengo algunas dudas que me gustaría obtener en el formulario de respuesta.
Primero que todo mi código.
/* Project: PLL Configuration (72 MHz)
* Author : Devjeet Mandal
* Date : 13/2/2018 20:27
*
*/
#include "stm32f10x.h"
#define HPRE_RESET_MASK ((uint32_t)0xFFFFFF0F)
#define PPRE2_RESET_MASK ((uint32_t)0xFFFFC7FF)
#define PPRE1_RESET_MASK ((uint32_t)0xFFFFF8FF)
#define PLLCLK_CONFIG_RESET_MASK ((uint32_t)0xFFC0FFFF)
#define SW_RESET_MASK ((uint32_t)0xFFFFFFFC)
#define LED_PORT_EN() ( RCC->APB2ENR |= RCC_APB2ENR_IOPDEN )
#define LED_PORT GPIOD
#define LED_MODE_BIT1 8
#define LED_MODE_BIT2 9
#define LED_CNF_BIT1 10
#define LED_CNF_BIT2 11
#define CNF_SET_PORTD(BIT1,BIT2) ( LED_PORT->CRL &= ~((1<<BIT1) | (1<<BIT2)) ) //General purpose output push-pull
#define MODE_SET_PORTD(BIT1,BIT2) ( LED_PORT->CRL |= (1<<BIT1) | (1<<BIT2) ) //Output mode, max speed 50 MHz.
#define SET_GPIO_BIT_PORTD(BIT) ( LED_PORT->BSRR = (1 << BIT) ) //For setting the Bit
#define RESET_GPIO_BIT_PORTD(BIT) ( LED_PORT->BSRR = ( (1 << BIT) << 16 ) ) //For Resseting Bit
void PLL_Config(void);
void Clock_Reset(void);
void HCLK_Config(uint32_t RCC_SYSCLK);
void PCLK2_Config(uint32_t RCC_HCLK);
void PCLK1_Config(uint32_t RCC_HCLK);
void PLLCLK_Config(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul);
void SYSCLK_Config(uint32_t RCC_SYSCLKSource);
void Delay(int ms);
void Led_Init(void);
void Blink_Led(int ms);
int main(void)
{
PLL_Config();
Led_Init();
while(1)
{
Blink_Led(1000);
}
}
/** @breif: For wait and doing nothing i.e for delay
* @param: delaya time
* @retVal: None
*/
void Delay(int ms)
{
int i,j;
for (i = 0; i < ms; ++i) {
for (j = 0; j < 1000; ++j);
}
}
/** @breif: Initalize GPIO For Led
* @param: None
* @retVal: None
*/
void Led_Init()
{
LED_PORT_EN(); //Enable RCC for Led Port
CNF_SET_PORTD(LED_CNF_BIT1,LED_CNF_BIT2); //SET CNF General purpose output push-pull
MODE_SET_PORTD(LED_MODE_BIT1,LED_MODE_BIT2); //SET MODE Output mode, max speed 50 MHz.
}
/** @breif: Blink Led Placed in PORT D Pin 2
* @param: Delay for each state(ON/OFF)
* @retVal: None
*/
void Blink_Led(int ms)
{
RESET_GPIO_BIT_PORTD(2); //Make Led High
Delay(ms); //wait
SET_GPIO_BIT_PORTD(2); //Make Led Low
Delay(ms); //wait
}
/** @breif: Configure PLL 72 MHz
* @param: None
* @retVal: None
*/
void PLL_Config(void)
{
Clock_Reset(); //RESET Clock
RCC->CR |= RCC_CR_HSEON; //ENABLE HSE
/* wait till HSE Ready */
while ( !( RCC->CR & RCC_CR_HSERDY ));
/* Doubt: Enable Prefetch Buffer */
/* Doubt: Flash 2 wait state */
HCLK_Config(RCC_CFGR_HPRE_DIV1); //configure HCLK AHB clock
PCLK2_Config(RCC_CFGR_PPRE2_DIV1); //cofigure PCLK2 APB2 clock
PCLK1_Config(RCC_CFGR_PPRE1_DIV2); //configure PCLK1 APB1 clock
PLLCLK_Config(RCC_CFGR_PLLSRC, RCC_CFGR_PLLMULL9); //configure PLLCLK 72MHz
RCC->CR |= RCC_CR_PLLON; //ENABLE PLL
/* Wait till PLL is Ready */
while (!(RCC->CR & RCC_CR_PLLRDY));
SYSCLK_Config(RCC_CFGR_SW_PLL);
/* wait till PLL is used as system clock */
while (!(RCC->CFGR & RCC_CFGR_SWS_PLL));
}
/** @breif: Select PLL as system clock source
* @param: RCC_CFGR_SW_PLL = ((uint32_t)0x00000002)
* @retVal: None
*/
void SYSCLK_Config(uint32_t RCC_SYSCLKSource)
{
uint32_t tmpreg = 0;
tmpreg = RCC->CFGR;
/* Clear SW[1:0] bits */
tmpreg &= SW_RESET_MASK;
/* Set SW[1:0] bits according to RCC_SYSCLKSource value */
tmpreg |= RCC_SYSCLKSource;
/* Store the new value */
RCC->CFGR = tmpreg;
}
/** @breif: Set PCLK1 = HCLK/2
* HCLK divided by 2
* @param: RCC_CFGR_PLLSRC = ((uint32_t)0x00010000)
* @param: RCC_CFGR_PLLMULL9 = ((uint32_t)0x001C0000)
* @retVal: None
*/
void PLLCLK_Config(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul)
{
uint32_t tmpreg = 0;
tmpreg = RCC->CFGR;
/* Clear PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */
tmpreg &= PLLCLK_CONFIG_RESET_MASK;
/* Set the PLL configuration bits */
tmpreg |= RCC_PLLSource | RCC_PLLMul;
/* Store the new value */
RCC->CFGR = tmpreg;
}
/** @breif: Set PCLK1 = HCLK/2
* HCLK divided by 2
* @param: RCC_CFGR_PPRE1_DIV2 = ((uint32_t)0x00000400)
* @retVal: None
*/
void PCLK1_Config(uint32_t RCC_HCLK)
{
uint32_t tmpreg = 0;
tmpreg = RCC->CFGR;
/* Clear PPRE1[2:0] bits */
tmpreg &= PPRE1_RESET_MASK;
/* Set PPRE1[2:0] bits according to RCC_HCLK value */
tmpreg |= RCC_HCLK;
/* Store the new value */
RCC->CFGR = tmpreg;
}
/** @breif: Set PCLK2 = HCLK
* HCLK not divided
* @param: RCC_CFGR_PPRE2_DIV1 = ((uint32_t)0x00000000)
* @retVal: None
*/
void PCLK2_Config(uint32_t RCC_HCLK)
{
uint32_t tmpreg = 0;
tmpreg = RCC->CFGR;
/* Clear PPRE2[2:0] bits */
tmpreg &= PPRE2_RESET_MASK;
/* Set PPRE2[2:0] bits according to RCC_HCLK value */
tmpreg |= RCC_HCLK;
/* Store the new value */
RCC->CFGR = tmpreg;
}
/** @breif: Set HCLK = SYSCLK
* SYSCLK not divided
* @param: RCC_CFGR_HPRE_DIV1 = ((uint32_t)0x00000000)
* @retVal: None
*/
void HCLK_Config(uint32_t RCC_SYSCLK)
{
uint32_t tmpreg = 0;
tmpreg = RCC->CFGR;
/* Clear HPRE[3:0] bits */
tmpreg &= HPRE_RESET_MASK;
/* Set HPRE[3:0] bits according to RCC_SYSCLK value */
tmpreg |= RCC_SYSCLK;
/* Store the new value */
RCC->CFGR = tmpreg;
}
/** @breif: Resets the Clock
* @param: None
* @retVal: None
*/
void Clock_Reset(void)
{
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
RCC->CFGR &= (uint32_t)0xF0FF0000;
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF;
/* Reset HSEBYP bit */
RCC->CR &= (uint32_t)0xFFFBFFFF;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &= (uint32_t)0xFF80FFFF;
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000;
}
Dudas:
-
Al configurar el PLL, vi que había dos líneas "Habilitar búfer de captación previa" y "Estado de espera de Flash 2" que estaba allí en la biblioteca de periféricos estándar. ¿Qué significa esta línea y por qué necesito hacer esto? ¿Cómo afectarán estas líneas a mi configuración de PLL?
-
Si no configuro el PLL, mi sistema funcionará en 8MHz, es decir, en el cristal provisto a bordo, ¿verdad?
-
Aquí parpadeo un LED después de configurar PLL. Pero mientras configuramos el LED, necesitamos configurar el MODO, que es "Modo de salida, velocidad máxima de 50 MHz". Según el manual del usuario. Entonces, ¿cómo está afectando mi configuración de PLL el parpadeo del LED? ¿Funciona mi Led a 72MHz o 50MHz?
-
¿Este código establece el reloj del sistema en 72MHz? ¿Hay alguna forma fácil de saber a qué frecuencia funciona mi sistema?
Haré Timers y USART después de esto y creo que para eso se requiere la configuración de PLL. Cualquier sugerencia será realmente útil.
Gracias de antemano