HSE的时钟操作
汇编语言,用分号注释;__main,C库函数 ,
HSE:外部时钟
HSI:内部时钟,当HSE故障时使用
PLLCLK锁相环:将低速时钟倍频成高
如何控制HSE
- 首先---打开启动文件(startup_stm32f40xx.s)
- 然后复制(system_stm32f4xx.c)文件里面的函数static void SetSysClock(void)
- 修改函数static void SetSysClock(void)把多余的芯片控制函数全部给删除,只留对应芯片的时钟设置
- (然后正常流程)声明函数
- 在主函数调用函数
- (如果不取消(startup_stm32f40xx.s)的时钟启动函数,需要加一句初始化时钟端口)(复位RCC的所有寄存器 RCC_DeInit(); )
下面是用汇编语言写的启动文件的顺序,先初始化时钟,然后生成__main,这个地方注意,
__main的生成需要在target里面勾选Use Micro LIB才可以;
程序中的【weak】为弱定义如果在后面更改,那么这个地方就不使用,但是需要在更改的地方做一下初始化。
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
bsp_clkconfig.c文件
#include "bsp_clkconfig.h"
void User_SetSysClock(void)
{
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
//复位RCC的所有寄存器
RCC_DeInit();
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
//等待HSE启动稳定,如果超时则退出
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;
}
//HSE启动成功
if (HSEStatus == (uint32_t)0x01)
{
/* Select regulator voltage output Scale 1 mode */
//选着电压调节器的模式为1
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
PWR->CR |= PWR_CR_VOS;
/* HCLK = SYSCLK / 1*/
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK / 2*/
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
/* PCLK1 = HCLK / 4*/
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
//配置主PLL
/* Configure the main PLL */
// RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
// (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
RCC->PLLCFGR = 9 | (336<< 6) | (((2 >> 1) -1) << 16) |
(RCC_PLLCFGR_PLLSRC_HSE) | (7 << 24);
/* Enable the main PLL */
//使能
RCC->CR |= RCC_CR_PLLON;
/* Wait till the main PLL is ready */
//等待主锁相环稳定
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Configure Flash prefetch, Instruction cache, Data cache and wait state */
FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
/* Select the main PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_PLL;
/* Wait till the main PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != 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 */
}
}
bsp_clkconfig.h文件
#ifndef __BSP_CLKCONFIG_H
#define __BSP_CLKCONFIG_H
#include "stm32f4xx.h"
void User_SetSysClock(void);
#endif
主文件
/**
******************************************************************************
* @file main.c
* @author fire
* @version V1.0
* @date 2015-xx-xx
* @brief 控制多彩流水灯
******************************************************************************
* @attention
*
* 实验平台:野火 STM32 F407 开发板
* 论坛 :http://www.firebbs.cn
* 淘宝 :https://fire-stm32.taobao.com
*
******************************************************************************
*/
#include "stm32f4xx.h"
#include "./led/bsp_led.h"
#include "bsp_clkconfig.h"//需要指定文件夹
#include "./rcc/bsp_clkconfig.h"
void Delay(__IO u32 nCount);
/**
* @brief 主函数
* @param 无
* @retval 无
*/
int main(void)
{
User_SetSysClock();
/* LED 端口初始化 */
LED_GPIO_Config();
/* 控制LED灯 */
while (1)
{
LED1( ON ); // 亮
Delay(0xFFFFF);
LED1( OFF ); // 灭
Delay(0xFFFFF);
}
}
void Delay(__IO uint32_t nCount) //简单的延时函数
{
for(; nCount != 0; nCount--);
}
/*********************************************END OF FILE**********************/