技术文档

单片机复位后sp= 跟电师傅学单片机(19):单片机控制转移指令图文讲解3

小编 2024-11-25 技术文档 23 0

跟电师傅学单片机(19):单片机控制转移指令图文讲解3

一:绝对调用指令

绝对调用指令表

在实际单片机程序编程中,有时需要在主程序里面引用另外一段程序,引用的程序一般称为子程序,子程序可以多次反复调用,用起来很方便,还减少了编程程序的长度。

比如,要用到一个延时程序。怎么用呢?就是要把延时程序存放到程序存储器ROM单元中,只要知道存放的地址,用这个指令ALL addr11就可转去运行这个延时程序,运行完后还能返回。

addr11:调用程序的范围:2的11次方=2K

ALL addr11绝对调用指令最大的特点:调用了还能回来。

前面讲的有条件和无条件指令是:转走了就不用回来了。

但是它们类似的地方: 都是转移指令。

ALL addr11指令功能:

子程序短调用指令。是主程序调用子程序,调用子程序的范围是2KB。

PC:是单片机程序计数器,程序从哪里执行,完全由PC里的内容决定,始终是指定下一条将要执行指令的地址(是16位地址),单片机系统上电或复位时,PC的初始值为0000H。

SP:是51单片机堆栈指针,是一个专用的8位寄存器,系统复位后,SP初始化为07H,使得堆栈指针实际上是由08H单元开始。堆栈用于存储子程序调用、中断程序调用时程序返回的地址,或者用来临时保存某一寄存器的值。

二:长调用指令

长调用指令表

addr16:调用程序的范围:2的16次方=64K

ALL addr16指令功能:

子程序长调用指令,也称为远程调用指令。是主程序调用子程序,调用子程序的范围是64KB。

三:返回指(2条)

返回指令表

RET指令功能:

是子程序返回指令。是使子程序返回主程序。RET返回指令要与调用指令成对出现,缺一不可,否则会出现错误。

RET返回指令使用时应放在子程序的末尾,该指令可从堆栈中取出断点地址,送回是单片机程序计数器PC,并从断点处开始继续执行程序,即是单片机程序计数器PC指向主程序调用该子程序指令的下一个地址。

RETI指令功能:

中断子程序返回指令,使中断子程序返回主程序。

RET指令和RETI指令共同点:

基本功能是相同的,都是使子程序返回主程序,使单片机程序计数器PC指向下一个地址的指令。

RET指令和RETI指令区别:

在执行RETI指令时,还将清除中断响应时所置位的优先级状态触发器,开放中断逻辑,使得已申请的较低级的中断源可以响应。

四:空操作指令

空操作指令表

NOP指令功能:

空操作指令,它不作任何操作,但要消耗一个机器周期的时间,一般用于单片机程序延时或等待。

到此为止,17条单片机控制转移类指令讲解完毕,谢谢阅读!欢迎留言讨论,共同提高!

单片机如何从上电复位执行到main函数?

单片机如何从上电复位执行到main函数?

\\\插播一条:文章末尾有惊喜哟~///

从事嵌入式开发的搭档可能会思考过一个问题,我们一般都是使用芯片厂商提供的驱动库和初始化文件,直接从main函数初始写程序,那么系统上电之后,程序怎么引导进main函数执行的呢?还有,系统上电之后RAM的数据是随机的,那么定义的全局变量的初始值又是怎么实现的呢?

下面我将带着这两个问题,以Cortex-M架构为例,采用IAR EWARM作为编译工具链,从系统上电之后执行的第一条代码初始,梳理系统的启动过程,了解编译器在此期间所做的工作。其他的工具链,如Keil和GCC在系统初始化过程所做的工作也是相似的,但详细的实现有所差异。

1、启动文件

芯片厂商提供的启动文件,一般是采用汇编语言编写,少数用C语言。在启动文件中一般至少存在下面两个局部内容:

1、向量表

2、默认的中断和异常处理程序

向量表实际上是一个数组,放置在存储器的零地址,每个元素存储的是各个中断或异常处理程序的入口地址。以STM32F107芯片基于IAR工具的启动文件为例:

文件的开头定义了一个名为__vector_table的全局符号,“DATA”的作用是在代码段中定义一个数据区,用作向量表。数据区的内容是使用DCD指令定义的32位宽度常量,除了第一个sfe(CSTACK)比较特殊以为,其他的常量都是异常和中断效劳程序的地址(在编译时函数名会被替换成函数的入口地址)。sfe(CSTACK)是IAR汇编器段操作,用于获取段(section)的完毕地址,在这里意欲何为呢?

