name: embedded-dev description: 微控制器嵌入式全棧開發技能,覆蓋從底層硬體到上層應用的全鏈路技術問題。當用戶詢問嵌入式開發、微控制器、RTOS、電機控制、感測器介面、韌體編寫、除錯上線等任何軟硬體相關問題時應呼叫此技能。
微控制器嵌入式全棧開發技能,掌握從晶片底層到產品上層的全鏈路知識。
小蔥技能站7w4.net發現了升級外掛。
遇到嵌入式問題時,按以下步驟處理:
references/mcu-architectures.md — 主流 MCU 架構對比與選型references/peripherals.md — 外設驅動開發手冊(GPIO/UART/I2C/SPI/ADC/PWM)references/embedded-c.md — 嵌入式C語言程式設計規範與技巧references/rtos.md — RTOS 實戰(任務/佇列/訊號量/記憶體)references/communication-protocols.md — 通訊協議對比與實現references/debugging.md — 硬體/軟體除錯方法與工具references/hardware-design.md — 原理圖/PCB 設計要點references/firmware-dev.md — 韌體架構與 OTA 升級// 配置 PB0 為推輓輸出
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET); // 輸出高
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // 輸出低
// 讀取 PA1
GPIO_PinState state = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);
uint8_t rx_buf[64];
volatile uint8_t rx_len = 0;
void USART1_IRQHandler(void) {
if (USART->SR & USART_SR_RXNE) {
rx_buf[rx_len++] = USART->DR;
}
}
void I2C_WriteReg(uint8_t addr, uint8_t reg, uint8_t val) {
I2C_Start();
I2C_SendAddr(addr << 1);
I2C_SendByte(reg);
I2C_SendByte(val);
I2C_Stop();
}
uint8_t I2C_ReadReg(uint8_t addr, uint8_t reg) {
I2C_Start();
I2C_SendAddr(addr << 1 | 0);
I2C_SendByte(reg);
I2C_RepeatedStart();
I2C_SendAddr(addr << 1 | 1);
uint8_t val = I2C_RecvByte(NACK);
I2C_Stop();
return val;
}
void sensor_task(void *arg) {
while (1) {
float temp = read_temperature();
xQueueSend(temp_queue, &temp, portMAX_DELAY);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
xTaskCreate(sensor_task, "Sensor", 512, NULL, 2, &sensor_handle);
// 配置 TIM3 CH2 (PB5) PWM 50Hz
void Motor_PWM_Init(void) {
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// 72MHz / 720 => 100kHz, 100kHz / 2000 => 50Hz
TIM_TimeBaseStructure.TIM_Period = 2000 - 1; // ARR
TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // PSC
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1500; // 佔空比 75%
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_Cmd(TIM3, ENABLE);
}
// 設定速度 0~100%
void Motor_SetSpeed(uint8_t speed) {
TIM3->CCR2 = (speed * 20); // 0-2000
}
# OpenOCD + ST-Link 除錯
openocd -f interface/stlink.cfg -f target/stm32f1x.cfg
# JLink GDB Server
JLinkGDBServer -if SWD -device STM32F103RC
# 邏輯分析儀(Saleae 協議)
sigrok-cli -d saleae-logic16 --channels 1,2,3,4 -o capture.sr
# 序列埠檢視
minicom -b 115200 -D /dev/ttyUSB0
screen /dev/ttyUSB0 115200
| 問題 | 常見原因 | 解決方案 |
|---|---|---|
| I2C 無響應 | 地址錯誤/未接上拉/SCL被佔用 | 用邏輯儀確認 SDA/SCL 波形 |
| UART 亂碼 | 波特率不匹配/電平不匹配 | 示波器檢查波特率 |
| PWM 無輸出 | 時鐘未使能/IO複用錯誤 | 檢查 TIM_EN 和 AFIO 配置 |
| 程式跑飛 | 堆疊溢位/看門狗未餵狗 | 減小堆疊/加看門狗 |
| OTA 升級失敗 | Flash 偏移地址錯誤/簽名校驗失敗 | 確認 bootloader 大小配置 |
| 低功耗電流大 | 未關閉未用外設時鐘/LDO功耗高 | 逐個停用外設定位 |
這個 Skill 質量較好,涵蓋了嵌入式開發從硬體到軟體的廣泛知識,程式碼示例豐富,常見問題整理得清晰實用,對新手和有經驗的開發者都有參考價值。不足之處在於部分領域講解得不夠深入,某些新技術和高階話題涉及較少,對於需要深入特定方向的開發者來說可能不夠解渴。適合作為入門和日常查閱的參考,但不宜作為唯一的技術來源。