本篇博文最後修改時間:2019年09月18日 15:16。
一、簡介
本文以STM32F103編程爲例,介紹STM32F103系統時鐘初始化及延遲函數編寫
二、實驗平臺
電腦平臺:Windows7 64位旗艦
編譯軟件:Keil5
硬件平臺:STM32F103RC
三、版權聲明
博主:_懵懂
聲明:此博客僅供參考不做任何商業用途,最終解釋權歸原博主所有。
原文地址:http://blog.csdn.NET/qq_18842031
懵懂之MCU交流羣:136384801
四、實驗前提
1、在進行本文步驟前,請先安裝keil5版本;準備好STM32F103RC硬件平臺。
五、基礎知識
暫無
六、源碼地址
暫無
七、關聯文章
暫無
八、實驗內容
1.初始化系統時鐘
/*外部時鐘最高72MHz 內部時鐘最高64MHz*/
typedef enum{
HAL_CLOCK_HSE_SYS = (unsigned char)0x01, /*外部時鐘*/
HAL_CLOCK_HSI_SYS = (unsigned char)0x02 /*內部時鐘*/
}Type_Hal_Clock_Sys;
typedef enum{
HAL_CLOCK_36MHZ = (unsigned char)0x01,
HAL_CLOCK_48MHZ = (unsigned char)0x02,
HAL_CLOCK_56MHZ = (unsigned char)0x03,
HAL_CLOCK_64MHZ = (unsigned char)0x04,
HAL_CLOCK_72MHZ = (unsigned char)0x05
}Type_Hal_Clock_Mhzx;
/*********************************************************************
* @fn Hal_SysClock_Init()
*
* @brief 系統時鐘初始化
*
* @param Type_Hal_Clock_Sys : HAL_CLOCK_HSE_SYS HAL_CLOCK_HSI_SYS
* @param Type_Hal_Clock_Mhzx : HAL_CLOCK_20MHZ HAL_CLOCK_36MHZ HAL_CLOCK_48MHZ HAL_CLOCK_56MHZ HAL_CLOCK_64MHZ HAL_CLOCK_72MHZ
*
* @return None.
********************************************************************/
unsigned int Hal_SysClock_Init(Type_Hal_Clock_Sys clockx,Type_Hal_Clock_Mhzx mHzx)
{
unsigned int newSysClock = 0;
RCC_DeInit();
switch(clockx)
{
case HAL_CLOCK_HSE_SYS:
{
ErrorStatus HSEStartUpStatus;
RCC_HSEConfig(RCC_HSE_ON);
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
FLASH_SetLatency(FLASH_Latency_2);
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
switch(mHzx)
{
case HAL_CLOCK_36MHZ:
{
RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_9);
newSysClock = 36000000;
}
break;
case HAL_CLOCK_48MHZ:
{
RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_12);
newSysClock = 48000000;
}
break;
case HAL_CLOCK_56MHZ:
{
RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_14);
newSysClock = 56000000;
}
break;
case HAL_CLOCK_64MHZ:
{
RCC_PLLConfig(RCC_PLLSource_HSE_Div2, RCC_PLLMul_16);
newSysClock = 64000000;
}
break;
case HAL_CLOCK_72MHZ:
{
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
newSysClock = 72000000;
}
break;
default:
break;
}
}
}
break;
case HAL_CLOCK_HSI_SYS:
{
RCC_HSICmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
FLASH_SetLatency(FLASH_Latency_2);
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
switch(mHzx)
{
case HAL_CLOCK_36MHZ:
{
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);
newSysClock = 36000000;
}
break;
case HAL_CLOCK_48MHZ:
{
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_12);
newSysClock = 48000000;
}
break;
case HAL_CLOCK_56MHZ:
{
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_14);
newSysClock = 56000000;
}
break;
case HAL_CLOCK_64MHZ:
{
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);
newSysClock = 64000000;
}
break;
default:
break;
}
}
break;
default:
break;
}
RCC_PLLCmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while (RCC_GetSYSCLKSource() != 0x08);
return newSysClock;
}
2.延遲函數相關
提示:選擇系統時鐘36M時延遲誤差較大
static unsigned charfac_us=0; //us延時倍乘數
static unsigned short fac_ms=0; //ms延時倍乘數,在ucos下,代表每個節拍的ms數
/*********************************************************************
* @fn Hal_delay_init()
*
* @brief 延遲函數初始化
*
* @param mHzx : HAL_CLOCK_36MHZ HAL_CLOCK_48MHZ HAL_CLOCK_46MHZ HAL_CLOCK_64MHZ HAL_CLOCK_72MHZ
* @param sysClock : 系統時鐘 例如 72000000M
*
* @return None.
********************************************************************/
void Hal_delay_init(Type_Hal_Clock_Mhzx mHzx)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
switch(mHzx)
{
case HAL_CLOCK_36MHZ:
{
SystemCoreClock = 36000000;
}
break;
case HAL_CLOCK_48MHZ:
{
SystemCoreClock = 48000000;
}
break;
case HAL_CLOCK_56MHZ:
{
SystemCoreClock = 56000000;
}
break;
case HAL_CLOCK_64MHZ:
{
SystemCoreClock = 64000000;
}
break;
case HAL_CLOCK_72MHZ:
{
SystemCoreClock = 72000000;
}
break;
default:
break;
}
fac_us=SystemCoreClock/8000000;
fac_ms=(unsigned short)fac_us*1000;
}
/*********************************************************************
* @fn Hal_delay_us()
*
* @brief n us 精準延數
*
* @param nus:需要延時的時間
*
* @return None.
********************************************************************/
void Hal_delay_us(unsigned short nus)
{
unsigned int temp;
SysTick->LOAD=nus*fac_us;
SysTick->VAL=0x00;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16)));
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL =0X00;
}
/*********************************************************************
* @fn Hal_delay_ms()
*
* @brief n ms 精準延數
*
* @param nms:需要延時的時間
*
* @return None.
********************************************************************/
void Hal_delay_ms(unsigned short nms)
{
unsigned int temp;
SysTick->LOAD=(u32)nms*fac_ms;
SysTick->VAL =0x00;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16)));
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL =0X00;
}
2.編寫主函數
/*********************************************************************
* @fn main()
*
* @brief 主函數
*
* @param None.
*
* @return None.
********************************************************************/
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure; /*配置GPIO*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
Hal_SysClock_Init(HAL_CLOCK_HSE_SYS,HAL_CLOCK_72MHZ);
Hal_delay_init(HAL_CLOCK_72MHZ);
while(1)
{
Hal_delay_us(1000);
GPIO_SetBits(GPIOB,GPIO_Pin_1);
Hal_delay_us(1000);
GPIO_ResetBits(GPIOB,GPIO_Pin_1);
}
}