ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

APM32F072RB自研板实战:CMSIS-DAP烧录与SDK移植避坑指南

APM32F072RB自研板实战:CMSIS-DAP烧录与SDK移植避坑指南 1. 为什么我选择APM32F072RB做自研板手头有一批之前画STM32F072板子剩下的物料正好看到极海APM32F072RB的引脚和STM32F072基本Pin-to-Pin兼容价格却便宜不少就动了心思干脆打一版自己的开发板顺便把CMSIS-DAP烧录链路和官方SDK完整跑一遍看看这颗国产Cortex-M0到底能不能在真实项目里顶上去。先说结论能用而且用起来比想象中顺但前提是你得知道几个关键节点在哪里。这篇就把我从画板、打样、焊接到CMSIS-DAP调试器配置、Keil环境搭建、官方SDK踩坑的全过程摊开讲重点放在那些官方文档不会写、但你不注意就会卡半天的细节上。APM32F072RB的核心规格先摆一下ARM Cortex-M0内核最高48MHz主频128KB Flash16KB SRAM封装LQFP64。外设方面带1个CAN、2个USART、2个SPI、2个I2C、1个USB 2.0全速设备接口、12位ADC、DAC、比较器基本上STM32F072有的它都有。对于做电机控制、USB HID设备、CAN节点、传感器采集这类场景这颗芯片的资源是够用的。我这次的目标很明确做一块能直接替代手头STM32F072开发板的自制板用CMSIS-DAP调试器烧录Keil MDK编译官方SDK跑通GPIO、UART、USB三个基础外设。下面按实际操作的顺序展开。2. 自制开发板的硬件设计取舍2.1 最小系统电路的几个关键决策自制板的核心是最小系统电源、晶振、复位、启动模式、调试接口。这几块看起来简单但每一块都有坑。电源部分我用了AMS1117-3.3输入5V来自USB Type-C。这里有个细节APM32F072RB的VDDA和VDD是分开的虽然官方数据手册说可以接在一起但如果你要用ADC或者DACVDDA最好单独走一个磁珠加电容滤波。我第一版图省事直接把VDDA和VDD短接结果ADC采样值跳动大概在±8个LSB后来加了磁珠和100nF1uF去耦跳动降到±2个LSB以内。这个不是玄学是模拟供电的纹波直接耦合到了ADC参考上。晶振方面APM32F072RB支持外部4-32MHz晶振我用了8MHz无源晶振配两个20pF电容。这里要注意极海的芯片对晶振的负性阻抗要求比ST稍微严格一点如果你用的晶振ESR偏高比如某些便宜的小体积晶振可能会出现起振慢甚至不起振的情况。我实测用NDK的8MHz晶振ESR 60Ω没问题但换了一个杂牌晶振ESR 120Ω就偶尔起振失败。所以选晶振时ESR尽量控制在80Ω以内。复位电路用了标准的10k上拉加100nF电容另外加了一个复位按键。启动模式BOOT0通过10k电阻下拉到地需要进Bootloader时用跳线帽拉到3.3V。这里有个容易忽略的点BOOT0的电阻不要用太大我一开始用了100k下拉结果上电瞬间BOOT0引脚被内部弱上拉拉高了一小段时间芯片进了Bootloader而不是从Flash启动。换成10k之后问题消失。调试接口我留了标准的SWD四线SWDIO、SWCLK、GND、3.3V外加一个NRST。这里建议把NRST也引出来因为CMSIS-DAP在某些情况下需要硬件复位才能连接。2.2 PCB布局中影响烧录成功率的细节PCB布局这块我踩了一个很典型的坑SWD信号线走线太长且没有包地。第一版板子SWDIO和SWCLK走了大概8cm而且旁边就是USB的差分线结果CMSIS-DAP调试器经常识别不到芯片偶尔能连上但烧录到一半就断开。后来重新布局把调试接口放在板子边缘SWD走线控制在3cm以内并且两边包地中间加了一个100Ω的串联电阻靠近芯片端。改版之后连接稳定性大幅提升连续烧录50次没有一次失败。另外如果你板子上有USB接口USB的D和D-一定要走差分对阻抗控制在90Ω左右。我第一版没注意这个USB枚举成功率大概只有70%重新走线后基本100%枚举成功。还有一个细节APM32F072RB的NRST引脚内部有弱上拉但如果你板上复位电容太大比如用了1uFCMSIS-DAP的复位信号可能驱动不够导致复位不彻底。建议复位电容用100nF不要超过220nF。3. CMSIS-DAP调试器的选型与配置3.1 为什么不用ST-Link而选CMSIS-DAP手头有ST-Link V2但APM32F072RB用ST-Link烧录时Keil会提示“Cannot access target”或者“Flash Download failed”。原因是ST-Link的固件会检查目标芯片的IDCODE而APM32F072RB的IDCODE和STM32F072不完全一致虽然都是Cortex-M0但极海有自己的ID。虽然可以通过修改Keil的FLM文件绕过但比较麻烦。CMSIS-DAP的好处是它是ARM官方定义的调试接口协议不绑定特定厂商。我用的是基于DAPLink固件的调试器某宝上十几块钱的那种Keil里选“CMSIS-DAP Debugger”就能直接用不需要额外配置。而且CMSIS-DAP支持拖拽烧录如果调试器带U盘功能量产时很方便。3.2 Keil中CMSIS-DAP的配置步骤与常见报错在Keil MDK中配置CMSIS-DAP的流程如下打开Options for Target进入Debug选项卡在Use下拉框中选择“CMSIS-DAP Debugger”点击Settings在Debug选项卡中确认Port选择“SW”Max Clock根据你的走线质量选择走线短选10MHz走线长选1MHz在Flash Download选项卡中确认Programming Algorithm里有APM32F072RB对应的Flash算法这里最常见的报错是“No Cortex-M Device found”或者“Cannot access target”。排查顺序如下先确认调试器的SWDIO、SWCLK、GND、3.3V四根线是否接对特别是3.3V不要接成5V确认目标板是否上电APM32F072RB的VDD必须在2.0-3.6V之间确认BOOT0是否为低电平从Flash启动如果以上都没问题尝试降低Max Clock到1MHz还不行的话检查NRST是否接了有些CMSIS-DAP调试器需要NRST才能连接我遇到过一个比较隐蔽的问题调试器的3.3V输出能力不足。有些便宜的CMSIS-DAP调试器3.3V输出只有100mA左右而我的板子上有LCD背光和几个LED总电流超过了200mA导致调试器一连接就掉电。后来给板子单独供电调试器只接SWDIO、SWCLK、GND三根线问题解决。提示如果你用的是带隔离的CMSIS-DAP调试器注意隔离器的供电方向有些隔离器需要目标板供电才能工作有些则需要调试器供电。接反了会导致无法连接。3.3 用CMSIS-DAP配合Keil的Flash算法配置APM32F072RB的Flash算法在极海官方SDK包里有一个FLM文件需要手动添加到Keil的Flash Download列表里。具体操作找到官方SDK包里的APM32F07x_128.FLM文件复制到Keil安装目录的ARM\Flash文件夹下在Keil的Flash Download选项卡中点击Add选择这个FLM文件确认Start地址为0x08000000Size为0x20000128KB这里有个坑极海官方SDK里的FLM文件可能有好几个版本如果你用的是旧版烧录时可能会报“Flash Download failed - Target DLL has been cancelled”。解决办法是去极海官网下载最新的SDK包用里面的FLM文件替换。另外Keil的版本也会影响。我用的Keil MDK 5.36没问题但朋友用5.28版本时CMSIS-DAP的驱动会冲突需要手动替换CMSIS-DAP.dll。建议用5.30以上版本。4. 官方SDK的结构与移植要点4.1 SDK目录结构解析与文件取舍极海官方SDK的目录结构大致如下APM32F07x_SDK/ ├── Libraries/ │ ├── CMSIS/ │ │ ├── Device/ │ │ │ └── Geehy/ │ │ │ └── APM32F07x/ │ │ │ ├── Include/ │ │ │ └── Source/ │ │ └── Include/ │ └── APM32F07x_StdPeriphDriver/ │ ├── inc/ │ └── src/ ├── Examples/ │ ├── GPIO/ │ ├── USART/ │ ├── USB/ │ └── ... └── ...实际项目里你只需要Libraries文件夹下的CMSIS和StdPeriphDriverExamples可以拿来参考但不要直接编译进去。我建议把Libraries整个复制到你的工程目录下然后在Keil里添加对应的.c文件。这里有个细节极海的StdPeriphDriver和ST的StdPeriph库API风格很像但函数名有细微差别。比如ST的GPIO_Init在极海里叫GPIO_ConfigRCC_EnableAPB2PeriphClock在极海里叫RCC_EnableAPB2PeriphClock这个倒是一样。移植ST代码时不能直接复制需要对照极海的头文件改函数名。4.2 时钟配置中的隐藏陷阱APM32F072RB的时钟树和STM32F072基本一致但有一个关键区别极海的HSI出厂校准值可能和ST不同。如果你用HSI作为PLL源需要确认HSI_VALUE宏定义是否正确。官方SDK里默认是80000008MHz但实际芯片的HSI可能有±1%的偏差。我实测用HSI跑48MHz时UART波特率误差在2%左右115200bps下偶尔会出现误码。后来换成HSE8MHz晶振作为PLL源波特率误差降到0.1%以内通信稳定。配置时钟的代码如下基于官方SDKvoid SystemClock_Config(void) { RCC_EnableHSE(); while(RCC_ReadStatusFlag(RCC_FLAG_HSERDY) RESET); RCC_EnablePLL(RCC_PLL_SOURCE_HSE, RCC_PLL_MUL_6); while(RCC_ReadStatusFlag(RCC_FLAG_PLLRDY) RESET); RCC_ConfigAHBPrescaler(RCC_SYSCLK_DIV1); RCC_ConfigAPB1Prescaler(RCC_HCLK_DIV1); RCC_EnableAHBPeriphClock(RCC_AHB_PERIPH_GPIOA | RCC_AHB_PERIPH_GPIOB | RCC_AHB_PERIPH_GPIOC); RCC_EnableAPB1PeriphClock(RCC_APB1_PERIPH_USART2); RCC_EnableAPB2PeriphClock(RCC_APB2_PERIPH_USART1); RCC_ConfigSysClk(RCC_SYSCLK_SOURCE_PLL); while(RCC_ReadStatusFlag(RCC_FLAG_PLLRDY) RESET); }注意RCC_PLL_MUL_6这个参数8MHz HSE × 6 48MHz正好是APM32F072RB的最高主频。如果你用HSI需要先RCC_EnableHSI()并等待RCC_FLAG_HSIRDY。4.3 GPIO与UART的实操配置GPIO配置和ST的StdPeriph库几乎一样但极海的GPIO_Config函数参数结构体名字是GPIO_Config_T不是ST的GPIO_InitTypeDef。下面是一个UART2的配置示例void UART2_Config(void) { GPIO_Config_T gpioConfig; USART_Config_T usartConfig; RCC_EnableAHBPeriphClock(RCC_AHB_PERIPH_GPIOA); RCC_EnableAPB1PeriphClock(RCC_APB1_PERIPH_USART2); gpioConfig.pin GPIO_PIN_2 | GPIO_PIN_3; gpioConfig.mode GPIO_MODE_AF; gpioConfig.speed GPIO_SPEED_50MHz; gpioConfig.outtype GPIO_OUT_TYPE_PP; gpioConfig.pupd GPIO_PUPD_PU; gpioConfig.af GPIO_AF_1; GPIO_Config(GPIOA, gpioConfig); usartConfig.baudRate 115200; usartConfig.wordLength USART_WORD_LEN_8B; usartConfig.stopBits USART_STOP_BIT_1; usartConfig.parity USART_PARITY_NONE; usartConfig.mode USART_MODE_TX | USART_MODE_RX; usartConfig.hardwareFlowControl USART_HARDWARE_FLOW_NONE; USART_Config(USART2, usartConfig); USART_Enable(USART2, ENABLE); }这里有个坑极海的GPIO复用功能编号AF和ST可能不同。比如PA2作为USART2_TX在ST上是AF1在极海上也是AF1但有些引脚不一样。一定要查极海的数据手册里的“Alternate Function Mapping”表不要直接照搬ST的配置。5. 烧录与调试中的典型问题排查5.1 CMSIS-DAP识别不到芯片的完整排查链路这个问题我遇到过三次每次原因都不一样。下面是我总结的排查链路第一步确认硬件连接SWDIO、SWCLK、GND、3.3V四根线是否接对目标板是否上电电压是否在2.0-3.6V之间BOOT0是否为低电平第二步确认调试器状态CMSIS-DAP调试器的指示灯是否正常通常连接成功后会常亮或闪烁在Keil的Settings里能否看到调试器序列号换一个USB口试试有些USB Hub供电不足会导致调试器工作异常第三步确认Keil配置Debug选项卡是否选了CMSIS-DAP DebuggerPort是否选了SWMax Clock是否降到了1MHzFlash Download里是否有正确的FLM文件第四步确认芯片状态芯片是否被读保护了如果之前烧录时勾选了读保护需要先解除芯片是否进入了低功耗模式如果是需要硬件复位NRST是否接了有些调试器需要NRST才能连接我遇到的最诡异的一次是调试器能识别到芯片但烧录到一半就报“Flash Download failed”。后来发现是板子上的USB差分线离SWD线太近烧录时USB枚举产生的干扰耦合到了SWCLK上。把USB线拔掉再烧录就正常了。所以如果你板子上有USB烧录时尽量拔掉USB线。5.2 Keil中查看结构体变量与堆栈溢出的技巧Keil的Debug模式下默认的Watch窗口只能看基本变量看结构体需要展开。如果你想直接看结构体的所有成员可以在Watch窗口输入结构体变量名然后右键选择“Expand”。如果结构体指针输入(*指针名)再展开。查看堆栈是否溢出Keil有一个隐藏功能在Debug模式下打开View - Analysis Windows - Call Stack可以看到当前的调用栈深度。如果栈深度接近你分配的栈大小通常在启动文件里定义比如Stack_Size EQU 0x00000400就有溢出的风险。更直接的方法是在栈的起始和结束位置填充特定值比如0xDEADBEEF运行一段时间后检查这些值是否被覆盖。我在启动文件里把栈大小从1KB改成了2KB因为USB中断加上UART中断嵌套时1KB栈确实不够用。5.3 USB外设枚举失败的几个原因APM32F072RB的USB外设和STM32F072基本一致但官方SDK里的USB库有一些细节需要注意USB时钟必须精确为48MHz如果你用HSI作为PLL源USB枚举可能会失败。建议用HSE。USB的DP和DM引脚需要配置为复用推挽输出并且要开启USB时钟。官方SDK里的USB描述符文件usb_desc.c需要根据你的VID/PID修改不要直接用默认的。我第一版USB枚举失败原因是usb_desc.c里的bMaxPower设成了100mA但我的板子实际电流超过了100mA主机拒绝枚举。改成250mA后正常。6. 从STM32F072迁移到APM32F072RB的注意事项6.1 寄存器级差异与兼容性对照虽然APM32F072RB和STM32F072 Pin-to-Pin兼容但寄存器级别有一些差异项目STM32F072APM32F072RB备注IDCODE0x1F00x1F0极海自定义ST-Link会检查CMSIS-DAP不检查HSI校准出厂校准出厂校准值可能不同建议用HSEFlash编程标准算法需要极海FLM不能直接用ST的FLMUSB库ST USB库极海USB库API风格类似但函数名不同中断向量表标准基本一致少数中断优先级不同实际迁移时如果你用的是StdPeriph库大部分代码可以直接复制但需要改函数名。如果你用的是HAL库极海也提供了HAL库版本但和ST的HAL库不完全兼容需要重新适配。6.2 官方SDK中容易忽略的宏定义官方SDK里有一个apm32f07x.h文件里面定义了很多宏其中几个容易忽略但很关键的HSE_VALUE默认8000000如果你用的晶振不是8MHz必须改HSI_VALUE默认8000000但实际可能有偏差SystemCoreClock系统主频默认48000000如果你改了时钟配置这个值也要改我遇到过一个bugUART波特率怎么算都不对后来发现SystemCoreClock还是默认的48MHz但我实际把主频降到了24MHz。改了这个宏之后波特率就正常了。7. 实测性能与稳定性数据7.1 GPIO翻转速度与中断响应时间我用示波器测了一下GPIO翻转速度在48MHz主频下用GPIO_Toggle函数翻转PA0实测频率大概在2.4MHz左右。如果直接用寄存器操作GPIOA-ODATA ^ GPIO_PIN_0可以到6MHz左右。这个速度和STM32F072基本一致。中断响应时间方面我用外部中断触发GPIO翻转从触发到中断服务函数里翻转GPIO实测延迟大概在1.2us左右。这个延迟包括中断向量取址、现场保护、函数调用等开销。对于大多数应用来说够用了。7.2 ADC采样精度与USB传输稳定性ADC方面我用12位精度、采样时间239.5周期测一个稳定的3.3V参考采样值在4090-4095之间跳动换算下来精度大概在10.5位左右。这个精度对于大多数传感器采集够用了但如果要做精密测量建议外接参考电压芯片。USB传输方面我用CDC类做了一个虚拟串口连续传输1MB数据没有出现丢包或错误。传输速度大概在800KB/s左右接近USB全速的理论上限1.2MB/s。这个表现比我之前用STM32F072的USB CDC略好一点可能是极海的USB库优化得不错。8. 个人实操心得与后续扩展方向这颗芯片我用下来最大的感受是它确实能替代STM32F072但你不能假设它和ST完全一样。几个关键点再强调一下第一调试器尽量用CMSIS-DAP不要用ST-Link。ST-Link虽然能通过修改FLM文件勉强用但稳定性不如CMSIS-DAP而且每次换芯片都要重新配置。第二晶振和复位电路的参数不要照搬ST的参考设计。极海对晶振的ESR要求更严格复位电容不要超过220nF。第三官方SDK里的宏定义一定要检查特别是HSE_VALUE、HSI_VALUE、SystemCoreClock这三个。我因为没改SystemCoreClock浪费了半天时间排查UART波特率问题。第四USB应用一定要用HSE作为时钟源HSI的精度不够枚举容易失败。后续我打算用这块板子做一个CAN转USB的适配器把APM32F072RB的CAN外设和USB外设都用上。CAN部分官方SDK里有例程但USB和CAN同时工作时中断优先级需要仔细配置不然会出现CAN接收中断被USB中断打断导致丢帧的情况。这个等我调通了再单独写一篇。如果你也在用APM32F072RB或者正在考虑从STM32F072迁移过来希望这篇能帮你少走点弯路。有什么问题欢迎在评论区交流我看到都会回。
返回列表