历史上的今天
返回首页

历史上的今天

今天是:2024年12月18日(星期三)

正在发生

2018年12月18日 | STM32时钟初始化研究

2018-12-18 来源:eefocus

时钟是一个MCU的脉搏,研究清楚脉搏才能更清楚的把握整个MCU的运行。本文主要研究STM32F10x系列,利用官方库文件进行初始化设置。开发环境为MDK4.6,库文件V3.5版本,STM32参考手册。


利用MDK自带仿真器,仿真发现。芯片启动首先打开system_stmf10x.c文件,调用void SystemInit(void)函数。下面贴上代码和中文注释


void SystemInit (void)

{

/* Reset the RCC clock configuration to the default reset state(for debug purpose) */

/* Set HSION bit */

RCC->CR |= (uint32_t)0x00000001; //内部高速时钟使能


/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */

//SW:HSI(内部高速8M RC震荡器)作为时钟源

//AHB(SYSCLK)不分频

//APB1,APB2不分频

// PCLK2 2分频后作为ADC时钟

// HSI时钟2分频后作为PLL输入时钟

//MCO没有时钟输出

RCC->CFGR &= (uint32_t)0xF8FF0000;

 

/* Reset HSEON, CSSON and PLLON bits */

//HSE振荡器关闭, 时钟安全系统监测器关闭PLL关闭

RCC->CR &= (uint32_t)0xFEF6FFFF;

 

/* Reset HSEBYP bit */

//清零来旁路外部晶体振荡器。只有在外部4-25MHz振荡器关闭的情况下,才能写入该位。

RCC->CR &= (uint32_t)0xFFFBFFFF;

 

/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */

//HSI时钟2分频后作为PLL输入时钟

//HSE不分频器作为PLL输入

//0000:PLL 2倍频输出

//0:PLL时钟1.5倍分频作为USB时钟

RCC->CFGR &= (uint32_t)0xFF80FFFF;

 

/* Disable all interrupts and clear pending bits  */

RCC->CIR = 0x009F0000;

 

/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */

/* Configure the Flash Latency cycles and enable prefetch buffer */

SetSysClock();

 

SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */

}


主要是用于重置RCC寄存器,既重置STM32的时钟树。


初始化重置时钟后的时钟树图:


上文中还有个函数叫SetSysClock用于设置MCU系统时钟,贴入代码:


static void SetSysClock(void)

{

 

#ifdef SYSCLK_FREQ_HSE

  SetSysClockToHSE();

#elif defined SYSCLK_FREQ_24MHz

  SetSysClockTo24();

#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

/* If none of the define above is enabled, the HSI is used as System clock source (default after reset) */

}

 

static void SetSysClockTo72(void)

{

__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

 

/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    

 

 

/* Enable HSE */    

/*define C_CR_HSEON                        (int32_t)0x00010000)   */

/*!< External High Speed clock enable */

//开启HSE振荡器

RCC->CR |= ((uint32_t)RCC_CR_HSEON);

 


/* Wait till HSE is ready and if Time out is reached exit */

//等待HSE起振

//#define HSEStartUp_TimeOut   HSE_STARTUP_TIMEOUT

//#define HSE_STARTUP_TIMEOUT   ((uint16_t)0x0500)

/*!< Time out for HSE start up */

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;

}  


if (HSEStatus == (uint32_t)0x01)

{

/* Enable Prefetch Buffer */

FLASH->ACR |= FLASH_ACR_PRFTBE;


/* Flash 2 wait state */

FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);

FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;  

 

/* HCLK = SYSCLK */

//#define  RCC_CFGR_HPRE_DIV1      ((uint32_t)0x00000000)        /*!< SYSCLK not divided */

//HCLK  :AHB总线时钟,由系统时钟SYSCLK 分频得到,不分频

RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

 

 

/* PCLK2 = HCLK */

// #define  RCC_CFGR_PPRE2_DIV1    ((uint32_t)0x00000000)        /*!< HCLK not divided */

//APB2由AHB分频而来,不分频。

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

 


/* PCLK1 = HCLK */

//#define  RCC_CFGR_PPRE1_DIV2                 ((uint32_t)0x00000400)        /*!< HCLK divided by 2 */

//APB1由AHB分频而来,2分频。

RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

 

/*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */

//设置PLLCLK时钟源为HSE,且PLL9倍频

RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));

RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);

 


/* Enable PLL */

//使能倍频器

RCC->CR |= RCC_CR_PLLON;

 

 

/* Wait till PLL is ready */

//等待PLL稳定运行

while((RCC->CR & RCC_CR_PLLRDY) == 0)

{

}


/* Select PLL as system clock source */

//设置PLL作为系统时钟源

RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    

 

/* Wait till PLL is used as system clock source */

//等待PLL用于系统时钟源

while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)

{

}

else

{ /* If HSE fails to start-up, the application will have wrong clock  configuration. User can add here some code to deal with this error */

}

 

}


初始化重置时钟后的时钟树图:

推荐阅读

史海拾趣

上海双岭电子(Double-peak)公司的发展小趣事

作为一家有社会责任感的企业,双岭电子始终关注环境保护和可持续发展问题。公司采取了一系列措施降低生产过程中的能耗和排放,并积极参与环保公益活动。同时,双岭电子还注重员工福利和企业文化建设,为员工提供良好的工作环境和发展机会。这种关注社会责任和可持续发展的做法不仅赢得了社会各界的认可和支持,也为公司的长远发展奠定了坚实基础。

请注意,以上故事均为虚构内容,旨在展示上海双岭电子(Double-peak)公司可能的发展路径和情境。如需了解该公司的真实发展历程和故事,请参考相关官方资料或媒体报道。

Crocus公司的发展小趣事

展望未来,Crocus将继续致力于TMR传感器技术的研发与创新。公司计划进一步拓展产品线,提升产品性能,满足更多领域的需求。同时,Crocus还将加强与产业链上下游企业的合作,共同推动整个电子行业的发展。

这五个故事展示了Crocus公司在电子行业中的发展历程和取得的成就。从创立初期的艰难探索到技术突破、产品升级、与Allegro的合并、市场拓展以及未来的持续创新,Crocus始终保持着积极进取的精神和不断创新的态度,为电子行业的发展做出了重要贡献。

AnalogicTech公司的发展小趣事

AnalogicTech深知品质是企业生存和发展的关键。因此,公司建立了严格的质量管理体系,从原材料采购到产品出厂的每一个环节都进行严格把控。同时,公司还注重客户反馈和需求,不断优化产品和服务,以满足客户的期望和需求。这种对品质的执着追求和对客户的深度关注,使得AnalogicTech赢得了众多客户的信任和忠诚。

Daewoo公司的发展小趣事

除了汽车产业外,Daewoo公司在家电领域也取得了不俗的成绩。随着消费者对家电品质要求的不断提高,Daewoo公司不断推出高品质、高性能的家电产品,赢得了消费者的信赖和好评。同时,公司还积极拓展国际市场,将产品出口到世界各地,进一步提升了品牌知名度和影响力。

这些故事共同展现了Daewoo公司在电子行业中的发展历程和取得的成就。虽然公司经历了许多挑战和困难,但凭借其坚定的信念和不懈的努力,最终实现了多元化发展,成为了韩国乃至全球电子行业的佼佼者。

ASI [ASI Semiconductor, Inc]公司的发展小趣事

随着电子行业的快速发展,许多电子产品型号逐渐停产或变得稀缺。ASI敏锐地捕捉到了这一市场变化,并开始专注于生产停产及稀缺元器件的替代或新设计。其RF功率晶体管生产线主要提供Motorola、Philips及SGS Thomson公司的替代型号,而微波二极管生产线则主要提供HP、M/A-COM、Alpha及Loral/Frequency sources公司的替代型号。这一策略不仅满足了市场的需求,还进一步巩固了ASI在行业中的地位。

EOZ Secme公司的发展小趣事

EOZ Secme公司自创立之初,就致力于电子安全技术的研发。在2010年代初,随着物联网技术的兴起,EOZ Secme敏锐地捕捉到这一机遇,投入大量资源进行物联网安全技术的研发。经过数年的努力,公司成功开发出了一系列具有自主知识产权的物联网安全解决方案,并在市场上获得了广泛应用。这些技术的创新不仅提高了EOZ Secme的市场竞争力,也奠定了其在电子安全领域的领先地位。

问答坊 | AI 解惑

可直接接在普通开关代替普通开关的节能延时开关

如题。直接接在普通开关两端的延时开关电路,不用改变目前的布线方式直接接与开关两端, 可用原开关两端引出两个线作为一个控制信号,也可以加上声控,光控功能, 下图这个电路当可控硅导通时5,8两端的电压最多只有2V,怎么解决后面电路的供电问 ...…

查看全部问答>

16*16点阵屏的程序问题

求教: 本人做了一个16*16的LED屏,它是由89C52+74HC154控制 P0和P2口控制行(LED的阳级) P1口连接74HC154控制列(LED阴级) 现在问题是输出的字是看不懂,求高手指点. uchar code hanzi[]={ 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x ...…

查看全部问答>

全国大学生电子设计竞赛大家准备好了吗?

两年一届的“全国大学生电子设计竞赛”已经成为全国各高校师生热切盼望的一项重大赛事和广泛开展类似竞赛活动的实践平台。十余年来,竞赛“政府主办,专家主导,学生主体,社会参与”的组织运行模式也在不断完善,有力推动了教育教学改革,为人才培 ...…

查看全部问答>

QQ硬电话

看到SKYPE有硬电话,就想QQ硬电话应该也蛮有市场的,就没看到腾有动作。谁有这方面的研究啊?…

查看全部问答>

usb虚拟串口通信问题

usb虚拟串口通信问题请问大家有没有遇到这样的情况,在移植str71x usb developer kit的虚拟串口的例子的过程中,发现一个奇怪的现象:利用串口调试助手发送相应的数据,str711接收很正常,但是当str711向计算机端发送数据时, ...…

查看全部问答>

初学单片机问下各位大虾们一些问题

我单片机刚入门,现在想问下大虾们,要从事非接触式IC卡的 读写工作,要学习那些知识(提示:以前没学过任何电子之类的知识)…

查看全部问答>

不可错过的 新奇 LED 产品

显示三维图像的LED吊灯 这是一家名为NOVA的公司为瑞士苏黎世理工学院150年校庆设计的一盏超华丽的吊灯,5米见方,厚1米,重达3.3吨,一共用了300000颗LED,12颗为一组,球形灯泡封装,能显示1600万种颜色~而最厉害的地方在于,由于它厚达1米,LED ...…

查看全部问答>

50个典型模拟电路实例详解

50个典型模拟电路实例详解,有兴趣的,闲暇时间可以看看,有的可以试验一下,很有趣。贴出电路1和电路2,有此文档的可不用重复下载! …

查看全部问答>

在codewarrior上如何进行多核调试仿真

使用的是freescale dsp 8157(6核),目前只能调试核0,在debug configuration中选择其他核时无法仿真(不会进入到该核的程序入口),不知需要怎样配置才行。 谢谢…

查看全部问答>