STM32单片机上电后时钟的默认配置过程

发布者:玉树琼花最新更新时间:2018-12-18 来源: eefocus关键字:STM32  单片机  上电后  时钟  配置过程 手机看文章 扫描二维码
随时随地手机看文章

写作原由:今日接手用stm32f100xx芯片开发的项目,以前用的是stm8s 和stm32f103xx芯片;因为在别人的项目代码的基础上做2次开发,但是发现那个代码main函数中没有对系统时钟的设置的相关函数,一直纳闷,但也没有深究,直至昨日 调试时出现串口收发数据出错,源代码在原项目的板子上串口发送、接收数据正常,同样程序在项目板子上收发的数据不正确, 两块板子芯片一样,串口收发管脚一样,最后发现原来板子外部晶振是8MHZ ,新板子外部晶振是12MHZ; 而在STM32固件库中,默认的外部晶振是8MHZ,由于时钟源不正确,导致波特率不正确,当然收发的数据也不正确了…..我勒个去!都怪自己平时看问题“不求甚解”。


波特率与时钟源关系公式: 
IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate))


为了深入思考,我提出了一些疑问,通过解答这些问题更深入的了解时钟;


问题一:对系统时钟的设置的相关函数,在main函数中找不到,那在哪里?还是说根本没有对系统时钟进行配置?


问题二:既然用了外部晶振做系统时钟,那为什么没看到启动外部晶振的操作?


问题三:串口的时钟源是什么?串口时钟源跟系统时钟的关系?


问题四:程序中串口时钟源是怎样实现对波特率的关系的?


现附上我找到上面3个问题答案做的一张框架图:希望博友参考此图理解我后面的内容:



在进入主题之前我们先了解一些必要的基础知识—-stm32系列芯片的种类和型号:


startup_stm32f10x_cl.s 互联型的器件,STM32F105xx,STM32F107xx 
startup_stm32f10x_hd.s 大容量的STM32F101xx,STM32F102xx,STM32F103xx 
startup_stm32f10x_hd_vl.s 大容量的STM32F100xx 
startup_stm32f10x_ld.s 小容量的STM32F101xx,STM32F102xx,STM32F103xx 
startup_stm32f10x_ld_vl.s 小容量的STM32F100xx 
startup_stm32f10x_md.s 中容量的STM32F101xx,STM32F102xx,STM32F103xx 
startup_stm32f10x_md_vl.s 中容量的STM32F100xx (我项目中用的是此款芯片 stm32f100CB) 
startup_stm32f10x_xl.s flash在512K到1024K字节的STM32F101xx,STM32F102xx,STM32F103xx 
cl:互联型产品,stm32f105/107系列 
vl:超值型产品,stm32f100系列 
xl:超高密度产品,stm32f101/103系列 
ld:低密度产品,FLASH小于64K 
md:中等密度产品,FLASH=64 or 128 
hd:高密度产品,FLASH大于128


(下图中的startup_stm32f10_ld.s应改为:startup_stm32f10x_md_vl.s)


stm32系列芯片系统时钟详解&&移植


问题一:对系统时钟的设置的相关函数,在main函数中找不到,那在哪里?还是说根本没有对系统时钟进行配置?


解答:高人指点,我看了一下启动文件startup_stm32f10x_md_vl.s,其中有一段汇编:


Reset handler
routineReset_Handler    PROC
        EXPORT  Reset_Handler             [WEAK]
        IMPORT  __main    
        IMPORT  systemInit                 
        BLX     R0                 
        LDR     R0, =__main
        BX      R0                 
        ENDP123456789


其中,


IMPORT __main IMPORT SystemInit      //IMPORT 声明了需要引用C语言中的main函数、systeminit函数,


LDR R0, = systeminint       //把systeminit 函数地址放到r0 寄存器;


BLX   R0    //跳到到R0 寄存器中的地址执行;


所以,在跳到main函数执行前,已经在SystemInit 函数中把系统时钟给设置好了;


