请选择 进入手机版 | 继续访问电脑版

菜鸟入门12,走近STM汇编程序

[复制链接]
西门听雨 发表于 2021-1-1 10:00:14 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
文章目录



  一.STM32的三种Boot模式的差别

stm32有哪三种BOOT模式?

  

  • 用户闪存存储器(Main Flash memory)
  • SRAM存储器(Embedded Memory)
  • 系统存储器(System memory)
STM32三种启动模式对应的存储介质均是芯片内置的,如下图:

三种BOOT模式启动的先容
所谓启动,一般来说就是指我们下好步调后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式。
第一种:Main Flash memory【从用户闪存(flash)启动】
  是STM32内置的Flash,一般我们使用JTAG或者SWD模式下载步调时,就是下载到这个内里,重启后也直接从这启动步调。
第二种:System memory【从系统存储器启动】
  从系统存储器启动,这种模式启动的步调功能是由厂家设置的。一般来说,这种启动方式用的比较少。系统存储器是芯片内部一块特定的区域,STM32在出厂时,由ST在这个区域内部预置了一段BootLoader,
也就是我们常说的ISP步调,这是一块ROM,出厂后无法修改。一般来说,我们选用这种启动模式时,是为了从串口下载步调,因为在厂家提供的BootLoader中,提供了串口下载步调的固件,可以通过这个BootLoader将步调下载到系统的Flash中。但是这个下载方式需要以下步调:
  

  • Step1:将BOOT0设置为1,BOOT1设置为0,然后按下复位键,这样才华从系统存储器启动BootLoader
  • Step2:最后在BootLoader的资助下,通过串口下载步调到Flash中
  • Step3:步调下载完成后,又有需要将BOOT0设置为GND,手动复位,这样,STM32才可以从Flash中启动可以看到,利用串口下载步调照旧比较的麻烦, 需要跳帽跳来跳去的,非常的不注重用户体验。
第三种;Embedded Memory【内置SRAM】
  内置SRAM,既然是SRAM,自然也就没有步调存储的能力了,这个模式一般用于步调调试。如果我只修改了代码中一个小小的地方,然后就需要重新擦除整个Flash,比较的费时,可以思量从这个模式启动代码(也就是STM32的内存中),用于快速的步调调试,等步调调试完成后,在将步调下载到SRAM中。
Flash、System memory和SRAM的访问地点
① Flash:访问地点为0x00000000或0x08000000
② System memory:访问地点为0x00000000或0x1FF00000
③ SRAM:启动时地点为0x00000000或0x20000000(STM32Fxx的参考手册上说,启动后只能在0x20000000开始访问,即启动后这个映射消失,需要重定位中断向量表,这是特例)
中断向量表
主闪存存储器
中断向量表从Flash的起始地点(0x08000000)开始存放。同时映射到0x00000000处。向量表偏移寄存器的值为0x00000000(实际映射到0x08000000)。
内置SRAM
中断向量表照旧存放在Flash中(Flash才华固化存储,SRAM只能加电才有效),只不外拷贝到SRAM的首地点0x20000000处。此时向量表偏移寄存器的值也是0x00000000(实际映射到0x20000000)。
无论用哪种模式启动,复位时栈顶指针总能在0x00000000(或0x08000000)处找到,而复位向量总能在0x00000004(或0x08000004)处找到。
通过实验举行验证

具体代码参考菜鸟入门6,STM32串口通信
用串口下载步调(系统存储器)

打开原本usart收发步调,编译

无误,用USB毗连指南者与上位机
不改变跳帽,开辟板的BOOT0和BOOT1接地,RXD和TXD分别接PA9和PA10
打开mcuisp,设置如下图

打开调试助手,设置完按下复位按钮
按下复位键,这样才华从系统存储器启动BootLoader
效果如图

用ST_Link下载步调( 用户闪存存储器)

上述文件编译无误后使用ST_LINK与指南者开辟板毗连好接入电脑
点击

举行设置

运行效果

不消按下复位键
串口烧录:打开串口后,没有任何反应,要实现通信必须要按一下复位键,才可以大概通信。
ST_Link烧录:打开串口之后,开辟板和上位机直接就可以直接举行通信。通过这一操纵,可以看出步调是直接被放置到FLASH中,而串口烧录的步调就不是位于FLASH中,需要复位才华在FLASH中启动。
二.在Keil下完成一个汇编步调的编写

要想完成汇编步调的编写,首先要知道什么是汇编
汇编语言先容

汇编语言(assembly language)是一种用于电子计算机、微处理处罚器、微控制器或其他可编程器件的低级语言,亦称为符号语言。在汇编语言中,用助记符(Mnemonics)取代呆板指令的操纵码,用地点符号(Symbol)或标号(Label)取代指令或操纵数的地点。在不同的设备中,汇编语言对应着不同的呆板语言指令集,通过汇编过程转换成呆板指令。广泛地说,特定的汇编语言和特定的呆板语言指令集是一一对应的,不同平台之间不可直接移植。 许多汇编步调为步调开辟、汇编控制、辅助调试提供了额外的支持机制。有的汇编语言编程工具常常会提供宏,它们也被称为宏汇编器。汇编语言不像其他大多数的步调设计语言一样被广泛用于步调设计。在本日的实际应用中,它通常被应用在底层,硬件操纵和高要求的步调优化的场合。驱动步调、嵌入式操纵系统和实时运行步调都需要汇编语言。

