基于STM汇编设计

三种Boot模式的差异

所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式。
在这里插入图片描述

Main Flash memory
是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,自然也就没有程序存储的能力了,这个模式一般用于程序调试。假如我只修改了代码中一个小小的地方,然后就需要重新擦除整个Flash,比较的费时,可以考虑从这个模式启动代码(也就是STM32的内存中),用于快速的程序调试,等程序调试完成后,在将程序下载到SRAM中。

二、开发BOOT模式选择。

1、通常使用程序代码存储在主闪存存储器,配置方式:BOOT0=0,BOOT1=X;

2、Flash锁死解决办法:

开发调试过程中,由于某种原因导致内部Flash锁死,无法连接SWD以及Jtag调试,无法读到设备,可以通过修改BOOT模式重新刷写代码。

修改为BOOT0=1,BOOT1=0即可从系统存储器启动,ST出厂时自带Bootloader程序,SWD以及JTAG调试接口都是专用的。重新烧写程序后,可将BOOT模式重新更换到BOOT0=0,BOOT1=X即可正常使用。
参考:
链接: link.
3.内置SRAM(Embedded Memory)
内置SRAM这个模式一般用于程序调试。
4.三种模式的访问地址
主闪存存储器:访问地址为0x00000000或0x08000000
系统存储器:访问地址为0x00000000或0x1FF00000
内置SRAM:启动时地址为0x00000000或0x20000000
5.中断向量表
主闪存存储器
中断向量表从Flash的起始地址(0x08000000)开始存放。同时映射到0x00000000处。向量表偏移寄存器的值为0x00000000(实际映射到0x08000000)。
内置SRAM
中断向量表还是存放在Flash中(Flash才能固化存储,SRAM只能加电才有效),只不过拷贝到SRAM的首地址0x20000000处。此时向量表偏移寄存器的值也是0x00000000(实际映射到0x20000000)。

无论用哪种模式启动,复位时栈顶指针总能在0x00000000(或0x08000000)处找到,而复位向量总能在0x00000004(或0x08000004)处找到。

在STM32上创建一个汇编工程

:
在这里插入图片描述
选择一个目录,然后选择芯片:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
输入代码:

 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

编译:
在这里插入图片描述
然后点击魔法棒
生成hex文件:
在这里插入图片描述
开始调试
在这里插入图片描述

选择ST-LINK
在这里插入图片描述
点击旁边的settings
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

:020000040800F2
:100000001806002031010008390100083B010008F2
:100010003D0100083F010008410100080000000008
:100020000000000000000000000000004301000884
:1000300045010008000000004701000849010008D0
:100040004B0100084B0100084B0100084B01000860
:100050004B0100084B0100084B0100084B01000850
:100060004B0100084B0100084B0100084B01000840
:100070004B0100084B0100084B0100084B01000830
:100080004B0100084B0100084B0100084B01000820
:100090004B0100084B0100084B0100084B01000810
:1000A0004B0100084B0100084B0100084B01000800
:1000B0004B0100084B0100084B0100084B010008F0
:1000C0004B0100084B0100084B0100084B010008E0
:1000D0004B0100084B0100084B0100084B010008D0
:1000E0004B0100084B0100084B0100084B010008C0
:1000F0004B0100084B0100084B0100084B010008B0
:100100004B0100084B0100084B0100084B0100089F
:100110004B0100084B0100084B0100084B0100088F
:100120004B0100084B0100084B0100084B0100087F
:100130000948804709480047FEE7FEE7FEE7FEE77B
:10014000FEE7FEE7FEE7FEE7FEE7FEE704480549B7
:10015000054A064B704700004F020008590300088B
:1001600018000020180600201802002018020020A5
:100170000CB50020019000906C48006840F480307D
:100180006A49086000BF6948006800F400300090C8
:100190000198401C0190009818B90198B0F5A06F23
:1001A000F1D16248006800F4003010B101200090E5
:1001B00001E0002000900098012843D15C480068CD
:1001C00040F010005A4908600846006820F003001B
:1001D00008600846006840F0020008605348406824
:1001E000524948600846406848600846406840F404
:1001F000806048600846406820F47C1048600846EB
:10020000406840F4E81048600846006840F080709C
:10021000086000BF4548006800F000700028F9D071
:100220004248406820F00300404948600846406862
:1002300040F00200486000BF3C48406800F00C00FD
:100240000828F9D10CBD10B5FFF792FF10BD10B50D
:100250003648006840F001003449086008464068AC
:10026000344908403149486008460068324908402E
:100270002E4908600846006820F48020086008467F
:10028000406820F4FE0048604FF41F008860FFF7CC
:10029000DAFF4FF000602949086010BD10B5002159
:1002A00000200022214B5B6803F00C0121B10429DE
:1002B00006D0082928D107E0214B224C236027E0F3
:1002C0001F4B204C236023E0184B5B6803F4701035
:1002D000164B5B6803F48032022303EB904022B993
:1002E000194B4343174C23600DE0104B5B6803F43C
:1002F000003323B1144B4343124C236003E0104BF3
:100300004343104C236003E00D4B0E4C236000BFB1
:1003100000BF064B5B68C3F303130C4CE15C094B55
:100320001B68CB40074C236010BD0000001002404A
:10033000002002400000FFF8FFFFF6FE08ED00E09D
:1003400000127A000000002000093D000400002097
:1003500070477047704700004FF00A004FF00B01E4
:100360004FF00C024FF00D0300F009F800F00AF80E
:1003700000F00BF8DFF81CE0DFF81CF0FEE74FF0B0
:10038000050570474FF0060670474FF007074FF01E
:10039000080870477F0300088B03000800A24A0486
:1003A0000000000000000000010203040607080925
:040000050800035993
:00000001FF

