畢業(yè)設(shè)計:從原理圖到代碼的完整解析)
簡介基于STM32單片機的智能手環(huán)項目是一套完整的畢業(yè)設(shè)計資料涵蓋硬件原理圖、軟件源碼和詳細設(shè)計文檔適合電子信息、自動化、計算機等相關(guān)專業(yè)學生用于畢業(yè)設(shè)計、課程設(shè)計或項目練手。壓縮包內(nèi)共104個文件其中c和h源碼負責心率測量、計步顯示、血壓提醒等功能邏輯與底層驅(qū)動bmp和png圖片用于開機廣告、菜單界面等屏幕顯示pdf和docx文檔介紹設(shè)計方案與使用方法db數(shù)據(jù)庫可存儲運行數(shù)據(jù)整套資料大小約17.74MB目錄結(jié)構(gòu)清晰便于對照學習。項目代碼經(jīng)過測試運行穩(wěn)定支持二次開發(fā)或直接作為畢設(shè)課設(shè)成果。已有809人學習下載無論你是要完成畢業(yè)設(shè)計還是想入手嵌入式開發(fā)這套資料都能提供從原理到實現(xiàn)的全流程參考幫助你快速上手項目。1. STM32智能手環(huán)畢業(yè)設(shè)計拿到資料包先別急著燒錄收到“基于STM32單片機的智能手環(huán) 源碼原理圖詳細文檔配套全部資料畢業(yè)設(shè)計.zip”這個壓縮包很多人的第一反應是解壓、打開 Keil 工程、編譯下載。但 STM32 智能手環(huán)這類項目真正值錢的是“整條鏈路”而不是“能跑起來”。答辯老師最常問的是某一個引腳為什么這樣接、計步閾值怎么定、I2C 總線上掛了三個設(shè)備為什么沒沖突、掉電后 RTC 還走不走。這些答案都在原理圖和源碼里需要你順著硬件、驅(qū)動、應用、文檔一層層拆開看。所以第一步不是燒錄而是把壓縮包當學習樣本按硬件到軟件的順序自己過一遍。2. 硬件原理圖STM32最小系統(tǒng)到手環(huán)外設(shè)的接線2.1 先讀 STM32F103C8T6 最小系統(tǒng)原理圖別在電源和晶振上翻車看一張手環(huán)原理圖我一般按電源、時鐘、復位、啟動模式、下載調(diào)試五步走。STM32F103C8T6 是 48 腳芯片常見于智能手環(huán)、魚缸控制器這類小項目外設(shè)不多但 IO 夠用。電源部分通常用 AMS1117-3.3 把 5V 降到 3.3V或者用鋰電池供電時加一顆 TP4056 充電和升壓/降壓電路。注意 VDD 和 VDDA 上必須有 100nF 加 1μF 的去耦電容缺了這兩顆電容ADC 采集電池電壓時會跳得厲害。晶振這里是最容易出問題的地方。8MHz 主晶振要并聯(lián)一個 1MΩ 電阻兩個引腳各接一個 15pF 到 22pF 的負載電容到地電容值需要和晶振規(guī)格書匹配不是隨便裝一顆就能穩(wěn)定起振。STM32F103C8T6 如果外接 HSE就必須把 OSC_IN/OSC_OUT 固定到 PD0/PD1 上如果是內(nèi)部 HSI那么 PD0/PD1 可以復用為普通 IO。做手環(huán)一般還會加 32.768kHz 晶振給 RTC只能接 PC14/PC15同時這兩個腳不能再配別的外設(shè)。BOOT0 引腳必須通過 10kΩ 下拉到 GND很多手環(huán)原理圖會把 BOOT0 用一個 0Ω 電阻接地方便下載時改跳線。啟動模式要保證上電從主 Flash 運行否則程序燒進去不跑。復位電路在 NRST 上接 10kΩ 上拉和 100nF 電容ST-Link 連接時也建議把 NRST 引到調(diào)試接口這樣用 ST-Link Utility 擦除芯片時更穩(wěn)定。調(diào)試接口建議用一個 4Pin 或者 5Pin 排針引出 SWDIO、SWCLK、GND、3.3V不需要帶復位腳也可以。使用 ST-Link 的 SWD 模式只需要兩根線比 JTAG 省腳。原理圖核對到這里可以順手檢查 VREF 是否接 VDDF103C8T6 內(nèi)部參考電壓固定為 3.3V不需要額外電路。最小系統(tǒng)確認沒問題后再去看傳感器和顯示部分。2.2 手環(huán)外設(shè)選型與模塊接口I2C、SPI、UART 怎么分配智能手環(huán)的常見功能包括計步、心率、時間顯示和藍牙上報。基于這些功能外設(shè)一般選擇 MPU6050 加速度計、MAX30102 心率傳感器、SSD1306 OLED 屏和 HC-08 藍牙透傳模塊。它們的接口如下表功能模塊常見型號接口STM32F103C8T6 引腳建議加速度/陀螺儀MPU6050I2CPB8: SCLPB9: SDAOLED 顯示屏SSD1306 0.96寸I2CPB8: SCLPB9: SDA心率傳感器MAX30102I2CPB8: SCLPB9: SDAPB5: INT藍牙透傳HC-08 / ATK-HC05UARTPA9: TXPA10: RX按鍵輕觸按鍵 x3GPIOPA0: 返回PA1: 確認PA2: 加一三個 I2C 設(shè)備可以掛在同一條總線上但必須保證從機地址不同。MPU6050 默認地址是 0x68AD0 接高電平時變成 0x69SSD1306 的 7 位地址一般是 0x3C這個地址硬件固定MAX30102 的默認地址是 0x57三者剛好錯開。每個設(shè)備在 PCB 布局上都要加去耦電容I2C 的 SCL 和 SDA 還要分別接 4.7kΩ 上拉電阻到 3.3V上拉電阻不加上拉不起來通信會時好時壞。OLED 選 I2C 接口的版本比 SPI 版本少兩根控制線布板更省位置。SSD1306 的復位引腳 RES 可以接 MCU 的 PB4也可以直接接 RC 復位電路為了穩(wěn)定我一般用 MCU 控制 RES。按鍵接口要加上 10kΩ 下拉電阻PA0 本身支持 WakeUp待機模式下可以當喚醒源。心率傳感器 MAX30102 的 INT 引腳最好接外部中斷這樣沒有檢測到脈搏時主控不用一直讀 FIFO。為了后面寫代碼方便把整張原理圖的引腳映射整理成頭文件。這樣原理圖評審時也能對著引腳看少走回頭路。下面是一段示意#define PIN_SCL GPIO_PIN_8 #define PIN_SDA GPIO_PIN_9 #define I2C_GPIO GPIOB #define HR_INT_PIN GPIO_PIN_5 #define HR_INT_PORT GPIOB #define BT_TX_PIN GPIO_PIN_9 #define BT_RX_PIN GPIO_PIN_10 #define BT_UART USART1這段定義把 I2C、心率中斷、藍牙串口的引腳和串口號固定下來。項目中所有驅(qū)動文件只引用這些宏不改裸引腳號。這樣原理圖和代碼一一對應后面調(diào)試時查錯也方便。如果中途換引腳只需改這一個頭文件。2.3 用嘉立創(chuàng)EDA或Altium Designer檢查原理圖ERC、頁碼和BOM核對原理圖繪制完成不是終點電氣規(guī)則檢查必須跑一遍。在嘉立創(chuàng)EDA中打開“設(shè)計規(guī)則檢查”會看到懸空引腳、單端網(wǎng)絡(luò)、重復頁碼等告警。比如有同學在畫圖時把多頁原理圖每頁都設(shè)成 page number 1生成網(wǎng)表后就會出現(xiàn)“有 2 張或以上原理圖頁面page number 都設(shè)成了 1”的錯誤導出到 PCB 時網(wǎng)絡(luò)連接全亂。遇到這種問題需要重新設(shè)置每一頁的圖紙編號保證唯一。Altium Designer 里可以執(zhí)行 Project - Compile在 Messages 面板按錯誤級別篩選。最常見的 ERC 告警是“Unconnected Pin”和“Net has only one pin”前者說明某根線沒連上后者說明網(wǎng)絡(luò)標簽漏了比如 SDA 引腳旁寫了 SDA但傳感器端的標簽寫成了 SDA0兩個網(wǎng)絡(luò)實際沒連通。這種問題在原理圖上不會紅報但焊接完所有傳感器都讀不到。核對完電氣規(guī)則后生成 BOM 表。逐項檢查封裝和供貨0805 電容、0603 電阻、LQFP48 的 STM32 芯片、OLED 排針方向。嘉立創(chuàng)EDA可以直接聯(lián)動立創(chuàng)商城看庫存Altium 則需要去具體供應商核對。尤其注意晶振的負載電容指定 20pF 就不要換成 22pF否則頻率偏差可能讓串口亂碼。BOM 對了再送去打樣焊接回來才能順利進入軟件階段。3. 源碼工程從STM32CubeMX初始化到手環(huán)驅(qū)動框架3.1 用 STM32CubeMX 配置時鐘、I2C、UART生成完整工程源碼包里可能自帶 Keil 工程但我建議用 STM32CubeMX 重新生成一遍因為初始化代碼復用度更高也方便查參數(shù)。選擇芯片型號 STM32F103C8TxRCC 打開 HSE使用外部晶振Debug 選擇 Serial Wire也就是 SWD 模式。時鐘樹里把 HSE 8MHz 經(jīng) PLL 倍頻到 72MHzAPB1 總線設(shè)置為 36MHzAPB2 設(shè)置為 72MHz。I2C1 配置為 Fast Mode速率 400kHz地址 7 位模式。注意 I2C 時鐘源來自 APB1如果 APB1 是 36MHzI2C 外設(shè)時鐘 36MHz400kHz 的分頻系數(shù)是 90。STM32CubeMX 會自動計算但你要確認它沒有報錯。USART1 配置為異步模式波特率 115200數(shù)據(jù)位 8停止位 1無校驗開啟發(fā)送和接收中斷。GPIO 配置 PA0-PA2 為輸入下拉模式。PB5 配置為外部中斷上升沿觸發(fā)使能。配置完成后生成 MDK-ARM 工程在 Keil 里編譯。這里有一個很常見的坑如果電腦里同時裝了 Keil C51 和 Keil MDK打開工程時可能加載了錯誤的編譯套裝報“not a valid MDK project”或者找到不到頭文件。這時需要在 Project - Manage - Project Items 里檢查 Toolchain 是不是 ARM Compiler 5/6同時 Global 里確認 STM32F1xx_DFP 支持包已安裝。3.2 手環(huán)核心驅(qū)動I2C 讀 MPU6050 和寫 OLED 的最小代碼在 CubeMX 生成的main.c基礎(chǔ)上把驅(qū)動單獨放到 BSP 目錄。MPU6050 初始化最關(guān)鍵是退出睡眠模式并配置采樣率下面是精簡版#include mpu6050.h #define MPU6050_ADDR 0x68 #define PWR_MGMT_1 0x6B #define SMPLRT_DIV 0x19 #define CONFIG 0x1A #define ACCEL_CONFIG 0x1C uint8_t mpu6050_init(I2C_HandleTypeDef *hi2c) { uint8_t tmp 0x00; // 寫 0 到 PWR_MGMT_1退出 sleep并選擇內(nèi)部時鐘源 tmp 0x00; HAL_I2C_Mem_Write(hi2c, MPU6050_ADDR 1, PWR_MGMT_1, I2C_MEMADD_SIZE_8BIT, tmp, 1, 100); // 采樣率分頻輸出頻率 1kHz / (SMPLRT_DIV 1) tmp 0x07; HAL_I2C_Mem_Write(hi2c, MPU6050_ADDR 1, SMPLRT_DIV, I2C_MEMADD_SIZE_8BIT, tmp, 1, 100); // 加速度量程 ±2g寫入 0x00 tmp 0x00; HAL_I2C_Mem_Write(hi2c, MPU6050_ADDR 1, ACCEL_CONFIG, I2C_MEMADD_SIZE_8BIT, tmp, 1, 100); return 0; }所有 HAL 函數(shù)都帶一個hi2c指針用來指定 I2C1 還是 I2C2。MPU6050 的地址在數(shù)據(jù)手冊上是 7 位值 0x68HAL_I2C_Mem_Write要求傳入 8 位地址所以要左移一位變成 0xD0。100 是超時毫秒數(shù)在調(diào)試時如果返回 HAL_TIMEOUT說明上拉電阻或接線有問題或者設(shè)備地址寫錯。OLED 驅(qū)動更簡單。SSD1306 通過控制字節(jié)區(qū)分命令和數(shù)據(jù)0x00 表示后一個字節(jié)是命令0x40 表示后一個字節(jié)是數(shù)據(jù)。發(fā)送函數(shù)如下static void ssd1306_write(I2C_HandleTypeDef *hi2c, uint8_t type, uint8_t data) { uint8_t buf[2]; buf[0] type; // 0x00: 命令, 0x40: 數(shù)據(jù) buf[1] data; HAL_I2C_Master_Transmit(hi2c, 0x3C 1, buf, 2, 50); }這里 I2C 從機地址是 0x3C發(fā)送兩字節(jié)。控制字節(jié)的高位 Co 為 0 表示后面連續(xù)數(shù)據(jù)D/C# 位在最低位命令是 0x00數(shù)據(jù)是 0x40。把 OLED 的初始化命令序列封裝成數(shù)組循環(huán)調(diào)用再填充顯存屏幕就能亮了。3.3 源碼工程怎么組織BSP、App 和文檔目錄分離源碼工程如果只有main.c后期維護會非常痛苦。常見的做法是按 BSP板級支持包、App應用邏輯和 Doc 三層組織。目錄結(jié)構(gòu)如下Project/ ├─ Core/ # CubeMX 生成的 main.c、中斷、系統(tǒng)時鐘 │ ├─ Inc/ │ └─ Src/ ├─ Drivers/ # ST 官方 HAL 庫與 CMSIS 內(nèi)核文件 ├─ BSP/ # 板級驅(qū)動oled.c、mpu6050.c、max30102.c ├─ App/ # 應用邏輯menu.c、step_counter.c、power.c └─ Doc/ # 芯片手冊、調(diào)試記錄、通信協(xié)議說明BSP 層每個文件對應一個硬件外設(shè)對外只提供初始化函數(shù)和讀寫函數(shù)。App 層不直接操作 HAL只調(diào)用 BSP 提供的接口例如step_counter_update()。這樣如果換了一顆加速度傳感器只需要改 BSP 里的mpu6050.cApp 層計步邏輯完全不用動。源碼里的頭文件也要對應清晰mpu6050.h提供MPU_Init和MPU_Read_Acceloled.h提供OLED_ShowStringmenu.h提供狀態(tài)機輪詢。手環(huán)項目的源碼包如果目錄亂產(chǎn)物也難以核對。我會在Doc下放一份README.md寫清楚編譯工具鏈、燒錄步驟和每個驅(qū)動文件的職責這份 README 對畢業(yè)設(shè)計文檔編寫也有直接幫助。4. 手環(huán)功能實現(xiàn)計步、心率、OLED顯示與功耗控制4.1 計步算法從加速度數(shù)據(jù)到步數(shù)怎么算計步在 STM32 上不需要很復雜的神經(jīng)網(wǎng)絡(luò)一個閾值加消抖就能達到可演示效果。MPU6050 讀出三軸原始加速度先轉(zhuǎn)成單位 g再計算合量平方根。正常走路時加速度合量有周期性高峰峰值超過閾值就認為可能是一步。為了避免抖動要加上“最小步間隔”過濾。參考實現(xiàn)如下#define STEP_THRESHOLD 1.3f #define MIN_STEP_GAP 300u uint32_t step_count 0; static uint32_t last_step_ms 0; void step_detect(float x, float y, float z, uint32_t now_ms) { static float prev_norm 1.0f; float norm sqrtf(x * x y * y z * z); if (norm STEP_THRESHOLD norm prev_norm (now_ms - last_step_ms) MIN_STEP_GAP) { step_count; last_step_ms now_ms; } prev_norm norm; }STEP_THRESHOLD 選 1.3g 是因為正常走路垂直加速度峰值基本在 1.2g 到 1.5g。如果放在手上擺動幅度大可以提高到 1.5g放在口袋里可以降到 1.2g。MIN_STEP_GAP 設(shè)為 300ms對應最快每秒 3 步超過這個頻率就忽略掉防止抖動和誤觸產(chǎn)生多個峰值。采樣率保持 25Hz 足夠過高的采樣率只會增加計算量和功耗。4.2 心率采集MAX30102 的 INT 中斷與 FIFO 讀取心率模塊 MAX30102 內(nèi)部帶一個 FIFO可以緩存采樣數(shù)據(jù)。一般設(shè)置采樣率為 100HzLED 電流根據(jù)膚色和佩戴松緊調(diào)節(jié)。代碼里最關(guān)鍵的是中斷回調(diào)。手指放在傳感器上時INT 引腳會拉低或拉高進入下面回調(diào)void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin HR_INT_PIN) { hr_data_ready 1; } }主循環(huán)檢測到hr_data_ready為 1 后通過 I2C 讀取 MAX30102 的 FIFO 寄存器把紅光和紅外數(shù)據(jù)取出。因為 I2C 總線同時掛了 MPU6050 和 OLED主循環(huán)里讀取時要注意不能長時間占用總線否則 OLED 刷新會卡頓。可以把心率采集放在定時器中斷里觸發(fā)用標志位通知主循環(huán)批量讀取。實際測試中MAX30102 對佩戴位置非常敏感手指壓緊或松動都會讓數(shù)據(jù)失真。因此不能只看瞬時值需要做 10 個點的滑動平均再把波峰間隔換算成心率。這個算法放在 App 層與驅(qū)動分離。文檔里要寫明波峰檢測的閾值是動態(tài)的通常取最近 1 秒數(shù)據(jù)最大值的 80%而不是固定值。4.3 OLED 顯示與按鍵菜單用狀態(tài)機管理多個頁面手環(huán)界面一般包含時間、計步、心率、菜單四項。用狀態(tài)機而不是多個 if 嵌套來維護代碼清晰且好擴展。狀態(tài)定義如下typedef enum { PAGE_MAIN, PAGE_STEP, PAGE_HEART_RATE, PAGE_SET_TIME } page_index_t;按鍵按下時切換page_index并調(diào)用對應的顯示函數(shù)。長按和短按可以用同一個按鍵掃描函數(shù)區(qū)分PA0 短按返回上一級長按進入菜單。每次按鍵操作后點亮 OLED屏幕超時 10 秒自動熄滅。顯示驅(qū)動要記得SSD1306 是顯存型芯片寫顯存后要調(diào)用HAL_I2C_Mem_Write刷新否則屏幕內(nèi)容不會變化。刷新頻率控制在 20Hz 足夠不要不斷重繪。4.4 低功耗處理STOP 模式、RTC 喚醒和電池電壓測量手環(huán)是電池供電整機電流最好控制在 30mA 以下。MCU 大部分時間應處于 STOP 模式用 RTC 鬧鐘周期性喚醒比如每 1 秒醒來一次刷新時間或者每 10 秒醒來一次采集傳感器。進入 STOP 模式前要把 OLED 關(guān)掉、LED 滅掉并把 I2C 總線釋放。F103 的 STOP 模式代碼HAL_SuspendTick(); HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); HAL_ResumeTick(); SystemClock_Config();喚醒后第一件事必須重新調(diào)用SystemClock_Config()因為 STOP 模式會把 PLL 關(guān)掉如果不重新配置72MHz 主頻會變回內(nèi)部 8MHz串口波特率會亂。電池電壓通過 PA1 接一個分壓電阻到 3.3V用 ADC1 采集換算公式uint16_t adc HAL_ADC_GetValue(hadc1); float voltage adc * 3.3f / 4095.0f; float battery_v voltage * (100.0f 51.0f) / 51.0f;這里假設(shè)分壓電阻是 100kΩ 和 51kΩ根據(jù)實際原理圖調(diào)整系數(shù)。電池電壓低于 3.5V 時要提示充電并在 OLED 上顯示低電量圖標。5. 配套文檔原理圖說明、源碼注釋與論文組織5.1 一個健壯的畢設(shè)資料包應該包含哪些文檔壓縮包名稱里強調(diào)“詳細文檔配套全部資料”這說明畢業(yè)設(shè)計對資料的完整性要求很高。一個合格的手環(huán)資料包至少包含以下內(nèi)容分類文件名稱作用硬件資料原理圖 PDF、PCB、BOM 表評審、打樣、焊接軟件資料Keil 工程源碼、HEX 燒錄文件復現(xiàn)和現(xiàn)場燒錄說明文檔README、接線說明、編譯說明讓別人快速上手設(shè)計文檔開題報告、中期報告、畢業(yè)論文滿足學校要求測試文檔功能測試記錄、調(diào)試截圖、演示視頻證明系統(tǒng)可用很多同學只在壓縮包里放源碼和原理圖忽略了 BOM 和測試記錄。實際上BOM 表在打樣返工時特別重要測試記錄則展示你從問題到解決的過程答辯老師非常喜歡看這一類內(nèi)容。5.2 源碼注釋和文檔對應的關(guān)鍵參數(shù)詳細文檔不是把代碼抄一遍而是把“為什么這么設(shè)計”解釋清楚。比如 I2C 速率為什么是 400kHz 而不是 100kHz因為手環(huán)需要快速刷新 OLED但 MPU6050 對 400kHz 也完全支持。MPU6050 采樣率為什么設(shè)成 125Hz因為計步算法只用 25Hz降采樣后可以省電。MAX30102 的 LED 電流為什么設(shè)成 6.4mA因為太大會穿透手指導致信號飽和。這些參數(shù)說明要寫進“軟件設(shè)計”部分和源碼里的宏定義一一對應。建議在Doc目錄下放一個parameter_settings.md把所有可調(diào)參數(shù)列成表格包含默認值、調(diào)整范圍、對功耗和精度的影響。例如參數(shù)名默認值調(diào)整范圍說明STEP_THRESHOLD1.3f1.1f - 1.6f峰值超過該值才計一步SAMPLE_RATE25Hz10Hz - 50Hz計步采樣率OLED_REFRESH_MS50ms20ms - 100ms屏幕刷新周期越低越耗電5.3 畢業(yè)論文各章節(jié)怎樣引用源碼和原理圖畢業(yè)論文寫“硬件電路設(shè)計”時不要貼整張原理圖而是拆成電源模塊、STM32 最小系統(tǒng)、傳感器模塊、藍牙模塊四部分每部分用一張局部原理圖或者引腳說明表格。寫“軟件設(shè)計”時把系統(tǒng)結(jié)構(gòu)畫成模塊框圖描述 BSP/App 分層關(guān)系然后針對計步和心率各寫一個偽代碼邏輯。測試章節(jié)則放實際測量數(shù)據(jù)待機電流、通信距離、計步誤差。文檔里所有圖編號要和資料包里的原理圖頁對應老師按圖索驥時能快速定位到原始文件。6. 驗證與進階讓手環(huán)從“能跑”到“能答辯”6.1 拿到板子后的六步硬件聯(lián)調(diào)第一步萬用表測電源對地阻抗避免短路。第二步上電后用示波器或邏輯分析儀看 8MHz 晶振波形起振不正常直接查兩個 20pF 電容和 1MΩ 電阻。第三步用 ST-Link 連接打開 ST-Link Utility如果提示 “Error: No STM32 Target Found”先查 SWDIO、SWCLK 是否接反、目標板是否供電、BOOT0 是否被拉高。第四步燒錄一個最簡單的 LED 閃爍程序確認內(nèi)核能跑。第五步用 I2C 掃描程序確認總線上三個設(shè)備的地址。第六步逐個測試按鍵、OLED、藍牙每項通過后再組合測試。掃描 I2C 設(shè)備地址的小函數(shù)可以寫在一個獨立工程里也可以臨時放在主循環(huán)里for (uint8_t addr 1; addr 127; addr) { if (HAL_I2C_IsDeviceReady(hi2c1, addr 1, 1, 10) HAL_OK) { printf(Addr: 0x%02X\r\n, addr); } }這個循環(huán)會把總線上所有有響應的地址打印到串口和原理圖上的地址一一對照。MPU6050 顯示 0x68SSD1306 顯示 0x3CMAX30102 顯示 0x57這樣硬件連接基本可信。串口如果打印亂碼檢查串口助手的波特率是不是 115200以及 STM32 虛擬串口驅(qū)動是否安裝。6.2 進階改造加入 FreeRTOS 和手機藍牙如果學有余力可以在現(xiàn)有源碼中引入 FreeRTOS用三個任務(wù)分別管理傳感器采集、OLED 顯示和按鍵處理。I2C 總線是共享資源每個設(shè)備訪問時要加互斥鎖否則 OLED 刷新和心率讀取會互相打斷。藍牙模塊已經(jīng)在硬件預留了 UART1可以讓手環(huán)定時把步數(shù)和心率打包成一行 JSON 數(shù)據(jù)發(fā)送到手機藍牙調(diào)試助手用手機 APP 或微信小程序顯示。最值得做的低功耗優(yōu)化是把 MAX30102 和 OLED 的電源單獨用 MOS 管控制待機時徹底斷電這樣整機待機電流能從 20mA 降到 1mA 以下。調(diào)試功耗時用萬用表串聯(lián)在電池正極分別測運行、睡眠、關(guān)機三擋電流記錄到測試文檔里。頻率、電流、顯示刷新率這幾個數(shù)據(jù)證書齊全了答辯時無論是被問硬件還是軟件都能拿出實際測量結(jié)果來印證。本文還有配套的精品資源點擊獲取