实际上这是获取堆栈基地址的操作。IAR在链接器脚本(*.icf)文件中定义堆栈,实际是定义了一个名为“CSTACK”的空闲块(block),如下图的脚本命令所示。所谓的块就是保留一段不间断的地址空间,用来作为堆栈或者堆。当然,块也能够是用内容的,例如能够用来管理段,但不在今天的探讨范围。

我们知道Cortex-M架构的堆栈模型是满减栈,堆栈从高地址向低地址增长,因此堆栈的基地址是CSTACK的完毕地址。

向量表的第一个元素是栈基址这是由Cortex-M架构定义的。系统上电后硬件自动从向量表中获取,并设置主堆栈指针MSP,而不是像其他ARM架构,堆栈指针须要通过软件来设置。

向量表中第二个元素是复位异常(Reset_Handler)的入口地址。系统上电后,硬件自动从__vector_table + 4的位置读取,并从读取到的地址初始执行。系统上电后CPU执行的第一条是Reset_Handler函数的第一条语句。

上面的THUMB命令表示接下来的代码采用THUMB模式(Cortex-M只支持Thumb-2指令集);SECTION用于定义一个段,段名为“.ResetHandler”,段的类型是代码(CODE);REODER指示用给定的名称开启一个新的段;ROOT指示链接器,当段内的符号没有被引用,链接器也不能够丢弃这个段。

PUBWEAK是弱定义,假如用户在其他位置编写了中断处理函数,在连接时实际链接用户所编写的,启动文件中用汇编写的效劳函数会忽略。之所以要在启动文件中以弱定义的方式编写全部的异常和中断效劳函数,是为了防止用户在没有编写效劳函数的情况下开启并触发了中断,导致系统的不确定。

2、系统初始化过程

在EWARM的工程Options > Debugger > Setup中将“Run to”勾选取消,这样在进入调试之后就会停第一条要执行的代码的位置:

进入调试之后会停在启动文件Reset_Handler函数第一条汇编指令位置:

此时,通过寄存器观察窗口查看SP的值为0x20009820。通过链接时生成的map文件,查看CSTACK的地址范围,0x20009820正好是CSTACK的完毕地址。有了MSP,C代码就能运行了。

ystemInit函数是芯片厂商依据ARM的CMSIS规范提供的一个系统根底配置函数,配置根底的时钟系统和向量表重定位等。这里的LDR是伪指令,它将SystemInit函数的地址加载到寄存器R0,实际上是通过PC偏移寻址来获取SystemInit的地址。

从上面的图能够发现一个问题,在反汇编窗口能够观察到SystemInit的地址是0x20000150,但加载到R0寄存器后却是0x20000151。这是由于在使用跳转指令更新PC时,须要置PC的LSB为1,以表示THUMB模式,由于Cortex-M不支持ARM模式,因此LSB总是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版本默认变量初始化操作可能会采用压缩算法,实际变量初始化调用的函数可能有区别。

在全局变量未初始化之前,通过watch窗口能够看到,变量的值都是随机数。

在__iar_data_init3执行完成后,全部变量的初值赋值已经完成。

在__cmain函数的最后,跳转到用户的main函数,最终初始用户的代码执行。

了解了编译器所提供的初始化过程和处理器架构,我们能够依据自己的需求定制系统的初始化。

例如,在进入__iar_program_start之前,就能够执行必要的硬件初始化操作,能够用汇编写,也能够用C写。还能够手动控制变量的初始化操作,自己实现变量的初始化。甚至,完全不采用IAR编译器提供的初始化操作,自己从复位序列引导至main函数那也是能够的。

硬件开发工具:

Altium Designer 17.1

编程开发工具:

KEIL 4

程序下载工具:

STC-ISP

串口驱动:

CH341SER

单片机最小系统介绍

单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理才能的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统,在工业控制领域广泛应用。从上世纪80年代,由当时的4位、8位单片机,开展到此时的300M的高速单片机。本文的单片机特指51单片机,详细芯片型号是STC89C52RC。需注意STC89C51,STC89C52,AT89C51,AT89C52都是51单片机的一种详细芯片型号。

最小系统组成:

51单片机最小系统:单片机、复位电路、晶振(时钟)电路、电源

