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.pswp.cn/pingmian/74217.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/74217.shtml
英文地址,請注明出處:http://en.pswp.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、…