yaomei65 发表于 2016-5-15 23:48:24

关於时钟设置 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其他都没去修改

freeelectron 发表于 2016-5-18 09:17:10

hse起振后,不是有个倍频的过程吗?

wenyangzeng 发表于 2016-5-18 10:35:24

STM32F072RB DISCO好像没有焊接外部晶振呀

wolfgang 发表于 2016-5-18 12:49:55

检查晶振是否起振。

sting 发表于 2016-5-18 12:50:48

先检查外部晶振有无起振,在void SetSysClock(void),若hse无起振,就不会倍频到48Mhz,单片机会继续使用内部hsi,所以是8Mhz

Dylan疾风闪电 发表于 2016-5-18 16:20:28

贴一个我自己常用的时钟初始化代码。
调用很简单:
#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
}

Dylan疾风闪电 发表于 2016-5-18 16:23:54

对于一般的应用,可以不焊HSE。
即使是USB的应用,也可以通过HSI倍频PLL到48MHz,来使用。(DEMO板测试正常)
这段代码我从2010年开始用到现在了,每次换MCU也只是对其进行局部调整#if
希望对你有帮助~~
:):):):)

Dylan疾风闪电 发表于 2016-5-18 16:26:35

使用我的时钟初始化,将defined(STM32F042) 替换成defined(STM32F072)就可以了。

huaiqiao 发表于 2016-5-18 17:13:29

像这个072的 discovery的板子是不带HSE的,除非楼主您自己焊接。
估计如果跑例程的话,他自带的是HSI了。这个要看时钟树了

zcl201207 发表于 2016-5-18 23:28:28

:):):):):):):)

zhenweiaaa 发表于 2020-8-28 17:41:30

谢谢lz
页: [1]
查看完整版本: 关於时钟设置 SystemInit