最小系统用到的引脚

1、主电源引脚(2根)

VCC:电源输写,接+5V电源

GND:接地线

2、外接晶振引脚(2根)

XTAL1:片内振荡电路的输写端

XTAL2:片内振荡电路的输出端

3、控制引脚(4根)

RST/VPP:复位引脚

电源

设计使用的电源接口是DC 5V。USB座能够查到手机充电口,电脑USB端取电。接好线路后,按下电源开关,单片机即可初始工作。

输写电源及启动按键

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 Pin排针J4HDR2.54-LI-2PCON21

HEADER 44 Pin排针JP3, P6HDR2.54-LI-4PHEADER 42

红色直插5mm LEDLED1, LED2LED 5MM-RLED-5MM2

CON84 Pin排针P0, P1, P2, P3HDR2.54-LI-8PCON84

KEY自锁按键POWER_BUTTONSW-8X8X8HEADER 3X21

DC 5V电源DC 5V插座PW_5VDC05HEADER 31

10K电阻R1AXIAL0.3RES21

2K电阻R2, R3AXIAL0.3RES22

SW-PB轻触按键S1SW-0606SW-PB1

STC89C52RC8-Bit Microcontroller with 4K Flash ROMU1DIP40AT89C511

11.0592M晶振Y1OSC HC-49SCRYSTAL1

假如不想直接焊芯片到板子,能够买个下图黑色的紧锁座。规格选DIP40

PCB板制作

方法1:学校实验室常用的DIY腐蚀电路板制作(略)

方法2:外发给专业的PCB工厂。举荐嘉立创https://www.jlc.com/#

可代发,须要请私信

空板正反面:

空板

焊接注意事项

直插电解电容,和LED灯是有正负极之分的。

电解电容正负极分辨:

1.看实物套管

2.看引脚长短:

电解电容正极引线比较长、负极稍短

LED灯正负极分辨:

1.引脚长短也能够看出来,发光二极管的正负极,引脚长的为正极,短的为负极。

2.万用表打到二极管档,分别短接LED灯引脚,假如亮,红表笔接的是正极。

最终实物:

焊接好的实物如图

程序烧录及测试

测试用的51单片机型号是STC89C52RC,是国产品牌宏晶科技STC量产的8051单片机。

测试代码

#include

#include

//数据类型定义

typedef unsigned char uchar;

typedef unsigned int uint;

uchar flag1s = 0;

uint one_sec_flag = 0;

sbit TEST_LED=P1^0;

void main()

{

EA=1;//开总中断

TMOD=0X01;//T0的工作模式为模式1

TH0=0X4C;

TL0=0X00;//11.0592M晶振 50ms定时初值

ET0=1; //允许定时器1中断

TR0=1;//启动定时器0

while(1)

{

if(flag1s)//一秒刷新一次

{

TEST_LED = 0;

}else{

TEST_LED = 1;

}

}

}

void Timer0() interrupt 1

{

TH0=0XBB;

TL0=0X00;

if(++one_sec_flag

return;//提前完毕函数

}

if(flag1s)

{

flag1s = 0;

}else{

flag1s = 1;

}

one_sec_flag=0;

}

编译之后产生test.hex烧录文件。

下载器及下载驱动

STC89C52单片机下载器实际上就是USB转TTL串口,如下图所示

某宝上的下载器

驱动:压缩包中的CH341SER.EXE

先安装驱动才能下载代码到单片机中。

程序下载

硬件准备:

下载器的RXD连接芯片的TXD(P30),下载器的TXD连接芯片的RXD(P31),本设计引出了芯片的RXD和TXD,如上图所示连接即可。

软件准备:

STC-ISP.exe双击翻开,下载步骤

1选择选择单片机型号

2.选择下载器的串口

3.翻开编译生成的HEX文件

4.点击下载

下载界面

等待

此时,按下电源开关给单片机上电,下载软件会识别出单片机,然后自动下载程序。下载成功后会有提醒。

烧写成功

测试效果:测试LED灯一秒间隔闪烁。

新一代烧写工具 - STM32CubeProgrammer

STM32CubeProgrammer(STM32CubeProg)是STM32微控制器的专用编程工具。 STM32用户都知道,当完成程序调试,须要对芯片进行程序代码烧录编程,一般会有三个选择:通过调试接口【JTAG/SWD】?

AI电堂发表于STM32...

