单片机相关知识
8位、32位单片机区别
指 CPU处理的数据的宽度,参与运算的寄存器的数据长度
8 位单片机可以同时进行2个8位的2进制数相加,而 16位单片机则大一倍,可以同时让2个16位的2进制数相加。
一、8051相关知识
C51 启动过程
当用keil作为开发环境,创建一个工程时,需要选择所使用的单片机型号,然后Keil会将相应单片机的startup.A51文件拷贝到工程目录下,在编译时,该文件会被编译到最终的目标文件中。
startup.A51文件主要完成了如下过程 :
1、初始化8051硬件堆栈的大小和堆栈指针;
2、初始化中断向量表,分配每个中断的入口地址和中断服务函数;
3、初始化内部RAM空间,即DATA/IDATA,将内容清零;
4、初始化外部RAM空间,即XDATA/PDATA,将内容清零;
5、初始化SMALL/COMPACT/LARGE模式下reentrant函数使用的堆栈指针;
6、调用main()函数,去执行我们编写的代码。
这里提到了SMALL,LARGE,COMPACT三种模式。
不同内存模式下的堆栈。Keil 编译器中有三种模式设置。这是由51处理器繁多的寻址模式导致的,不同的寻址模式有不同的效率。
small模式:
在small模式中,所有默认变量均装入单片机内部的RAM中,51单片机默认内部RAM只有128B;52单片机默认256B。
该模式下的优点是访问速度快,缺点是空间有限。
变量存储在内部ram里。
compact模式:
在compact模式中,所有默认变量均位于单片机的256B RAM中,
和在small模式中使用关键字 pdata来定义数据变量的效果一样,
在该模式下程序总变量空间不能超过256B。
变量存储在外部ram里,使用页8位间接寻址。
large模式:
在large模式中,所有默认变量可放在多达64KB的RAM中,
包括内部RAM和外部RAM,这和使用关键字xdata 来定义变量的效果一样。
变量存储在外部Ram里,使用16位间接寻址。
大部分的应用都是选择Small的模式。
空间含义
空间名称 | 地址范围 | 说明 |
---|---|---|
DATA | 00H~7FH | 片内RAM直接寻址区 |
IDATA | 00H~FFH | 片内RAM间接寻址区 |
XDATA | 0000H~FFFFH | 片外RAM数据区 |
PDATA | 外部扩展RAM的低256个字节 | |
CODE | 0000H~FFFFH | 片内外ROM代码区 |
存储器
8051 在系统结构上采用 哈佛结构
哈佛结构:
哈佛结构是一种将程序存储和数据存储分开存放的结构
冯·诺伊曼结构:
也称普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的存储器结构。
冯.诺依曼体系与哈佛体系的区别
二者的区别就是程序空间和数据空间是否是一体的.
1、早期的微处理器大多采用冯诺依曼结构,典型代表是Intel公司的X86微处理器, 取指令和取操作数都在同一总线上,通过分时复用的方式进行的,缺点是在高速运行时,不能达到同时取指令和取操作数,从而形成了传输过程的瓶颈.2、哈佛总线技术应用是以DSP和ARM为代表的.采用哈佛总线体系结构的芯片内部程序空间和数据空间是分开的,这就允许同时取指令和取操作数,从而大大提高了运算能力.
- 在物理结构上分为四类:
1、片外、片内程序存储器(ROM)
2、片外、片内数据存储器(RAM)
- 在用户使用角度来看分三类:
1、片内、片外 统一编址的程序存储器地址空间
2、片内数据存储器地址空间
3、片外数据存储器地址空间
程序存储器 用来存放用户程序和常用的表格、常数,采用只读存储器(ROM)作为程序存储器。
数据存储器 用来存放程序运行中的数据、中间计算结果等,采用随机访问存储器(RAM)作为数据存储器
程序存储器
单片机的PC是指程序计数器(Program Counter)。程序计数器PC用于存放下一条将要执行的指令地址,是一个16位专用寄存器,不能通过MOV指令来操作,对用户来说是不可见的。当执行一条指令时,首先需要根据PC中存放的指令地址,将指令取出送到指令寄存器中,此过程称为“取指令”。与此同时,PC中的地址编制的程序进行自动加1跳转操作,得到下一条指今的地址。当前一条指令执行完毕,CPU再根据PC取出下一条指令的地址,并再得到再下条指令地址,依次执行每一条指令。
片内数据存储器
片内RAM 最大可寻址256个字节,分为低128字节单元、高128字节单元
- 低128单元(00H - 7FH)
低128单元也分为三个区域,
1、通用工作寄存器区
2、位寻址区
3、用户数据存储区
1、通用工作寄存器区 00H - 1FH
最低32个单元(地址为00H~1FH)为4个通用工作寄存器组。
每个寄存器组含有8个8位寄存器,编号为R0 ~R7。
程序状态字寄存器(PSW)来管理中的2位RS0、RS1用来确定当前采用哪一个工作寄存器组
在某一时刻只能选用其中的一组寄存器工作,系统复位后,指向工作寄存器组0
如果用户程序不需要4个工作寄存器区,则不用工作寄存器单元可以作一般的RAM使用
2、位寻址区 20H - 2FH
20H - 2FH 这16个单元,每个单元( 20H - 2FH)都有 8位的位地址,每个单元都可以作为一般的RAM单元使用
3、用户数据存储区 30H - 7HF
RAM区又称为数据缓存区,8051单片机的用户RAM区有80个存储单元(字节)
地址编号为30H~7FH,用户RAM区一般用来存储随机数据和运算中间结果等。
- 高128单元(7FH - FFH)
对特殊寄存器只能使用直接寻址模式,高128字节中,除了 程序计数器 PC以外,有21个特殊功能的寄存器,又称专用寄存器SFR,离散的分布在空间内。
21个特殊寄存器中,有11个可以位寻址
片外数据存储器
片外RAM 可以由特殊寄存器——数据指针寄存器DPTR寻址
是16位,所以可以寻址64K
系统时钟、时钟频率,机器周期,与执行指令的时间
- 时钟频率
晶振频率即为时钟频率(提供的系统时钟)
如果采用 32khz的RC震荡器,并且设置2分频
那么这里实际工作时的 时钟频率 = 震荡频率 / 2 = 16Mhz,此时的系统时钟为16Mhz。
- 机器周期
先说明一个概念,12T单片机,1T单片机。
学生时代常用的51单片机都是12T单片机,即 机器频率 = 时钟频率 / 12
现在的51单片机都是1T单片机,即 机器频率 = 时钟频率
T数越小,机器频率越高,也就是说,1T的单片机是执行速度最快的单片机。
- 指令周期
51单片机的指令可以分为单周期指令,双周期指令和四周期指令。
单周期指令的执行时间为1个机器周期,双周期指令的执行时间为2个机器周期,四周期指令的执行时间为4个机器周期。
拿_nop_进行说明,它是单周期指令,执行它需要1个机器周期。
二、STM32相关知识
ARM架构
在ARMv7架构,ARM处理器分为 cortex-A 、cortex-R、cortex-M 三个系列,分别代表三种不同的应用领域:
cortex-A 系列:Application
主要是高性能的处理器。相比于其它两种处理器,特点是增加了内存管理单元MMU,对于运行大型的应用操作系统,MMU是必不可少的元件。
cortex-R 系列, Real-time
主要是实时性的特点。一个常见的认知误区是:实时性就是处理快。但是事实上,实时性代表的是处理时间上的确定性和低延迟,即一个操作可以在指定的短时间内完成,MMU引入的地址转换通常不能满足其实时性的要求,所以 R 系列处理器并不挂载 MMU。
cortex-M 系列, Microcontroller
即微处理器,主打中低端市场。真实应用场景中,更多的是大型中控搭配小型嵌入式控制系统,小型嵌入式节点通常是海量的,比如智能家居、物联网等等,这一种系统的特点在于低功耗、低成本,相对的高性能,在中低端市场,性价比通常是一个主要的衡量因素。
STM32 启动流程
烧录启动模式(ICP、ISP、IAP 、BOOT0、BOOT1)
我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式。
1、BOOT0 = 0:Flash memory启动方式( ICP(In Circuit Programing)在电路编程 )
启动地址:0x08000000是STM32内置的 Flash ,一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。基本上都是采用这种模式,
ICP使用SWD接口进行烧录程序。常用的烧录工具为J-Link、ST-Link、Nu-Link。与之配套的烧录软件为J-Flash、NuMicro_ICP_Programming_Tool、st-link utility。使用硬件对应厂家的软件以及仿真器都可以烧录程序
2、BOOT0 = 0,BOOT1 = 1 :System memory启动方式(ISP(In System Programing)在系统编程)
启动地址:0x1FFF0000从系统存储器启动,这种模式启动的程序功能是由厂家设置的。
STM32在出厂时,由ST在这个区域内部预置了一段BootLoader, 这是一块 ROM ,出厂后无法修改。我们选用这种启动模式时,是为了从串口下载程序,因为在厂家提供的BootLoader 中,提供了串口下载程序的固件,可以通过这个BootLoader将程序下载到系统的Flash中。但是这个下载方式需要以下步骤:
1、将BOOT0设置为1,BOOT1设置为0,然后按下复位键,这样才能从系统存储器启动BootLoader
2、最后在BootLoader的帮助下,通过串口下载程序到Flash中
3、程序下载完成后,又有需要将BOOT0设置为GND,手动复位,
使用引导程序(bootloader)加上外围UART/USB等接口进行烧录。
比如:利用 STC-ISP 对 STC芯片 编程 ,利用 FlyMcu 对 STM32 编程
3、BOOT0 = 1,BOOT1 = 1 :SRAM启动方式(IAP(In applicating Programing)在应用编程)
启动地址 0x20000000 内置SRAM,没有程序存储的能力了,这个模式一般用于程序调试。假如我只修改了代码中一个小小的 地方,然后就需要重新擦除整个Flash,比较的费时,可以考虑从这个模式启动代码(也就是STM32的内存中),用于快速的程序调试,等程序调试完成后,在将程序下载到SRAM中
IAP就是通过软件实现在线电擦除和编程的方法。
IAP技术是从结构上将Flash存储器映射为两个存储体,当运行一个存储体上的用户程序时,可对另一个存储体重新编程,之后将程序从一个存储体转向另一个。
STM32启动文件:startup
- 1、初始化堆栈指针
栈Stack
开辟栈的大小为 0X00000400(1KB),数据段名为 STACK, NOINIT 即不初始化,READWRITE可读可写, 8(2^3)字节对齐
__initial_sp紧挨着SPACE语句放置,表示栈的结束地址,即栈顶地址,栈是由高向低生长的。
堆Heap
开辟堆的大小为 0X00000200(512B),数据段名为 Heap, NOINIT 即不初始化,READWRITE可读可写, 8(2^3)字节对齐
__heap_base 表示堆的起始地址, __heap_limit 表示堆的结束地址。堆是由低向高生长的,跟栈的生长方向相反。
PRESERVE8 表示指定当前文件的推栈按照8字节对齐
THUMB 表示后面指令位THUMB指令
THUBM 是 ARM 以前的指令集, 16bit,现在 Cortex-M 系列的都使用 THUMB-2 指令集, THUMB-2 是 32 位的,
兼容 16 位和 32 位的指令,是 THUMB 的超集。
- 2、初始化中断向量表,得到程序指针 PC
定义一个数据段名为RESET,DATA表示数据, READONLY表示只读
表示向量表的开始地址(全局属性)
表示向量表的结束地址(全局属性)
表示向量表的大小(全局属性)
中断向量表的第一句 0x0000 0000 存放的是__initial_sp栈顶的指针
中断向量表的第二句 0x0000 0004 存放的是Reset_Handler函数入口地址
从 WWDGT_IRQHandler 到 USBFS_IRQHandler,都是用户使用的。
- 3、复位程序
定义一个数据段名为。text,CODE表示数据, READONLY表示只读
执行的第一个程序
Reset_Handler PROC :表示复位子程序开始
EXPORT Reset_Handler [WEAK] :表示声明一个标号为全局变量,并且可以用户自定义
IMPORT __main : 引入 _main函数
IMPORT SystemInit : 引入 SystemInit函数
LDR R0, =SystemInit” : 是将函数 SystemInit 的地址放到寄存器 R0 中保存
BLX R0” 是跳转到 R0 : 寄存器存储的地址处运行
B是直接跳转指令,
B后加L表示保存PC的值到寄存器 R14,可以在执行完跳转全部指令后返回跳转前的位置。
B后加X是表示根据跳转的地址改变当前的状态
LDR R0, =__main” : 此句是将 __main 函数的地址放到寄存器 R0中保存。
( 注意: __main 和 main 不是一个函数。__main 是库函数,用于由非C语言环境转换为C语言环境时使用的 )
BX R0 : 寄存器存储的地址处运行, 配置完后执行main函数,并且不用返回
ENDP : 结束
- 4、中断服务函数
PROC : 一个新程序
EXPORT : 声明一个标号(可重定义)
B . : 表示无限循环
ENDP : 退出
- 5、 用户堆栈初始化
ALIGN: 对指令或者数据存放的地址进行对齐,后面会跟一个立即数。缺省表示4 字节对齐。
如果DEF:__MICROLIB成立就把__heap_limit、__heap_base、__initial_sp声明为全局文件
如果没定义会执行__user_initial_stackheap PROC这段代码来初始化(我们都是会定义DEF:__MICROLIB这个的所以不会跑去执行下面这段代码区执行)
文件存储的基本概念
1、RAM和ROM
RAM是 Random Access Memory 的缩写。随机存取存储器 ,掉电会丢失数据
SRAM是静态(S指的static)RAM,静态指的不需要刷新电路,数据不会丢失,SRAM速度非常快,是目前读写最快的存储设备了
DRAM是动态RAM,动态指的每隔一段时间就要刷新一次数据,才能保存数据,速度也比SRAM慢,不过它还是比任何的ROM都要快。
ROM只读存储器ROM Read Only Memory的缩写
掉电不丢失数据,容量大,价格便宜,存储速度不如RAM。
PROM:(Programmable ROM)可编程ROM,只能写一次,就不能再改变了。
EPROM:(Erasable Programmable Read Only Memory)可抹除可编程只读内存
抹除时将线路曝光于紫外线下,则资料可被清空,并且可重复使用。
EEPROM:(Electrically Erasable Programmable Read Only Memory)电子式可抹除可编程只读内存
运作原理类似EPROM,但是抹除的方式是使用高电场来完成,因此不需要透明窗。
FLASH:存储器又称闪存,它结合了ROM和RAM的长处
不仅具备电子可擦除可编程(EEPROM)的性能,还不会断电丢失数据同时可以快速读取数据。
2、Code,RO-data,RW-data,ZI-data所代表的意思
Keil编译成功的最后会有如下信息,便是程序代码的数据信息:
Code:
代码存储区,它指的是编译器生成的机器指令。
存放在ROM 区(也就是STM32 的内部 Flash 中)
RO-data:ReadOnly data
只读数据存储区, 表示 程序定义的常量,如const关键字定义的常量、数组,函数中的常量
存放在ROM 区(也就是STM32 的内部 Flash 中),因而程序不能修改其内容
RW-data:ReadWrite data
读写数据存储区 ,表示 已初始化的全局变量、局部变量
执行的时候它们会常驻在 RAM 区,因而应用程序可以修改其内容
ZI-data:Zero Initialize
零初始化数据区,表示 未初始化的变量(全局和局部变量)
若没有定义该变量(全局和局部变量)赋予初始值,编译器会把它当 ZI-data 来对待
ZI-data 的栈空间(Stack)及堆空间(Heap):
- 在 C语言中,函数内部定义的局部变量属于栈空间,进入函数的时候从向栈空间申请内存给局部变量,退出时释放局部变量,归还内存空间
- 使用 malloc动态分配的变量属于堆空间。在程序中的栈空间和堆空间都是属于 ZI-data 区域的,这些空间都会被初始值化为 0值。
程序的大小 Total ROM Size = Code + RO Data + RW Data
3、ARM程序
1、ARM程序的组成
ARM程序 是指在ARM系统中正在执行的程序。
一个ARM程序包含3部分:RO,RW、ZI
RO:只读区域,RO Size = Code + RO Data
RW:读写区域,RW Size = RW Data + ZI Data
2、ARM映像文件的组成
ARM映像文件就是指烧录到ROM中的bin文件,也称为image文件。
之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。
三、RTOS相关知识
RTOS全称为:Real Time OS,实时操作系统
强调的是:实时性。
实时系统、非实时系统、硬实时 、软实时
实时系统
在规定时间内能给出对应的结果。既关注程序是否能正确执行,还要求在固定的时限内完成。
非实时系统
是指不需要考虑时间限制的
普通用户界面、数据库管理、文字处理等领域,这些系统不需要强调任务的及时性,因此对时间的要求比较宽松。
实时操作系统分为 硬实时 和 软实时 两类
硬实时系统
硬实时系统有一个刚性的、不可改变的时间限制
它不允许任何超出时限的错误。超时错误会带来损害甚至导致系统失败、或者导致系统不能实现它的预期目标。
软实时系统
软实时系统是一个柔性灵活的,它可以容忍偶然的超时错误。失败造成的后果并不严重,
有的应用要求系统在95%的情况下都会确保在规定的时间内完成某个动作,而不一定要求100%。在许多情况下,这样的“软性”正确率已经可以达到用户期望的水平。