STM32技能综合巩固

一、深入理解ARMCPU架构及其指令格式、ARM汇编语言编程方法

1.汇编语言编程,实现LED灯

新建keil项目,选择芯片
在这里插入图片描述

选择运行环境以及配置
![[Pasted image 20250401193413.png]]

![[Pasted image 20250401193634.png]]

添加.s文件
![[Pasted image 20250401193737.png]]

汇编程序:
AREAMYDATA,DATA

AREAMYCODE,CODE
ENTRY
EXPORT__main

__main
MOVR0,#10
MOVR1,#11
MOVR2,#12
MOVR3,#13
;LDRR0,=func01

BL func01
;LDRR1,=func02
BL func02

BL func03
LDRLR,=func01
LDRPC,=func03
B.

func01
MOVR5,#05
BXLR

func02
MOVR6,#06
BXLR

func03
MOVR7,#07
MOVR8,#08
BXLR

点亮PC13程序:
LED0
EQU
0x4001100C
RCC_APB2ENR
EQU
0x40021018
GPIOC_CRH
EQU
0x40011004
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
LDR R0,[R0]
ORR R0,R0,#0x10
LDR R1,=RCC_APB2ENR
STR R0,[R1]
LDR R0,=GPIOC_CRH
LDR R0,[R0]
BIC R0,R0,#0xF0000
ORR R0,R0,#0x30000
LDR R1,=GPIOC_CRH
STR R0,[R1]
MOV R0,#1
(LED灭)
LSL R0,R0,#13
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
LSL R0,R0,#13
LDR R1,=LED0
STR R0,[R1]
POP {R0,R1,PC}
Delay
PUSH {R0-R2,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-R2,PC}
END

2.对比C语言寄存器

C语言寄存器模式代码:
#include “stm32f10x.h”
void delay(u16 num)
{
u16 i,j;
for(i=0;i<num;i++)
for(j=0;j<0x800;j++);
}
int main(void)
{
RCC->APB2ENR = 0x0000001C;
while(1)
{
GPIOB->ODR &= ~(1 << 5);
delay(100);

GPIOB->ODR |= (1 << 5);
delay(200);
}
}

分析:
汇编语言的hex比C语言寄存器代码小。
汇编语言直接使用CPU指令操作寄存器,而C语言寄存器经过编译后会产生额外的指令。C代码编译后会自动添加一些启动和初始化代码。纯汇编需要手动定义程序入口和段属性。

二、熟悉ARM 汇编语言与C语言混合编程方式,掌握反汇编工具

1.在Keil中修改C程序的 主函数为其他名称

C程序主函数名并非必须为main。在ARM开发中,入口函数的名称可以自定义。
在 startup 文件中修改入口点声明
![[Pasted image 20250401200246.png]]

2.IDA Pro工具

加载hex/bin文件
![[Pasted image 20250401200850.png]]

使用 IDA Pro 对给定的 hex(bin)文件进行反汇编分析,找出控制LED 灯闪烁的相关代码段。这可能涉及对GPIO端口配置、延时函数以及LED状态 切换等相关代码的识别。在反汇编代码中,查找与(PB0)端口操作相关的指令, 如GPIO初始化、输出电平设置以及可能的延时循环等部分。
在 IDA Pro 中对反汇编后的代码进行修改,将与 PC13 相关的操作改为针 对 PA1 的操作。修改完成后,使用 IDA Pro 的重新汇编功能或其他相关工具 将修改后的汇编代码转换为二进制文件。将生成的二进制文件下载到目标硬件 平台进行验证,观察 PA1 LED 灯是否按照预期进行闪烁。在验证过程中,可 使用示波器、逻辑分析仪等工具监测 PA1 端口的电平变化,确保程序功能修 改正确。
源代码:
![[Pasted image 20250401201843.png]]

IDA汇编:
![[Pasted image 20250401202007.png]]

三、掌握gcc编译工具集编译、链接源程序生成二进制应用程序

1.配置C/C++环境

安装gcc:sudo apt-get install gcc
![[Pasted image 20250401204543.png]]

安装g++:sudo apt-get install g++
![[b2facef77e274941f5b87ad4369bf6d.png]]

安装gbd:sudo apt-get install gdb
![[1f8f87dc87e149a83e0cd42b177dcd9.png]]

2.安装、配置VScode

3.安装、配置arm-none-eabi-gcc 交叉编译工具链

下载解压完成后,进入 “arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi”文件夹进入“bin”文件夹。
打开profile 文件,在最后输入:
export PATH=$PATH:/home/yml/mondrian/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi/bin
执行:source profile

4.安装CubeMX

测试程序
![[Pasted image 20250401205812.png]]

四、了解ARM 应用程序的上电复位初始化、startup启动到跳转到C语言main 函数入库的过程

1.STM32的启动过程

