bs_bcu_app/tmp/sys.c

199 lines
5.9 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.

/**
****************************************************************************************************
* @file sys.c
* @author 正点原子团队(ALIENTEK)
* @version V1.0
* @date 2021-10-14
* @brief 系统初始化代码(包括时钟配置/中断管理/GPIO设置等)
* @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
****************************************************************************************************
* @attention
*
* 实验平台:正点原子 探索者 F407开发板
* 在线视频:www.yuanzige.com
* 技术论坛:www.openedv.com
* 公司网址:www.alientek.com
* 购买地址:openedv.taobao.com
*
* 修改说明
* V1.0 20211014
* 第一次发布
****************************************************************************************************
*/
#include "./SYSTEM/sys/sys.h"
/**
* @brief 设置中断向量表偏移地址
* @param baseaddr: 基址
* @param offset: 偏移量
* @retval 无
*/
void sys_nvic_set_vector_table(uint32_t baseaddr, uint32_t offset)
{
/* 设置NVIC的向量表偏移寄存器,VTOR低9位保留,即[8:0]保留 */
SCB->VTOR = baseaddr | (offset & (uint32_t)0xFFFFFE00);
}
/**
* @brief 执行: WFI指令(执行完该指令进入低功耗状态, 等待中断唤醒)
* @param 无
* @retval 无
*/
void sys_wfi_set(void)
{
__ASM volatile("wfi");
}
/**
* @brief 关闭所有中断(但是不包括fault和NMI中断)
* @param 无
* @retval 无
*/
void sys_intx_disable(void)
{
__ASM volatile("cpsid i");
}
/**
* @brief 开启所有中断
* @param 无
* @retval 无
*/
void sys_intx_enable(void)
{
__ASM volatile("cpsie i");
}
/**
* @brief 设置栈顶地址
* @note 左侧若出现红X, 属于MDK误报, 实际是没问题的
* @param addr: 栈顶地址
* @retval 无
*/
void sys_msr_msp(uint32_t addr)
{
__set_MSP(addr); /* 设置栈顶地址 */
}
/**
* @brief 进入待机模式
* @param 无
* @retval 无
*/
void sys_standby(void)
{
__HAL_RCC_PWR_CLK_ENABLE(); /* 使能电源时钟 */
SET_BIT(PWR->CR, PWR_CR_PDDS); /* 进入待机模式 */
}
/**
* @brief 系统软复位
* @param 无
* @retval 无
*/
void sys_soft_reset(void)
{
NVIC_SystemReset();
}
/**
* @brief 时钟设置函数
* @param plln: 主PLL倍频系数(PLL倍频), 取值范围: 64~432.
* @param pllm: 主PLL和音频PLL预分频系数(进PLL之前的分频), 取值范围: 2~63.
* @param pllp: 主PLL的p分频系数(PLL之后的分频), 分频后作为系统时钟, 取值范围: 2, 4, 6, 8.(仅限这4个值)
* @param pllq: 主PLL的q分频系数(PLL之后的分频), 取值范围: 2~15.
* @note
*
* Fvco: VCO频率
* Fsys: 系统时钟频率, 也是主PLL的p分频输出时钟频率
* Fq: 主PLL的q分频输出时钟频率
* Fs: 主PLL输入时钟频率, 可以是HSI, HSE等.
* Fvco = Fs * (plln / pllm);
* Fsys = Fvco / pllp = Fs * (plln / (pllm * pllp));
* Fq = Fvco / pllq = Fs * (plln / (pllm * pllq));
*
* 外部晶振为 8M的时候, 推荐值: plln = 336, pllm = 8, pllp = 2, pllq = 7.
* 得到:Fvco = 8 * (336 / 8) = 336Mhz
* Fsys = pll_p_ck = 336 / 2 = 168Mhz
* Fq = pll_q_ck = 336 / 7 = 48Mhz
*
* F407默认需要配置的频率如下:
* CPU频率(HCLK) = pll_p_ck = 168Mhz
* AHB1/2/3(rcc_hclk1/2/3) = 168Mhz
* APB1(rcc_pclk1) = pll_p_ck / 4 = 42Mhz
* APB1(rcc_pclk2) = pll_p_ck / 2 = 84Mhz
*
* @retval 错误代码: 0, 成功; 1, 错误;
*/
uint8_t sys_stm32_clock_init(uint32_t plln, uint32_t pllm, uint32_t pllp, uint32_t pllq)
{
HAL_StatusTypeDef ret = HAL_OK;
RCC_OscInitTypeDef rcc_osc_init = {0};
RCC_ClkInitTypeDef rcc_clk_init = {0};
__HAL_RCC_PWR_CLK_ENABLE(); /* 使能PWR时钟 */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* 设置调压器输出电压级别,以便在器件未以最大频率工作 */
/* 使能HSE并选择HSE作为PLL时钟源配置PLL1开启USB时钟 */
rcc_osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSE; /* 时钟源为HSE */
rcc_osc_init.HSEState = RCC_HSE_ON; /* 打开HSE */
rcc_osc_init.PLL.PLLState = RCC_PLL_ON; /* 打开PLL */
rcc_osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSE; /* PLL时钟源选择HSE */
rcc_osc_init.PLL.PLLN = plln;
rcc_osc_init.PLL.PLLM = pllm;
rcc_osc_init.PLL.PLLP = pllp;
rcc_osc_init.PLL.PLLQ = pllq;
ret = HAL_RCC_OscConfig(&rcc_osc_init); /* 初始化RCC */
if(ret != HAL_OK)
{
return 1; /* 时钟初始化失败,可以在这里加入自己的处理 */
}
/* 选中PLL作为系统时钟源并且配置HCLK,PCLK1和PCLK2 */
rcc_clk_init.ClockType = ( RCC_CLOCKTYPE_SYSCLK \
| RCC_CLOCKTYPE_HCLK \
| RCC_CLOCKTYPE_PCLK1 \
| RCC_CLOCKTYPE_PCLK2);
rcc_clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; /* 设置系统时钟时钟源为PLL */
rcc_clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1; /* AHB分频系数为1 */
rcc_clk_init.APB1CLKDivider = RCC_HCLK_DIV4; /* APB1分频系数为4 */
rcc_clk_init.APB2CLKDivider = RCC_HCLK_DIV2; /* APB2分频系数为2 */
ret = HAL_RCC_ClockConfig(&rcc_clk_init, FLASH_LATENCY_5); /* 同时设置FLASH延时周期为5WS也就是6个CPU周期 */
if(ret != HAL_OK)
{
return 1; /* 时钟初始化失败 */
}
/* STM32F405x/407x/415x/417x Z版本的器件支持预取功能 */
if (HAL_GetREVID() == 0x1001)
{
__HAL_FLASH_PREFETCH_BUFFER_ENABLE(); /* 使能flash预取 */
}
return 0;
}
#ifdef USE_FULL_ASSERT
/**
* @brief 当编译提示出错的时候此函数用来报告错误的文件和所在行
* @param file指向源文件
* line指向在文件中的行数
* @retval 无
*/
void assert_failed(uint8_t* file, uint32_t line)
{
while (1)
{
}
}
#endif