问题二:既然用了外部晶振做系统时钟,那为什么没看到启动外部晶振的操作?


我们在解答这个问题前,先到SystemInit函数里面做更深入的了解:



我们进入setsysclock()函数,看其中作了哪些操作:



我项目中用的是此款芯片 stm32f100CB,内部晶振是24MHZ, 所以应进入执行SetSysClockTo24() 函数:



解析:


void SetSysClockTo24函数中主要做了下面几件事:(不同颜色功能分别对应上面对应颜色代码部分)


1.启动外部晶振作为系统时钟源;


2.等待外部晶振起振;


3.(起振后)对系统时钟源进行分频:(默认外部是HSE–8MHZ晶振) PLL configuration: = (HSE / 2) * 6 = 24 MHz


  1. 配置HCLK、PCLK1、PCLK2 与系统时钟源的关系;


问题三:串口的时钟源是什么?串口时钟源跟系统时钟的关系?


回答这个问题前,我们先来看stm32f100芯片手册数据图(第12页):


stm32系列芯片系统时钟详解&&移植


从图里面我们可看出串口1的时钟源是PCLK1;


上面问题2的代码中我们看到PCLK1是时钟源24MHZ的1分频,即还是24MHZ;


问题四:程序中串口时钟源是怎样实现对波特率的关系的?


由问题3我们知道串口时钟源是24mhz,依据公式:IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate)))


库中自动设置IntegerDivider 存入寄存器中;


关键字:STM32  单片机  上电后  时钟  配置过程 引用地址:STM32单片机上电后时钟的默认配置过程

上一篇:STM32 串行通信 USART 程序例举
下一篇:stm32时钟初始化分析

推荐阅读最新更新时间:2024-03-16 16:20

如何扭转电压比较器不被重视的问题
  电压比较器在单片机中的出现始于20世纪90年代末。当时,大家认为这项技术仅降低了成本而已。因为,这样的比较器需要的硅器件较少,又能使单片机比较两个模拟电压。于是,认为电压比较器仅仅是一个“1位ADC”的观点始终占据主导地位,并且一直持续到21世纪的头几年。   幸运的是,当8位单片机开始不断涉足更多的混合信号应用时,越来越多具有模拟背景的设计人员开始使用单片机。这些采用混合信号单片机的设计人员非常熟悉电压比较器的灵活性和功能,便着手发掘其潜能。使用片上电压比较器的应用不断涌现,包括传感器输出的模拟信号到数字信号的转换、逻辑门、放大器以及电源转换。   遗憾的是,混合信号单片机设计人员的人数尚不足以有效推广电压比较器。因此,