复位后启动模式的选择
复位方式有三种:上电复位,硬件复位和软件复位。当产生复位,并且离开
复位状态后,CM3 内核做的第一件事就是读取下列两个32 位整数的值:
(1)从地址 0x00000000 处取出堆栈指针 MSP 的初始值,该值就是栈顶
地址。
(2)从地址 0x00000004 处取出程序计数器指针 PC 的初始值,该值指向
复位后执行的第一条指令。

内核在离开复位状态后会从映射的地址中取值给栈指针MSP及程序指针 PC,然后执行指令,我们一般以存储器的类型来区分自举过程,例如内部FLASH 启动方式、内部SRAM启动方式以及系统存储器启动方式。

内部FLASH启动方式:
当芯片上电后采样到BOOT0引脚为低电平时,0x00000000和0x00000004 地址被映射到内部FLASH的首地址0x08000000和0x08000004。因此,内核 离开复位状态后,读取内部FLASH的0x08000000地址空间存储的内容,赋值 给栈指针MSP,作为栈顶地址,再读取内部FLASH的0x08000004地址空间存 储的内容,赋值给程序指针PC,作为将要执行的第一条指令所在的地址。具备 这两个条件后,内核就可以开始从PC指向的地址中读取指令执行了。

内部SRAM启动方式:
当芯片上电后采样到BOOT0和BOOT1引脚均为高电平时, 0x00000000和0x00000004地址被映射到内部SRAM的首地址0x20000000和 0x20000004,内核从SRAM空间获取内容进行自举。 在实际应用中,由启动文件starttup_stm32f10x.s决定了0x00000000和 0x00000004地址存储什么内容,链接时,由分散加载文件(sct)决定这些内容的 绝对地址,即分配到内部FLASH还是内部SRAM。 这里的启动文件和分散加载文件有点不好理解,当说“由启动文件决定了 0x00000000和0x00000004地址存储什么内容”时,指的是启动文件定义了这两 个关键地址处的内容:一个是堆栈指针的初始值,另一个是指向复位处理程序的 指针。而“由分散加载文件决定这些内容的绝对地址”则意味着,尽管启动文件设 定了逻辑上的地址,但是具体的物理地址(即这些内容实际上位于FLASH还是 SRAM)是由分散加载文件来决定的。这允许开发者根据需要调整最终的内存布 局,同时保持启动代码的逻辑不变。

系统存储器启动方式:
当芯片上电后采样到BOOT0引脚为高电平,BOOT1为低电平时,内核将 从系统存储器的0x1FFFF000及0x1FFFF004获取MSP及PC值进行自举。系 统存储器是一段特殊的空间,用户不能访问,ST公司在芯片出厂前就在系统存 储器中固化了一段代码。因而使用系统存储器启动方式时,内核会执行该代码, 该代码运行时,会为ISP提供支持(InSystemProgram),如检测USART1/2、CAN2 及USB通讯接口传输过来的信息, 并根据这些信息更新自己内部FLASH的内 容,达到升级产品应用程序的目的,因此这种启动方式也称为ISP启动方式。

2.STM32的启动方式实验

代码:
#include “led.h”
#include “delay.h”
//#include"key.h"
#include “sys.h”
#include “usart.h”
#include <stdio.h>
#include <stdlib.h>
int k1= 1; //已初始化全局int型变量k1
int k2; //未初始化全局int型变量k2
staticint k3 = 2;//已初始化静态全局int型变量k3
staticint k4; //未初始化静态全局int型变量k4
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优
先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
//KEY_Init(); //初始化与按键连接的硬件接口
while(1)
{
static int m1 = 2; //已初始化静态局部int型变量m1
static int m2; //未初始化静态局部int型变量m2
int i1; //未初始化局部int型变量i1
int i2; //未初始化局部int型变量i2
char *p; //未初始化局部char型指针变量p
char str[10] =“hello”;//已初始化局部char型数组str
char *var1 = “123456”; //已初始化局部char型指针变量var1
char *var2 = “abcdef”; //已初始化局部char型指针变量var2
int *p1 =malloc(4); //已初始化局部int型指针变量p1
int *p2 =malloc(4); //已初始化局部int型指针变量p2
printf(“栈区-变量地址\r\n”);
printf(“未初始化局部int型变量i1 :0x%p\r\n”,&i1);
printf(“未初始化局部int型变量i2 :0x%p\r\n”,&i2);
printf(“未初始化局部char型指针变量p :0x%p\r\n”,&p);
printf(“已初始化局部char型数组str :0x%p\r\n”,str);
//test();
printf(“\n堆区-动态申请地址\r\n”);
printf(“已初始化局部int型指针变量p1 :0x%p\r\n”,p1);
printf(“已初始化局部int型指针变量p2 :0x%p\r\n”,p2);
printf(“\n.bss段地址\r\n”);
printf(“未初始化全局int型变量k2 :0x%p\r\n”,&k2);
printf(“未初始化静态全局int型变量k4 :0x%p\r\n”,&k4);
printf(“未初始化静态局部int型变量m2 :0x%p\r\n”,&m2);
printf(“\n.data段地址\r\n”);
printf(“已初始化全局int型变量k1 :0x%p\r\n”,&k1);
printf(“已初始化静态全局int型变量k3 :0x%p\r\n”,&k3);
printf(“已初始化静态局部int型变量m1 :0x%p\r\n”,&m1);
printf(“\n常量区地址\r\n”);
printf(“已初始化局部char型指针变量var1:0x%p\r\n”,var1);
printf(“已初始化局部char型指针变量var2:0x%p\r\n”,var2);
printf(“\n代码区地址\r\n”);
printf(“程序代码区main函数入口地址:0x%p\r\n”, &main);
free(p1);
free(p2);
}
}

