微控制器:Single-Chip Microcomputer,單片微型計算機,是一種積體電路晶片
CPU:CPU
記憶體:SRAM
硬碟:FLASH
主機板:外設
儀器儀表:電源/示波器/焊臺
家用電器:空調/冰箱/洗衣機
工業控制:機器人/PLC/電梯
汽車電子:GPS/ABS/胎壓監測
:資料與程式儲存在同一儲存器,分時複用
CoreMark分數:https://www.eembc.org/coremark/scores.php
ARM公司官網:https://www.arm.com/
ARM開發者官網:https://developer.arm.com/
STM32:
ST:意法半導體 M:MCU/MPU 32:32位
ST累計推出了:5大類、18個系列、1000多個型號的Cortex核心微控制器
ST中文社群網:https://www.stmcu.org.cn
ST官網: https://www.st.com
正點原子論壇:www.openedv.com/forum.php
STM32 主要分兩大塊, MCU 和 MPU, MCU 不能跑 Linux,而 MPU可以跑 Linux。
晶片的基本引數:
1,主頻/FLASH/SRAM
2,工作電壓/最大電流
3,IO引腳接入電壓範圍
4,單個IO引腳最大電流
獲取MDK:
MDK安裝 = MDK軟體安裝 + 器件支援包
MDK軟體下載:https://www.keil.com/download/product
器件支援包下載:https://www.keil.com/dd2/pack/
複製下載演算法到Flash資料夾,如 D:\MDK5.34\ARM\Flash(可選)
安裝CH340 USB虛擬串列埠驅動,資料線插入開發板中
程式在Projects\MDK-ARM中
I/O :表示輸入/輸出引腳
編譯結果看:Build Output視窗
資料型別:佔用Flash or SRAM:說明
Code:表示程式碼大小
RO-Data:表示只讀資料所佔的空間大小,一般是指 const 修飾的資料大小。
RW-Data:初值為非 0的可讀可寫資料
ZI-Data:初值為0 的可讀可寫資料
FLASH佔用:Code+RO+RW
SRAM佔用:RW+ZI
hex檔案在Output中
利用串列埠給 STM32 下載程式碼:
USB_UART 透過 USB 線連線電腦->電源燈亮起(藍色)->USART1的 RXD、PA9,TXD 、PA10透過跳線帽連線->BOOT0、GND,BOOT1、GND透過跳線帽連線->按一下復位按鍵->使用上位機軟體下載程式碼->雙擊開啟 ATK-XISP->波特率推薦設定為 76800->選擇 DTR 的低電平復位,RTS 高電平進 BootLoader->下載成功後,會有“共寫入 xxxxKB,進度 100%,耗時 xxxx 毫秒”
使用 DAP 下載與除錯程式:
DAP 透過 USB 線連線電腦,透過 20P 灰排線連線開發板->開發板供電->
開啟MDK IDE:
魔術棒->Debug->use: CMSIS-DAP Debugger->勾選Run to main->
點選 Settings->Port:SW->Max Clock:8Mhz->
Utilities ->勾選 Use Debug Driver->點選 Settings->選中 Reset and Run->如果沒有 flash 演算法,點選 Add 按鈕自行新增->
F7 ->F8
使用 DAP 模擬除錯程式:
Register:暫存器視窗
Disassembly:反彙編視窗,方便從彙編級別檢視程式執行狀態
Call Stack + Locals:呼叫關係和區域性變數視窗,檢視函式呼叫關係,以及函式的區域性變數
Debug 工具條
關閉Disassembly視窗->新增Watch1視窗->雙擊 Enter expression,將全域性變數: g_fac_us (在 delay.c 裡面定義)加入 Watch1 視窗->
在 delay_init 函式處放置一個斷點->點選執行到該斷點處->執行進去->執行過去(g_fac_us值顯示出來)->執行進去
從 Call Stack + Locals 視窗看到函式的呼叫關係,其原則是: 從下往上看,即下一個函式呼叫了上一個函式
MDK5 使用技巧:
自定義字型顏色:
設定->Encoding:Chinese GB2312(Simplified)->勾選View White Space(編輯器的空格可見)->勾選Insert spaces for tabs(程式碼對齊)->Tab size:4->
Colors & Fonts 選項卡->C/C++ Editor Files(設定自己的程式碼的字型和顏色)->
User Keywords 選項卡,設定使用者定義關鍵字
看看某個變數或陣列是在哪個地方定義,快速定位:
魔術棒->Output->勾選 Browse Information->編譯->
右鍵->Go to Definition Of
快速註釋/消註釋塊程式碼的功能->右鍵->高階(Advanced)->註釋選擇(Comment Selection)
快速開啟標頭檔案:右鍵->Open Document
define :預處理命令,它用於宏定義
常見的格式:define 識別符號 字串
識別符號:宏名。
ifdef 條件編譯:條件編譯命令最常見的形式為:
#ifdef 識別符號
程式段 1
#else
程式段 2
#endif
當識別符號已經被定義過(一般是用#define 命令定義),則對程式段 1 進行編譯, 否則編譯程式段 2。 其中#else 部分也可以沒有
extern 外部申明:
extern :置於變數或者函式前,以表示變數或者函式的定義在別的檔案中。 extern 申明變數可以多次,但定義只有一次
typedef:為現有型別建立一個新的名字,或稱為型別別名,用來簡化變數的定義。定義結構體的型別別名和列舉型別。
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
…
} GPIO_TypeDef;
宣告結構體型別:
struct 結構體名
{
成員列表;
}變數名列表;
在結構體申明的時候可以定義變數,也可以申明之後定義:struct 結構體名字 結構體變數列表 ;
結構體成員變數的引用方法是:結構體變數名字.成員名
指標:本質是指向一個地址,從而可以訪問一片記憶體區域。
申明指標我們一般以 p 開頭:char * p_str = “This is a test!”;
p_num:變數的地址
*p_num:指向的地址所儲存的值
&p_num:指標自身的地址
儲存器本身是沒有地址資訊的,儲存器分配地址的過程就叫儲存器對映。
給暫存器的地址命名的過程就叫暫存器對映。
暫存器的地址=外設基地址+地址偏移量
=匯流排基地址(BUS_BASE_ADDR)+匯流排基地址的偏移量(PERIPH_OFFSET)+外設基地址的偏移量(REG_OFFSET)
例如:GPIOB_ODR地址 = AHB1匯流排基地址 + GPIOB外設偏移量 + 暫存器偏移量
外設基地址在stm32參考手冊2.3儲存器對映中檢視
/*GPIOB_ODR 暫存器的地址為: 0x4002 0414, 假設我們要控制GPIOB 的 16 個 IO 口都輸出 1*/
#define GPIOB_ODR *(unsigned int *)(0x40020414)
GPIOB_ODR = 0XFFFF;
/*這個宏定義過程就可以稱之為暫存器的對映。*/
新建一個工程框架:
開啟 MDK 軟體->專案->新的->STM32 型號(要安裝對應的器件 pack 才會顯示這些內容)->
自動建立了 3 個資料夾:
DebugConfig:除錯設定資訊檔案(.dbgconf),不可刪除
Listings:編譯過程產生的連結列表等檔案
Objects:編譯過程產生的除錯資訊、 .hex、預覽、 .lib 檔案等->
先把 MDK 自動生成的這兩個資料夾(Listings 和 Objects)刪除
Heap_Size EQU 0x00000000
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
LDR R0, =0xE000ED88 ;使能浮點運算 CP10,CP11
LDR R1,[R0]
ORR R1,R1,#(0xF << 20)
STR R1,[R0]
;暫存器版本程式碼,因為沒有用到 SystemInit 函式,所以註釋掉以下程式碼為防止報錯!
;HAL 庫版本程式碼,建議加上這裡(外部必須實現 SystemInit 函式),以初始化
;stm32 時鐘等.
;IMPORT SystemInit
;LDR R0, =SystemInit
;BLX R0
LDR R0, =__main
BX R0
ENDP
設定使用 FPU:魔術棒->Target1選項卡->Floating Point Hardware:Double Precision
使用 AC6 編譯器,Misc Controls : -Wnoinvalid-source-encoding->
新增main.c->新增到分組->編譯會報錯修改stm32fxx_it.c新增標頭檔案#include "stm32f4xx_hal.h"