单片机如何从上电复位开始执行主要功能?
\\\\\\插播一条:文章末尾有惊喜哟~///\\ \\ \\插一句:文末有惊喜~//
从事嵌入式开发的合作伙伴可能想过一个问题。一般我们使用芯片厂商提供的驱动库和初始化文件,直接从主函数开始写程序。那么,系统上电后,如何将程序引导到主函数中执行呢?还有,系统上电后RAM中的数据是随机的,那么定义的全局变量的初始值是如何实现的呢?
带着这两个问题,我将以Cortex-M架构为例,用IAR EWARM作为编译工具链,从系统上电后执行的第一段代码开始,梳理系统的启动过程,从而了解编译器在此期间所做的工作。其他工具链,如Keil和GCC,在系统初始化过程中也做类似的工作,只是具体实现不一样。
1.启动文件
芯片厂商提供的启动文件一般都是用汇编语言写的,少数是用C语言写的。通常,启动文件中至少有两个本地内容:
1.向量表
2.默认中断和异常处理程序
向量表实际上是一个数组,放在内存的零地址,每个元素存储每个中断或异常处理程序的入口地址。以基于IAR工具的STM32F107芯片启动文件为例:
在文件的开头,定义了一个名为__vector_table的全局符号。“数据”的作用是在代码段中定义一个数据区,作为向量表使用。数据区的内容是由DCD指令定义的32位宽度常数。除了第一个sfe(CSTACK),其他常量都是异常和中断服务程序的地址(编译时会用函数的入口地址替换函数名)。Sfe(CSTACK)是一种IAR汇编程序段操作,用于获取段的结束地址。这里的意图是什么?
其实这是一个获取堆栈基址的操作。IAR在链接器脚本(*。icf)文件,实际上定义了一个空 free block,名为“CSTACK”,如下图的脚本命令所示。所谓块,就是保留一个不间断的地址空作为栈或者堆使用。当然,块也可以是面向内容的,例如,它们可以用于管理段,但这超出了今天讨论的范围。
我们知道Cortex-M架构的栈模型是全栈归约,栈从高地址向低地址增长,所以栈的基址就是CSTACK的结束地址。
向量表的第一个元素是堆栈基址,由Cortex-M架构定义。系统上电后,硬件自动从向量表中获取并设置主堆栈指针MSP,不像其他ARM架构需要软件设置堆栈指针。
向量表中的第二个元素是复位异常的入口地址(Reset_Handler)。系统上电后,硬件自动从__vector_table+4的位置读取,最初从读取地址开始执行。系统上电后CPU执行的第一句话就是Reset_Handler函数的第一条语句。
上面的THUMB命令表示下一段代码采用THUMB模式(Cortex-M只支持Thumb-2指令集);节用于定义一个名为\”的段。ResetHandler”并且段的类型是代码;REODER表示打开一个具有给定名称的新段;ROOT表示链接器,当段中的符号没有被引用时,链接器不能丢弃该段。
PUBWEAK是一个弱定义。如果用户在另一个位置写一个中断处理程序,用户在启动文件中写的服务函数在连接时实际链接时会被忽略。之所以所有的异常和中断服务函数都要以弱定义的方式写在启动文件中,是为了防止用户在没有写服务函数的情况下启动和触发中断,从而导致系统不确定性。
2.系统初始化过程
EWARM >调试器>中的工程选项;选中设置中的“运行到”进行取消,这样调试后将停止第一个要执行的代码的位置:
调试完成后,它会停在启动文件中Reset_Handler函数的第一条汇编指令的位置:
此时,通过寄存器观察窗口,SP的值为0x20009820。通过链接时生成的映射文件看一下CSTACK的地址范围,0x20009820正好是CSTACK的结束地址。有了MSP,C代码就可以运行了。
YstemInit功能是芯片厂商根据ARM的CMSIS规范提供的系统配置功能,比如配置时钟系统,重新定位向量表等。这里的LDR是一条伪指令,它将SystemInit函数的地址加载到寄存器R0中,实际上是通过PC偏移量寻址获得SystemInit的地址。
从上图可以发现一个问题。在反汇编窗口中,我们可以观察到SystemInit的地址是0x20000150,但是加载到R0寄存器后,它是0x20000151。这是因为当用跳转指令更新PC时,PC的L应置1以指示THUMB模式。由于Cortex-M不支持ARM模式,L始终为1。
执行芯片厂商提供的SystemInit函数后,跳转到__iar_program_start,这是iar编译器提供的初始化代码入口。
__iar_program_start会先执行__iar_init_core和__iar_init_vfp两个函数,可以完成一些与CPU和FPU相关的初始化操作。这两个函数会存在于ARM架构的一些打包的运行时库中,用户可以自己重写这两个函数来实现一些相关的操作。
之后,跳转到__cmain函数执行。在__cmain中调用一个__low_level_init函数,专门用来给用户提供一个初始初始化操作,在全局变量初始化之前执行,比如可以在__low_level_init中初始化SDRAM,这样就可以在SDRAM中定义和使用全局变量。
__low_level_init可以在任何C文件中编写。注意它的返回值。如果返回0,后面会跳过变量初始化操作,正常情况下会返回1。
3.全局变量的初始化
之后进入__iar_data_init3函数,在这里将完成所有带有初始值的全局/静态变量的赋值和全局/静态变量的零初始化。分别调用__iar_copy_init3和__iar_zero_init3,将链接器在ROM区生成的变量初始值复制到变量的地址。注意,新EWARM版本的默认变量初始化操作可能采用压缩算法,实际变量初始化调用的函数可能不同。
在全局变量初始化之前,您可以通过“监视”窗口看到变量的值是随机数。
__iar_data_init3执行完成后,所有变量的初始值赋值都已完成。
在__cmain函数的最后,跳转到用户的main函数,最后开始用户的代码执行。
知道了编译器提供的初始化流程和处理器架构,我们就可以根据自己的需求定制系统的初始化。
比如在进入__iar_program_start之前,可以进行必要的硬件初始化操作,可以用汇编或者c写,也可以手动控制变量的初始化操作,自己实现变量的初始化。甚至有可能从复位序列引导到主函数,而根本不使用IAR编译器提供的初始化操作。
硬件开发工具:
Altium Designer 17.1
编程开发工具:
KEIL 4
程序下载工具:
STC-ISP
串口驱动程序:
CH341SER
单片机最小系统介绍
微控制器是一种集成电路芯片。它是一个集CPU、RAM、ROM、各种I/O口、中断系统、定时器/计数器(可能包括显示驱动电路、脉宽调制电路、模拟多路复用器、A/D转换器等功能于一体的小型完善的微机系统。)用超大规模集成电路技术集成到硅芯片中。从80年代开始,从当时的4位、8位单片机到300米高速单片机。本文中的单片机指的是51单片机,详细的芯片型号为STC89C52RC。需要注意的是,STC89C51、STC89C52、AT89C51、AT89C52都是51单片机的详细芯片型号。
最低系统组成:
单片机最小系统:单片机、复位电路、晶振(时钟)电路、电源。
最小系统使用的引脚
1.主电源引脚(2个引脚)
VCC:电源输入和写入,连接+5V电源。
GND:地线
2.外部晶体振荡器引脚(2个引脚)
XTAL1:片内振荡电路的输入和写入端
XTAL2:片内振荡电路的输出端
3.控制引脚(4个引脚)
RST/VPP:复位引脚
电源
设计中使用的电源接口是DC 5V。U支架可以找到手机的充电口,电脑的U端取电。接好线后,按下电源开关,单片机就可以初步工作了。
输入和写入电源和启动按钮
DC 5V连接线
重接电路
重接电路
电路图中,电容大小为10uf,电阻大小为10k。
在5V正常工作的51单片机中,小于1.5V的电压信号为低电平信号,大于1.5V的电压信号为高电平信号。可以计算出,当电容充电到0.7倍电源电压时,即电容两端电压为3.5V,电阻两端电压为1.5v,大约需要T=RC=10K*10UF=0.1S..
也就是说,在微控制器上电的0.1S内,电容两端电压从0-3.5V递增,10K电阻两端电压此时从5-1.5V递减(串联电路中电压之和为总电压),因此RST引脚接管的电压为5V-1.5V,即从高电平到低电平的过程。
单片机的RST引脚高电平有效,即复位;低电平没有影响,就是单片机正常工作。因此,在启动的0.1S内,单片机系统的RST引脚接管了持续时间约为0.1S的高电平信号,从而实现了自动复位。
微控制器启动0.1S后,电容C上的电压持续充电至5V。此时,10K电阻两端的电压接近0V,RST处于低电平,系统工作正常。按下该键时,开关打开。此时电容两端形成回路,电容短路。因此,在按键的过程中,电容器最初释放先前充入的电力。随着时间的推移,电容的电压在0.1S内从5V释放到1.5V甚至更小,根据串联电路电压是所有地方的总和,此时10K电阻两端的电压为3.5V,甚至更大,所以RST管脚接高电平。单片机系统的自动复位。
晶体振荡器电路
晶体振荡器电路
晶体振荡器的基本概念晶体振荡器称为晶体振荡器。每个单片机系统都有晶体振荡器,它是由应时晶体加工而成,镀有电极。其主要特点是通电后会产生机械振动,可以为单片机提供稳定的时钟源。晶体振荡器提供的时钟频率越高,单片机的运行速度越快。晶体振荡器工作在谐振状态,晶体可以将电能和机械能相互转换,从而提供稳定准确的单频振荡。
晶振开始振动后,产生的振动信号会经过XTAL1引脚,依次经过振荡器和时钟发生器的处理,得到机器周期信号,作为指令操作的依据。51单片机常用的晶体振荡器有12M和11.0592M
部件清单和原型焊接
组件列表
CommentDescriptionDesignatorFootprintLibRefQuantity足迹自由数量
30P陶瓷电容C2,C3CAP-2.54Cap2
10uF/16V直插式电解电容器CE1CAP 1.5*4*8CE1
CON9直接插入排除10KJ0R SIP9-2.54CON91
CON22针针排列j4hr2.54-li-2pcon21
接头44引脚针脚JP3,p6hdr 2.54-LI-4p接头42
红色插件5mm ledledd1,led2led5mm-rled-5mm2。
CON84引脚P0引脚,P1,P2,P3HDR2.54-LI-8PCON84
钥匙自锁按钮POWER_BUTTONSW-8X8X8HEADER 3X21
DC 5V电源DC 5V插座PW _ 5V DC 05接头31
10K电阻器R1AXIAL0.3RES21
2K电阻R2,R3轴0.3RES22
触摸按键S1SW-0606SW-PB1。
带4K闪存ROMU1DIP40AT89C511的STC89C52RC8位微控制器
11.0592M晶体振荡器Y1OSC HC-49s晶体1
如果不想直接把芯片焊在板上,可以买一个黑色的锁座,如下图。规格为DIP40。
PCB板制作
方法一:学校实验室常用DIY腐蚀电路板制作(略)
方法二:送专业PCB厂。推荐嘉利创https://www.jlc.com/#
可以代发,需要请私信。
空电路板的正面和背面:
空板
焊接中的注意事项
直插式电解电容用LED灯分正负极。
电解电容器的正负分辨率;
1.看看物理外壳
2.看看针的长度:
电解电容器的阳极引线比较长,阴极略短。
LED灯的正负分辨率:
1.引脚的长度也能看出来,还有LED的正负极,长引脚是正极,短引脚是负极。
2.将万用表转到二极管位置,分别短接LED灯引脚。如果它是开着的,红色手写笔连接到正极。
最终物理对象:
焊接对象如图所示。
程序烧录和测试
测试用的51单片机型号为STC89C52RC,是国内品牌宏景科技STC量产的8051单片机。
试验码
#包括
#包括
//数据类型定义
typedef无符号字符uchar
typedef无符号整数单元;
uchar flag 1s = 0;
uint one _ sec _ flag = 0;
it test_led=p1^0;
void main()
{
EA = 1;//打开主机中断
TMOD = 0x 01;//T0的工作模式是模式1。
TH0 = 0X4C
TL0 = 0X00//11.0592M晶体振荡器50ms定时初始值
ET0 = 1;//允许定时器1中断
TR0 = 1;//启动定时器0
while(1)
{
If(flag1s)//每秒刷新一次。
{
TEST _ LED = 0;
}否则{
TEST _ LED = 1;
}
}
}
无效定时器0()中断1
{
TH0 = 0XBB
TL0 = 0X00
如果(++一秒钟标志
返回;//提前完成功能
}
if(标志1s)
{
flag 1s = 0;
}否则{
flag 1s = 1;
}
one _ sec _ flag = 0;
}
编译后,生成test.hex刻录文件。
下载器和下载驱动程序
STC89C52单片机下载器其实就是一个U转TTL的串口,如下图所示。
某宝上的下载器
驱动器:压缩包里的CH341SER.EXE
在将代码下载到微控制器之前安装驱动程序。
程序下载
硬件准备:
下载器的RXD连接到芯片的TXD(P30),下载器的TXD连接到芯片的RXD(P31)。这个设计引出了芯片的RXD和TXD,可以按上图所示连接。
软件准备:
STC-ISP.exe双击打开并下载步骤。
1选择单片机的型号。
2.选择下载器的串行端口。
3.打开编译生成的十六进制文件。
4.点击下载
下载界面
等待
此时,按下电源开关给微控制器上电,下载软件会识别微控制器,然后自动下载程序。下载成功后会有提醒。
刻录和写入成功
测试效果:测试LED灯每隔一秒闪烁一次。
新一代烧录工具——STM 32 cube programmer
STM32 Cube编程器(STM32 Cube Prog)是STM 32微控制器的专用编程工具。所有STM32用户都知道,程序调试完成后,需要将程序代码烧录在芯片上。一般有三种选择:通过调试接口【JTAG/SWD】?
艾堂发表于STM32…
学习STM32单片机不可绕过的串口
作为一个单片机初学者,你会乐意用程序点亮LED,还是乐意用程序点亮数码管?这是好事,也是继续学习的动力。但是数据相关的实验是进一步学习单片机和STM32的一道坎?
无糖的
MCS-51系列单片机串行通信实验(二)
1.实验目标1)掌握单片机串行通信的调试方法2)编写简单的串行通信协议2。实验设备1)装有Widows操作系统的计算机。2)调试软件keil仿真实验版keil插件串口调试工具软件- sscom虚拟调试串口
彩蛋:最近有同学跟我要单片机的资料,我特意花几个月时间,总结了我10年产品研发经验,资料包几乎覆盖了C语言、单片机、模电数电、原理图和PCB设计、单片机高级编程等等,非常适合初学者入门和进阶。除此以外,再含泪分享我压箱底的22个热门开源项目,包含源码+原理图+PCB+说明文档,不是市面上打包卖的那种课程,我认为教程多未必是好事,10年前我自学快,除了自身执行力以外,还有就是教程少。不要害羞做伸手党,等你一个小红点。后期我也会组建一些纯技术交流的小圈子,让大家能认识更多的大佬,有个好的圈子,你对行业的认知一定是最前沿的。彩蛋:最近有同学找我要单片机的资料。我花了几个月的时间总结了我10年的产品开发经验。资料包几乎涵盖了C语言、单片机、模拟与数字电学、原理图与PCB设计、单片机高级编程等。非常适合初学者入门和进阶。另外,我会和泪分享我衣橱最底层的22个热门开源项目,包括源代码+原理图+PCB+文档,不是市面上打包出售的那种课程。我觉得教程多不是好事。十年前,我自学很快。除了我自己的执行,也很少有教程。不要羞于做牵手党,等你做小红点。以后我也会建立一些纯技术交流的小圈子,让大家认识更多的大佬,有一个好的圈子。你的行业知识一定是最前沿的。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。