串口输出结果:
![[Pasted image 20250401213137.png]]

从中可以分析,main函数入口地址、常量区及代码区的存储地址都在 0x8000000开始的,说明程序成功从FALSH运行;全局和静态变量、栈区的地 址也都分配在0x20000000储存地址(高地址)处,堆区的地址分配在0x00000000 处。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/74217.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P2Rank网页端:预测蛋白结合口袋+vina分子对接

P2Rank 是一种基于机器学习的蛋白质口袋预测工具&#xff0c;用于识别蛋白质结构中的潜在配体结合位点。它采用了一种基于物理特征的打分方法&#xff0c;结合随机森林&#xff08;Random Forest&#xff09;机器学习模型&#xff0c;以提高口袋预测的精确度。 该程序有在线工具…

安装windows server 2016没有可选硬盘,设备安装过ubuntu系统

如果在安装 Windows Server 2016 时无法识别已安装过 Ubuntu 的硬盘&#xff0c;可能是由于硬盘分区格式&#xff08;如 ext4&#xff09;与 Windows 不兼容&#xff0c;或缺少必要的驱动程序。以下是详细的解决方案&#xff1a; 1. 检查 BIOS/UEFI 设置 确认硬盘模式 • 重启电…

Debian系统_主板四个网口1个配置为WAN,3个配置为LAN

Debian系统_主板四个网口1个配置为WAN&#xff0c;3个配置为LAN 一、重新配置网口 1、查看当前网口的状态 ifconfig 或者 ip link show 或者 ls /sys/class/net 2、修改网络配置文件 sudo vi /etc/network/interfaces 注意WAN口的网关地址如果是192.168.3.1的话&#xff0c;L…

springboot整合Thymeleaf web开发出现Whitelabel Error Page

背景 在做java端上应用开发的时候&#xff0c;从资源和部署操作成本两方面考虑&#xff0c;一般会将前端的静态资源直接与后端应用一起打包&#xff0c;通过springboot内嵌的Tomcat提供web服务。进入web首页登录一直到后续业务流程正向操作&#xff0c;页面都能正常加载静态资…

JavaScript元素尺寸与位置

目录 client 家族与 offset 家族 一、client 家族&#xff1a;内容区域 内边距 示例代码 应用场景 二、offset 家族&#xff1a;内容区域 内边距 边框 滚动条 示例代码 应用场景 三、综合应用场景 1. 动态调整元素高度 2. 拖拽元素 3. 判断元素是否在视口内 四…

GZ073网络系统管理赛项赛题第1套模块A:网络构建解题笔记

2. 设备 接口或VLAN VLAN名称 二层或三层规划 说明 S1 VLAN10 CAIWU Gi0/1至Gi0/4 财务部 VLAN20 XIAOSHOU Gi0/5至Gi0/8 销售部 VLAN30 YANFA Gi0/9至Gi0/12 研发部 VLAN40 SHICHANG Gi0/13至Gi0/16 市场部 VLAN50 AP Gi0/20至Gi0/21 无线AP管理 VL…

jmeter web压力测试 压测

下载地址 Apache JMeter - Download Apache JMeter 1. 设置线程组 2. 设置http请求头 3. 设置http请求体 4. 设置结果条目 常用函数 ${__RandomString(8, abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789)}${__javaScript( ${__Random(1000, 10000)} /…

大语言模型(LLM)应用开篇 | RAG方法论概述 | 构建知识库探索

大型语言模型应用开篇 | RAG技术 | 构建知识库探索 1、大语言模型&#xff08;LLM&#xff09;应用开篇2、RAG技术2.1 基于RAG实现知识库问答系统的基本步骤2.2 RAG与其他技术的关系与区别 1、大语言模型&#xff08;LLM&#xff09;应用开篇 现在是2025年&#xff0c;DeepSeek…

fbx bip互转 测试OK

目录 fbx bip互转 3dmax插件fbx转bip: 测试可以转: MotionBuilder fbx转bip fbx bip互转 3dmax插件fbx转bip: 测试可以转: 不用插件!!无脑把Mxiamo转bip骨骼动画 - CG软件插件脚本交流 - Powered by Discuz!

8个实用销售工具

CRM系统&#xff08;客户关系管理系统&#xff09; 特点&#xff1a;能集中管理客户信息&#xff0c;如联系方式、交易记录、偏好等&#xff0c;还可对销售流程进行自动化管理。 用途&#xff1a;帮助销售团队跟踪客户&#xff0c;分析客户行为&#xff0c;预测销售趋势&am…

【家政平台开发(6)】筑牢家政平台安全防线:全方位隐私与安全需求解析

本【家政平台开发】专栏聚焦家政平台从 0 到 1 的全流程打造。从前期需求分析&#xff0c;剖析家政行业现状、挖掘用户需求与梳理功能要点&#xff0c;到系统设计阶段的架构选型、数据库构建&#xff0c;再到开发阶段各模块逐一实现。涵盖移动与 PC 端设计、接口开发及性能优化…

IP 地址规划中的子网划分:/18 网络容纳 64 个 C 段(/24)的原理与应用解析

整体表格说明 这是某市教育城域网中某县教育相关机构的IP地址规划表&#xff0c;明确了某县一中和某县教育局的IP地址范围&#xff0c;包括终端使用地址段、业务互访地址段。 概念解析 64个C段终端及互联地址 C段地址&#xff1a;一个C段是IP地址中的一个/24网络&#xff08;…

python生成并绘制各种类型声音噪声

python生成并绘制各种类型声音噪声 1、效果 白噪声: 工业设备振动噪声: 2、噪声类型 主要噪声类型有: 白噪声:全频段能量均匀分布 直接生成高斯分布随机数粉红噪声:能量随频率增加按1/f衰减(适合声学测试) 使用IIR滤波器对白噪声进行滤波处理布朗噪声:能量随频率增加…

软考-数据库系统工程师第四版pdf

软考-数据库系统工程师第四版pdf git中的文件相对没有那么清楚&#xff0c;网盘的有高清版 github下载 这里我给出仓库地址 链接: https://github.com/yaodada123/ruankao-pdf https://github.com/yaodada123/ruankao-pdf gitee下载 https://gitee.com/yao-hengchao/ruank…

Linux(24)——系统调优

目录 一、tuned 软件包&#xff1a; 1、安装并启用 tuned &#xff1a; 2、验证 tuned 软件包&#xff1a; &#xff08;1&#xff09;是否安装&#xff1a; &#xff08;2&#xff09;是否启用&#xff1a; &#xff08;3&#xff09;是否正在运行&#xff1a; 二、系统…

文件系统--软硬链接/动静态库

inode 是文件系统中的一个重要概念&#xff0c;用于存储文件的元数据。 inode 的结构和内容 文件权限&#xff1a;定义了文件所有者、所属组以及其他用户对文件的读、写、执行权限。文件所有者和所属组&#xff1a;记录了文件的所有者和所属的用户组信息。文件大小&#xff1…

WebSocket原理详解(二)

WebSocket原理详解(一)-CSDN博客 目录 1.WebSocket协议的帧数据详解 1.1.帧结构 1.2.生成数据帧 2.WebSocket协议控制帧结构详解 2.1.关闭帧 2.2.ping帧 2.3.pong帧 3.WebSocket心跳机制 1.WebSocket协议的帧数据详解 1.1.帧结构 WebSocket客户端与服务器通信的最小单…

MySQL 进阶 面经级

会用数据库&#xff0c;找大厂工作是远远不够的。 本人2025美团暑期AI面试好几个MySQL场景问题不会答&#xff0c;已脏面评。遂在此整理学习&#xff01; 文章目录 美团AI面1.数据库分片sharding的概念&#xff0c;它有什么优势和挑战?优势Sharding 挑战 2. 分库分表的常见策…

基于单片机的智能奶茶机(论文 +源码)

1总体架构设计 本课题为基于单片机的智能奶茶机设计&#xff0c;其系统架构上设计如图2.1所示&#xff0c;整个系统包括了DS18B20温度传感器、继电器模块、LCD液晶、蜂鸣器、按键、STC89C52单片机等器件&#xff0c;在功能上用户可以通过按键键控制选择甜度和添加物以及设置温度…

Hue:一个大数据查询工具

Hue&#xff08;Hadoop User Experience&#xff09;是一个用于大数据平台、数据库以及数据仓库查询的开源工具&#xff0c;旨在通过 Web 界面简化用户与 Hadoop 生态系统以及各种数据存储的交互。 Hue 支持的数据源包括数据库&#xff08;Apache Hive、Apache Impala、MySQL、…