[单片机]
如何扭转电压比较器不被重视的问题
51单片机实现按住一个独立按键不松手的连续步进触发
一、使用proteus绘制简单的电路图,用于后续仿真 二、编写程序 /******************************************************************************************************************** ---- @Project: Independent-KEY ---- @File: main.c ---- @Edit: ZHQ ---- @Version: V1.0 ---- @CreationTime: 20200507 ---- @ModifiedTime: 2020
[单片机]
51<font color='red'>单片机</font>实现按住一个独立按键不松手的连续步进触发
单片机软复位几种方法
如从机收到复位命令(软件命令),程序怎么使机器复位?虽然要使软件始终处于可控状态,最好不要用 复位 ,因为复位是纯硬件过程,软件是不可控的.但是我们还是要讨论方法,一般流传的方法如下: 1、放狗; 2、((void(code *)(void))0x0000)(); 3、用单片机一个引脚控制点一下RSTRST; 4、用单片机一个引脚控制重新加电; 5、用单片机自带的软件复位指令或内狗指令; 6、goto大法; 方法1: 放狗 是单片机软复位的最好办法,也基本上是唯一的一个办法。但并不是所有单片机都具备看门狗的功能,也不是一个万全之策。 办法2:这不是复位,只是把程序转到地址0
[单片机]
80C196单片机鼠标接口程序设计实例
摘要:通过对鼠标底层通信原理及协议的深入分析,探讨了鼠标在80C196单片机系统中的应用价值与可行性,并介绍了鼠标接口软件设计的原理及方法,给出了80C196单片机与Microsoft鼠标的具体接口程序。 关键词:鼠标 接口技术 软件设计 接口程序 80C196单片机由于低格低、处理能力强,在信号分析、数据采集等很多领域得到了广泛应用,在目标系统中使用各种规格的液晶或CRT显示器也越来越多。因此在这样的单片机系统中引入鼠标,将会方便操作,提高工作效率。鼠标内核本质上是一个二维的角度或位移信号检测装置,耗电极少、可靠性高、价格低廉,可能在许多场合发挥作用。鼠标与主机之间通过RS-232标准串行接口进行通信,信息传送是单方向、无条
[单片机]
单片机中用c编程时头文件reg51.h及reg52.h解析
单片机中用c编程时头文件reg51.h及reg52.h解析 我们在用c语言编程是往往第一行就是reg51.h或者其他的自定义头文件,我们怎么样来理解呢? 1) 文件包含 处理。 程序的第一行是一个 文件包含 处理。 所谓 文件包含 是指一个文件将另外一个文件的内容全部包含进来。程序中包含REG51.h 文件的目的是为了要使用P1 (还有其他更多的符号)这个符号,即通知C 编译器,程序中所写的P1 是指80C51 单片机的P1 端口而不是其它变量。这是如何做到的呢? 打开reg51.h 可以看到这样的一些内容: (此文件一般在C:KEILC51INC下 ,INC文件夹根目录里有不少头文件,并且里面还有很多以公司分类
[单片机]
单片机74LS138扩展中断
硬件连接: 代码: #include reg52.h #include intrins.h #define uchar unsigned char #define uint unsigned int sbit LED = P1^0; void EX_INT0() interrupt 0 { uchar bi = P2 & 0x07; P0 = _cror_(0x7f,bi); } void main() { uint i; IE = 0x81; IT0 = 0; while(1) { LED = !LED; for(i=0;i 30000;i++);
[单片机]
<font color='red'>单片机</font>74LS138扩展中断
MSP430的学习(3)
MSP430单片机具有基本定时器(Basic Timer1),经常用于低功耗当中,他工作的目的就是支持软件和各种外围模块工作于低频率 低功耗条件下。通过对SMCLK或者ACLK进行分频,向其他外围模块提供低频控制信号。 Bacis Timer1有两个计数单元(BTCN1 BTCN2和一个控制单元BTCTL。他可作为两个独立的8位定时器或一个16位定时器。 一:Basic Timer1的寄存器 同过控制仅存器的设置可以对计数单元BTCNT1 BTCNT2进行软件控制。当出现异常状况时,该寄存器各位保持原状态。用户程序在Basic Timer初始化期间来设定操作条件。 1:BTCTL控制寄存器:其信息决定了Timer1的运行状况
[单片机]
八位微控制器有哪些可以节约代码空间的代码优化技巧?
本文将介绍一些优化技术,帮助设计人员节约多达 10% 的代码空间,从而让容量有限的程序存储器支持更多新特性和补丁。 良好的操作方法 许多程序员在 32 位处理器上学习编写软件,如 Intel 的 Pentium 处理器或某种 ARM 平台。不过,嵌入式领域的软件编写需要不同的思路。在 32 位 CPU 上,存储比特位的最佳方法通常是使用 32 位变量。对 8 位处理器而言,最好的办法就是采用单字节。像增强型 8051s 等某些处理器可能提供特殊的 1 位变量。 嵌入式处理器通常会超出标准的哈佛架构将存储器分散到不同的存储器空间中,有的相互重叠,有的又是相互分离。例如,8051 中常见的存储器空间包括 CODE、XDATA、DA
[单片机]
八位<font color='red'>微控制器</font>有哪些可以节约代码空间的代码优化技巧?
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved