
1. 刚拆箱别急着焊先把这块板子的底细摸清STM32F103开发板刚到手的心情我太懂了——一块蓝色的小板子或者红色、黑色视品牌而定配一堆杜邦线、一个USB转TTL模块有的还带一块OLED屏看着就让人手痒。但你先把烙铁放下别急着往面包板上怼咱们先花十分钟把板子的底细搞清楚后面能少走两个礼拜的弯路。STM32F103是什么它是意法半导体推出的Cortex-M3内核32位微控制器主频最高72MHz。给没接触过单片机的朋友打个比方Arduino Uno是8位AVR芯片主频16MHzFlash只有32KB而F103C8T6这颗芯片是32位内核主频72MHzFlash 64KBRAM 20KB外设丰富得多——3个串口、2个SPI、2个I2C、1个USB 2.0全速接口、2个高级定时器加4个通用定时器、10个ADC通道。性能完全不在一个量级。这块板子能做什么说几个真实场景在家里做一个小鱼缸控制器监测水温、定时喂食、控制灯和循环泵做一个报站器接个喇叭和显示屏模拟公交报站做个小四轴飞控的底层验证平台给打印机加个驱动控制板做个数控机床的简易手轮面板。这些都是我在论坛和群里看到有人拿F103做出来的东西。STM32的价值就在于它像一块“万能积木”只要你学会把GPIO、定时器、串口、ADC这些外设组合起来很多点子都能落地。这篇文章给跟我一样刚把板子买回来、准备认真学STM32的朋友。我不会灌高深理论就按我自己从零学过来的路径把环境搭建、外设学习顺序、常见坑全部摊开讲全是实操验证过的经验。2. 环境搭建三板斧Keil、芯片包、固件库先上结论学STM32目前最主流的开发环境还是Keil MDK-ARM也就是常说的Keil5。虽然现在VSCode GCC OpenOCD这套组合越来越流行但考虑到资料匹配度、教程数量、调试器兼容性新手阶段用Keil5是最省心的。2.1 安装Keil5和STM32F1芯片包Keil5的安装分两步装IDE本体再装芯片支持包DFPDevice Family Pack。很多人只装了IDE就跑去新建工程结果找不到STM32F103C8就是这个原因。具体操作去Keil官网下载MDK-ARM一路Next安装即可注意安装路径别带中文。打开Pack Installer搜索STM32F1找到Keil.STM32F1xx_DFP这个包点击Install。如果在线下载慢去官网或论坛下载离线包双击即可安装。装好后新建工程在MCU选择界面搜STM32F103C8选中就能看到这颗芯片。有个常见问题Pack Installer里搜不到器件多半是网络问题或者Pack版本太旧。解决办法是手动装离线DFP包或者去Pack官网下载对应版本。另外注意只装了F4、F7的包不能编译F1程序F1必须装F1的DFP。还有个容易被忽略的点Keil5默认编译器版本可能是AC5ARMCC和AC6ARMCLANG并存新版安装包甚至默认AC6。如果你编译老工程时遇到“Variable declared inside while statement”这种错误大概率是AC5的代码丢到AC6下编译了。去Options for Target里的Target页把编译器版本切回AC5或者修改代码兼容AC6。我建议新手统一用AC5标准库工程绝大多数是按AC5写的少折腾。2.2 标准库和HAL库到底选哪个这是新手绕不开的第一个灵魂拷问。直接给建议如果你学F103是为了找工作、做项目、打基础学标准库如果你为了快速出东西、或者后续要用STM32CubeMX图形化配置工具学HAL库。为什么这么建议标准库的特点是“直接、透明”。想操作一个外设库函数就是那一条点开源码能看明白它到底改了哪个寄存器——这对理解芯片工作机制非常有帮助。HAL库封装得很深层级多、回调函数多新手很容易“会调但不知道为啥”。我在跟新人交流时问一句“HAL_UART_Transmit里面发生了什么”大部分答不上来就是这个原因。但另一方面ST官方已经停止维护标准库了新出的芯片只有HAL库。所以我的路线建议是用标准库入门F103把ARM内核和外设工作机制搞清楚之后再花几天过一遍HAL库和CubeMX去适应新项目的主流写法。这里补充一个热点话题现在不少人用VSCode搭建STM32开发环境配GCC工具链和J-Link下载。这套组合的好处是代码编辑体验好、免费、跨平台。但如果你连Keil都还没跑通先别急着上VSCode等基础打牢再换。VSCode配置STM32开发的要点无非三件事装好arm-none-eabi-gcc交叉编译器、配置好c_cpp_properties.json的include路径、写好launch.json给Cortex-Debug调试器用。其中launch.json里要指定OpenOCD路径或J-Link的GDB Server新手最容易卡在这。2.3 新建工程的正确姿势标准库新建工程说难不难但确实繁琐。直接给一套“不会出错”的流程准备标准库源码包STM32F10x Standard Peripheral Library解压后找到Project、Libraries两个文件夹。在工作目录下建三个文件夹User存放main.c等、Obj存放编译产物、List存放链接列表文件。把Libraries\CMSIS里的core_cm3.c、startup_stm32f10x_md.s注意选md中等容量对应F103C8拷进工程。把Libraries\STM32F10x_StdPeriph_Driver里的inc和src两个文件夹拷进工程。在Keil里新建工程把上述源文件按组添加启动文件组、CMSIS组、外设驱动组、用户代码组。最关键的一步在Options for Target - C/C里定义STM32F10X_MD和USE_STDPERIPH_DRIVER两个宏并把include路径全部加进去。漏定义宏的话编译会报一堆“unknown type name”错误。在Options for Target - Linker里勾选“Use Memory Layout from Target Dialog”然后在Target页设置好ROMIROM10x8000000大小0x10000和RAMIRAM10x20000000大小0x5000分别对应64KB Flash和20KB RAM。这里专门提一下.ld文件。如果你用GCC工具链VSCode那套环境链接脚本.ld文件就是分配Flash和RAM的配置文件如果用Keil虽然不直接写.ld但Target页的IROM1/IRAM1设置本质上是同一件事。很多人把RAM大小填错比如F103C8实际RAM只有20KB却填了64KB编译通过但一运行就跑飞。记住C8T6的Flash是0x1000064KB、RAM是0x500020KB别贪。提示新建工程后先别写任何代码直接编译一个空工程确认没有报错再往下走。这一步能筛掉一半的环境问题。3. 点灯只是开始GPIO和时钟是STM32的命根子3.1 时钟树不看这个后面全懵STM32和8位单片机最大的区别之一就是时钟系统。51单片机或者AVR上电就是一个内部RC时钟跑着而STM32上电后默认运行在HSI内部高速时钟8MHz想要72MHz主频就必须通过PLL锁相环去倍频。时钟树是整个芯片的“心脏电路”所有外设的时钟源都从这里分配。F103的SYSCLK最大72MHz它由HSE外部晶振一般是8MHz经过PLL倍频得到8MHz ÷ 2 × 18 72MHz。这个计算式里的每个参数在RCC配置代码中都能看到。如果你配错了PLL倍频倍数比如设成16得到64MHz时序就会乱表现为串口波特率偏、定时器定时不准。新手常犯的错是不开外设时钟。F103为了省电所有外设的时钟默认是关闭的你直接操作GPIOB的寄存器是没反应的必须先调用RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE)把时钟打开。这个“先开时钟再配外设”的思维是STM32和51单片机最本质的差异。还有个细节串口1挂在APB2上最高72MHz串口2和3挂在APB1上最高36MHz定时器2到7虽然挂在APB1上但它们的时钟频率是APB1的两倍72MHz这涉及到“TIMx倍频器”的规则。用标准库的RCC_GetClocksFreq去算波特率不会踩坑但自己手算时容易算错。3.2 GPIO配置八种模式怎么选STM32的GPIO有八种工作模式听起来多归纳一下就是四类输入浮空、上拉、下拉、模拟和输出开漏、推挽、推挽复用、开漏复用。怎么选直接给口诀驱动LED、蜂鸣器这些简单负载推挽输出GPIO_Mode_Out_PP因为推挽结构能输出较强的拉电流和灌电流。读取按键、开关信号上拉输入或下拉输入取决于按键是接GND还是接VCC。模拟信号采样ADC输入模拟输入别用数字输入模式不然采出来的值会受内部上下拉影响。USART、SPI、I2C等外设的信号引脚复用推挽输出因为引脚的控制权从GPIO模块转移到了外设模块。I2C的SDA/SCL开漏输出因为I2C协议需要“线与”功能多设备共享总线时开漏是必须的。速度选项也很关键。GPIO_Speed_2MHz、10MHz、50MHz不是“跑多快”的意思而是输出驱动器的翻转速率上限。50MHz模式下的输出压摆率大EMI辐射也大所以不是越快越好——点个LED用2MHz足够了驱动SPI屏或SD卡才需要50MHz。我见过有人把所有引脚都配成50MHz高速模式结果板子在某些环境下不稳定改回合适速度就好了。3.3 用串口把调试信息打出来如果你只学会一个调试手段那必须是串口。它的原理不复杂USART发送时把数据寄存器里的字节按配置好的波特率逐位发出去接收反之。但实际调起来你才体会到它的重要性——看变量值、定位卡死位置、打印协议数据全靠这一条线。用标准库发串口数据的代码三行就能写出来USART_InitStructure.USART_BaudRate 115200; USART_Init(USART1, USART_InitStructure); USART_SendData(USART1, ch); while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) RESET);注意USART_Init之后还有个USART_Cmd(USART1, ENABLE)千万别漏。很多人调串口发现发不出去八成是USART_Cmd没调用。串口调试的经验之谈波特率一定要和上位机一致115200、8、N、1是标配接线注意TX交叉接RX板子的TXD接USB转TTL的RXD接反了啥也没有电平必须是TTL电平别直接把板子接到RS232的DB9接口上那是±12V的电压会烧芯片。如果开发板自带USB转串口芯片比如CH340直接插USB线就行但要确认驱动装好Windows 10以上一般自动装好老系统需要手动装CH340驱动。还有一个被坑过很多次的点不要在while(1)主循环里高频发送调试信息比如每毫秒发一次。如果波特率只有9600发送一个字节就要1ms左右发送队列满了数据就丢了。正确做法是加个简单的状态机或者用DMA传输或者降低打印频率。新手先记住“调试打印频率别太高”这个原则。4. 外设逐个击破定时器、ADC、通信接口4.1 定时器延时、PWM、输入捕获一把梭STM32的定时器资源非常丰富F103C8有TIM1高级定时器、TIM2/3/4通用定时器还有两个基本定时器。定时器的本质是一个计数器它根据时钟源不断向上计数计数到设定值后触发中断或更新事件。这个机制可以干三件事第一做延时。网上看到很多“Delay函数卡死”的问题十有八九是用的循环延时for(i0;i100000;i)在优化等级不同时时间不一样或者用了SysTick延时但没配置好时钟。SysTick是ARM内核自带的24位递减计数器用标准库的SysTick_Config(SystemCoreClock / 1000)就能配成1ms中断一次的节拍在中断里维护一个计数值Delay就准了。卡死的常见原因是中断优先级没设置好或者中断服务函数里忘了清标志位。第二输出PWM。PWM就是“快速开关输出”通过调整占空比控制平均电压。TIM输出PWM的频率由预分频器PSC和自动重载值ARR决定时钟频率 ÷ (PSC1) ÷ (ARR1)。比如要输出1kHz的PWMAPB1定时器时钟72MHzPSC设71、ARR设99972MHz ÷ 72 ÷ 1000 1kHz。控制舵机一般需要50Hz也就是周期20ms对应PSC设71、ARR设为19999占空比从0.5ms到2.5ms对应0到180度。我用F103控SG90舵机就是这么配的实测很稳。第三输入捕获测频率。这个功能利用定时器的输入捕获通道记录外部信号上升沿到达时计数器的值两次捕获值相减得到周期取倒数就是频率。做超声波测距也用得上——发射超声波后记录回波引脚变高电平的时间乘以声速再除以2就是距离。超声波测距是STM32新手项目里非常经典的一个。HC-SR04模块的时序很简单给Trig引脚一个10微秒以上的高电平脉冲模块就会发射超声波同时把Echo引脚拉高直到收到回波才拉低。用定时器输入捕获或者外部中断加定时器就能测出Echo的高电平持续时间t距离 t × 340m/s ÷ 2。我实测下来HC-SR04在20cm到3米范围内精度都不错超过3米衰减明显。注意供电要用5VEcho返回的是5V电平而STM32的引脚是3.3V容忍直接接有烧引脚风险最好加分压电阻或者用电平转换模块。4.2 ADC把模拟世界数字化ADC在F103上是12位逐次逼近型16个外部通道分布在PA0-PA7、PB0-PB1等引脚上。它做的事情很简单模拟电压转数字值。12位精度意味着0~3.3V被分成4096份所以电压 ADC值 × 3.3 / 4095。用标准库采集ADC的流程开启ADC1时钟 - 配置GPIO为模拟输入 - 配置ADC1工作参数分辨率、采样周期、触发方式- 使能ADC1 - 校准 - 启动转换 - 等待转换完成 - 读取数据寄存器。这里踩过一个坑采样周期设置太短会抖动尤其是高阻抗信号源。建议把采样时间拉到239.5个周期数值稳定很多。另外注意ADC的参考电压VREF如果你的板子把VREF接到了3.3V满量程就是3.3V有些板子支持外部参考数值计算时要看清楚。“STM32鱼缸”这个项目其实就是ADC加温度传感器加继电器加串口屏的组合用DS18B20或NTC热敏电阻采集水温ADC采集水位继电器控制加热棒和循环泵再用串口屏或者OLED显示状态。F103的ADC能力对这个项目绰绰有余。4.3 串口通信进阶和ESP32、云平台联动学完USART基本收发之后就该玩点联动的了。现在很多项目都是STM32做主控、ESP32做WiFi模块两者之间用串口通信。这里就涉及通信协议的设计——不能裸发一堆0x01 0x02就完事得有个帧头、长度、校验、帧尾。我常用的简单协议是0xAA 0x55帧头 数据长度 类型 数据 CRC8校验接收端用状态机解析。热词里的“巴法云”是一个免费的物联网云平台ESP32或STM32通过HTTP或TCP把数据上报上去手机小程序就能看到。STM32本身没有WiFi所以一般是STM32把传感器数据通过串口发给ESP32ESP32再把数据POST到巴法云。这套链路看着麻烦拆开就是一个个小模块串口通信、HTTP协议、JSON解析每个都是嵌入式工程师的日常。如果要让STM32直接联网可以外挂ENC28J60或W5500以太网模块F103也能跑精简的TCP/IP协议栈。“STM32 http库”这条路就是用标准库驱动以太网控制器配合lwIP协议栈实现HTTP请求。做物联网方向的可以考虑这个方向。4.4 CAN总线为什么连不上CAN总线在工业控制领域非常重要F103的bxCAN模块支持CAN 2.0A和2.0B协议。新手用CAN最容易遇到的问题就是“为什么连不上”原因大部分出在这几处第一终端电阻没接。CAN总线两端必须有120欧终端电阻匹配阻抗否则信号反射严重根本通信不起来。很多开发板没有板载终端电阻你得在总线两端各接一个120欧。第二波特率不匹配。CAN的波特率由分频和同步跳转宽度等参数决定两端必须完全一致。标准库配置CAN的代码需要设置BS1、BS2和Prescaler计算波特率APB1时钟 ÷ Prescaler ÷ (1 BS1 BS2)。比如36MHzPrescaler4、BS16、BS23波特率就是36M ÷ 4 ÷ (163) 900kbps。第三回环测试正常但组网失败。建议先用回环模式LoopBack验证收发代码没问题再改回正常模式接总线。我踩过的坑是忘了把CAN引脚PB8、PB9配置成复用推挽输出导致引脚不干活。第四CAN_H和CAN_L接反。CAN总线的两根线必须对应好接反了也会导致收发异常。如果出现“stm32 can通信突然连不上”这种问题先查物理连接再查波特率最后查代码。5. 进阶折腾USB、屏幕、传感器5.1 让STM32变成一个USB设备“stm32如何做usb设备”是个很好的进阶方向。F103内置USB 2.0全速接口可以做成USB键盘、USB鼠标、USB虚拟串口、USB存储等设备。核心是理解USB协议栈和描述符。网上最常见的方案是ST官方的USB-FS-Device开发库配上不同的类驱动HID类做键盘鼠标CDC类做虚拟串口。HID类的好处是不用装驱动系统自带CDC类的好处是即插即用电脑里出现一个COM口。新手做USB设备建议先用现成的例程跑通把枚举过程看清楚。USB设备工作之前要先完成枚举——主机给设备发各种标准请求GET_DESCRIPTOR、SET_ADDRESS等设备依次回复设备描述符、配置描述符、接口描述符、端点描述符。这些描述符就是“USB设备的身份证”要改产品名、VID/PID都在描述符里改。之前用F103做了一个USB键盘的例子只用了HID键盘类主机识别后按键上报正常整个过程最折腾的就是描述符没写对。USB协议看着吓人但其实在HID报告描述符里定义一下按键扫描码的格式就行。如果不想从底层折腾也可以用STM32CubeMX生成一个CDC虚拟串口工程图形化配置USB时钟和端点代码量小很多。5.2 ILI9341屏幕驱动与读ID踩坑“stm32使用ili9341读id是a1a1”这个情况我太熟了——它是SPI接口屏幕的经典故障。正常情况下读ILI9341的ID应该返回0x9341读到0xA1A1或者0x0000说明SPI通信有问题。可能的坑按概率排序第一发送命令和发送数据的引脚接反。一般屏幕是DC引脚数据/命令选择接错了屏幕不会正常工作ID读出来往往是错的。先检查DC、CS、SCLK、MOSI四个线的接法。第二SPI模式配置错误。ILI9341要求SPI Mode 0CPOL0、CPHA0或者Mode 3很多例程默认Mode 0。如果用CPU的SPI外设要确认SPI_InitStructure里的SPI_CPOL和SPI_CPHA用模拟SPI的话时序写对了其实比硬件SPI更不容易踩坑。第三读ID的时序问题。ILI9341读ID要先发0xD3命令读ID4命令然后读4字节头尾字节要舍弃如果照搬了不规范的例程可能读到的就是0xA1A1这种错误值。正确的读ID流程是CS拉低 - 发0xD3 - 连续读4字节0x00 0x93 0x41 0x00取中间两位0x93 0x41就是0x9341。如果DEBUG都不需要有一种更简单的排查法不管ID对不对直接往屏幕写满屏纯色比如全部0xF800红色如果屏幕有反应说明SPI基本是通的问题只可能出在初始化序列或读ID时序上。这是从一个做屏幕驱动的老工程师那里学来的土办法实测比看寄存器快多了。5.3 超声波测距实战前面在定时器部分提过超声波测距的原理这里展开说代码层面的实现。用F103测HC-SR04的标准姿势配置一个定时器做输入捕获或者简单点用外部中断加一个计时变量。Trig引脚比如PA0配成推挽输出先拉低。给Trig一个10微秒高电平用延时函数精确控制。等待Echo引脚变高开启定时器计时。Echo变低时停止计时读出计时值。距离 计时值 × 定时器时钟周期 × 声速 ÷ 2。实际写的代码里定时器采用72MHz时钟不分频那么1个tick就是1/72微秒。如果测到Echo高电平持续了4600个tick时间就是4600 × 13.89纳秒 ≈ 63.9微秒距离约等于0.0000639 × 340 ÷ 2 ≈ 0.0109米 10.9毫米等等这里要算清楚63.9微秒 × 340米/秒 0.0217米除以2就是0.0109米约1.09厘米。这个数太小了实际中距离更远时tick数更大。比如1米距离声速来回2米时间约5.88毫秒tick数约423529个这超出了16位定时器65535的范围所以要用32位定时器或者定时器溢出计数配合。这个细节很重要——HC-SR04最远能到4米左右对应tick数可能超过16位上限要么用TIM2这种32位定时器要么在中断里做溢出计数。有两个实操细节一个是Echo高电平时间很短最小10微秒级如果用轮询方式读引脚容易错过所以要么用输入捕获、要么用外部中断另一个是测距循环里要避免阻塞比如主循环里连续测10次取平均每测一次就延时60ms因为HC-SR04不允许连续触发太频繁。注意62kHz以上的超声波在空气中衰减很快HC-SR04的40kHz探头实际有效距离在2-3米内比较可靠。超过这个距离不如换激光测距模块。5.4 方向扩展伺服电机与485通信“stm32控制伺服电机485”是工业方向的需求。伺服驱动器一般支持Modbus协议通过RS485总线控制此时STM32需要外挂一个RS485收发器比如MAX485把UART的TTL电平转成差分信号。接线是A接A、B接B半双工模式下要注意方向控制引脚——发送时拉高DE接收时拉低RE。程序上就是串口发送Modbus RTU帧地址 功能码 寄存器地址 数据 CRC16校验。这方面建议先把Modbus RTU协议看明白特别是CRC16的计算。网上有现成的查表法代码直接抄就行。用STM32标准库做Modbus主站无非就是计算好CRC、通过串口发出去、再等从站回复加上超时重发机制。做完这个其实你就已经一只脚迈进了工业控制的大门。另一个相关方向是“五线四相步进电机stm32”。五线四相步进电机用ULN2003驱动板就能带起来控制原理是给四相绕组按顺序通电比如A-B-C-D单四拍或AB-BC-CD-DA双四拍。F103只要用普通GPIO按节拍输出就行稍微复杂一点的是加减速算法梯形加减速这需要在定时器中断里动态调整步进间隔。这个项目对理解“定时器中断 状态机”非常有帮助做完了再去碰伺服485会轻松很多。6. 新人避坑手册我踩过的那些坑踩坑是学习的一部分但有些坑提前知道能省很多时间。把新手阶段最常见的几个问题整理成一份避坑清单按高频程度排序。6.1 芯片包装不上、工程编译不过Keil里搜不到STM32F1器件99%是DFP没装。手动安装离线包时要注意版本兼容某些老DFP在最新版Keil里可能报错。编译报错里最常见的是“cannot open source file stm32f10x.h”这就是include路径没加好去Options for Target - C/C - Include Paths把标准库的CMSIS和外设驱动头文件目录都加进去。还有一个经典报错是“undefined symbol RCC_APB2PeriphClockCmd”这是忘了把stm32f10x_rcc.c添加到工程里或者USE_STDPERIPH_DRIVER宏没定义。说起来都是小事但刚上手能卡一下午。6.2 JTAG引脚复用导致下载失败“stm32禁用jtag”是个大坑。PA13、PA14、PA15、PB3、PB4这几个引脚默认是JTAG调试功能如果你把它们配置成普通GPIO比如PA15做LEDPB4做按键必须先在代码里调用GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE)关闭JTAG功能只保留SWD的PA13/PA14。但问题来了一旦下载了这个配置普通下载器用JTAG方式就连不上了。解决办法很简单用SWD模式下载ST-Link或J-Link都支持SWD。如果实在只能用JTAG就按住板子的复位键在Keil里点下载等出现“Connecting”提示时马上松开复位键利用启动瞬间短暂的时间把程序烧进去——这个手法当年练了不少次。更彻底的办法是按住复位键的同时擦除整个Flash或者用串口ISP方式把Flash擦掉再重来。6.3 延时函数卡死前面提过循环延时最大的问题是不可控。如果用了SysTick延时还卡死检查这三处SysTick_Config里传入的时钟值是不是SystemCoreClock72MHz中断服务函数SysTick_Handler里有没有清标志并递减计数以及优先级分组配置有没有把SysTick优先级设得太低导致没法打断主循环。另外如果同时用了RTOS比如FreeRTOSSysTick会被RTOS占用此时Delay函数就得换成RTOS提供的延时API这个坑非常隐蔽。6.4 芯片第一脚怎么确认“stm32芯片第一脚怎么确认”这个问题看着基础但真有人搞错过。ST的LQFP封装引脚1在芯片左上角有个圆形凹点有些芯片上还有一条斜角标记。拿到芯片后把凹点对准左上角逆时针数引脚就是1到N。开发板上丝印一般也会标注但有些小厂板子丝印不清晰最好以芯片实体的圆点为准。接反电源3.3V接GND是新手最危险的错误之一轻则发烫重则烧芯片。做东西之前拿万用表蜂鸣挡测一下板子的VCC和GND之间有没有短路通电之后再量一遍电源电压这是多年养成的习惯。6.5 CAN突然连不上、SPI偶发错误这类心累问题“stm32 can通信突然连不上”这种问题大部分不是程序改动导致的而是物理层总线接触不良、终端电阻松动、线缆太长信号反射。排查时拿出示波器看CAN_H和CAN_L之间的差分信号如果波形畸形就查匹配电阻和线缆。没有示波器的话就从最简单处入手重新插拔连接器、万用表测终端电阻、检查有没有把CAN_H和CAN_L接反。SPI偶发错误则常常是时钟速率太高或者片选信号没做好去毛刺降速一档往往就稳定了。排错习惯是问题出现后先冷静三秒问自己“我最近改了哪个地方”。嵌入式调试有一条铁律——先怀疑最近改动再怀疑硬件最后才怀疑编译器。很多莫名其妙的Bug其实就是自己昨天改的一个变量类型导致的。7. 学习路线建议一个月入门到能自己做东西7.1 入门路线表把适合新手的路线整理成一张表照着走就行阶段时间学习内容验收标准第一阶段第1周环境搭建、GPIO点灯、按键输入能独立新建工程并控制LED闪烁、读取按键状态第二阶段第2周时钟系统、SysTick延时、USART串口收发能用串口与上位机交互做一个简单的PC控制台命令第三阶段第3周定时器、PWM、ADC能输出可调PWM驱动舵机能读取电位器电压并在串口显示第四阶段第4周SPI/I2C通信外接OLED屏或LCD屏、传感器能读取DS18B20温度或MPU6050姿态并显示在屏幕上这个路线的核心思路是“每个阶段都有一个看得见摸得着的成品”而不是干巴巴地学寄存器。每完成一个验收标准信心就长一分这是能给的最实在的建议。搞完四周基础你已经能看懂大部分例程了剩下的就是靠项目和需求驱动学习。7.2 进阶项目方向学完一个月的课程之后就可以考虑做项目了。建议选一个“有痛点、有交互、有数据”的题目。举几个方向智能鱼缸水温检测DS18B20、水位检测ADC、自动喂食舵机、水泵控制继电器、OLED显示。便携式报站器按键输入站点编号串口语音模块播报OLED屏显示到站信息。数控机床简易手轮用旋转编码器读取手轮转动方向和计数通过串口或CAN发给上位机。手持激光测距仪VL53L0X飞行时间传感器配合OLED屏。实验室自动滴定装置五线四相步进电机加驱动器配合限位开关做精确位置控制。“基于stm32的毕业设计”我多说一句毕设选题千万别贪大一个F103能稳定完成的题目比一个H7都跑不稳的题目得分高得多。把功能做到稳定、文档齐全、能现场演示就已经超过一半的人了。7.3 学习资源与工具推荐学STM32必备的几个东西一块F103开发板市面上常见的蓝色板或正点原子、野火的板子都可以、一个ST-Link V2下载调试器十几块钱比山寨J-Link稳、一根USB转TTL线CH340芯片那种、一套杜邦线加面包板、一个万用表、一块OLED屏I2C接口的SSD1306最适合起步。代码学习方面推荐三个路径先把标准库固件源码目录结构过一遍然后照着现成例程改最后再自己从零建一个工程。切记不要全盘复制粘贴一定要动手敲哪怕敲完发现和例程一模一样感觉也完全不同。文档方面官方《STM32F10x参考手册》是终极依据遇到奇怪问题就翻它。中文版网上有但注意别找太老的版本。数据手册也要备着查引脚定义、电气特性都用得上。8. 写在最后这块板子只是起点最后说点题外话。STM32这条路走到后面你会发现最重要的不是背住某个库函数而是建立起“看芯片数据手册、读时序图、动手调试”的底层能力。我刚拿到第一块F103板子的时候连Keil的工程都不会建但就是一天天折腾从点灯到串口从串口到定时器再到后来做USB设备、做Modbus每一步都踩过坑但每一步都实打实进步了。这块板子买回来就是成功的开始。接下来要做的就一件事打开Keil点亮你的第一颗LED。剩下的路咱们边踩坑边学。如果你在实操中遇到问题把报错信息和操作步骤发出来这板子我带不少人入门过常见问题基本都见过大概率能帮你一把。后续我还会继续写定时器、USB、RTOS这些进阶内容也都是实地跑过的。折腾STM32的队伍随时欢迎你加入。