📄 system_stm32f10x.c
字号:
/**
******************************************************************************
* @文件 system_stm32f10x.c(汉化版)
* @概述 CMSIS Cortex-M3 系统外围访问层设置的源文件
* @作者 STMicroelectronics - MCD 应用程序组
* @版本 V3.0.0
* @日期 04/06/2009
* @翻译 ANSON/sweet1985 Email:airanson110@126.com
* @日期 01/07/2009
******************************************************************************
*
* 这个固件仅仅是提供给客户作为设计产品而编写程序的参考目的使客户节约时间。由于
* 客户使用本固件在开发产品编程上产生的结果意法半导体公司不承担任何直接的和间接
* 的责任,也不承担任何损害而引起的赔偿。
*
* <h2><center>&复制; 版权所有 2009 意法半导体公司</center></h2>
* 翻译版本仅供学习,如与英文原版有出入应以英文原版为准。
******************************************************************************
*/
/** @此处添加 用户_包含的头文件
* @{
*/
#include "stm32f10x.h"
/**
* @}
*/
/** @此处添加 用户_变量定义
* @{
*/
/**
* @}
*/
/** @此处添加 用户_定义
* @{
*/
/*!< 删除希望应用的系统时钟前的注释线(SYSCLK)
频率 (或在复位之后 HSI 作为系统时钟来源) */
//#define SYSCLK_FREQ_HSE HSE_Value
//#define SYSCLK_FREQ_20MHz 20000000
//#define SYSCLK_FREQ_36MHz 36000000
//#define SYSCLK_FREQ_48MHz 48000000
//#define SYSCLK_FREQ_56MHz 56000000
#define SYSCLK_FREQ_72MHz 72000000
/*如果你使用系统板外部安装的SRAM作为的数据存储器就删除注释线 */
#ifdef STM32F10X_HD
/* #define DATA_IN_ExtSRAM */
#endif /* STM32F10X_HD */
/**
* @}
*/
/** @此处添加 用户_宏命令
* @{
*/
/**
* @}
*/
/** @此处添加 用户_变量
* @{
*/
/*******************************************************************************
* 时钟 定义
*******************************************************************************/
#ifdef SYSCLK_FREQ_HSE
const uint32_t SystemFrequency = SYSCLK_FREQ_HSE; /*!< 系统时钟频率 (核心 时钟) */
const uint32_t SystemFrequency_SysClk = SYSCLK_FREQ_HSE; /*!< 系统时钟 */
const uint32_t SystemFrequency_AHBClk = SYSCLK_FREQ_HSE; /*!< AHB 系统总线速率 */
const uint32_t SystemFrequency_APB1Clk = SYSCLK_FREQ_HSE; /*!< APB 外围总线 1 (低)速 */
const uint32_t SystemFrequency_APB2Clk = SYSCLK_FREQ_HSE; /*!< APB 外围总线 2 (高)速 */
#elif defined SYSCLK_FREQ_20MHz
const uint32_t SystemFrequency = SYSCLK_FREQ_20MHz; /*!< 系统时钟频率 (核心 时钟) */
const uint32_t SystemFrequency_SysClk = SYSCLK_FREQ_20MHz; /*!< 系统时钟 */
const uint32_t SystemFrequency_AHBClk = SYSCLK_FREQ_20MHz; /*!< AHB 系统总线速率 */
const uint32_t SystemFrequency_APB1Clk = SYSCLK_FREQ_20MHz; /*!< APB 外围总线 1 (低)速 */
const uint32_t SystemFrequency_APB2Clk = SYSCLK_FREQ_20MHz; /*!< APB 外围总线 2 (高)速 */
#elif defined SYSCLK_FREQ_36MHz
const uint32_t SystemFrequency = SYSCLK_FREQ_36MHz; /*!< 系统时钟频率 (核心 时钟) */
const uint32_t SystemFrequency_SysClk = SYSCLK_FREQ_36MHz; /*!< 系统时钟 */
const uint32_t SystemFrequency_AHBClk = SYSCLK_FREQ_36MHz; /*!< AHB 系统总线速率 */
const uint32_t SystemFrequency_APB1Clk = SYSCLK_FREQ_36MHz; /*!< APB 外围总线 1 (低)速 */
const uint32_t SystemFrequency_APB2Clk = SYSCLK_FREQ_36MHz; /*!< APB 外围总线 2 (高)速 */
#elif defined SYSCLK_FREQ_48MHz
const uint32_t SystemFrequency = SYSCLK_FREQ_48MHz; /*!< 系统时钟频率 (核心 时钟) */
const uint32_t SystemFrequency_SysClk = SYSCLK_FREQ_48MHz; /*!< 系统时钟 */
const uint32_t SystemFrequency_AHBClk = SYSCLK_FREQ_48MHz; /*!< AHB 系统总线速率 */
const uint32_t SystemFrequency_APB1Clk = (SYSCLK_FREQ_48MHz/2); /*!< APB 外围总线 1 (低)速 */
const uint32_t SystemFrequency_APB2Clk = SYSCLK_FREQ_48MHz; /*!< APB 外围总线 2 (高)速 */
#elif defined SYSCLK_FREQ_56MHz
const uint32_t SystemFrequency = SYSCLK_FREQ_56MHz; /*!< 系统时钟频率 (核心 时钟) */
const uint32_t SystemFrequency_SysClk = SYSCLK_FREQ_56MHz; /*!< 系统时钟 */
const uint32_t SystemFrequency_AHBClk = SYSCLK_FREQ_56MHz; /*!< AHB 系统总线速率 */
const uint32_t SystemFrequency_APB1Clk = (SYSCLK_FREQ_56MHz/2); /*!< APB 外围总线 1 (低)速 */
const uint32_t SystemFrequency_APB2Clk = SYSCLK_FREQ_56MHz; /*!< APB 外围总线 2 (高)速 */
#elif defined SYSCLK_FREQ_72MHz
const uint32_t SystemFrequency = SYSCLK_FREQ_72MHz; /*!< 系统时钟频率 (核心 时钟) */
const uint32_t SystemFrequency_SysClk = SYSCLK_FREQ_72MHz; /*!< 系统时钟 */
const uint32_t SystemFrequency_AHBClk = SYSCLK_FREQ_72MHz; /*!< AHB 系统总线速率 */
const uint32_t SystemFrequency_APB1Clk = (SYSCLK_FREQ_72MHz/2); /*!< APB 外围总线 1 (低)速 */
const uint32_t SystemFrequency_APB2Clk = SYSCLK_FREQ_72MHz; /*!< APB 外围总线 2 (高)速 */
#else /*!< 选定 HSI 作为系统时钟来源*/
const uint32_t SystemFrequency = HSI_Value; /*!< 系统时钟频率 (核心 时钟) */
const uint32_t SystemFrequency_SysClk = HSI_Value; /*!< 系统时钟 */
const uint32_t SystemFrequency_AHBClk = HSI_Value; /*!< AHB 系统总线速率 */
const uint32_t SystemFrequency_APB1Clk = HSI_Value; /*!< APB 外围总线 1 (低)速 */
const uint32_t SystemFrequency_APB2Clk = HSI_Value; /*!< APB 外围总线 2 (高)速 */
#endif
/**
* @}
*/
/** @此处添加 用户_函数
* @{
*/
static void SetSysClock(void);
#ifdef SYSCLK_FREQ_HSE
static void SetSysClockToHSE(void);
#elif defined SYSCLK_FREQ_20MHz
static void SetSysClockTo20(void);
#elif defined SYSCLK_FREQ_36MHz
static void SetSysClockTo36(void);
#elif defined SYSCLK_FREQ_48MHz
static void SetSysClockTo48(void);
#elif defined SYSCLK_FREQ_56MHz
static void SetSysClockTo56(void);
#elif defined SYSCLK_FREQ_72MHz
static void SetSysClockTo72(void);
#endif
/**
* @}
*/
/** @此处添加 用户_函数
* @{
*/
/**
* @简述 构建微控制器系统
* 初始化嵌入式闪存接口, 初始化 PLL 和 系统频率变量
* @参数 没有.
* @自变量 没有.
* @注解 : 这个功能也许仅仅在复位之后起作用.
*/
void SystemInit (void)
{
/*!< RCC 系统复位(调试目的) */
/*!< Set HSION bit */
/*内部高速时钟使能*/
RCC->CR |= (uint32_t)0x00000001;
/*!< Reset SW[1:0], HPRE[3:0], PPRE1[2:0], PPRE2[2:0], ADCPRE[1:0] and MCO[2:0] bits */
/*!<HIS被选作系统时钟,SYSCLK(系统时钟)未被分频,低速、高速总线时钟未被分频,ADC时钟被2分频,
微控制器无时钟输出*/
RCC->CFGR &= (uint32_t)0xF8FF0000;
/*!< Reset HSEON, CSSON and PLLON bits */
/* PLL锁相环失能,CSS时钟安全系统失能,外部高速时钟失能*/
RCC->CR &= (uint32_t)0xFEF6FFFF;
/*!< Reset HSEBYP bit */
/*清外部时钟可用标志*/
RCC->CR &= (uint32_t)0xFFFBFFFF;
/*!< Reset PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE bits */
/* USB时钟为PLL1.5分频,PLL倍频参数X2,HSE未被分频,HSI震荡时钟/2被当作PLL输入时钟 */
RCC->CFGR &= (uint32_t)0xFF80FFFF;
/*!使能所有时钟中断*/
RCC->CIR = 0x00000000;
/*!< 配置系统时钟频率, 系统总线(HCLK)与可编程时钟(PCLK)1、2 */
/*!< 配置闪存延迟周期,使能预取缓存 */
SetSysClock();
}
/**
* @简述 配置系统时钟频率, 系统总线(HCLK)与可编程时钟(PCLK)1、2
* @参数 没有.
* @自变量 没有.
* @注解 : 没有.
* @retval value: None.
*/
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_20MHz
SetSysClockTo20();
#elif defined SYSCLK_FREQ_36MHz
SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz
SetSysClockTo72();
#endif
/*!< 如果上面的定义都没有被激活,那么 HSI 将被用作系统时钟源 (在复位之后缺省) */
}
/**
* @简述 安装外部存储器. 在跳转到主函数(main)之前访问 startup_stm32f10x.s
* @参数 没有.
* @自变量 没有.
* @注解 : 没有.
* @retval value: None.
*/
#ifdef DATA_IN_ExtSRAM
/**
* @简述 安装外部存储器.
* 在跳转到主函数(main)之前访问 startup_stm32f10x_xx.s/.c
* 这个函数应用在外部 SRAM 安装在系统板上
* 这个 SRAM 将作为数据存储器
* (包括堆和栈).
* @参数 没有.
* @自变量 没有.
* @注解 : 没有.
* @retval value: None.
*/
void SystemInit_ExtMemCtl(void)
{
/*!< FSMC 保存在一个 SRAM ,如果还需要存储,那么调整寄存器地址*/
/*!< 使能 FSMC 时钟 */
RCC->AHBENR = 0x00000114;
/*!< 使能 GPIOD, GPIOE, GPIOF 和 GPIOG 时钟 */
RCC->APB2ENR = 0x000001E0;
/* --------------- SRAM 数据总线, 从新配置 ----------------------------------*/
/*---------------- SRAM 地址总线配置 ----------------------------------------*/
GPIOD->CRL = 0x44BB44BB;
GPIOD->CRH = 0xBBBBBBBB;
GPIOE->CRL = 0xB44444BB;
GPIOE->CRH = 0xBBBBBBBB;
GPIOF->CRL = 0x44BBBBBB;
GPIOF->CRH = 0xBBBB4444;
GPIOG->CRL = 0x44BBBBBB;
GPIOG->CRH = 0x44444B44;
/*---------------- FSMC 配置 ------------------------------------------------*/
/*---------------- 使能 FSMC Bank1_SRAM Bank --------------------------------*/
FSMC_Bank1->BTCR[4] = 0x00001011;
FSMC_Bank1->BTCR[5] = 0x00000200;
}
#endif /* DATA_IN_ExtSRAM */
#ifdef SYSCLK_FREQ_HSE
/**
* @简述 选择 HSE 作为系统时钟源 和配置 HCLK, PCLK2, PCLK1
* @参数 没有.
* @自变量 没有.
* @注解 : 这个功能也许仅仅在复位之后起作用.
* @retval value: None.
*/
static void SetSysClockToHSE(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/*!< SYSCLK, HCLK, PCLK2 and PCLK1 配置 ---------------------------*/
/*!< 使能 HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/*!< 等待 HSE 准备好 如果超时则退出 */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/*!< 使能预取缓存 */
FLASH->ACR |= FLASH_ACR_PRFTBE;
/*!< Flash 0 wait state */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
/*!< HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/*!< PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/*!< PCLK1 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
/*!< 选择 HSE 作为系统时钟源 */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE;
/*!< 等待 HSE 作为系统时钟源 */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04)
{
}
}
else
{ /*!< 如果 HSE 启动失败, 申报为错误时钟. 用户可以再次添加代码处理这个错误 */
/*!< 执行无限循环 */
while (1)
{
}
}
}
#elif defined SYSCLK_FREQ_20MHz
/**
* @简述 设置系统时钟为 20MHz ,配置 HCLK, PCLK2, PCLK1
* @参数 没有.
* @自变量 没有.
* @注解 : 这个功能也许仅仅在复位之后起作用.
* @retval value: None.
*/
static void SetSysClockTo20(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/*!< SYSCLK, HCLK, PCLK2 and PCLK1 配置 ---------------------------*/
/*!< 使能 HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/*!< 等待 HSE 准备好 如果超时则退出 */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/*!< 使能预取缓存 */
FLASH->ACR |= FLASH_ACR_PRFTBE;
/*!< Flash 0 wait state */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -