STM32研究生教案.docx
《STM32研究生教案.docx》由会员分享,可在线阅读,更多相关《STM32研究生教案.docx(73页珍藏版)》请在冰豆网上搜索。
STM32研究生教案
STM32初级学习
第一章初识Cortex-M32
1.1ARMCortex-M3处理器初探2
1.2从Cortex-M3处理器内核到基于Cortex-M3的MCU3
第二章开发环境MDK、J-link的搭建及系统调试7
2.1JLINK驱动安装7
2.2MDK环境搭建7
2.3MDK破解11
第三章如何新建工程13
第四章工程编译及仿真、程序的下载18
4.1工程编译19
4.2仿真环境的搭建20
4.3JLINK下载23
第五章了解stm32库文件26
第六章简单例程分析28
6.1流水灯介绍28
6.1.1STM32的地址映射32
6.1.2STM32库对寄存器的封装37
6.1.3STM32的时钟系统(程序的心脏,每个例程公共的模块)39
6.1.4流水灯例程44
6.1.5仿真结果分析48
6.1.6程序下载到开发板后的结果显示48
6.2系统滴答定时器SysTick48
6.2.1实例分析51
6.2.2仿真结果分析:
55
6.2.3程序下载55
6.3EXTI外部中断55
6.3.1NVIC结构体成员58
6.3.2抢占优先级和响应优先级58
6.3.3NVIC的优先级组59
6.3.4EXTI外部中断60
6.3.5例程程序61
6.4串口部分62
6.4.1波特率控制63
6.4.2收发控制64
6.4.3数据存储转移部分64
6.4.4实例解析65
6.5ADC(DMA模式)65
6.5.1ADC简介65
6.5.2STM32的ADC主要技术指标66
6.5.3ADC工作过程分析67
6.5.4ADC采集例程分析68
第一章初识Cortex-M3
1.1ARMCortex-M3处理器初探
ARMCortex-M3处理器,作为Cortex系列的处女作,为了让32位处理器入主作庄单片机市场,轰轰烈烈地诞生了!
由于采用了最新的设计技术,它的门数更低,性能却更强。
许多曾经只能求助于高级32位处理器或DSP的软件设计,都能在CM3上跑得很快很欢。
嵌入式处理器市场正在32位化,相信用不了多久,CM3就一定会在这美丽新世界中脱颖而出。
下面我们共同来了解一下CM3的优势:
•性能强大。
在相同的主频下能做处理更多的任务,全力支持劲爆的程序设计。
•功耗低。
延长了电池的寿命——这简直就是便携式设备的命门(如无线网络应用)。
•实时性好。
采用了前卫甚至革命性的设计理念,使它能极速地响应中断,而且响应中断所需的周期数是确定的。
•代码密度得到很大改善。
一方面在大型应用程序优势,另一方面为低成本设计而省吃俭用。
•使用更方便。
现在从8位/16位处理器转到32位处理器之风刮得越来越猛,更简单的编程模型和更透彻的调试系统,为与时俱进的人们大大减负。
•低成本的整体解决方案。
让32位系统比和8位/16位的还便宜,低端的Cortex-M3单片机甚至还卖不到1美元。
•遍地开花的优秀开发工具。
免费的,便宜的,全能的开发环境。
值得一提的是,CM3并不是第一个被拿去做万金油型处理器的内核。
那廉颇虽老却依然骁勇的ARM7/ARM9处理器,在通用嵌入式处理器市场中德高望重,至今拥有无数铁杆粉丝。
半导体业界的群英们,像NXP(philips)、TI、Atmel、OKI、ST等,都以ARM为内核,做出了各自身怀绝技的32位MCU。
ARM7作为最受欢迎的32位嵌入式处理器,被载入了亮煌煌的几页史册——每年超过10亿片出货量,为各行各业的嵌入式设备中都找得到它们的身影。
1.2从Cortex-M3处理器内核到基于Cortex-M3的MCU
Cortex-M3处理器内核是单片机的中央处理单元(CPU)。
完整的基于CM3的MCU还需要很多其它组件。
在芯片制造商得到CM3处理器内核的使用授权后,它们就可以把CM3内核用在自己的硅片设计中,添加存储器,外设,I/O以及其它功能块。
Cortex-M3是一款低功耗处理器,具有门数目少,中断延迟短,调试成本低的特点,是为要求有快速中断响应能力的深度嵌入式应用而设计的。
该处理器采用ARMv7-M架构。
Cortex-M3处理器整合了以下组件:
Cortex-M3的一个简化视图
●处理器内核。
这款门数目少,中断延迟短的处理器具备以下特性:
—ARMv7-M:
Thumb-2ISA子集,包含所有基本的16位和32位Thumb-2指令,用于多媒体,SIMD,E(DSP)和ARM系统访问的模块除外。
—只有分组的SP
—硬件除法指令,SDIV和UDIV(Thumb-2指令)
—处理模式(handlermode)和线程模式(threadmode)
—Thumb状态和调试状态
—可中断-可继续(interruptible-continued)的LDM/STM,PUSH/POP,实现低中
断延迟。
—自动保存和恢复处理器状态,可以实现低延迟地进入和退出中断服务程序(ISR)。
—支持ARMv6架构BE8/LE
—ARMv6非对齐访问
●嵌套向量中断控制器(NVIC)。
它与处理器内核紧密结合实现低延迟中断处理,并具有以下特性:
—外部中断可配置为1~240个
—优先级位可配置为3~8位
—中断优先级可动态地重新配置
—优先级分组。
分为占先中断等级和非占先中断等级
—支持末尾连锁(tail-chaining)和迟来(latearrival)中断。
这样,在两个中断之间没有多余的状态保存和状态恢复指令的情况下,使能背对背中断(back-to-backinterrupt)处理。
—处理器状态在进入中断时自动保存,中断退出时自动恢复,不需要多余的指令。
●存储器保护单元(MPU)。
MPU功能可选,用于对存储器进行保护,它具有以下特
性:
—8个存储器区
—子区禁止功能(SRD),实现对存储器区的有效使用。
—可使能背景区,执行默认的存储器映射属性。
●总线接口
—AHBLiteICode、DCode和系统总线接口
—APB专用外设总线(PPB)接口
—Bitband支持,bit-band的原子写和读访问。
—存储器访问对齐
—写缓冲区,用于缓冲写数据。
●低成本调试解决方案,具有以下特性:
—当内核正在运行、被中止、或处于复位状态时,能对系统中包括Cortex-M3寄
存器组在内的所有存储器和寄存器进行调试访问。
—串行线(SW-DP)或JTAG(JTAG-DP)调试访问,或两种都包括。
—Flash修补和断点单元(FPB),实现断点和代码修补。
—数据观察点和触发单元(DWT),实现观察点,触发资源和系统分析(system
profiling)
—仪表跟踪宏单元(ITM),支持对printf类型的调试。
—跟踪端口的接口单元(TPIU),用来连接跟踪端口分析仪。
—可选的嵌入式跟踪宏单元(ETM),实现指令跟踪。
第二章开发环境MDK、J-link的搭建及系统调试
2.1JLINK驱动安装
在用JLINK下载和调试程序之前,我们需要线在电脑上安装JLINK驱动,如果电脑上已经安装JLINK驱动,则可跳过这一步。
在野火M3光盘目录下:
3-安装软件\1-JLINKV8驱动点击Setup_JLinkARM_V428c.exe,完成JLINK驱动的安装。
安装过程非常简单,这里将跳过。
在安装完成后,我们将JLINK插接到电脑的USB口,即可在我的电脑\管理\设备管理器\通用串行总线控制器中看到一个J-Linkdriver。
要注意的是在安装完JLINK驱动后,一定要将JLINK插接到电脑的USB口,否则在电脑的设备管理器中是查看不到J-Linkdriver的。
当你把JLINK拔出电脑的USB口时候,J-Linkdriver就会消失。
2.2MDK环境搭建
在我们学习编写代码之前需要先要把MDK这个软件安装好,野火用的版本是V4.14,在安装完成之后可以在工具栏help->aboutuVision选项卡中查看到版本信息。
MDK是一个集代码编辑,编译,链接和下载于一体的集成开发环境(KDE)。
MDK这个名字我们可能不熟悉,但说到KEIL,学过51的朋友就再熟悉不过了。
后来KEIL被ARM公司收购之后就改名为MDK了,所以学过51的朋友是很快就可以熟悉这个开发环境的。
在MDK安装目录下:
3-安装软件\2-MDK找到MDK414.exe,点击MDK414.exe,在弹出MDK安装界面后,按照如下步骤操作即可。
●点击Next.
●把对勾上,点击Next。
●点击Next,默认安装在C:
\keil目录下。
(选择你想要安装的路径)
●在用户名中填入名字(可随便写,可空格),在邮件地址那里填入邮件地址(可随便写,可空格),点击Next。
●正在安装,请耐心等待。
●点击Finish,安装完成。
●此时就可在桌面看到MDK的快捷图标,如下所示:
2.3MDK破解
安装完MDK开发环境后,在下载程序的时候会有40K的代码限制,我们需要破解软件即可完成大程序代码的编译,在软件安装目录下:
找到KEIL_Lic.exe,点击KEIL_Lic.exe,如下图所示
在弹出的界面中的CID选项框中填入MDK的CID(MDK的CID在MDK开发环境中的菜单栏File\LicenseManagemant中获取到如下面两幅图所示),在Target下拉框中选择ARM,然后点击Generate按钮,复制产生的CIDCode,然后回到MDK开发环境中的菜单栏File\LicenseManagemant中,把刚刚在注册机复制到的CIDCode粘贴到NewLicenseIDCode(LIC):
框中,然后点击AddLIC,,点击close,大功告成:
)。
第三章如何新建工程
●开始新建工程
点击桌面UVision4图标,启动软件。
如果是第一次使用的话会打开一个自带的工程文件,我们可以通过工具栏Project->CloseProject选项把它关掉。
在工具栏Project->NewμVisionProject…新建我们的工程文件,我们将新建的工程文件保存在桌面的STM32-Study\Project文件夹下,文件名可以任意取(按自己意愿选择),点击保存。
●接下来的窗口是让我们选择公司跟芯片的型号,我们用的芯片是ST公司的STM32F103ZET6,有64KSRAM,512KFlash,属于高集成度的芯片。
按如下选择即可。
●接下来的窗口问我们是否需要拷贝STM32的启动代码到工程文件中,这份启动代码在M3系列中都是适用的,一般情况下我们都点击否,我们这里用的是ST的库,库文件里面也自带了这一份启动代码,所以为了保持库的完整性,我们就不需要开发环境为我们自带的启动代码了,稍后我们自己手动添加,这里我们点击否。
●此时我们的工程新建成功,如下图所示。
但我们的工程中还没有任何文件,接下来我们需要在我们的工程中添加所需文件
●在STM32Study文件夹下,我们新建User文件夹,用来存放用户自己创建的文件,然后系统库文件夹,和启动文件复制到STM32Study下,以及STM32F10xR.LIB(以上这些文件在系统库中查找),添加成功后如下图所示。
在Target1上右键选中ManageComponents…选项,新建四个组,分别命名为lib、user、start,从名字上字面上start文件夹下存放启动文件,user文件夹下存放用户创建文件,lib存放系统库文件。
●接下来我们往我们这些新建的组中添加文件,双击哪个组就可以往哪个组里面添加文件。
我们在start里面添加STM32F10x.s启动文件,在user组里面添加main.c和stm32f10x_it.c这两个文件,在lib组里面添加STM32F10xR.LIB。
注意,这些组里面添加的都是汇编文件跟C文件,头文件是不需要添加的。
最终效果如下图:
到这里工程的创建就完成了,接下来就是对工程的编译和仿真,来验证工程创建的是否正确,以及程序是否是我们想要看到的效果。
第四章工程编译及仿真、程序的下载
在MDK界面中,我们可以看到左边的工具栏中有三个按钮,现在我们从左往右来介绍下这三个按钮的功能。
●第一个按钮:
Translate就是编译当下修改过的文件,检查下有没有语法错误,并不会去链接库文件,也不会生成可执行文件。
●第二个按钮:
Build就是编译当下修改过的文件,它包含了语法检查,链接动态库文件,生成可执行文件。
●第三个按钮:
Rebuild重新编译整个工程,跟Build这个按钮实现的功能是一样的,但有所不同的是它编译的是整个工程的所有文件,耗时较大。
因此:
当我们编辑好我们的程序之后,只需要用第二个Build按钮就可以,即方便又省时。
第一个跟第三个按钮用的比较少。
4.1工程编译
点击Build按钮,MDK开始编译我们创建的工程,编译通过后会出现编译通过,如果出现0个错误,0个警告,说明编译程序编写没有语法上的错误,但程序是否正确,需要进一步验证。
(如下图所示界面编译通过)
从上面界面中我们可以看到,Code编译生成的代码大小,RO是程序中的指令和常量,RW是程序中的已初始化变量,ZI是程序中的未初始化的变量。
4.2仿真环境的搭建
●点击Debug,选择使用仿真器。
●接下来进行仿真验证,点击Start/StopDebugSession按钮进入仿真环境
●仿真界面如下图所示
●我们可以过观测外围设备观测器来观测程序的运行情况,也可以通过窗口分析窗口来观测程序的运行状态。
下面我们还是以GPIO通用外部IO口程序来进行仿真验证程序的运行状态,下面的章节会对GPIO的例程做更详细的介绍。
Ø首先通过外设观测器来观测,如下图所示:
Ø我们来观测GPIOA口的状态,进入A口的外围观测界面。
Ø按下F5键,或者点击工具栏中Run按钮,程序开始运行,可以看到IO口引脚的变化情况。
Ø另外,我们可以通过窗口观测器来观测程序的运行情况。
点击窗口观测器按钮进入观测器,然后点击Setup添加观测的IO口(例如观测GPIOA口的6、7、8、9,输入PORTA.6、PORTA.7、PORTA.8、PORTA.9),输入完成后点击运行Run,可以看到波形图变化情况,如下所示。
Ø波形变化情况
4.3JLINK下载
●插上DC-5V电源给开发板供电,再插上JLINK。
Ø点击TargetOptions…->Debug进行设置,按如下所示进行设置。
Ø点击TargetOptions…->Utilities进行设置,设置内容如下图所示
●点击MDK工具栏中的Load按钮就可将编译好的程序下载到开发板中。
●下载成功之后,程序就会自动运行。
如果发现程序没有运行,则可按下开发板中的复位按键。
●这里要注意的是:
程序在烧写到开发板后是否自动运行,是可以在MDK开发环境:
TargetOptions…->Debug->Setting->FalashDownLoad中设置的;按下面设置好后,程序下载完成后可自动运行,不需要手动复位。
第五章了解stm32库文件
library2008文件夹下有inc(include的缩写)跟src(source的简写)这两个文件夹以及库里带的一个启动文件文件夹,最新的库官方网站上有的更详细,大家可以去官网上下载,这里以library2008进行介绍。
src里面是每个设备外设的驱动程序,这些外设是芯片制造商在Cortex-M3核外加进去的。
进入librarie2008目录如下图所示:
Ø在src和inc文件夹里的就是ST公司针对每个STM32外设而编写的库函数文件,每个外设对应一个.c和.h后缀的文件。
我们把这类外设文件统称为:
stm32f10x_ppp.c或stm32f10x_ppp.h文件,PPP表示外设名称。
Ø如针对模数转换(ADC)外设,在src文件夹下有一个stm32f10x_adc.c源文件,在inc文件夹下有一个stm32f10x_adc.h头文件,若我们开发的工程中用到了STM32内部的ADC,则至少要把这两个文件包含到工程里。
第六章简单例程分析
6.1流水灯介绍
想要控制LED灯,当然是通过控制STM32芯片的I/O引脚电平的高低来实现。
在STM32芯片上,I/O引脚可以被软件设置成各种不同的功能,如输入或输出,所以被称为GPIO(General-purposeI/O)。
而GPIO引脚又被分为GPIOA、GPIOB„„GPIOG不同的组,每组端口分为0~15,共16个不同的引脚,对于不同型号的芯片,端口的组和引脚的数量不同,具体请参考相应芯片型号的datasheet。
于是,控制LED的步骤有:
1.GPIO端口引脚多-->就要选定需要控制的特定引脚
2.GPIO功能如此丰富-->配置需要的特定功能
3.控制LED的亮和灭-->设置GPIO输出电压的高低
要控制GPIO端口,就要涉及到控制相关的寄存器。
这时我们就要查一查与GPIO相关的寄存器了,可以通过《STM32参考手册》(最新版本)来查阅寄存器的定义方式。
以上的7个寄存器,相应的功能在参考手册上有详细的说明。
可以分为以下4类,其功能简要概括如下:
1.配置寄存器:
选定GPIO的特定功能,最基本的如:
选择作为输入还是输出端口。
2.数据寄存器:
保存了GPIO的输入电平或将要输出的电平。
3.位控制寄存器:
设置某引脚的数据为1或0,控制输出的电平。
4.锁定寄存器:
设置某锁定引脚后,就不能修改其配置。
注:
要想知道其功能严谨、详细的描述,请读者养成习惯在正式使用时,要以官方的datasheet为准,在这里只是简单地概括其功能进行说明。
关于寄存器名称上标号x的意义,如:
GPIOx_CRL、GPIOx_CRH,这个x的取值可以为图中括号内的值(A„„E),表示这些寄存器也跟GPIO一样,也是分组的。
也就是说,对于端口GPIOA和GPIOB,它们都有互不相干的一组寄存器,如控制GPIOA的寄存器名为GPIOA_CRL、GPIOA_CRH等,而控制GPIOB的则是不同的、被命名为GPIOB_CRL、GPIOB_CRH等寄存器。
从这个图我们可以知道STM32的功能,实际上也是通过配置寄存器来实现的。
配置寄存器的具体参数,需要参考《STM32参考手册》的寄存器说明。
见下图。
如图,对于GPIO端口,每个端口有16个引脚,每个引脚的模式由寄存器的4个位控制,每四位又分为两位控制引脚配置(CNFy[1:
0]),两位控制引脚的模式及最高速度(MODEy[1:
0]),其中y表示第y个引脚。
这个图是GPIOx_CRH寄存器的说明,配置GPIO引脚模式的一共有两个寄存器,CRH是高寄存器,用来配置高8位引脚:
pin8~pin15。
还有一个称为CRL寄存器,如果我们要配置pin0~pin7引脚,则要在寄存器CRL中进行配置。
举例说明对CRH的寄存器的配置:
当给GPIOx_CRH寄存器的第28至29位设置为参数“11”,并在第30至31位设置为参数“00”,则把x端口第15个引脚的模式配置成了“输出的最大速度为50MHz的通用推挽输出模式、”,其它引脚可通过其GPIOx_CRH或GPIOx_CRL的其它寄存器位来配置。
至于x端口的x是指端口GPIOA还是GPIOB还要具体到不同的寄存器基址,这将在后面分析。
接下来分析要控制引脚电平高低,需要对寄存器进行什么具体的操作。
由寄存器说明图可知,一个引脚y的输出数据由GPIOx_BSRR寄存器位的2个位来控制分别为BRy(BitResety)和BSy(BitSety),BRy位用于写1清零,使引脚输出低电平,BSy位用来写1置1,使引脚输出高电平。
而对这两个位进行写零都是无效的。
(还可以通过设置寄存器ODR来控制引脚的输出。
)
例如:
对x端口的寄存器GPIOx_BSRR的第0位(BS0)进行写1,则x端口的第0引脚被设置为1,输出高电平,若要令第0引脚再输出低电平,则需要向GPIOx_BSRR的第16位(BR0)写1。
6.1.1STM32的地址映射
温故而知新——stm32f10x_map.h文件
首先请大家回顾一下在51单片机上点亮LED是怎样实现的。
这太简单了,几行代码就搞定。
以上代码就可以点亮P0端口与LED阴极相连的LED灯了,当然,这里省略了启动代码。
为什么这个P0=0;句子就能控制P0端口为低电平,关键之处在于这个代码所包含的头文件。
在这个文件下有以下的定义:
这些定义被称为地址映射。
所谓地址映射,就是将芯片上的存储器甚至I/O等资源与地址建立一一对应的关系。
如果某地址对应着某寄存器,我们就可以运用c语言的指针来寻址并修改这个地址上的内容,从而实现修改该寄存器的内容。
正是因为头文件中有了对于各种寄存器和I/O端口的地址映射,我们才可以在51单片机程序中方便地使用P0=0xFF;TMOD=0xFF等赋值句子对寄存器进行配置,从而控制单片机。
Cortex-M3的地址映射也是类似的。
Cortex-M3有32根地址线,所以它的寻址空间大小为2^32bit=4GB。
ARM公司设计时,预先把这4GB的寻址空间大致地分配好了。
它把地址从0x40000000至0x5FFFFFFF(512MB)的地址分配给片上外设。
通过把片上外设的寄存器映射到这个地址区,就可以简单地以访问内存的方式,访问这些外设的寄存器,从而控制外设的工作。
结果,片上外设可以使用C语言来操作。
M3存储器映射见下图。
stm32f10x.h这个文件中重要的内容就是把STM32的所有寄存器进行地址映射。
如同51单片机的头文件一样,stm32f10x.h像一个大表格,我们在使用的时候就是通过宏定义进行类似查表的操作,大家想像一下没有这个文件的话,我们要怎样访问STM32的寄存器?
有什么缺点?
不进行这些宏定义的缺点有:
1、地址容易写错
2、我们需要查大量的手册来确定哪个地址对应哪个寄存器
3、看起来还不好看,且容易造成编程的错误,效率低,影响开发进度。
当然,这些工作都是由ST的固件工程师来完成的,只有设计M3的人才是最了解M3的,才能写出完美的库。
在这里我们以外接了LED灯的外设GPIOC为例,在这个文件中有这样的一系列宏定义:
这几个宏定义是从文件中的几个部分抽离出来的,具体的读者可参考stm32f10x_map.h源码。
●外设基地址
首先看到PERIPH_BASE这个宏,宏展开为0x40000000,并把它强制转换为uint32_t的32位类型数据,这是因为地STM32的地址是32位的,是不是觉得0x40000000这个地址很熟?
是的,这个是Cortex-M3核分配给片上外设的从0x40000000至0x5FFFFFFF的512MB寻址空间中的第