赞
踩
所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式。
BOOT1 | BOOT0 | 启动模式 | 说明 |
---|---|---|---|
X | 0 | 主闪存存储器 | 主闪存存储器被选为启动区域 |
0 | 1 | 系统存储器 | 系统存储器被选为启动区域 |
1 | 1 | 内置SRAM | 内置SRAM被选为启动区域 |
STM32上电或者复位后,代码区始终从0x00000000开始,三种启动模式其实就是将各自存储空间的地址映射到0x00000000中。
(1)从Flash(主闪存) 启动,将主Flash地址0x08000000映射到0x00000000,这样代码启动之后就相当于从0x08000000开始。
(2)从RAM 启动,将RAM地址0x20000000映射到0x00000000,这样代码启动之后就相当于从0x20000000开始。
(3)从系统存储器启动。首先控制BOOT0 BOOT1管脚,复位后,STM32与上述两种方式类似,从系统存储器地址0x1FFF F000开始执行代码。系统存储器存储的其实就是STM32自带的bootloader代码,在bootloader中提供了UART1的接口,通过此接口可以将用户所需的程序代码下载到主Flash中,下载完毕后,此时程序代码已经存储在主Flash当中,这时切换启动模式(从主Flash启动),复位后所执行的就是刚刚下载到Flash中的代码了。
Step1:将BOOT0设置为1,BOOT1设置为0,然后按下复位键,这样才能从系统存储器启动BootLoader
Step2:最后在BootLoader的帮助下,通过串口下载程序到Flash中
Step3:程序下载完成后,又有需要将BOOT0设置为GND,手动复位,这样,STM32才可以从Flash中启动可以看到
1、程序代码:
#include <stdio.h> #include <stdlib.h> //定义全局变量 int init_global_a = 1; int uninit_global_a; static int inits_global_b = 2; static int uninits_global_b; void output(int a) { printf("hello"); printf("%d",a); printf("\n"); } int main( ) { //定义局部变量 int a=2; static int inits_local_c=2, uninits_local_c; int init_local_d = 1; output(a); char *p; char str[10] = "lyy"; //定义常量字符串 char *var1 = "1234567890"; char *var2 = "qwertyuiop"; //动态分配 int *p1=malloc(4); int *p2=malloc(4); //释放 free(p1); free(p2); printf("栈区-变量地址\n"); printf(" a:%p\n", &a); printf(" init_local_d:%p\n", &init_local_d); printf(" p:%p\n", &p); printf(" str:%p\n", str); printf("\n堆区-动态申请地址\n"); printf(" %p\n", p1); printf(" %p\n", p2); printf("\n全局区-全局变量和静态变量\n"); printf("\n.bss段\n"); printf("全局外部无初值 uninit_global_a:%p\n", &uninit_global_a); printf("静态外部无初值 uninits_global_b:%p\n", &uninits_global_b); printf("静态内部无初值 uninits_local_c:%p\n", &uninits_local_c); printf("\n.data段\n"); printf("全局外部有初值 init_global_a:%p\n", &init_global_a); printf("静态外部有初值 inits_global_b:%p\n", &inits_global_b); printf("静态内部有初值 inits_local_c:%p\n", &inits_local_c); printf("\n文字常量区\n"); printf("文字常量地址 :%p\n",var1); printf("文字常量地址 :%p\n",var2); printf("\n代码区\n"); printf("程序区地址 :%p\n",&main); printf("函数地址 :%p\n",&output); return 0; }
2、通过ST-Link下载程序:
3、结果查看:
4、结果分析:
实验结论和理论一致
汇编语言(Assembly Language)是任何一种用于 电子计算机 、 微处理器 、 微控制器 或其他可编程器件的低级语言,亦称为符号语言。. 在汇编语言中,用 助记符 代替 机器指令 的 操作码 ,用地址符号或标号代替指令或 操作数 的地址。. 在不同的设备中,汇编语言对应着不同的机器语言 指令集 ,通过汇编过程转换成机器指令。. 特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植。
对比:
汇编语言相比于c语言来说更接近于底层,更加接近机器语言,汇编语言能够使得单片机更加高效的完成功能,在同样的机型下,汇编语言所编写的程序能够完成相对更复杂的工作,比起c语言更加强大,但是由于比较青涩难懂,c语言还是更容易被大众接收。
1.前面基本和c一样,工程创建后记得修改运行环境:
2.创建一个文件,记得选.s文件
3.撰写代码:
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文件中第一个字节表示本行数据的长度;第二、三字节表示本行数据的起始地址;第四字节 表示数据类型;
LED0 EQU 0x42218194 //此处地址根据实际计算得来 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
通过查看PB5宏定义查看PB5的物理地址(也可以通过寄存器点灯例程查找)
效果:
这个和之前点灯的效果一样,就是灯在闪烁。
汇编语言的学习尤为重要,但是用的还是比较生涩,因为是比较底层的代码,相对还是有点难理解,希望以后有机会多多接触。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。