总体特点
1.呆板相关性
这是一种面向呆板的低级语言,通常是为特定的计算机或系列计算机专门设计的。因为是呆板指令的符号化体现,故不同的呆板就有不同的汇编语言。使用汇编语言能面向呆板并较好地发挥呆板的特性,得到质量较高的步调。
2.高速度和高效率
汇编语言保持了呆板语言的优点,具有直接和轻便的特点,可有效地访问、控制计算机的各种硬件设备,如磁盘、存储器、CPU、I/O端口等,且占用内存少,执行速度快,是高效的步调设计语言。
3.编写和调试的复杂性
由于是直接控制硬件,且简单的任务也需要许多汇编语言语句,因此在举行步调设计时必须八面见光,需要思量到一切大概的问题,合理调配和使用各种软、硬件资源。这样,就不可制止地加重了步调员的负担。与此相同,在步调调试时,一旦步调的运行出了问题,就很难发现。
汇编步调编写

首先我们打开KEIL5,新建一个工程为AL

对工程举行设置,因为我用的是指南者,所以选择STM32F103VE

勾选这两个选项

选中Source Group 1,右键,选择Add New Item to Group,添加源文件

选择 Asm File (.s) ,设置文件名称为TEST,点击生存


可以开始汇编步调的编写了,
这里给出代码
  1. AREA MYDATA, DATA         AREA MYCODE, CODE        ENTRY        EXPORT __main__main        MOV R0, #10        MOV R1, #11        MOV R2, #12        MOV R3, #13        ;LDR R0, =func01        BL        func01        ;LDR R1, =func02        BL        func02                BL         func03        LDR LR, =func01        LDR PC, =func03        B .                func01        MOV R5, #05        BX LR        func02        MOV R6, #06        BX LR        func03        MOV R7, #07        MOV R8, #08                BX LR        end
复制代码
编译并动态调试,调试界面如下

用记事本打开方式查察hex文件


HEX文件是记载文本行的ASCII文本文件,在Intel HEX文件中,每一行是一个HEX记载,由十六进制数组成的呆板码或者数据常量,Intel HEX文件常常被用于将步调或数据传输
存储到ROM、EPROM,大多数编程器和模拟器使用Intel HEX文件。

记载格式
一个Intel HEX文件可以包含任意多的十六进制记载,每条记载有五个域,下面是一个记载的格式。
  : llaaaatt[dd。。。]cc
        每一组字母是独立的一域,每一个字母是一个十六进制数字,每一域至少由两个十六进制数字组成,下面是字节的形貌。        冒号 是每一条Intel HEX记载的开始   
ll 是这条记载的长度域,他体现数据(dd)的字节数目。   
aaaa 是地点域,他体现数据的起始地点   
tt 这个域体现这条HEX记载的范例,他有大概是下面这几种范例   
00 —-数据记载   
01 —-文件竣事记载   
02 —-扩展段地点记载   
04 —-扩展线性地点记载   
dd 是数据域,体现一个字节的数据,一个记载大概有多个数据字节,字节数目可以 查察ll域的说明   
cc 是效验和域,体现记载的效验和,计算方法是将本条记载冒号开始的所有字母对 所体现的十六进制数字   
都加起来然后模除256得到的余数最后求出余数的补码便是本效验字节cc。   
数据记载   
Intel HEX文件由若干个数据记载组成,一个数据记载以一个回车和一个换行竣事     
三.简单的STM32 汇编步调—闪烁LED

按照上述方法新建工程,但是设置情况不需要勾选
添加led.s汇编文件
代码如下
  1. LED0 EQU 0x40010c00RCC_APB2ENR EQU 0x40021018GPIOA_CRH EQU 0x40010804Stack_Size      EQU     0x00000400                AREA    STACK, NOINIT, READWRITE, ALIGN=3Stack_Mem       SPACE   Stack_Size__initial_sp                AREA    RESET, DATA, READONLY__Vectors       DCD     __initial_sp               ; Top of Stack                DCD     Reset_Handler              ; Reset Handler                                                        AREA    |.text|, CODE, READONLY                                    THUMB                REQUIRE8                PRESERVE8                                    ENTRYReset_Handler                 BL LED_InitMainLoop        BL LED_ON                BL Delay                BL LED_OFF                BL Delay                                B MainLoop             LED_Init                PUSH {R0,R1, LR}                                LDR R0,=RCC_APB2ENR                ORR R0,R0,#0x04                LDR R1,=RCC_APB2ENR                STR R0,[R1]                                LDR R0,=GPIOA_CRH                BIC R0,R0,#0x0F                LDR R1,=GPIOA_CRH                STR R0,[R1]                                LDR R0,=GPIOA_CRH                ORR R0,R0,#0x03                LDR R1,=GPIOA_CRH                STR R0,[R1]                                MOV R0,#1                 LDR R1,=LED0                STR R0,[R1]                             POP {R0,R1,PC}             LED_ON                PUSH {R0,R1, LR}                                    MOV R0,#0                 LDR R1,=LED0                STR R0,[R1]                             POP {R0,R1,PC}             LED_OFF                PUSH {R0,R1, LR}                                    MOV R0,#1                 LDR R1,=LED0                STR R0,[R1]                             POP {R0,R1,PC}                          Delay                PUSH {R0,R1, LR}                                MOVS R0,#0                MOVS R1,#0                MOVS R2,#0                DelayLoop0                        ADDS R0,R0,#1                CMP R0,#330                BCC DelayLoop0                                MOVS R0,#0                ADDS R1,R1,#1                CMP R1,#330                BCC DelayLoop0                MOVS R0,#0                MOVS R1,#0                ADDS R2,R2,#1                CMP R2,#15                BCC DelayLoop0                                                POP {R0,R1,PC}                     ;         NOP             END
复制代码

烧录到板子上,
效果如下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )