STM32F0系列Cortex-M0原理与实践(txt+pdf+epub+mobi电子书下载)


发布时间:2020-05-11 18:43:24

点击下载

作者:张燕妮 编

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

STM32F0系列Cortex-M0原理与实践

STM32F0系列Cortex-M0原理与实践试读:

前言

如果问一个设计人员,产品设计时,选择器件最关心的因素是什么,那么跟得上形势发展可能是常见的、很重要的一个因素。如果问老板选择器件最关心的因素是什么,可能只有“便宜”两个字。ST公司的STM32F0x芯片是一款基于Cortex-M0,兼顾性能与价格优势于一体的32位处理器。ST公司的Cortex-M3系列产品已经在国内拥有大量客户群体,STM32F0x芯片的用户群也在日益扩大中。

Cortex-M0芯片具有小型、低功耗、低闸数、精简程序代码的特点,内建各种模拟与混合信号组件及多种高速通信能力器件,开发人员可以直接跳过16位系统,以接近8位系统的成本开销获取32位系统的性能。Cortex-M0芯片是学习ARM处理器的最佳入门选择。

STM32F0x在Cortex-M0芯片基础上继承了ST公司Cortex-M3系列2产品优点,并对一些不足之处进行了修正(例如IC外设),还增加了一些优秀功能(例如USART的超时检测),适用于工业控制器、家庭自动化、打印机和白色家电、游戏机、DVD/蓝光播放机和音频/视频接收机等。

STM32F0x具有如下特点。

百货迎百客,按需选择:STM32F0x根据外设情况,将产品划分成多种系列,并不是一种大而全的芯片,用户可根据产品需求与成本选用不同芯片。例如,对于是否需要CAN通信就限制选择范围与成本。

一招鲜吃遍天下:STM32F0x家族成员比较多,但不代表各自为政。STM32F0x家族的外设与引脚位置不是一对一。在相同封装下STM32F0x芯片引脚定义相同,通过外设复用选用不同外设。而且借助ST公司提供STM32F0x固件库开发的应用程序可在STM32F0x家族(只要包含该外设)随意运行。书中的代码除了CAN通信一章,程序可以在各种STM32F0x上运行。

全书共17章。其中第1~4章是基础;第5~15章是外设功能讲解;第16、17章是综合实例与高级功能。

第1章首先讲解相比8位机,Cortex-M0的优势,以及如何从8位机过渡到Cortex-M0,并说明Cortex-M0的基础与特征,主要有寄存器、存储器映射、系统总线、存储器保护单元、嵌套中断控制器;最后一部分会说明STM32F0x在同类产品的优势以及特点,为何选用STM32F0x进行产品的开发。

第2章主要讲解了进行STM32F0软件开发需要准备的条件,分别介绍了MDK以及J-ink、U-ink、Stlink仿真器。MDK是原Keil公司的产品,对于熟悉Keil C51单片机开发的用户会感受到ARM公司对C8051用户的重视,也非常欢迎该用户群体过渡到Cortex-M0的开发中。

第3章讲解有关硬件设计的基础,主要包括STM32F0x的电源、时钟,以及本书所使用的电路图。

第4章讲解进行STM32F0x软件开发的固件库内容。固件库内容涉及了ARM公司的CMSIS标准及ST公司的固件库标准。其中CMSIS是理解目前ARM对软件组织结构以及系统启动文件的规范,也是目前所有Cortex-M内核CPU软件设计的要求与基础。最后讲解了使用ST公司固件库建立工程文件的过程。

第5章~第14章讲解了STM32F0x的系统定时器、GPIO、NVIC、2UART、IC、SPI、ADC、DAC、PWM、定时器、CAN。每1章均提供了1~2个实际项目中的使用实例,涉及实际开发中使用各种芯片的注意事项以及技巧(或者说作者的经验教训)。

第16章讲解RTX操作系统,介绍Keil自带的实时操作系统的原理与使用过程。结合第4章的超级循环和中断模式,读者可根据自己产品特点选用相应的软件程序框架。

第17章是关于如何使用STM32F0x设计一个USB的电流、电压检测器,从设计需求、硬件设计、软件设计等方面进行详细分析,引导读者如何做产品设计、开发。

本书的第1~8章、第10~11章和第13~17章由张燕妮编写,第9章由谢玲和王洪玲编写,第12章由贾芳和丁维才编写,同时丁维才对全书代码进行了验证。