进修STM32单片机,绕不开的串口

刚初始学单片机的你,是不是会因用程序把LED点亮而感到高兴,会因用程序把数码管点亮而感到高兴。这是好事,这也是想继续进修下去的动力。但是数据相关的实验是进修单片机和STM32的一道坎?

SugarlesS

MCS-51系列单片机串口通讯实验(2)

1.实验目标1)掌握51单片机串行通讯调试方法 2)会简略的串行通讯协议编写 2.实验器材1)Widows操作系统的电脑。 2)调试软件 keil仿真实验版keil外挂串口调试工具软件--sscom虚拟调试串口

彩蛋:最近有同学跟我要单片机的资料,我特意花几个月时间,总结了我10年产品研发经验,资料包几乎覆盖了C语言、单片机、模电数电、原理图和PCB设计、单片机高级编程等等,非常适合初学者入门和进阶。除此以外,再含泪分享我压箱底的22个热门开源项目,包含源码+原理图+PCB+说明文档,不是市面上打包卖的那种课程,我认为教程多未必是好事,10年前我自学快,除了自身执行力以外,还有就是教程少。不要害羞做伸手党,等你一个小红点。后期我也会组建一些纯技术交流的小圈子,让大家能认识更多的大佬,有个好的圈子,你对行业的认知一定是最前沿的。

相关问答

51系列 单片机 为()位单片机.2.8051单片机有两种 复位 方式,既...

[最佳回答]1.MCS-51系列单片机为(8)位单片机.2.8051单片机有两种复位方式,既上电复位和手动复位.复位后SP=(07H),PC=(0000H),PSW=(00H),P0=(F...

【有谁会做这5道关于 单片机 的填空题1. 单片机复位 时PC=H, SP= H...

[最佳回答]1.0000H,07H,第0组2.程序,数据,三,SFR,21个3.没看懂你的空在哪?可以看成是数据总线,地址总线和控制总线!4.外部中断0,外部中断1,定时/计数器0...

当“ SP 被赋值后” 单片机复位后 其值应为多少?

SP被赋值后单片机复位后其值应为:SP值为07H。复位期间不产生ALET和~PSEN信号。复位后PC值为0000H。P0---P3口值为FFH。一、单片机简介:SP被赋值后单片机复位...

单片机 sp 是什么意思啊-ZOL问答

SP指的是堆栈指针详细解释如下:堆栈是一种数据结构,和他相类似的有队列。如果对数据结构有这样的要求:先将数据放到该区内,先放的后出后放的先出。这种结构...

单片机 中的问题:MCS-51 复位 时,ACC、PSW、 SP 、P0~P3的值分别是多少?

特殊:堆栈SP=07H;P0,P1,P2,P3,P4为0FFH;其他都为0;所以ACC=0;PSW=0;特殊:堆栈SP=07H;P0,P1,P2,P3,P4为0FFH;其他都为0;所以ACC=0;...

单片机复位 是什么意思?有什么作用-ZOL问答

单片机复位是什么意思?有什么作用讨论回答(6)首先你要知道单片机是属于数字电路,数字电路就只有“0”低电平和“1”高电平两个状态。这两状态是已知状态...

单片机 测试题二,填空题(共5题,每空1分)1. 复位 SP 的值为__...

[最佳回答]分开答吧,我答前几题.后面的朋友继续.二,填空题(共5题,每空1分)1.复位时SP的值为_07H____,P1口的值为__0FFH_____.2.MCS-51单片机存储器物理上分...

有几道 单片机 的题想请教一下。1.51 单片机复位后 ,PC指向()RO...

[最佳回答]1.51单片机复位后,PC指向(00H)ROM地址。A.00HB.100HC.200HD.300H2.当单片机从8751芯片内部RAM的20H单元中读取某一数据时,应使用(MOVA,20...

51 单片机 sp 寄存器多少位?

151单片机的sp寄存器是8位的。251单片机是一种8位的微控制器,其寄存器的位数也是8位。SP寄存器是栈指针寄存器,用于指向栈的顶部位置,其位数也是8位。38位...

有哪几种方法使 单片机复位 ? 复位后 各寄存器、RAM中的状态如何?

上电复位,复位引脚复位,不管哪种复位,PC指针都指向0000H,再往后看程序做了哪些初始化程序,就知道,寄存器,RAM值了,上电复位,复位引脚复位,不管哪种复位,PC指...

猜你喜欢