单片机上电顺序_单片机程序执行顺序 - CSDN
  • 发生

    理解这篇文章之前,我们需要配合了解两个基础知识。

    一个是加载视图和运行试图,一个是单片机的存储空间。

    这篇文章会涉及两个新内容,而加载视图又涉及启动代码和Scatter文件。

    所以通过集成环境讲解启动代码总显得力不从心。

    这里我们从编译器和链接器开始讲起。

    1、C语言的编译都是按照文件进行编译的,编译完成后,每一个.c文件会生成相应的.o文件,这个过程是编译器(ARMCC)做的。

    2、因为各个.o的信息是分散的,函数变量都是们没有统一编址的,所以lds链接器需要将各个.o文件的信息汇总到一起,就是code+RO+RW的位置,这就形成了加载视图。

    3、启动代码starts.s 做一些基础工作外,根据Scatter文件的信息 ,对RW进行搬移,搬移到RAM中,方便后期的访问。

    4、搬移完成后,我们就可以访问全局变量了(这个时候全局变量都是在RAM里的,我们通过map文件看到的)

     

    展开全文
  • 单片机中用来存储程序数据及常量数据或变量数据,凡是c文件及h文件中所有代码、全局变量、局部变量、’const’限定符定义的常量数据、startup.asm文件中的代码(类似ARM中的bootloader或者X86中的BIOS,一些低端的...
    ROM:(Read Only Memory)程序存储器
    在单片机中用来存储程序数据及常量数据或变量数据,凡是c文件及h文件中所有代码、全局变量、局部变量、’const’限定符定义的常量数据、startup.asm文件中的代码(类似ARM中的bootloader或者X86中的BIOS,一些低端的单片机是没有这个的)通通都存储在ROM中。
    RAM:(Random Access Memory)随机访问存储器
    用来存储程序中用到的变量。凡是整个程序中,所用到的需要被改写的量,都存储在RAM中,“被改变的量”包括全局变量、局部变量、堆栈段。
    程序经过编译、汇编、链接后,生成hex文件。用专用的烧录软件,通过烧录器将hex文件烧录到ROM中(究竟是怎样将hex文件传输到MCU内部的ROM中的呢?),因此,这个时候的ROM中,包含所有的程序内容:无论是一行一行的程序代码,函数中用到的局部变量,头文件中所声明的全局变量,const声明的只读常量,都被生成了二进制数据,包含在hex文件中,全部烧录到了ROM里面,此时的ROM,包含了程序的所有信息,正是由于这些信息,“指导”了CPU的所有动作。
    可能有人会有疑问,既然所有的数据在ROM中,那RAM中的数据从哪里来?什么时候CPU将数据加载到RAM中?会不会是在烧录的时候,已经将需要放在RAM中数据烧录到了RAM中?
    要回答这个问题,首先必须明确一条:ROM是只读存储器,CPU只能从里面读数据,而不能往里面写数据,掉电后数据依然保存在存储器中;RAM是随机存储器,CPU既可以从里面读出数据,又可以往里面写入数据,掉电后数据不保存,这是条永恒的真理,始终记挂在心。
    清楚了上面的问题,那么就很容易想到,RAM中的数据不是在烧录的时候写入的,因为烧录完毕后,拔掉电源,当再给MCU上电后,CPU能正常执行动作,RAM中照样有数据,这就说明:RAM中的数据不是在烧录的时候写入的,同时也说明,在CPU运行时,RAM中已经写入了数据。关键就在这里:这个数据不是人为写入的,CPU写入的,那CPU又是什么时候写入的呢?听我娓娓道来。
    上回说到,ROM中包含所有的程序内容,在MCU上电时,CPU开始从第1行代码处执行指令。这里所做的工作是为整个程序的顺利运行做好准备,或者说是对RAM的初始化(注:ROM是只读不写的),工作任务有几项:

    1、 为全局变量分配地址空间---à如果全局变量已赋初值,则将初始值从ROM中拷贝到RAM中,如果没有赋初值,则这个全局变量所对应的地址下的初值为0或者是不确定的。当然,如果已经指定了变量的地址空间,则直接定位到对应的地址就行,那么这里分配地址及定位地址的任务由“连接器”完成。
    2、 设置堆栈段的长度及地址---à用C语言开发的单片机程序里面,普遍都没有涉及到堆栈段长度的设置,但这不意味着不用设置。堆栈段主要是用来在中断处理时起“保存现场”及“现场还原”的作用,其重要性不言而喻。而这么重要的内容,也包含在了编译器预设的内容里面,确实省事,可并不一定省心。平时怎么就没发现呢?奇怪。
    3、 分配数据段data,常量段const,代码段code的起始地址。代码段与常量段的地址可以不管,它们都是固定在ROM里面的,无论它们怎么排列,都不会对程序产生影响。但是数据段的地址就必须得关心。数据段的数据时要从ROM拷贝到RAM中去的,而在RAM中,既有数据段data,也有堆栈段stack,还有通用的工作寄存器组。通常,工作寄存器组的地址是固定的,这就要求在绝对定址数据段时,不能使数据段覆盖所有的工作寄存器组的地址。必须引起严重关注。
    这里所说的“第一行代码处”,并不一定是你自己写的程序代码,绝大部分都是编译器代劳的,或者是编译器自带的demo程序文件。因为,你自己写的程序(C语言程序)里面,并不包含这些内容。高级一点的单片机,这些内容,都是在startup的文件里面。仔细阅读,有好处的。
    通常的做法是:普通的flashMCU是在上电时或复位时,PC指针里面的存放的是“0000”,表示CPU从ROM的0000地址开始执行指令,在该地址处放一条跳转指令,使程序跳转到_main函数中,然后根据不同的指令,一条一条的执行,当中断发生时(中断数量也很有限,2~5个中断),按照系统分配的中断向量表地址,在中断向量里面,放置一条跳转到中断服务程序的指令,如此如此,整个程序就跑起来了。决定CPU这样做,是这种ROM结构所造成的。
    其实,这里面,C语言编译器作了很多的工作,只是,你不知道而已。如果你仔细阅读编译器自带的help文件就会知道很多的事情,这是对编译器了解最好的途径。
    I/O口寄存器:

    也是可以被改变的量,它被安排在一个特别的RAM地址,为系统所访问,而不能将其他变量定义在这些位置。
    中断向量表:
    中断向量表是被固定在MCU内部的ROM地址中,不同的地址对应不同的中断。每次中断产生时,直接调用对应的中断服务子程序,将程序的入口地址放在中断向量表中。
    ROM的大小问题:
    对于flash类型的MCU,ROM空间的大小通常都是整字节的,即为ak*8bits。这很好理解,一眼就知道,ROM的空间为aK。但是,对于某些OTP类型的单片机,比如holtek或者sonix公司的单片机,经常看到数据手册上写的是“OTP progarming ROM 2k*15bit。。。。。”,可能会产生疑惑,这个“15bit”认为是1个字节有余,2个字节又不足,那这个ROM空间究竟是2k,多于2k,还是4k但是少了一点点呢?
    这里要明确两个概念:一个是指令的位宽,另一个是指令的长度。指令的位宽是指一条指令所占的数据位的宽度;有些是8位位宽,有些是15位位宽。指令长度是指每条指令所占的存储空间,有1个字节,有2个字节的,也有3个字节甚至4个字节的指令。这个可以打个形象的比方:我们做广播体操时,有很多动作要做,但是每个复杂的动作都可以分解为几个简单的动作。例如,当做伸展运动时,我们只听到广播里面喊“2、2、3、4、5、6、7、8”,而这里每一个数字都代表一个指令,听到“3”这个指令后,我们的头、手、腰、腿、脚分别作出不同的动作:两眼目视前方,左手叉腰,右手往上抬起,五指伸直自然并拢打开,右腿伸直,左腿成弓步······等等一系列的分解动作,而要做完这些动作的指令只有一个“3”,要执行的动作却又很多,于是将多个分解动作合并成一个指令,而每个分解动作的“位宽”为15bits。实事上也确实如此,当在反汇编或者汇编时,可以看到,复合指令的确是有简单的指令组合起来的。

    到此,回答前面那个问题,这个OTP的ROM空间应该是2K,指令位宽为15位。一般的,当指令位宽不是8的倍数时,则说明该MCU的大部分指令长度是一个字节(注:该字节宽度为15位,不是8位),极少数为2个或多个字节,虽然其总的空间少,但是其能容下的空间数据并不少。
    展开全文
  • 步进电机是将脉冲信号转变为角位移或线位移的开环控制元件。在非超载情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。这一...

    1.步进电机图片

     

    2.步进电机介绍

    步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。这一线性关系的存在,加上步进电机只有周期性的误差而无累积误差等特点,使得步进电机在速度、位置等控制领域的控制操作非常简单。虽然步进电机应用广泛,但它并不像普通的直流和交流电机那样在常规状态下使用,它必须由双环形脉冲信号、功率驱动电路等组成控制系统方可使用.因此.用好步进电机也非易事,它涉及机械、电机、电子及计算机等许多专业知识。

    3.步进电机分类

    (1)永磁式(PM)。一般为二相,转矩和体积较小,步距角一般为7.5°或15°。

    (2)反应式(VR)。一般为三相,可实现大转矩输出.步距角一般为1.5°,但噪声和振动都很大。在欧美等发达国家20世纪80年代已经淘汰。

    (3)混合式(HB)。指混合了永磁式和反应式的优点。它又分为二相和五相,二相步距角一般为180°,而五相步距角一般为0.72°。这种步进电机的应用最为广泛。

    4.技术指标

        (1)步进电机的静态指标

        ①相数—电机内部的线圈组数。目前常用的有二相、三相、四相、五相步进电机。电机相数不同,其步距角也不同。一般二相电机的步距角为0.9°/1.8°,三相为0.75°/1.5°、五相为0.36°/0.72°。在没有细分驱动器时,用户主要靠选择不同相数的步进电机来满足自己步距角的要求.如果使用细分驱动器,则“相数”将变得没有意义,用户只需在驱动器上改变细分数,就可以改变步距角。

        ②步距角—表示控制系统每发一个步进脉冲信号,电机所转动的角度。电机出厂时给出了一个步距角的值,如86BYG250A型电机的值为0.9°/1.8°(表示半步工作时为0.9°、整步工作时为1.8°),这个步距角可称为“电机固有步距角”,它不一定是电机实际工作时的真正步距角,真正的步距角和驱动器有关。

        ③拍数—完成一个磁场周期性变化所需脉冲数或导电状态.或指电机转过一个步距角所需脉冲数。以四相电机为例,有四相四拍运行方式,即AB-BC-CD-DA-AB:四相八拍运行方式,即A-AB-B-BC-C-CD-D-DA-A

        ④定位转矩—电机在不通电状态下,转子自身的锁定力矩(由磁场齿形的谐波以及机械误差造成).

    ⑥保持转矩—步进电机通电但没有转动时,定子锁住转子的力矩。它是步进电机最重要的参数之一,通常步进电机在低速时的力矩接近保持转矩。由于步进电机的输出力矩随速度的增大而不断衰减,输出功率也随速度的增大而变化,所以保持转矩就成了衡量步进电机最重要参数之一。比如,当人们说2N·m的步进电机时,在没有特殊说明的情况下,是指保持转矩为2N·m的步进电机。

    (2)步进电机的动态指标

    ①步距角精度—步进电机每转过一个步距角的实际值与理论值的误差,用百分比表示:误差/步距角X100%。不同运行拍数其值不同,四拍运行时应在5%之内,八拍运行时应在15%以内。

    ②失步—电机运转时运转的步数不等于理论上的步数,称为失步。

    ③失调角—转子齿轴线偏移定子齿轴线的角度.电机运转必存在失调角,由失调角产生的误差,采用细分驱动是不能解决的。

    最大空载起动频率—电机在某种驱动形式、电压及额定电流下,在不加负载的情况下,能够直接起动的最大频率。

    最大空载运行频率—电机在某种驱动形式、电压及额定电流下,电机不带负载的最高转速频率。

    运行矩频特性—电机在某种测试条件下,测得运行中输出力矩与频率关系的曲线称为运行矩频特性。它是电机诸多动态曲线中最重要的,也是电机选择的根本依据,如图所示。

    电机一但选定,电机的静力矩确定,而动态力矩却不然.电机的动态力矩取决于电机运行时的平均电流(而非静态电流),平均电流越大,电机输出力矩越大.即电机的频率特性越硬。

      

     

    其中.曲线3电流最大或电压最高;曲线I电流最小或电压最低,曲线与负载的交点为负载的最大速度点。要使平均电流大,尽可能提高驱动电压,或采用小电感大电流的电机。      

    ④电机的共振点—步进电机均有固定的共振区域,其共振区一般在50r/min-80r/min或在180r/min左右。电机驱动电压越高,电机电流越大,负载越轻,电机体积越小。则共振区向上偏移,反之亦然。为使电机输出电矩大、不失步且整个系统的噪声降低,一般工作点均应偏移共振区较多。因此,在使用步进电机时应避开此共振区。     

    5.步进电机工作原理

    步进电机是一种将电脉冲转换成相应角位移或线位移的电磁机械装置。它具有快速启、停能力,在电机的负荷不超过它能提供的动态转矩时,可以通过输入脉冲来控制它在一瞬间的启动或停止。步进电机的步距角和转速只和输入的脉冲频率有关,和环境温度、气压、振动无关,也不受电网电压的波动和负载变化的影响。因此,步进电机多应用在需要精确定位的场合。  

    (1)工作原理

    步进电机有三线式、五线式和六线式,但其控制方式均相同,都要以脉冲信号电流来驱动.假设每旋转一圈需要200个脉冲信号来励磁,可以计算出每个励磁信号能使步进电机前进1.8°。其旋转角度与脉冲的个数成正比。步进电动机的正、反转由励磁脉冲产生的顺序来控制。六线式四相步进电机是比较常见的,它的控制等效电路如下图所示。它有4条励磁信号引线A,/A,B,/B 通过控制这4条引线上励磁脉冲产生的时刻,即可控制步进电机的转动.每出现一个脉冲信号,步进电机只走一步。因此,只要依序不断送出脉冲信号,步进电机就能实现连续转动。   

     

    (2)励磁方式

    步进电机的励磁方式分为全步励磁和半步励磁两种。其中全步励磁又有一相励磁和二相励磁之分;半步励磁又称一二相励磁。假设每旋转一圈需要200个脉冲信号来励磁,可以计算出每个励磁信号能使步进电动机前进1.8°。简要介绍如下。

    ①一相励磁—在每一瞬间,步进电机只有一个线圈导通.每送一个励磁信号,步进电机旋转1.8,这是三种励磁方式中最简单的一种。

    其特点是:精确度好、消耗电力小,但输出转矩最小,振动较大。如果以该方式控制步进电机正转,对应的励磁顺序如下表所示。若励磁信号反向传送,则步进电机反转。表中的1和0表示送给电机的高电平和低电平。

     

    ②二相励磁—在每一瞬间,步进电动机有两个线圈同时导通。每送一个励磁信号,步进电机旋转1.8。

    其特点是:输出转矩大,振动小,因而成为目前使用最多的励磁方式。如果以该方式控制步进电机正转,对应的励磁顺序见下表。若励磁信号反向传送,则步进电机反转。

     

      ③一二相励磁—为一相励磁与二相励磁交替导通的方式。每送一个励磁信号,步进电机旋转0.9。

    其特点是:分辨率高,运转平滑,故应用也很广泛。如果以该方式控制步进电机正转,对应的励磁顺序见下表。若励磁信号反向传送,则步进电机反转。

     

    6.步进电机的驱动

    步进电机的驱动可以选用专用的电机驱动模块,如L298, FF5754等,这类驱动模块接口简单,操作方便,它们既可驱动步进电机,也可驱动直流电机。除此之外,还可利用三极管自己搭建驭动电路。不过这样会非常麻烦,可靠性也会降低。另外,还有一种方法就是使用达林顿驱动器ULN2003,该芯片单片最多可一次驱动八线步进电机,当然如果只有四线或六线制的也是没有问题的。

    首先我们看一下电路原理图

     本实验采用四线双极性步进电机,该电机与TC1117连接如上图所示,M_IN为单片机控制口,M_OUT为电机接入口,其中M_IN分别控制步进电机的相序A,B.

    TC1117芯片工作逻辑真值表:

    开发板上使用的 4线双极性步进电机,其有两相A,B,每个绕组有两根线,A+和A-B+和 B-,运行方式可以是A+ —A-—B+—B-,如果想换个方向运行,可以是 A- —A+—B—B+。

    步进电机的四个引脚A+、A-、B+、B-分别连接到OUA、OUTB、OUTC、OUTD四个引脚

     

    实际物理连接图如下:

     

     

    示例程序为:

     

       #include "reg52.h"
       
       typedef unsigned char u8;
       typedef unsigned int u16;
    
       sbit MOTOA = P1^0; //A+引脚
       sbit MOTOB = P1^1; //A-引脚
       sbit MOTOC = P1^2; //B+引脚
       sbit MOTOD = P1^3; //B-引脚
    
       #define SPEED 60000
    
       void delay(u16 i) //延时函数
       {
       while(i --);
       }
    
       void main()
       {
    
       P1 = 0x00; //电机处于待机状态
       while(1)
       {
       MOTOA = 1; //A+状态
       MOTOB = 0;
       MOTOC = 1;
       MOTOD = 1;
       delay(SPEED); //延时
    
       MOTOA = 0; //A-状态
       MOTOB = 1;
       MOTOC = 1;
       MOTOD = 1;
       delay(SPEED); //延时
    
       MOTOA = 1; //B+状态
       MOTOB = 1;
       MOTOC = 1;
       MOTOD = 0;
       delay(SPEED); //延时
    
       MOTOA = 1; //B-状态
       MOTOB = 1;
       MOTOC = 0;
       MOTOD = 1;
       delay(SPEED); //延时
    
       }
       }
    
    
    
    
    

     

    上例程序驱动步进电机的方向为: A+ —A-—B+—B-,

    如果想换个方向运行,也就是 A- —A+—B—B+,可以使用以下程序:

       #include "reg52.h"
       
       typedef unsigned char u8;
       typedef unsigned int u16;
    
       sbit MOTOA = P1^0; //A+引脚
       sbit MOTOB = P1^1; //A-引脚
       sbit MOTOC = P1^2; //B+引脚
       sbit MOTOD = P1^3; //B-引脚
    
       #define SPEED 60000
    
       void delay(u16 i) //延时函数
       {
       while(i --);
       }
    
       void main()
       {
    
       P1 = 0x00; //电机处于待机状态
       while(1)
       {
       MOTOA = 0; //A-状态
       MOTOB = 1;
       MOTOC = 1;
       MOTOD = 1;
       delay(SPEED); //延时
    
       MOTOA = 1; //A+状态
       MOTOB = 0;
       MOTOC = 1;
       MOTOD = 1;
       delay(SPEED); //延时
    
       MOTOA = 1; //B-状态
       MOTOB = 1;
       MOTOC = 0;
       MOTOD = 1;
       delay(SPEED); //延时
    
       MOTOA = 1; //B+状态
       MOTOB = 1;
       MOTOC = 1;
       MOTOD = 0;
       delay(SPEED); //延时
    
       }
       }
    
    
    
    
    

    如果想两个方向轮流运行,可以将上面两个程序结合在一块使用。

    展开全文
  • 求代码,作用是单片机控制继器用于自动操作键盘。要求:P01 导通三分钟,然后断开;P02 导通 10 秒后断开;P03 导通 0.5 秒后断开;P04 导通 0.2 秒后断开;P05 导通 0.5 秒后断开;P06 导通 0.2 秒后断开。断开 ...

    求代码,作用是单片机控制继电器用于自动操作键盘。

    要求:

    P01 导通三分钟,然后断开;
    P02 导通 10 秒后断开;
    P03 导通 0.5 秒后断开;
    P04 导通 0.2 秒后断开;
    P05 导通 0.5 秒后断开;
    P06 导通 0.2 秒后断开。

    断开 P06 之后,循环所有。 单片机 89C52RC。

    悬赏分:100 - 解决时间:2009-11-15 10:01
    ;-----------------------------------------------------------
    最佳答案:

    试试如下程序。
    //--------------------------------------------------
    #include
    #define uchar unsigned char
    #define uint unsigned int

    sbit P0_1 = P0^1;
    sbit P0_2 = P0^2;
    sbit P0_3 = P0^3;
    sbit P0_4 = P0^4;
    sbit P0_5 = P0^5;
    sbit P0_6 = P0^6;
    //--------------------------------------------------
    void delay1ms(uint z)
    {
        uint x, y;
        for(x = z; x > 0; x--) for(y = 110; y > 0; y--);
    }
    //--------------------------------------------------
    void main(void)
    {
        uint i, j;
        while(1) {
    //--------------
          P0_1 = 0;
          for (i = 0; i < 3; i++)
            for (j = 0; j < 120; j++) delay1ms(500); //共延时360*0.5=180秒
          P0_1 = 1;
    //--------------
          P0_2 = 0;
          for (j = 0; j < 20; j++)  delay1ms(500);   //共延时20*0.5=10秒
          P0_2 = 1;
    //--------------
          P0_3 = 0; delay1ms(500);       //延时0.5秒
          P0_3 = 1;
    //--------------
          P0_4 = 0; delay1ms(200);       //延时0.2秒
          P0_4 = 1;
    //--------------
          P0_5 = 0; delay1ms(500);       //延时0.5秒
          P0_5 = 1;
    //--------------
          P0_6 = 0; delay1ms(200);       //延时0.2秒
          P0_6 = 1;
        }
    }
    ;-----------------------------------------------------------
    回答者:  做而论道 - 十级   2009-11-14 23:25
    提问者对于答案的评价:非常感谢,测试通过...
    二楼写的也很不错,但是一段那么简单的程序搞那么多代码,对于我们菜鸟来说看不懂...
    原文网址:http://zhidao.baidu.com/question/125558527.html
    ;===========================================================

    展开全文
  • 我们正常在操作一款单片机的时候,都是从main函数开始进行编程的,但是单片机上电是从main函数开始执行的吗?答案当然是否定的,在main函数之前单片机最先执行的是硬件设置SP、PC然后是“启动文件”,一般主要是项目...

    先说启动文件

    我们正常在操作一款单片机的时候,都是从main函数开始进行编程的,但是单片机上电是从main函数开始执行的吗?答案当然是否定的,在main函数之前单片机最先执行的是硬件设置SP、PC然后是“启动文件”,一般主要是项目文件里面的startup_xxxxx.s文件。其实这个就是我们常说的Bootloader。

    其实不光STM32系列单片机是这样,我们接触的NXP的微控制器、TI的MSP430以及51单片机等等其实都是有上述的启动文件的。启动文件负责的就是从单片机复位开始到main函数之前这段时间所需要进行的工作。我们一般很少接触启动文件的主要原因是开发环境往往给开发者自动的提供了这个启动文件,不需要我们再去操心,直接从main函数开始进行设计就可以了。

    STM32三种启动方式

    接触过STM32系列单片机的朋友应该知道STM32有三种启动模式,用户可以通过设置BOOT0和BOOT1的引脚电平状态,来选择复位后的启动模式。

    需要注意的是STM32上电复位以后,代码区都是从0x00000000开始的,三种启动模式只是将各自存储空间的地址映射到0x00000000中。

    1. 从Flash启动,将Flash地址0x08000000映射到0x00000000,这样启动以后就相当于从0x08000000开始的,这是我们最常用的模式;
    2. 从SRAM启动,将SRAM地址0x20000000映射到0x00000000,这样启动以后就相当于从0x20000000开始的,用于调试,笔者基本没用过;
    3. 从系统存储器启动(可以看上篇文章里的内存映射图,System memory),将系统存储器地址0x1FFFF000映射到0x00000000,这样启动以后就相当于从0x1FFFF000开始执行的,值得注意的是这个系统存储器里面存储的其实是STM32自带的Bootloader代码,这其实是一个官方的IAP,它提供了可以通过UART1接口将用户的代码下载到Flash中的功能,下载完以后再切换到从Flash中启动就可以正常运行了。打个比方这个官方的Bootloader就相当于我们玩路由器时的“不死breed”。笔者之前在调STM32低功耗的时候将下载口给复用了其他功能导致“变砖”,就是通过这种方式恢复的

    在这里插入图片描述

    切回正题

    下面我们来具体看一下从用户的Flash启动STM32,从上电到main函数之间的这段时间都做了什么。

    1. 第一步是硬件设置SP、PC
      我们参考《Cortex-M3权威指南》向量表章节表7.6,如下图所示:

    在这里插入图片描述
    前两段地址主要是用来指定SP和PC的初值,上一节我们已经知道了映射关系,所以这时已自动从0x08000000位置处读取数据赋值给了栈指针SP,从0x08000004位置处读取数据赋值给了PC。需要注意的是这个复位向量初始值并不是固定的,可以通过一个叫“向量表偏移量寄存器”来修改定位。

    在这里插入图片描述
    下图是我们那个开源OLED时钟项目的HEX文件,用J-Flash打开就可以看到设置完的SP=0x20005B88,PC=0x0800282D。

    在这里插入图片描述

    1. 第二步是设置系统时钟
      我们接着来追踪系统的运行轨迹,上面我们已经知道了PC的地址为0x0800282D,但是这没有遵循4字节对齐,我们将其对齐为0x0800282C,这时我们打开项目文件里面的.map文件,找到这个地址,如下图示:

    在这里插入图片描述
    我们发现来到了第一节说的startup_xxxxx.s文件,我们打开startup文件找到:

    在这里插入图片描述
    我们发现运行到了SystemInit,C的世界我们就不陌生了,在项目文件的system_stm32f10x.c里面可以找到SystemInit函数,也就是初始化系统时钟了。

    1. 第三步是___main
      到这里大家可能会以为已经到了main函数了,其实不是这样的。___main和main是不一样的,我们寻找这个___main会发现找不到,startup文件里面没有,map文件里面也没有。其实它是在MDK自带的库里面了,主要的功能是软件设置SP、加载.data.bss并初始化栈区。由于需要在线跟踪才能看到,我在这里就不给大家列出来了,感兴趣的朋友可以深入研究一下。

    2. 最后来到C的世界
      在执行到___main的最后就跳转到了C文件的main函数了。

    最后用一张图来整体看一下流程:

    在这里插入图片描述

    总 结

    到这里STM32的存储器以及上电启动过程就完整的总结完了,希望对大家有所帮助,大家如果感兴趣可以在调试STM32的时候一步一步的来跟踪一下看看,每一款单片机的启动文件其实都是很值得玩味的,对我们系统的来体会控制器的架构、指令集、中断向量等内容是很有帮助的。大家如果将启动过程了解清楚了对我们后面来进行IAP等有意思的操作是很有帮助的。

    展开全文
  • 单片机之步进电机

    2019-08-21 10:44:10
    单片机的应用特别地多,其用途非常广泛,我们这些案例只是涉及其基本部分,没有深究,但是也是要作为一个了解的,今天就学习一下步进电机和可控步进电机 步进电机 实验现象 发现步进电机按照一定速度逆时针旋转,...
  • 从实现功能分析,软件可以分解3个功能模块: 1,步进电机控制模块 2,矩阵键盘输入模块 3,显示输出模块 步进电机工作原理 步进电机通过输入脉冲信号进行控制,即电机的总转动角度由输入脉冲总数决定,而...
  • 要求:用单片机实现一个电子密码锁的功能,一开始设置密码,设置从0-f,任意多少位密码(只要不超过十位),设置成功,蜂鸣器... 连线:P0键盘,P2倒着接数码管,P3.0接蜂鸣器,P1接步进电机 .../******************
  • 本系统以设计题目的要求为目的,采用80C51单片机为控制核心,利用超声波传感器检测道路的障碍,控制电动小汽车的自动避障,快慢速行驶,以及自动停车,并可以自动记录时间、里程和速度,自动寻迹和寻光功能。...
  • 步进电机是将脉冲信号转变为角位移或线位移的开环控制元件,是一种将脉冲转化为角位移的执行机构。通俗一点讲:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(即步进角)...
  • 步进电机是将脉冲控制信号转变为角位移或线位移的一种常用的数字控制执行元件,又称为脉冲电机。在驱动电源的作用下,步进电机受到脉冲的控制,其转子的角位移量和速度严格地与输入脉冲的数量和脉冲频率成正比。...
  • arm完成较为简单, 功用较为完善, 因而运用单片机控制较多。 用单片机控制的密码锁常运用汇编言语编写顺序, 显示器多数用数码管。 而本文所引见的电子密码锁运用移植性及可读性强的初级言语C言语编写, 显示更加...
  • STM32上电后启动过程

    2019-02-27 21:12:51
    微控制器(单片机上电后,是如何寻找到并执行main函数的呢?很显然微控制器无法从硬件定位main函数的入口地址,因为使用C语言作为开发语言后,变量/函数的地址便由编译器在编译时自行分配,这样一来main函数的...
  • PIC单片机之步进电机

    2020-07-14 08:46:10
    大家好, 通过前一期的学习, 我们已经对ICD2 仿真烧写器和增强型PIC 实验板的使用方法及学习方式有所了解与熟悉,学会了如何用单片机来控制发光管、继器、蜂鸣器、按键、数码管、RS232 串口等资源,体会到了学习...
  • http://www.elecfans.com/d/656396.html作为笔记STC单片机简介 STC单片机是一款增强型51单片机,完全兼容MCS-51,还增加了新的功能,比如新增两级中断优先级,多一个外中断,内置EEPROM,硬件看门狗,具有掉模式...
  • 关注【电子开发圈】微信公众号,一起学习吧!...电子DIY、Arduino、51单片机、STM32单片机、FPGA…… 电子百科、开发技术、职业经验、趣味知识、科技头条、设备拆机…… 点击链接,免费下载100G+电子设计学习资料! ...
  • 一、上电时序分析 C6678上电时序如下图所示,时序分析如下: 1、 所有电源及时钟稳定(RESET、POR、RESETFULL信号初始为低) 2、 拉高RESET信号 3、 拉高RESET后,POR信号至少保持100us后拉高 4、 保持GPIO引脚状态...
  • 关注【电子开发圈】微信公众号,一起学习吧!...电子DIY、Arduino、51单片机、STM32单片机、FPGA…… 电子百科、开发技术、职业经验、趣味知识、科技头条、设备拆机…… 点击链接,免费下载100G+电子设计学习资料! ...
  • 51单片机流水灯原理 在实验之前必须的准备工作有: 1.单片机 STC90C51 2.编译软件keil 3.烧写软件 ...实验说明:通过单片机芯片,定时在引脚P00,P01,...电流顺序:VCC正极进入 》 芯片P0.0触发一个高平 》 LED...
1 2 3 4 5 ... 20
收藏数 6,268
精华内容 2,507
关键字:

单片机上电顺序