书中讲解的源代码只摘取了与相应章节配套的部分进行了说明,需要完整代码,可从电子工业出版社电子信息出版分社(http://xxdz.phei.com.cn)下载。

感谢电子工业出版社的王敬栋、刘海艳两位编辑对本书的大力支持。感谢家人与朋友的理解和支持。

由于STM32F0x家族的新成员仍在不断增加中,并且作者水平有限以及时间仓促,难免有差错和不足之处恳请读者批评指正。张燕妮第1章低成本单片机世界的入侵者——Cortex-M0

Cortex-M0处理器是为迎合现在超低功耗和混合信号设备的需求而设计的。连接方式的多样化(例如以太网、USB、低功耗的无线)以及模拟传感器的使用(例如触摸传感器和加速度计)都带来了对处理器的新需求,通常这些应用均需高集成的模拟和数字功能来处理传输数据,而现有的8位和16位机需要付出增大代码量和提高时钟频率的代价才能满足应用要求。

Cortex-M0可以在保持低功耗、低成本的前提下满足这些需求,因此Cortex-M0处理器的用户群体在快速增长。

Cortex-M0处理器在2009年由ARM公司推出,向上兼容ARM的Cortex-M3,并且损耗很低。Cortex-M0在最小配置时仅有12000逻辑门,同8位或者16位机一样的少,但却是完全的32位处理器。

本章将主要介绍Cortex-M0的基本原理,主要包含编程模型、存储器模型、异常模型、电源管理、指令集;并重点分析Cortex-M0相比8位机优势在哪里,以及如何从8位机过渡到Cortex-M0;最后给出了STM32F0的特点。1.1 相比8位(16位)机为何要选择Cortex-M0

Cortex-M0处理器基于一个高集成、低功耗的32位处理器内核,采用3级流水线冯·诺伊曼结构(Von Neumann architecture)。通过简单、功能强大的指令集以及全面优化的设计(提供包括一个单周期乘法器在内的高端处理硬件),Cortex-M0处理器可实现极高的能效。Cortex-M0处理器采用ARMv6-M结构,使用16位的Thumb指令集,并包含Thumb-2技术,代码密度比8位和16位机都要高,这意味对于同样的程序可选用较少的Flash处理器,从而可节约成本和功耗。Cortex-M0的执行周期是0.896DMIPS/MHz,可使用较少的指令周期执行一个任务(即使32位乘法也可在一个周期内完成)。即使在处理不同优先级的嵌套中断情况,嵌套中断处理控制器(NVIC)也会使中断花销很少。

图1-1是Cortex-M0的具体实现框图。图1-1 Cortex-M0的具体实现框图

Cortex-M0处理器紧密集成了一个可配置的嵌套向量中断处理器(NVIC),提供业界领先的中断性能。NVIC具有以下功能:

包含一个不可屏蔽的中断(NMI);

提供零抖动中断选项;

提供4个中断优先级。

处理器内核和NVIC的紧密结合使得中断服务程序(ISR)快速执行,通过寄存器的硬件堆栈以及加载-乘和存储-乘操作的停止和重启等方式缩短了中断延迟时间。中断处理程序不需要任何汇编封装代码,不用消耗任何ISR代码。末尾连锁的优化大大地降低了从一个ISR切换到另一个ISR时的开销。为了优化低功耗设计,NVIC还与睡眠模式相结合,提供一个深度睡眠功能,使整个器件能够迅速掉电。

Cortex-M0处理器提供一个简单的系统级接口,使用AMBA技术来提供高速、低延迟的存储器访问。

Cortex-M0处理器执行一个完整的硬件调试方案,带有大量的硬件断点和观察点选项。通过一个非常适合微控制器和其他小型封装器件的2脚串行线调试(SWD)端口,Cortex-M0提供了一个高度透明的处理器、存储器和外设执行方式。

Cortex-M0被大量的现代编译器支持。中断服务程序可直接使用C语言编码而无须汇编语言。而且指令集仅仅有56条指令,便于学习。尽管Cortex-M0是一个高性能pipelined处理器,指令和中断的执行时序是完全确定的(零抖动),从而使得设计人员可以预测和分析精确时序。支持多种调试方式,除了ARM自己公司的MDK软件,另有大量第三方软件支持,以及基于ARM构建的大量操作系统支持。1.1.1 性能对比

8位机或者16位机的用户为何要转向Cortex-M0呢?Cortex-M0处理器与典型16位机差不多大小,但它具有比16位机更好的性能。表1-1是基于DMIPS的测试对比情况。表1-1 几种构架的DMIPS对比体系结构基于Dhrystone 2.1的预估DMIPS/MHz0.0094最初的80C51PIC180.01966快速80510.113H8S/300H0.16HCS120.19MSP4300.288H8S/26000.303S12X0.34PIC240.445Cortex-M00.896

从表1-1可以看出,Cortex-M0的处理速度比所有流行的16位处理都快,是最快的8051的8倍。

注:DMIPS:Dhrystone Million Instructions executed Per Second主要用于测整数计算能力。Dhrystone:1976年发布,主要用于测整数计算能力,Dhrystone的主体部分是一个由固定顺序指令构成的循环体。Dhrystone的结果表现形式是微处理器执行固定次数的该循环体所用的时间,用DMIPS来表示。DMIPS标准的优点在于可以比较衡量不同处理器的相对性能,并且被广泛应用于不同处理器间的性能比较。1.1.2 8位和16位体系结构的缺点

相比8位或16位机,Cortex-M0无体系结构的缺陷。下面是8位或16位机的一些缺陷。

8位和16位机结构的一个明显缺点是内存太小。程序和数据RAM太小限制了嵌入式产品的能力。其他的类似堆栈内存太小(例如8051堆栈位于内部RAM,被限制成256字节,包含register bank space)也影响软件设计。ARM的体系结构的处理器,其内存空间是非常大的,堆栈位于系统内存中,软件设计非常灵活。

许多8位和16位微控器通过将内存空间划分成内存页方式访问较大内存。软件开发反而因此变得困难,因为在不同的内存页中存取地址不直截了当。因为在不同内存页过渡切换,从而增大了代码尺寸,还降低了性能。然而,ARM微控器使用32位线性地址并不需要内存分页从而更容易使用,并提供更好的开发效率。

8位微控器体系结构的另外一个缺点是指令集。例如,8051过度依赖累加器寄存器来处理数据和内存传递,这样增加了代码尺长度。

地址模式也是影响8位机和16位机性能的一个因素。在Cortex-M0中有多种地址模式可用,从而保证代码长度和方便性。1.1.3 Cortex的软件移植性

相比8位机或者16位机,ARM的Cortex处理器的编程是非常方便的。ARM的Cortex微控器可全部使用C语言进行软件编程,从而缩短软件开发时间并提高软件的可移植性。即使软件人员计划使用汇编语言,指令集也是非常容易理解的。而且,因为编程模型类似ARM7TDMI,熟悉ARM处理器的人员会很快熟悉Cortex微控器。

Cortex-M0的构架可高效地实现嵌入式操作系统。在复杂应用中,使用嵌入式操作系统可轻松地处理并行任务。并且由于ARM是IP(intellectual property)的供应商,ARM处理器被广大微控器厂商采用,方便用户选型。

除了硬件,还有大量的嵌入式操作系统、代码库、开发工具以及其他资源供选择。良好的软件生态体系可将精力集中到开发中,提高产品开发速度。1.2 如何从8位机过渡到Cortex-M0

ARM公司的Joseph Yiu和Andrew Frame从堆栈内存、数据类型、非对齐数据等方面分析8位机与Cortex-M的差异,以及如何从8位机过渡到Cortex-M(包含Cortex-M0、Cortex-M3、Cortex-M4)。1.内存空间

ARM处理器采用32位寻址,可实现一个4GB的线性内存空间。该内存空间在结构上分成多个区。每个区都有各自的推荐用法(虽然并不是固定的)。统一内存架构不仅增加了内存使用的灵活性,而且降低了不同内存空间使用不同数据类型的复杂性。

相反地,8051微控制器具有多个内存空间。内存空间的分割增加有效地利用全部内存空间的困难,而且需要借助C语言扩展来处理不同的内存类型。

8051在外部RAM内存空间上最高支持64KB的程序内存和64KB的数据内存。理论上,可以利用内存分页来扩展程序内存大小。不过,内存分页解决方案并未标准化,换句话说,不同8051供应商的内存分页的实现并不相同。这不仅会增加软件开发的复杂性,而且由于处理页面切换增加软件开销,显著降低软件性能。

在ARM Cortex-M3或Cortex-M4上,SRAM区和外设区都提供了一个1MB的位段区(bit band region)。此位段区允许通过别名地址访问其内部的每个位。由于位段别名地址只需通过普通的内存存取指令即可访问,因此被C语言完全支持,不需要任何特殊指令。而8051提供了少量的位寻址内存(内部RAM上16字节和SFR空间上16字节)。处理这些位数据需要特殊指令支持此功能,并且C编译器需要扩展。

图1-2是Cortex-M内存映射方式。图1-3是8051的内存映射方式。图1-2 Cortex-M的内存映射方式图1-3 8051的内存映射方式2.堆栈内存

堆栈内存操作是内存架构的重要组成部分。在8051中,堆栈指针只有8位,同时堆栈位于内部的内存空间(上限为256个字节,并由工作寄存器和内部数据变量共享)。堆栈操作基于满递增模式。图1-4是8051的堆栈映射方式。图1-4 8051堆栈映射方式

与8051不同的是,ARM Cortex-M处理器使用系统内存作为堆栈,采用满递减模式。图1-5是Cortex-M堆栈示意图。图1-5 Cortex-M堆栈示意图

满递减堆栈内存模型更方便C语言。例如,微控制器中的SRAM的使用可以是使用动态分配内存空间的C库。图1-6是Cortex-M的堆与栈。尽管Cortex-M处理器的每次压栈需要32位的堆栈内存,RAM使用总体上仍然要比8051小。8051的变量通常是静态地放在IDATA上,而ARM处理的局部变量是放在堆栈内存上的,因此,只有当函数执行的时候,局部变量才会占用RAM空间。此外,ARM Cortex-M处理器提供第二个堆栈指针,以允许操作系统内核和进程堆栈使用不同的堆栈内存。这使得操作更可靠,也使操作系统设计更高效。(堆栈指针切换是自动处理的)图1-6 Cortex-M的堆与栈3.数据类型

8051和ARM处理器的数据类型有一些差异。由于数据大小不同,如果程序代码存在依赖数据类型大小或溢出行为,不做修改可能无法工作。表1-2为常见数据类型的大小,具体视编译器而定。表1-2 8051与ARM中的数据类型类型8051中的位数ARM中的位数char,unsigned char888/16/32(选用最enum16少的一个)short,unsigned short1616int,unsigned int1632long,unsigned long3232

数据类型大小不同的另一个影响是在ROM中保留常数数据所需的大小。例如,如果8051程序中包含一个整数型常数数组,那么需要修改代码,将该数组定义为短整型常数。否则,代码长度可能会因为该数组从16位变成32位而增加。由于8051架构的特性,8051的C编译器还支持一些数据类型和内存类型扩展,见表1-3。这些数据类型在ARM处理器上是不被支持的。表1-3 8051专有数据类型类型描述位数在0x20与0x3C之间的位bit1可寻址sbit在SFR区域的位可寻址1sfr专用功能寄存器8sfr1616位专用功能寄存器16 idata内部寻址区的数据 xdata外部寻址区数据 bdata片内可位寻址数据

由于8051的处理能力限制,大多数8051 C编译器会将“双精度”数据类型(64位)作为单精度(32位)来处理。而在ARM处理器中使用相同代码时,C编译器将使用双精度,因此程序行为可能会发生变化。例如,如果只需要单精度,需要采用如下类似修改方式进行修改。 X=T*atan(T2*sin(X)*cos(X)/(cos(X+Y)+cos(X-Y)-1.0)); /* double precision on ARM*/ Y=T*atan(T2*sin(Y)*cos(Y)/(cos(X+Y)+cos(X-Y)-1.0));

对于单精度运算,代码需要更改为: X=T*atanf(T2*sinf(X)*cosf(X)/(cosf(X+Y)+cosf(X-Y)-1.0F)); /*single precision on ARM*/ Y=T*atanf(T2*sinf(Y)*cosf(Y)/(cosf(X+Y)+cosf(X-Y)-1.0F));

对于不需要双精度精确度的应用程序,将代码更改为单精度能够提高性能并缩短代码长度。4.混用C语言和汇编程序

大多数情况下,完全可用C语言来编写Cortex-M应用程序。即使需要访问一些C编译器无法通过普通C代码生成的特殊指令,也可以使用CMSIS提供的隐含函数,或者根据需要在应用程序中使用汇编语言。可以在单独的汇编程序文件中编写汇编代码,也可以使用C编译器的特定方法将汇编代码混合在C程序文件中。

使用ARM(和Keil)开发工具时,将汇编代码插入C编程文件的方法称为“嵌入式汇编程序”。汇编代码被声明为函数,并可以被C代码调用。例如: int main(void) { int status; status =get_primask(); while(1); } __asm int get_primask(void) { MRS R0,PRIMASK;Put interrupt masking register in R0; BX LR ;return }

使用GCC和IAR编译器时,可以使用内嵌汇编程序将汇编代码插入C程序代码中。请注意,虽然包括RVDS和KEIL MDK-ARM在内的ARM开发工具中也包含内嵌汇编程序功能,但是ARM工具中的内嵌汇编程序仅支持ARM指令,并不支持Thumb指令,因此不能用于Cortex-M0处理器。在汇编程序和C语言混合环境中,可以通过汇编程序代码调用C函数,也可以通过C函数调用汇编程序代码。在简单的情况下,可以使用R0~R3作为函数的输入(R0作为第一个输入变量,以此类推),并使用R0来返回结果。函数应该保留R4~R11的值,而如果调用C函数,那么返回时该C函数可能会更改R0~R3和R12的值。1.3 编程模型

本节描述Cortex-M0的编程模型,主要是关于处理器的模式、堆栈和寄存器的。1.3.1 处理器的模式

处理器的模式有线程模式(Thread)和处理器模式(handler)两种。其中,线程模式用来执行应用软件,处理器在退出复位时进入线程模式。处理器模式用来处理异常,处理器在完成所有的异常处理后返回到线程模式。Cortex-M0不支持多特权级,能一直使用所有指令和访问所有资源。1.3.2 堆栈

处理器使用一个满递减堆栈。这就意味着堆栈指针指向堆栈存储器中的最后一个堆栈项。当处理器将一个新的项压入堆栈时,堆栈指针递减,然后将该项写入新的存储器单元。

处理器执行两个堆栈,主堆栈和进程堆栈,两个堆栈有自己独立的堆栈指针副本。在线程模式下,CONTROL寄存器控制着处理器使用主堆栈还是进程堆栈。在处理器模式下,处理器总是使用主堆栈。处理器操作的选择见表1-4。表1-4 处理器模式和堆栈使用的选择处理器的模式应用情况使用的堆栈 主堆栈或者进程堆线程模式执行应用程序栈。由CONTROL寄存器控制执行异常处理程处理器模式 主堆栈序1.3.3 内核寄存器

图1-7是处理器内核寄存器。图1-7 处理器内核寄存器组(1)通用寄存器

R0~R12是供数据操作使用的32位通用寄存器。(2)堆栈指针

堆栈指针(SP)是寄存器R13。在线程模式中,CONTROL寄存器的bit[1]指示了堆栈指针的使用情况。

0:主堆栈指针(MSP)。这是复位值。

1:进程堆栈指针(PSP)。

复位时,处理器将地址0x00000000的值加载到MSP中。(3)链接寄存器

链接寄存器(LR)是寄存器R14。它保存子程序、函数调用和异常的返回信息。复位时,LR的值不可知。(4)程序计数器

程序计数器(PC)是寄存器R15。它包含当前的程序地址。复位时,处理器将复位向量(地址:0x00000004)的值加载到PC。位0的值复位时被加载到EPSR的T位,必须为1。(5)程序状态寄存器

程序状态寄存器(PSR)由下列3种寄存器组合而成:

应用程序状态寄存器(APSR);

中断程序状态寄存器(IPSR);

执行程序状态寄存器(EPSR)。

在32位的PSR中,这3个寄存器的位域分配互斥。PSR的位分配见表1-5。表1-5 APSR、IPSR、EPSR寄存器的位分配

这3个寄存器可以单独访问,也可以2个一组或3个一组进行访问,访问时,将寄存器名称作为MSR或MRS指令的一个变量。例如:

使用寄存器名称PSR,用MRS指令来读所有寄存器。

使用寄存器名称APSR,用MSR指令来写APSR。

PSR的组合和属性见表1-6。表1-6 PSR的组合和属性寄存器类型组合[1][2]PSR R/WAPSR、EPSE和IPSR IEPSR ROEPSE和IPSR[1]IAPSR R/WAPSR和IPSR[2]EAPSR R/WAPSR和EPSR注:[1]处理器忽略对IPSR位的写操作。[2]读EPSR位时返回零,处理器忽略对EPSR位的写操作。

①应用程序状态寄存器:APSR包含执行完前面的指令后条件标志的当前状态。APSR的位分配见表1-7。表1-7 APSR的位分配位名称功能[31]N负值标志[30]Z零值标志[29]C进位或借位标志[28]V溢出标志[27:0]—保留

②中断程序状态寄存器:ISP包含当前中断服务程序(ISR)的异常编号。IPSR的位分配见表1-8。表1-8 IPSR的位分配位名称功能[31:6]—保留ISR_NUMBER:是当前异常的编号。0=线程模式1=保留2=NMI3=HardFault[5:0]异常编号4~10=保留11=SVCall12,13=保留14=PendSV15=SysTick16~47=IRQ0~IRQ3148~63=保留

③执行程序状态寄存器:EPSR包含Thumb状态位。EPSR的位分配见表1-9。表1-9 EPSR的位分配位名称功能 [31:25]保留24TThumb状态位[23:0]—保留

如果应用软件使用MRS指令直接读取EPSR将始终返回零。利用MSR指令来写EPSR的操作会被忽略。故障处理程序可以检查入栈PSR的EPSR值来确定故障的原因。下面的操作可以清除T为0。

[1]指令BLX、BX和POP{PC}。

[2]异常返回时恢复被压入栈中的xPSR值。

[3]进入异常时向量值的bit[0]。

在T位为0时尝试执行指令会导致HardFault或锁定故障。

可中断-可重启的指令有LDM和STM。如果在执行这两条中的其中一条指令的过程中出现中断,处理器就终止指令的执行。在处理完中断后,处理器再从头开始重新执行指令。(6)异常屏蔽寄存器

异常屏蔽寄存器禁止处理器处理异常。当异常可能影响到实时任务或要求连续执行的代码序列时,异常就被禁能。可以使用MSR和MRS指令或CPS指令改变PRIMASK的值来禁能或重新使能异常。PRIMASK寄存器阻止优先级可配置的所有异常被激活。有关寄存器的属性见表1-10。表1-10 PRIMASK寄存器的位分配位描述31:1保留0:无影响。01:阻止可配置优先级的异常激活(7)控制(CONTROL)寄存器

CONTROL寄存器控制着处理器处于线程模式时所使用的堆栈。CONTROL寄存器的位分配见表1-11。表1-11 CONTROL寄存器的位分配位功能31:2保留堆栈指针选择:CONTROL[1]0代表当前堆栈指针是MSP,1代表当前堆栈指针是PSP[0]保留

处理器模式始终使用MSP,因此,在处理器模式下,处理器忽略对CONTROL寄存器的有效堆栈指针位执行的明确的写操作。异常进入和返回机制会将CONTROL寄存器更新。在一个OS环境中,推荐运行在线程模式中的线程使用进程堆栈,内核和异常处理器使用主堆栈。默认情况下,线程模式使用MSP。要将线程模式中使用的堆栈指针切换成PSP,只需要使用MSR指令将有效堆栈位设置为1。

注意:当更改堆栈指针时,软件必须在MSR指令后立刻使用一个ISB指令。这样来保证ISB之后的指令执行时使用新的堆栈指针。1.4 存储器模型

Cortex-M0支持32位字、16位半字、8位字节,所有数据存储器访问都采用小端模式。指令存储器和专用外设总线(PPB)访问始终是小端模式。处理器有一个固定的存储器映射,提供4GB的可寻址存储空间。存储器映射如图1-8所示。图1-8 Cortex-M0存储器映射1.4.1 存储区、类型和属性

存储器映射分成多个区域。每个区域有一个相应的存储器类型,某些区域还有附加的存储器属性。存储器类型和属性决定了各个区域的访问方式。

主要的存储器类型如下。

常规存储器(Normal):处理器为了提高效率,可以重新对交易进行排序,或者刻意地进行读取。

Device存储器:处理器保护与Device或强秩序存储器(Strong-ordered memory)的其他交易相关的交易秩序。

强秩序存储器(Strong-Ordered):处理器保护与所有其他交易相关的交易秩序。

Device存储器和强秩序存储器的不同秩序要求意味着,存储器系统可以缓冲一个对Device存储器的写操作,但不准缓冲对强秩序存储器的写操作。1.4.2 存储器系统的存储器访问次序

对于大多数由明确的存储器访问指令引发的存储器访问,存储器系统都不保证访问秩序与指令的编写顺序完全一致,只要所有访问秩序的重新安排不影响指令序列的操作就行。一般情况下,如果两个存储器访问的顺序必须与两条存储器访问指令编写的顺序完全一致程序才能正确执行,软件就必须在两条存储器访问指令之间插入一条内存屏障指令。但是,存储器系统不保证Device存储器和强秩序存储器的一些访问秩序。对于两条存储器访问指令A1和A2,如果A1的编写顺序在前,两条指令所引发的存储器访问顺序见表1-12。表1-12 存储器访问排序注:-表示存储器系统不保证访问秩序。<表示观察到访问顺序与指令编写顺序一致,即A1总是在A2之前。1.4.3 存储器访问的行为

存储器映射中每个区域的访问行为见表1-13。表1-13 存储器访问的行为1.4.4 软件的存储器访问顺序

因为如下原因,程序流程的指令顺序不能担保相应的存储器交易顺序。

为了提高效率,处理器可以将一些存储器访问的顺序重新安排,只要不影响指令序列的操作就行;

存储器映射中的存储器或设备可能有不同的等待状态;

某些存储器访问被缓冲,或者是刻意为之。

1.4.2节描述了存储器系统在哪些情况下能保证存储器访问的秩序。但是,如果存储器访问的秩序十分重要,软件就必须插入一些内存屏障指令来强制保持存储器访问的秩序。处理器提供了以下内存屏障指令(memory barrier instruction)。

DMB:数据存储器屏障(DMB)指令保证先完成未处理的存储器交易,再执行后面的存储器交易。

DSB:数据同步屏障(DSB)指令保证先完成未处理的存储器交易,再执行后面的指令。

ISB:指令同步屏障(ISB)保证所有已完成的存储器交易的结果后面的指令都能辨认出来。

下面是内存屏障指令使用的一些例子。

向量表:如果程序改变了向量表中的一项,然后又使能了相应的异常,那么就在两个操作之间插入一条DMB指令。这就确保了,如果异常在被使能后立刻被采纳,处理器能使用新的异常向量。

自修改代码:如果一个程序包含自修改代码,代码修改之后在程序中立刻使用一条ISB指令。这就确保了后面的指令执行使用的是更新后的程序。

存储器映射切换:如果系统包含一个存储器映射切换机制,在切换存储器映射之后使用一条DSB指令。这就确保了后面的指令执行使用的是更新后的存储器映射。

对强秩序存储器(例如,系统控制块)执行的存储器访问不需要使用DMB指令。处理器保护与所有其他交易相关的交易秩序。1.5 异常模型1.异常状态

每个异常都处于下面其中一种状态。

无效:异常无效,未挂起。

挂起:异常正在等待处理器处理。一个外设或软件的中断请求可以改变相应的挂起中断的状态。

有效:一个异常正在被处理器处理,但处理尚未结束。一个异常处理程序可以中止另一个异常处理程序的执行。在这种情况下,两个异常都处于有效状态。2.异常类型

异常类型主要有以下几种。

复位:在上电或热复位时启动。异常模型将复位当作一种特殊形式的异常来对待。当复位产生时,处理器的操作停止(可能停止在一条指令的任何一点上)。当复位撤销时,从向量表中复位项提供的地址处重新启动执行。执行在线程模式下重新启动。

NMI(不可屏蔽中断):可以由外设产生,也可以由软件来触发。这是除复位之外优先级最高的异常。NMI永远使能,优先级固定为2。NMI不能被屏蔽,它的执行也不能被其他任何异常中止,不能被除复位之外的任何异常抢占。

HardFault:由于在正常操作过程中或在异常处理过程中出错而出现的一个异常。HardFault的优先级固定为-1,表明它的优先级要高于任何优先级可配置的异常。

SVCall:管理程序调用(SVC)异常是一个由SVC指令触发的异常。在OS环境下,应用程序可以使用SVC指令来访问OS内核函数和器件驱动。

PendSV:一个中断驱动的系统级服务请求。在OS环境下,当没有其他异常有效时,使用PendSV来进行任务切换。

SysTick:一个系统定时器到达零时产生的异常。软件也可以产生一个SysTick异常。在OS环境下,处理器可以将这个异常用作系统节拍。

中断(IRQ):外设发出或由软件请求产生的异常。所有中断都与指令执行不同步。在系统中,外设使用中断来与处理器通信。

表1-14说明各种异常类型以及向量地址特性。表1-14 各种异常类型的特性注:[1]为了简化软件层,CMSIS只使用IRQ编号,因此,对除中断外的其他异常都使用负值。IPSR返回异常编号。[2]地址值以4为步长,逐次递增。

对于除复位之外的异步异常,在异常被触发和处理器进入异常处理程序之间,处理器可以执行条件指令。3.异常处理程序

处理器使用以下处理程序处理异常。(1)中断服务程序(ISR):中断IRQ0~IRQ31是由ISR来处理的异常。(2)故障处理程序:HardFault是唯一一个由故障处理程序来处理的异常。(3)系统处理程序:NMI、PendSV、SVCall、SysTick和HardFault是由系统处理程序处理的全部异常。4.向量表

向量表包含堆栈指针的复位值以及所有向量处理程序的起始地址(也称为异常向量)。图1-9显示了异常向量在向量表中的放置顺序。每个向量的最低有效位必须为1,表明异常处理程序都是用Thumb代码编写的。向量表的地址固定为0x00000000。图1-9 向量表5.异常优先级

如表1-14所示,每个异常都有对应的优先级,越小的优先级值指示一个更高的优先级;除复位、HardFault和NMI之外,所有异常的优先级都是可配置的;如果软件不配置任何优先级,那么,所有优先级可配置的异常的优先级就都为0。

优先级值的配置范围为0~192。复位、HardFault和NMI这些有固定的负优先级值的异常优先级高于任何其他的异常。若给IRQ[0]分配一个高优先级值,给IRQ[1]分配一个低优先级值,就意味着IRQ[1]的优先级高于IRQ[0]。如果IRQ[1]和IRQ[0]都有效,先处理IRQ[1]。

如果多个挂起的异常具有相同的优先级,异常编号越小的挂起异常优先处理。例如,如果IRQ[0]和IRQ[1]正在挂起,并且两者的优先级相同,那么先处理IRQ[0]。

当处理器正在执行一个异常处理程序时,如果出现一个更高优先级的异常,那么这个异常就被抢占。如果出现的异常的优先级和正在处理的异常的优先级相同,这个异常就不会被抢占,与异常的编号大小无关。但是,新中断的状态为挂起。6.异常的进入和返回

有关异常进入与退出涉及下面4个定义。(1)抢占:当处理器正在执行一个异常处理程序时,如果一个异常的优先级比正在处理的异常的优先级更高,那么低优先级的异常就被抢占。当一个异常抢占另一个异常时,这些异常就被称为嵌套异常。(2)返回:当异常处理程序结束,并且满足以下条件时,异常就返回。没有优先级足够高的挂起异常要处理;已结束的异常处理程序没有在处理一个迟来的异常;处理器弹出堆栈,处理器状态恢复到中断出现之前的状态。(3)末尾连锁(Tail-chaining):这个机制加速了异常的处理。当一个异常处理程序结束时,如果一个挂起的异常满足异常进入的要求,就跳过堆栈弹出,控制权移交给新的异常处理程序。(4)迟来(Late-arriving):这个机制加速了抢占的处理。如果一个高优先级的异常在前一个异常正在保存状态的过程中出现,处理器就转去处理更高优先级的异常,开始提取这个异常的向量。状态保存不受迟来异常的影响,因为两个异常保存的状态相同。从迟来异常的异常处理程序返回时,要遵守正常的末尾连锁规则。

异常的进入是指当有一个优先级足够高的挂起异常存在,并且满足下面的任何一个条件,就进入异常处理:(1)处理器处于线程模式。(2)新异常的优先级高于正在处理的异常,这时,新异常就抢占了正在处理的异常。当一个异常抢占了另一个异常时,异常就被嵌套。

优先级足够高是指该异常的优先级比屏蔽寄存器中所限制的任何一个异常组的优先级都要高。优先级比这个异常要低的异常被挂起,但不被处理器处理。

当处理器处理异常时,除非异常是一个末尾连锁异常或迟来的异常,否则,处理器都把信息压入到当前的堆栈中。这个操作被称为入栈(stacking),8个数据字的结构被称为栈帧(stack frame)。图1-10是异常进入时堆栈的内容。图1-10 异常进入时堆栈的内容

入栈后,堆栈指针立刻指向栈帧的最低地址单元。栈帧按照双字地址对齐。栈帧包含返回地址。这是被中止的程序中下条指令的地址。这个值在异常返回时返还给PC,使被中止的程序恢复执行。处理器执行一次向量提取,从向量表中读出异常处理程序的起始地址。当入栈结束时,处理器开始执行异常处理程序。同时,处理器向LR写入一个EXC_RETURN值。这个值指示了栈帧对应哪个堆栈指针以及在异常出现之前处理器处于什么工作模式。如果在异常进入的过程中没有更高优先级的异常出现,处理器就开始执行异常处理程序,并自动将相应的挂起中断的状态变为有效。如果在异常进入的过程中有另一个优先级更高的异常出现,处理器就开始执行这个高优先级异常的异常处理程序,不改变前一个异常的挂起状态。这是一个迟来异常的情况。

异常返回是指当处理器处于处理器模式并且执行下面其中一条指令尝试将PC设为EXC_RETURN值时,出现异常返回。

POP指令:用来加载PC。

BX指令:用来使用任意的寄存器。

在异常进入时处理器将一个EXC_RETURN值保存到LR中。异常机制依靠这个值来检测处理器何时执行完一个异常处理程序。EXC_RETURN值的bit[31:4]为0xFFFFFFF。当处理器将一个相应的这种形式的值加载到PC时,它将检测到这个操作并不是一个正常的分支操作,而是异常已经结束。因此,处理器启动异常返回序列。EXC_RETURN的bit[3:0]指出了所需的返回堆栈和处理器模式,见表1-15。表1-15 异常返回的行为EXC_RET描述URN0xFFFFFF返回到处理器模式:异常返回获得主堆栈的状态。F1返回后执行使用MSP0xFFFFFF返回到线程模式:异常返回获得MSP的状态。返回F9后执行使用MSP0xFFFFFF返回到线程模式:异常返回获得PSP的状态。返回FD后执行使用PSP所有其他保留值7.故障处理

故障是异常的一个子集。所有的故障都导致HardFault异常被处理,或者,如果故障在NMI或HardFault处理程序中出现,会导致锁定。发生以下情况会导致故障。

在一个优先级等于或高于SVCall的地方执行SVC指令;

在没有调试器的情况下执行BKPT指令;

在加载或存储时出现一个系统产生的总线错误;

执行一个XN存储器地址中的指令;

从系统产生了一个总线故障的地址单元中执行指令;

在提取向量时出现了一个系统产生的总线错误;

执行一个未定义的指令;

由于T位之前被清零而导致不再处于Thumb状态的情况下执行一条指令;

尝试对一个不对齐的地址执行加载或存储操作。

只有复位和NMI可以抢占优先级固定的HardFault处理程序。HardFault可以抢占除复位、NMI或其他硬故障之外的任何异常。

如果在执行NMI或HardFault处理程序时出现故障,或者,在一个使用MSP的异常返回时出栈的却是PSR的时候系统产生一个总线错误,处理器进入一个锁定状态。当处理器处于锁定状态时,它不执行任何指令。在下列情况出现之前,处理器保持锁定状态。

复位;

调试器将锁定状态终止;

出现一个NMI,以及当前的锁定处于HardFault处理程序中。

如果锁定状态出现在NMI处理程序中,后面的NMI就无法使处理器离开锁定状态。1.6 电源管理

Cortex-M0处理器的睡眠模式可以降低功耗,通过SCR的SLEEPDEEP位选择睡眠模式。睡眠模式包含两种。

睡眠模式:停止处理器时钟,其他系统和外设时钟可能仍旧运行。

深度睡眠模式:绝大多数的STM32系统和外设时钟停止。产品级对应停止或者待机模式。

下面讲述进入睡眠模式的机制和唤醒条件。1.进入睡眠模式

系统可以产生伪唤醒事件,例如,一个调试操作唤醒处理器。因此,软件必须能够在这样的事件之后使处理器重新回到睡眠模式。程序中可以有一个空闲循环使得器件回到睡眠模式。(1)等待中断

等待中断指令(WFI)使器件立刻进入睡眠模式。当执行一个WFI指令时,处理器停止执行指令,进入睡眠模式。(2)等待事件

等待事件指令(WFE)根据一个一位的事件寄存器的值来进入睡眠模式。处理器执行一个WFE指令时检查事件寄存器的值。

0:处理器停止执行指令,进入睡眠模式。

1:处理器将寄存器的值设为0,并继续执行指令,不进入睡眠模式。

如果事件寄存器为1,表明处理器在执行WFE指令时不必进入睡眠模式。通常的原因是出现了一个外部事件,或者系统中的另一个处理器已经执行了SEV指令。软件不能直接访问这个事件寄存器。(3)Sleep-on-exit

如果SCR的SLEEPONEXIT位被设为1,当处理器完成一个异常处理程序的执行并返回到线程模式时,处理器立刻进入睡眠模式。如果应用只要求处理器在中断出现时运行,就使用这种机制。2.从睡眠模式唤醒

处理器的唤醒条件取决于使处理器进入睡眠模式所采用的机制。(1)从WFI或sleep-on-exit唤醒

通常,只有当检测到一个优先级足够高的异常导致进入异常处理时,处理器才唤醒。某些嵌入式系统在处理器唤醒之后可能必须先执行系统恢复任务,然后再执行中断处理程序。通过将PRIMASK位置位来实现这个操作。如果到来的中断被使能,并且优先级高于当前的异常优先级,处理器就唤醒,但不执行中断处理程序,直至处理器将PRIMASK设为0。(2)从WFE唤醒

如果出现以下情况,处理器被唤醒。(1)处理器检测到一个优先级足够高的异常导致进入异常处理。(2)在一个多处理器的系统中,系统中的另一个处理器执行了SEV指令。

另外,如果SCR的SEVONPEND位被置1,那么任何新的挂起中断都能触发一个事件和唤醒处理器,即使这个中断被禁能,或者这个中断的优先级不够高而导致无法进入异常处理。3.电源管理编程提示

ISO/IEC C语言不能直接产生WFI、WFE和SEV指令。CMSIS为这些指令提供了以下内在函数: void __WFE(void) /* 等待事件 */ void __WFI(void) /* 等待中断 */ void __SEV(void) /* 发送事件 */1.7 指令集

Cortex-M0采用ARM V6-M构架,只支持56条Thumb指令。这些指令既兼容Cortex-M3,又兼容ARM7处理器。

在开发Cortex-M0处理器应用程序时,用户不需要使用汇编语言。但有时为了优化C语言程序,提高代码的执行效率,会用到反汇编。所以为了方便查询,这里给出Cortex-M0的指令集,见表1-16。表1-16 Cortex-M0指令集影响标志助记符操作数描述位N,Z,{Rd,}Rn,RmADCS带进位加C,V{Rd,}Rn,<RmN,Z,ADD{S}加%">#imm>C,V将基于PC相对偏—ADRRd,label移的地址读到寄存器{Rd,}Rn,RmANDS位与计算N,Z{Rd,}Rm,<RsASRS算术右移N,Z,C%">#imm>B{cc}—label跳转{有条件}{Rd,}Rn,RmBICS位清除N,Z—BKPT#imm断点带链接的分支跳—BLlabel转带链接的间接跳—BLXRm转—BXRm间接跳转N,Z,CMNRn,Rm比较负值C,VRn,<Rm%">N,Z,CMP比较#imm>C,V修改处理器状—CPSIDi态,禁止中断修改处理器状—CPSIEi态,使能中断——DMB数据存储隔离——DSB数据同步隔离{Rd,}Rn,RmEORS异或N,Z——ISB指令同步隔离加载多个寄存Rn{!},reglist—LDM器,访问之后会递增地址从基于PC相对偏—LDRRt,label移地址上加载寄存器Rt,[Rn,<Rm—LDR以字加载寄存器%">#imm>]Rt,[Rn,<Rm以字节加载寄存—LDRB%">#imm>]器Rt,[Rn,<Rm以半字加载寄存—LDRH%">#imm>]器Rt,[Rn,<Rm以有符号字节加—LDRSB%">#imm>]载寄存器Rt,[Rn,<Rm以有符号半字加—LDRSH%">#imm>]载寄存器{Rd,}Rn,<RsLSLS逻辑左移N,Z,C%">#imm>{Rd,}Rn,<RsLSRS逻辑右移N,Z,C%">#imm>MOV{S}Rd,Rm传送Rd数据到RmN,Z将特殊功能寄存Rd,spec_reg—MRS器内容移到通用寄存器将通用寄存器内N,Z,spec_reg,RmMSR容移到特殊功能C,V寄存器MULSRd,Rn,Rm乘法,32结果N,ZMVNSRd,Rm取反的位操作N,Z——NOP空操作{Rd,}Rn,RmORRS逻辑或N,Zreglist—POP寄存器出栈reglist—PUSH寄存器压栈—REVRd,Rm按字节反转—REV16Rd,Rm按半字反转按有符号半字反—REVSHRd,Rm转{Rd,}Rn,RsRORS循环右移N,Z,CN,Z,{Rd,}Rn,#0RSBS逆向减法C,VN,Z,{Rd,}Rn,RmSBCS带符号减C,V——SEV发送事件批量存储寄存Rn!,reglist—STM器,Rn递减Rt,[Rn,<Rm将寄存器作为字—STR%">#imm>]来存储Rt,[Rn,<Rm将寄存器作为字—STRB%">#imm>]节来存储Rt,[Rn,<Rm将寄存器作为半—STRH%">#imm>]字来存储{Rd,}Rn,<RmN,Z,SUB{S}减法%">#imm>C,V—SVC#imm管理调用字节符号扩展到—SXTBRd,Rm32位半字符号扩展到—SXTHRd,Rm32位TSTRn,Rm逻辑与测试N,Z字节零扩展到32—UXTBRd,Rm位半字零扩展到32—UXTHRd,Rm位——WFE等待事件——WFI等待中断

ISO/IEC C代码不能直接访问Cortex-M0指令,而ARM公司提供的CMSIS可以直接访问Cortex-M0指令,并被多个编译器支持,也可以通过编译器的嵌入汇编指令方式进行。表1-17是CMSIS对应Cortex-M0指令的内部函数。表1-17 CMSIS内部函数用于生成Cortex-M0指令指令CMSIS intrinsic functionvoid enable_irq(void)CPSIE ivoid disable_irq(void)CPSID ivoid ISB(void)ISBvoid DSB(void)DSBvoid DMB(void)DMBvoid NOP(void)NOPuint32_t REV(uint32_t int value)REVREV16uint32_t REV16(uint32_t int value)REVSHuint32_t REVSH(uint32_t int value)SEVvoid SEV(void)WFEvoid WFE(void)void WFI(void)WFI

CMSIS也提供了一些用于通过MRS和MSR指令访问特殊寄存器的函数,见表1-18。表1-18 CMSIS的内部函数用于访问特殊寄存器

特殊寄存器访问方式CMSIS函数uint32_t get_PRIMASK (void)读PRIMASKvoid set_PRIMASK (uint32_t 写value)uint32_t get_CONTROL 读(void)CONTROLvoid set_CONTROL (uint32_t 写value)uint32_t get_MSP (void)读MSPvoid set_MSP (uint32_t 写TopOfMainStack)uint32_t get_PSP (void)读PSPvoid set_PSP (uint32_t 写TopOfProcStack)1.8 Cortex-M0内核外设

Cortex-M0内核外设如下。

NVIC:一个嵌入式中断控制器,支持低延迟的中断处理。

系统控制块(SCB):到处理器的编程模型接口。它提供系统执行信息和系统控制,包括配置、控制和系统异常的报告。

系统定时器(SysTick):一个24位的递减定时器。可以将其用作一个实时操作系统(RTOS)的节拍定时器,或者用作一个简单的计数器。1.9 STM32F0系列

意法半导体(STMicroelectronics,ST)是全球领先的半导体解决方案供应商,为传感及功率技术和多媒体融合应用领域提供创新的解决方案。ST推出了优秀的STM32F0系列产品。

STM32F0瞄准的正是成本敏感的8位和16位机应用市场,延续STM32的特性,而且继承了STM32成熟的IP组合,为客户提供完整的产品组合、承诺的生产能力和有竞争力的预算价格。STM32F0系列产品新增7个定时器,这些定时器可控制加热器或电动机等设备,例如,在一个电磁炉内同时控制多个电子元器件。

STM32F0系列集成了支持HDMI接口的消费电子控制器(CEC)的硬件,这有助于简化微控制器在众多家庭多媒体设备内的设计,准许开发人员采用最新的工业标准通信协议来设计接口,同时还能降低微控制器的CPU、存储器、外设接口的负荷,释放更多的能力去处理其他任务。CEC可由一个低速32kHz外部时钟源驱动,或者为降低系统成本,还可用8MHz内部时钟源驱动。此外,STM32F0的12MHz I/O信号状态翻转速度让开发人员能够在更低成本和功耗平台上实现复杂控制算法。

目前STM32F0系列主要有STM32F030超值型、STM32F0x1、STM32F0x2、STM32F0x四种形式。

STM32F030超值系列基于48MHz的ARM Cortex-M0处理器内核。STM32F030虽然只有8位微控制器的价格,但性能和特性并没有受到任何影响。

STM32F030采用ARM Cortex内核,运算速度高达48MHz。STM32F030是STM32系列中价格最低的产品,具有全套外设,例如高速12位ADC、先进且灵活的定时器、日历RTC和通信接口(如I2C、USART和SPI)。

当然对于用户而言,对于能够满足需求情况,更重要的是价格。现在意法半导体喊出的口号是32美分的芯片。

STM32F030的内部实时时钟和5通道直接存储器存取控制器(DMA),是同一价位微控制器所不具备的功能,这两项重要特性有助于简化应用开发,提高产品性能。

意法半导体还推出一套叫做探索套件的STM32F0专用评估板,这个探索板配备按键和LED指示灯,可通过USB数据线直接连接PC,板子上预装了大量的演示软件和固件例程。探索套件兼容市场领先的第三方软件开发工具提供商Atollic、IAR、Keil和TASKING开发的STM32软件开发环境。

作为同为ST公司的两兄弟,STM8与STM32F0不可避免地会短兵相见,它们在外设功能方面太相似了。表1-19是对双方功能统计,表面上看目前STM32F0外设方面仅仅多了USB,但实际上ST公司对STM32F0的外设功能作了很多改善(例如,STM32F0相比以往的ST公司产品线,RTC精确到亚秒级)。表1-19 STM8与STM32F0对比

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载