关於时钟设置 SystemInit
本帖最后由 yaomei65 于 2016-5-15 23:50 编辑所使用的版子是STM32F072RB DISCO
库用了STM32F0xx_StdPeriph 1.5.0版本
把库全部弄好 LED确实有出来
接下来要测试systick的时候delay一直不对
後来发现系统时间只有8MHZ 理论上要是48MHZ
截取一小段程序放在下方
里面的 "HSEStatus" 数值一直都是0
以至於无法设定时钟
我认为这是HSE没有就绪 请问我是有漏掉设定哪个步骤吗?
static void SetSysClock(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/******************************************************************************/
/* PLL (clocked by HSE) used as System clock source */
/******************************************************************************/
/* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
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;
}
在附上我的文档
除了main与it其他都没去修改
hse起振后,不是有个倍频的过程吗? STM32F072RB DISCO好像没有焊接外部晶振呀 检查晶振是否起振。 先检查外部晶振有无起振,在void SetSysClock(void),若hse无起振,就不会倍频到48Mhz,单片机会继续使用内部hsi,所以是8Mhz 贴一个我自己常用的时钟初始化代码。
调用很简单:
#define USE_EXTERNAL_HSE 0
#define USE_INTERNAL_HSI 1
#define SystemClockMHz 48//MHZ
void func()
{
if (HW_SystemClockMux(USE_EXTERNAL_HSE, SystemClockMHz) == 0) //为了USB尝试切换HSE时钟//SystemClockMHz
{
HW_SystemClockMux(USE_INTERNAL_HSI, SystemClockMHz); /* 配置系统时钟为48M for USB clock */
}
}
/**
* <b>配製系統主時鐘頻率。</b>
* <p>功能:選擇時鐘源,并進行PLL倍頻。
* @paramosc 高速時鐘源的選擇。
* @arg USE_EXTERNAL_HSE: 外部高速晶振
* @arg USE_INTERNAL_HSI: 內部高速晶振
* @parammaxFreq 芯片最大主频?M,查询对应的数据手册
* @return osc
* @version 2.0.0.0(20160407)
* <p-2014>实现CM0与CM3兼容完成!
* <p-2016>對字符串/單詞進行變更。
* @author Dylan
*/
uint8_t HW_SystemClockMux(uint8_t osc, uint8_t maxFreq)
{
#if defined (STM32F100) || defined (STM32F101) || defined (STM32F103)
uint8_t errCode = 0xff;
uint32_t sTimeCount, sTimeMax = 0xFFF;
#endif
HW_SystemPowerON();
switch(osc)
{
case USE_EXTERNAL_HSE:
#if defined (STM32F100) || defined (STM32F101) || defined (STM32F103)
RCC->CR |= 1<<16; //HSEON
sTimeCount = sTimeMax;
while(((RCC->CR>>17) & 0x1) == 0) //等待HSE就绪
{
if (sTimeCount--) return errCode;
}
RCC->CFGR |= (maxFreq/8-2)<<18; //设置PLL值倍频//HSE 8MHz
RCC->CFGR |= 1<<16; //切换PLL输入时钟源为0->1:HSI/2(4MHz)->HSE(8MHz)
//存在等待状态时,必须先开启预取缓冲区
if (maxFreq <= 24)
FLASH->ACR |= 0x30;//000:零等待状态,当 0 < SYSCLK ≤ 24MHz
else if (maxFreq <= 48)
FLASH->ACR |= 0x31;//001:一个等待状态,当 24MHz < SYSCLK ≤ 48MHz
else
FLASH->ACR |= 0x32;//010:两个等待状态,当 48MHz < SYSCLK ≤ 72MHz
RCC->CR |= 1<<24; //PLLON
sTimeCount = sTimeMax;
while(((RCC->CR>>25) & 0x1) == 0)//等待PLL就绪
{
if (sTimeCount--) return errCode;
}
RCC->CFGR |= 0x2; //PLL作为sysClk
sTimeCount = sTimeMax;
while(((RCC->CFGR>>2) & 0x3) != 0x02)//等待sysClk就绪
{
if (sTimeCount--) return errCode;
}
#elif defined(STM32F051) || defined(STM32F042) //none
#else
#warning "Make sure needn't define STM32Fxxx etc. ?"
#endif
break;
default: //case USE_INTERNAL_HSI:
RCC->CFGR &= 0xFFFEFFFF; //HSI 8MHz/2
RCC->CFGR |= ((maxFreq>>2)-2)<<18; //设置PLL值倍频
//存在等待状态时,必须先开启预取缓冲区
if (maxFreq <= 24)
FLASH->ACR |= 0x30;//000:零等待状态,当 0 < SYSCLK ≤ 24MHz
else if (maxFreq <= 48)
FLASH->ACR |= 0x31;//001:一个等待状态,当 24MHz < SYSCLK ≤ 48MHz
else
FLASH->ACR |= 0x32;//010:两个等待状态,当 48MHz < SYSCLK ≤ 72MHz
RCC->CR |= 1<<24; //PLLON
while(((RCC->CR>>25) & 0x1) != 1);//等待PLL就绪
RCC->CFGR |= 0x2; //PLL作为sysClk
while(((RCC->CFGR>>2)&0x3) != 0x02);//等待sysClk就绪
break;
}
return 0;
}
/**
* <b>芯片上电默认时钟配置。</b>
* <p>功能:用来恢复时钟系统到上电默认状态。
* @version 1.1.0.0(20140228)
* <p-2014>实现CM0与CM3兼容完成!
* @author Dylan
*/
void HW_SystemPowerON(void)
{
#if defined(STM32F051) || defined(STM32F042)
RCC->CR |= 0x00000001;//HSION
RCC->CR &= 0x0202FFFF;/* Reset HSEON, CSSON and PLLON, HSEBYP bit */
RCC->CFGR &= 0x0000000C;/* Reset SW, HPRE, PPRE, ADCPRE and MCOSEL,PLLSRC, PLLXTPRE and PLLMUL bits */
RCC->CFGR2 &= 0x00000000;/* Reset PREDIV1 bits *///与CFGR一起用作HSE-PLL设置
RCC->CFGR3 &= 0x00000000;/* Reset USARTSW, I2CSW, CECSW and ADCSW bits */
RCC->CR2 &= 0xFFFFFFFE;/* Reset HSI14 bit */
RCC->CIR = 0x00000000;/* Disable all interrupts */
#elif defined (STM32F100) || defined (STM32F101) || defined (STM32F103)
RCC->CR &= 0x0000FF83;//把HSI调整到8MHz±1%==》开启HSI==》等待就绪
RCC->CFGR = 0x00000400;//限制APB1时钟是HCLK_Div2
RCC->CIR = 0x00BF0000;//清除所有的RCC中断标志
//配置向量表
#ifdefVECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else/* VECT_TAB_FLASH*/
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
#else
#warning "Make sure needn't define STM32F051 etc. ?"
#endif
}
对于一般的应用,可以不焊HSE。
即使是USB的应用,也可以通过HSI倍频PLL到48MHz,来使用。(DEMO板测试正常)
这段代码我从2010年开始用到现在了,每次换MCU也只是对其进行局部调整#if
希望对你有帮助~~
:):):):) 使用我的时钟初始化,将defined(STM32F042) 替换成defined(STM32F072)就可以了。 像这个072的 discovery的板子是不带HSE的,除非楼主您自己焊接。
估计如果跑例程的话,他自带的是HSI了。这个要看时钟树了 :):):):):):):)
页:
[1]
2