第一个字节表示本行数据的长度;
第二、三字节表示本行数据的起始地址;
第四字节 表示数据类型;

hex文件的格式:

在这里插入图片描述

:(冒号)每个Intel HEX 记录都由冒号开头; LL 是数据长度域, 它代表记录当中数据字节 (D…D) 的数量; aaaa
是地址域, 它代表记录当中数据的起始地址; TT是代表HEX 记录类型的域 , 它可能是以下数据当中的一 个: 00:数据记录(Data
Record),用来记录数据,HEX文件的大部分记录都是数据记录。 01:文件结束记录(End of
FileRecord),用来标识文件结束,放在文件的最后,标识HEX文件的结尾。 02:扩展段地址记录(ExtendedSegment
Address
Record),用来标识扩展段地址的记录,扩展段地址记录(HEX86),它包含4~19位数据地址段。由于普通的Intel的HEX记录文件只能记录64K的地址范围,所以大于64K的地址数据要靠扩展段地址记录。
03:开始段地址记录(Start Segment Address Record) 04:扩展线性地址记录(Extended Linear
Address
Record),用来标识扩展线性地址的记录,扩展线性地址记录也叫32位地址记录或者HEX386记录,这些记录包含了数据在存储器里真实地址的高16位。
当一个扩展线性地址记录被读取后,将一直保持有效,直到它被另一个扩展地址记录改变。因为它记录的是后面数据在存储器里存放的真实起始地址,所以它的起始地址偏移量(Load
offset)总是0000。 05:开始线性地址记录(Start Linear Address
Record),32位机(80386或更高的CPU)的EIP寄存器里存放的地址(main函数的入口地址)。
D…D是数据域,它代表一个字节的数据。一个记录可以有许多数据字节。记录当中数据字节的数量必须和数据长度域(LL)中指定的数字相符。
CC是校验和域,它表示这个记录的校验和。校验和的计算是通过将记录当中所有十六进制编码数字对的值相加,以256为模进行以下补足。

各种进制数的后缀字母分别为:
B :二进制数。
Q :八进制数。
D :十进制数。
H :十六进制数。
关于%是取余和取模:
在JAVA、C、C++里,%是取余运算,英文remainder;
在Python里,%号是取模运算,英文modulus;
取余运算的除法是向零舍入,取模运算的除法是向小值舍入;
取余运算结果的符号与被除数相同,取模运算结果的符号与除数相同。

参考资料:
链接: link.

led汇编闪烁灯

创建一个新工程,芯片和上面一样,选择如下:
在这里插入图片描述
在这里插入图片描述

将代码输入:

LED0 EQU 0x40011004;定义引脚PC2 
RCC_APB2ENR EQU 0x40021018;配置RCC寄存器,时钟
GPIOC_CRL EQU 0x40011000;配置CRL寄存器
Stack_Size      EQU     0x00000400;栈的大小
;分配一个STACK段,该段不初始化,可读写,按8字节对齐。分配一个大小为Stack_Size的存储空间,并使栈顶的地址为__initial_sp。
                AREA    STACK, NOINIT, READWRITE, ALIGN=3;NOINIT: = NO Init,不初始化。READWRITE : 可读,可写。ALIGN =3 : 2^3 对齐,即8字节对齐。
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;BL:带链接的跳转指令。当使用该指令跳转时,当前地址(PC)会自动送入LR寄存器
MainLoop        BL LED_ON
                BL Delay
                BL LED_OFF
                BL Delay
                
                B MainLoop;B:无条件跳转。
             
LED_Init;LED初始化
                PUSH {R0,R1, LR};R0,R1,LR中的值放入堆栈
                
                LDR R0,=RCC_APB2ENR;LDR是把地址装载到寄存器中(比如R0)。
                ORR R0,R0,#0x04;ORR 按位或操作,将将R0的第二位置1,其他位不变
                LDR R1,=RCC_APB2ENR
                STR R0,[R1];STR是把值存储到寄存器所指的地址中。
                
                LDR R0,=GPIOC_CRL
                BIC R0,R0,#0x0F;BIC 先把立即数取反,再按位与
                LDR R1,=GPIOC_CRL
                STR R0,[R1]
                
                LDR R0,=GPIOC_CRL
                ORR R0,R0,#0x03
                LDR R1,=GPIOC_CRL
                STR R0,[R1]
                ;将PC2置1
                MOV R0,#1 
                LDR R1,=LED0
                STR R0,[R1]
             
                POP {R0,R1,PC};将栈中之前存的R0,R1,LR的值返还给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

编译
在这里插入图片描述
生成hex文件:
在这里插入图片描述
打开串口下载:
在这里插入图片描述
将hex文件烧录进去,核心板的闪烁灯间断闪烁:
在这里插入图片描述
在这里插入图片描述

总结

以上就是全部内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值