210 lines
5.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "sys.h"
//////////////////////////////////////////////////////////////////////////////////
/*************************************************************************/
//系统时钟初始化
//STM32H7工程模板-HAL库函数版本
//DevEBox 大越创新
//淘宝店铺mcudev.taobao.com
//淘宝店铺shop389957290.taobao.com
/*************************************************************************/
//////////////////////////////////////////////////////////////////////////////////
//使能CPU的L1-Cache
void Cache_Enable(void)
{
SCB_EnableICache();//使能I-Cache
SCB_EnableDCache();//使能D-Cache
SCB->CACR|=1<<2; //强制D-Cache透写,如不开启,实际使用中可能遇到各种问题
}
//时钟设置函数
//Fvco=Fs*(plln/pllm);
//Fsys=Fvco/pllp=Fs*(plln/(pllm*pllp));
//Fq=Fvco/pllq=Fs*(plln/(pllm*pllq));
//Fvco:VCO频率
//Fsys:系统时钟频率,也是PLL1的p分频输出时钟频率
//Fq:PLL1的q分频输出时钟频率
//Fs:PLL输入时钟频率,可以是HSI,CSI,HSE等.
//plln:PLL1倍频系数(PLL倍频),取值范围:4~512.
//pllm:PLL1预分频系数(进PLL之前的分频),取值范围:2~63.
//pllp:PLL1的p分频系数(PLL之后的分频),分频后作为系统时钟,取值范围:2~128.(且必须是2的倍数)
//pllq:PLL1的q分频系数(PLL之后的分频),取值范围:1~128.
//CPU频率(rcc_c_ck)=sys_d1cpre_ck=400Mhz
//rcc_aclk=rcc_hclk3=200Mhz
//AHB1/2/3/4(rcc_hclk1/2/3/4)=200Mhz
//APB1/2/3/4(rcc_pclk1/2/3/4)=100Mhz
//FMC时钟频率=pll2_r_ck=((25/25)*512/2)=256Mhz
//外部晶振为25M的时候,推荐值:plln=160,pllm=5,pllp=2,pllq=2.
//得到:Fvco=25*(160/5)=800Mhz
// Fsys=800/2=400Mhz
// Fq=800/2=400Mhz
//返回值:0,成功;1,失败。
void Stm32_Clock_Init(u32 plln,u32 pllm,u32 pllp,u32 pllq)
{
HAL_StatusTypeDef ret=HAL_OK;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
MODIFY_REG(PWR->CR3,PWR_CR3_SCUEN, 0);
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {}
//使能HSI48MHz给USB使用
RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState=RCC_HSE_ON;
RCC_OscInitStruct.HSI48State=RCC_HSI48_ON;
RCC_OscInitStruct.HSIState=RCC_HSI_OFF;
RCC_OscInitStruct.CSIState=RCC_CSI_OFF;
RCC_OscInitStruct.PLL.PLLState=RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource=RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLN=plln;
RCC_OscInitStruct.PLL.PLLM=pllm;
RCC_OscInitStruct.PLL.PLLP=pllp;
RCC_OscInitStruct.PLL.PLLQ=pllq;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
ret=HAL_RCC_OscConfig(&RCC_OscInitStruct);
if(ret!=HAL_OK) while(1);
RCC_ClkInitStruct.ClockType=(RCC_CLOCKTYPE_SYSCLK|\
RCC_CLOCKTYPE_HCLK |\
RCC_CLOCKTYPE_D1PCLK1 |\
RCC_CLOCKTYPE_PCLK1 |\
RCC_CLOCKTYPE_PCLK2 |\
RCC_CLOCKTYPE_D3PCLK1);
RCC_ClkInitStruct.SYSCLKSource= RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider=RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider=RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB1CLKDivider=RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider=RCC_APB2_DIV2;
RCC_ClkInitStruct.APB3CLKDivider=RCC_APB3_DIV2;
RCC_ClkInitStruct.APB4CLKDivider=RCC_APB4_DIV4;
ret=HAL_RCC_ClockConfig(&RCC_ClkInitStruct,FLASH_LATENCY_2);
if(ret!=HAL_OK) while(1);
__HAL_RCC_CSI_ENABLE() ;
__HAL_RCC_SYSCFG_CLK_ENABLE() ;
HAL_EnableCompensationCell();
}
#ifdef USE_FULL_ASSERT
//当编译提示出错的时候此函数用来报告错误的文件和所在行
//file指向源文件
//line指向在文件中的行数
void assert_failed(uint8_t* file, uint32_t line)
{
while (1)
{
}
}
#endif
//判断I_Cache是否打开
//返回值:0 关闭1 打开
u8 Get_ICahceSta(void)
{
u8 sta;
sta=((SCB->CCR)>>17)&0X01;
return sta;
}
//判断I_Dache是否打开
//返回值:0 关闭1 打开
u8 Get_DCahceSta(void)
{
u8 sta;
sta=((SCB->CCR)>>16)&0X01;
return sta;
}
#if defined(__clang__) //使用V6编译器(clang)
//THUMB指令不支持汇编内联
//采用如下方法实现执行汇编指令WFI
void __attribute__((noinline)) WFI_SET(void)
{
__asm__("wfi");
}
//关闭所有中断(但是不包括fault和NMI中断)
void __attribute__((noinline)) INTX_DISABLE(void)
{
__asm__("cpsid i \t\n"
"bx lr");
}
//开启所有中断
void __attribute__((noinline)) INTX_ENABLE(void)
{
__asm__("cpsie i \t\n"
"bx lr");
}
//设置栈顶地址
//addr:栈顶地址
void __attribute__((noinline)) MSR_MSP(u32 addr)
{
__asm__("msr msp, r0 \t\n"
"bx r14");
}
#elif defined (__CC_ARM) //使用V5编译器(ARMCC)
//THUMB指令不支持汇编内联
//采用如下方法实现执行汇编指令WFI
__asm void WFI_SET(void)
{
WFI;
}
//关闭所有中断(但是不包括fault和NMI中断)
__asm void INTX_DISABLE(void)
{
CPSID I
BX LR
}
//开启所有中断
__asm void INTX_ENABLE(void)
{
CPSIE I
BX LR
}
//设置栈顶地址
//addr:栈顶地址
__asm void MSR_MSP(u32 addr)
{
MSR MSP, r0 //set Main Stack value
BX r14
}
#endif
/*************************************************************************/
//系统时钟初始化
//STM32H7工程模板-HAL库函数版本
//DevEBox 大越创新
//淘宝店铺mcudev.taobao.com
//淘宝店铺shop389957290.taobao.com
/*************************************************************************/