STM32
直播中

龙献益

7年用户 938经验值
私信 关注
[问答]

如何在Keil下完成一个汇编程序的编写呢

STM32有哪三种BOOT模式?分别有何差异?
如何在Keil下完成一个汇编程序的编写呢?

回帖(1)

刘佳

2021-11-29 14:56: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)处找到。
通过实验进行验证
用串口下载程序(系统存储器)

打开原本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,点击保存










可以开始汇编程序的编写了,
这里给出代码

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汇编文件
代码如下

LED0 EQU 0x40010c00
RCC_APB2ENR EQU 0x40021018
GPIOA_CRH EQU 0x40010804






Stack_Size      EQU     0x00000400


                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_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
                    
                ENTRY
Reset_Handler
                BL LED_Init
MainLoop        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
  总结

以上就是走近STM32汇编程序的所有内容,通过这次的作业,我了解了汇编语言的使用语法,明白了汇编语言的重要意义。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分