ARTICLE DETAIL

资讯详情

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

APM32F072移植moonglow固件:从STM32到国产芯片的USB-CAN方案实践

APM32F072移植moonglow固件:从STM32到国产芯片的USB-CAN方案实践 USB-CAN模块坏了以后我第一反应是拆开看看能不能救回来。打开外壳看到主控丝印是APM32F072不是常见的STM32F072。当时手头正好有极海APM32F072的样品又想起GitHub上有moonglow这个开源的USB-CAN固件支持STM32F072平台就动了移植的心思。折腾了两天成功把moonglow固件刷进APM32F072系统稳定识别为USB-CAN设备能正常收发CAN报文。这篇文章就把完整的移植思路、修改点、踩坑过程记录下来给同样手上没有STM32但有国产替代芯片的朋友一条可参考的路径。1. USB-CAN方案复盘为什么我盯上了moonglow固件这年头搞嵌入式开发CAN总线调试基本是家常便饭。车规级产品、工业控制、电机驱动哪个都离不开CAN。写代码的时候可以用逻辑分析仪看波形但真正要跟总线上的其他节点通信还是得有一个可靠的USB-CAN转换器。市面上的USB-CAN模块价格两极分化。大牌如周立功、Kvaser动辄几百上千功能确实稳定但作为个人开发者或小团队这个成本并不低。便宜的杂牌模块几十块就能买到问题是用起来看运气有的驱动兼容性差有的收发丢包有的用一段时间就掉线。我之前那个杂牌模块就是用了不到半年就不识别了拆开一看主控丝印是APM32F072固件也没法自己刷等于直接报废。1.1 开源USB-CAN固件到底解决了什么问题moonglow是一个开源的固件项目目标是让带USB和CAN外设的MCU变成一个即插即用的USB-CAN分析工具。它实现了USB协议栈的Device端、CAN驱动、以及上位机通信协议刷进芯片之后插上电脑就会被识别成一个标准的CAN分析仪设备配合开源的PC端工具或者直接用SocketCAN操作就能完成CAN报文的收发、波特率设置、总线状态监控等操作。kvaser是CAN总线领域的老牌厂商它的硬件和软件生态非常成熟。moonglow固件在设计上参考了类kvaser设备的交互逻辑并且在Linux下可以被识别为candleLight或gs_usb设备直接纳入Linux内核的SocketCAN子系统。这意味着你不用装任何驱动插上就能用candump、cansend这些原生工具开发体验跟用Kvaser硬件基本一致。这个方案最大的意义在于你只需要一颗十几块的MCU加上一个CAN收发器芯片和USB座子就能做出一个功能不输几百块商业工具的调试设备。对于预算有限的爱好者、学生、初创团队来说这个性价比极具吸引力。1.2 移植路线评估直接烧录还是改代码最开始我抱了个侥幸心理APM32F072号称和STM32F072引脚兼容、外设兼容那是不是直接把moonglow编译出来的hex烧进去就能跑答案显然没那么简单。实际测试烧录后USB无法枚举设备管理器里压根看不到新硬件。原因在于兼容这两个字在不同场景下的含义差别太大。芯片厂商所说的兼容更多是指封装引脚定义一致、内核相同、大部分外设寄存器布局接近——但具体到时钟树配置、Flash大小、USB上拉控制位、以及部分寄存器的默认值都会有或大或小的差异。所以移植这件事不能抱着烧进去就能用的天真想法。正确的路线是先摸清两张芯片的差异点在哪再对照源代码逐个适配。好在这个工作量不算大moonglow代码结构清晰只要改对几个关键位置编译烧录就能跑起来。2. APM32F072与STM32F072的硬件差异盘点能被直接复用的与必须改动的动手改代码之前先把两个芯片的底细摸透。APM32F072是极海半导体推出的Cortex-M0内核MCU主频48MHzFlash从32KB到128KB不等RAM最多16KB。它有一个USB 2.0 Full-Speed Device控制器一个带多个FIFO的CAN控制器还带12位ADC、多个定时器和丰富通信外设。从命名和功能布局上看它对标的就是意法半导体的STM32F072系列。2.1 兼容到底兼容到什么程度引脚层面APM32F072和STM32F072的LQFP48封装确实完全对得上电源、地、晶振、下载接口位置都一样。这意味着烧录口和硬件电路直接复用不用改板子这也是我敢拿它来移植的底气。外设寄存器层面大部分功能模块的控制位很接近但并不是100%一致。以USB为例STM32F072的USB模块有一个专门的SYSCFG_CFGR1寄存器里的PA11_PA12_RMP位可以把USB_DM/USB_DP重映射到PA11/PA12之外的引脚。APM32F072的USB则没有这类重映射能力USB引脚固定挂在PA11/PA12上。这类细微差异如果不查数据手册直接用STM32的库函数去操作轻则某个功能不生效重则直接触发硬件错误。时钟树也是重灾区。STM32F072内部有一个用于USB的时钟源是HSI48频率精确为48MHz专门给USB外设提供时钟。APM32F072的USB时钟来源是HSI经过分频或倍频得到路径不同配置寄存器的含义也不同。moonglow源码里如果像操作STM32那样去使能HSI48并等待它就绪在APM32上就会卡死在超时循环里。Flash容量也要特别注意。我的APM32F072样品是64KB Flash版本而moonglow默认是按128KB Flash的映射来布局固件和Bootloader的。这导致两个问题一是编译出的固件体积可能放不下二是Bootloader和App各自的Flash区域划分必须根据实际容量重新计算否则Bootloader跳转App时会跳到错误地址表现为烧录提示成功但上电没反应。2.2 外设复用与中断映射的对比APM32F072的CAN控制器和STM32F072一样都挂载在APB1总线上引脚默认从PA11(CAN_RX)/PA12(CAN_TX)引出。但这里有个致命冲突USB也默认占用PA11/PA12。所以正常设计下USB-CAN设备必须把CAN引脚重映射出去。STM32F072解决这个冲突的方式是通过SYSCFG重映射把CAN引脚从PA11/PA12换到PB8/CAN_TX和PB9/CAN_RX或者换到其他组合。APM32F072同样需要重映射操作但重映射寄存器的位置和位定义跟STM32不一样必须查极海的参考手册不能拿着STM32的寄存器地址直接写。中断部分CAN的RX中断在STM32F072上是USB_LP_CAN_RX0_IRQn这是一个复合中断号USB低优先级中断和CAN接收中断共用同一个入口。APM32F072虽然也把USB和CAN的中断放在了一起但中断向量表的排列顺序、IRQ number的定义有差异直接编译STM32的启动文件会出问题。3. 编译环境搭建与固件源码梳理移植的第一步是先把工程在本地编译通过。这里说的是moonglow官方仓库的源码下载下来之后目录结构大致是这样的bootloader/独立的引导程序负责任务启动时的固件更新。firmware/主要的应用固件代码。lib/依赖的底层驱动库和USB协议栈。Makefile顶层构建脚本。3.1 工具链选择与工程配置项目基于Makefile构建没有用到IDE这是好事也是门槛。好事在于只要你装了交叉编译工具链在任何系统上都能编译门槛在于你得自己装工具链。以Linux环境为例需要安装的是arm-none-eabi-gcc。如果用的是Ubuntu系发行版直接sudo apt install gcc-arm-none-eabi make如果是Windows可以直接安装ARM官方提供的GNU Arm Embedded Toolchain把bin目录加入PATH即可。工具链装好之后进入firmware目录直接执行make。第一次编译大概率会报错常见的几个原因我在后面踩坑部分统一说。如果代码没有任何改动理论上应该能编译出firmware.bin和firmware.hex两个烧录文件。3.2 源码里必须重点读的几个文件虽然目标是能跑起来但你不能瞎改。必须对源码结构有个基本认知尤其是以下几个部分usb_descriptor.cUSB描述符的定义。PID、VID、设备名字符串都在这里大概率要改。can.cCAN外设初始化、收发逻辑的核心。main.c主循环负责把USB和CAN两个外设的数据交互串起来。system_stm32f0xx.c时钟初始化。注意它虽然名叫stm32但里面如果调用了STM32特定的时钟配置函数就必须针对APM32改。linker script通常是.ld文件定义了Flash和RAM的地址布局。64KB和128KB的芯片用的脚本不一样。moonglow有一个很重要的设计它包含了一个独立的bootloader。Bootloader在Flash的前半段App固件在后半段。这样设计的好处是后续固件升级时不用接调试器可以用USB直接刷写类似IAP。坏处是两段程序需要共享Flash空间如果你的芯片是64KB留给App的空间就比较紧张。我最后的选择是放弃Bootloader直接刷App固件到Flash起始地址0x08000000。原因后面细说。3.3 第一次编译先让工程跑起来别急着改代码先原样编译一次。这一步的意义在于确认你的工具链没问题源码没有依赖遗漏。我当时的经验是直接编译可以通过生成的bin文件大约60多KB放进64KB Flash会超一点需要优化。如果你看到链接错误提示region FLASH overflowed就说明Flash放不下。不用慌这是正常的后面缩小固件体积就好。4. 逐个击破的移植修改点时钟、USB、CAN与引脚定义如果一切顺利你现在已经能做一次原样编译接下来就是动真格的时候。按照影响系统的优先级我从时钟开始讲。4.1 系统时钟初始化USB 48MHz从哪里来这是整个移植里最容易卡住的一步。moonglow的时钟初始化代码来自STM32标准外设库的SystemInit函数。在STM32F072中它的逻辑是使能HSI8MHz内部时钟然后配置PLL把PLL输出设为48MHz同时使能HSI48专门给USB用。在STM32F072上HSI48是一个独立时钟源专为USB设计通过RCC_CR2寄存器控制。APM32F072没有HSI48这个概念。它只有一个HSI8MHzUSB的48MHz时钟来自HSI经过PLL倍频后从PLL的专用输出通道引出。换句话说USB设备时钟和系统主时钟是同一个PLL的不同输出。具体到我做的配置是让系统主频跑到48MHzUSB时钟也复用同一份配置。用极海的SDK函数重写时钟初始化部分后关键代码如下void SystemInit(void) { /* 使能HSI */ RCC_HSI_Enable(); /* 等待HSI就绪 */ while (RCC_HSI_IsReady() RESET); /* 配置PLL8MHz * 6 48MHz */ RCC_PLL_Config(RCC_PLLSOURCE_HSI, RCC_PLL_MUL6); RCC_PLL_Enable(); while (RCC_PLL_IsReady() RESET); /* 系统时钟切换到PLL */ RCC_SYSCLK_Config(RCC_SYSCLKSOURCE_PLLCLK); while (RCC_GetSYSCLKSource() ! RCC_SYSCLKSOURCE_PLLCLK); /* 使能USB时钟 */ RCC_USB_CLK_Enable(); }注意PLL倍频系数是6不是STM32典型的9。因为APM32F072的PLL输入是8MHz倍频6得到48MHz这个频率既能满足USB需求也能让系统主频达标一举两得。4.2 USB描述符与VID/PID调整时钟打通之后USB才能开始工作。但USB描述符不改的话电脑识别出来的设备名字、厂商信息都不对。打开usb_descriptor.c找到设备描述符和字符串描述符的定义。你可以保留moonglow默认的VID/PID比如VID0x1d50OpenMokoPID0x606fCANable这个组合在Linux下会被识别为gs_usb设备直接就能用SocketCAN操作堪称免驱神组合。如果你追求插上电脑显示自定义名字可以修改字符串描述符里的厂商名和产品名。我改成了自己的英文ID和USB-CAN Analyzer这个名字。注意字符串描述符是UTF-16LE编码直接写ASCII字符串到源码里可能会乱码建议用十六进制字节数组来定义。4.3 CAN引脚重映射与GPIO配置系统时钟和USB描述符搞定后接下来是最容易踩坑的CAN引脚配置。moonglow默认的CAN引脚在STM32F072上是PB8/PB9。这个配置的原理前面说过USB占用了默认的PA11/PA12所以CAN必须挪窝。在STM32上这个重映射是通过SYSCFG-CFGR1的CAN_RMP位来设置。到了APM32F072这里重映射的寄存器存在但位的位置可能不一样。极海的参考手册里这个功能位于SYSCFG模块的某个配置寄存器中具体偏移和位定义要对着手册查。我当时琢磨了很久发现极海其实提供了一套完整的固件库函数其中就有GPIO_PinRemapConfig这类封装直接用库函数要比翻寄存器省心得多。/* 使能CAN和GPIO时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2_PERIPH_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1_PERIPH_CAN, ENABLE); /* 重映射CAN到PB8/PB9 */ GPIO_PinRemapConfig(GPIO_REMAP_CAN, ENABLE); /* 配置PB8为CAN_RX上拉输入PB9为CAN_TX复用推挽输出 */ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU; GPIO_Init(GPIOB, GPIO_InitStructure);如果你的板子硬件上把CAN收发器接到了别的引脚组合比如PA5/PA6这类有些DIY板子为了布线方便会这么干那么重映射配置和GPIO初始化都要跟着换。判断方法很简单看原理图上CAN收发器的TXD/RXD接到了MCU的哪两个引脚。4.4 中断优先级与NVIC配置CAN收发数据是中断驱动的。CAN接收中断在APM32F072上对应的是USB_LP_CAN_RX0_IRQn名字跟STM32一致但中断优先级分组方式可能不同。这里有一个常见的坑如果代码里使能了CAN接收中断但是忘记在NVIC里配置中断优先级那么中断永远不会触发现象是CAN发送正常因为发送是轮询的但接收永远是空的。一个简单的NVIC配置示例NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel USB_LP_CAN_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority 0; NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; NVIC_Init(NVIC_InitStructure);4.5 编译链接阶段链接脚本与Flash分区如果你跟我一样用的是64KB版本APM32F072那么链接脚本一定要改。默认的moonglow链接脚本假设Flash是128KB并且给Bootloader预留了空间。如果直接烧到64KB芯片上轻则编译超容量重则烧录后跑飞。我的做法是删除BootloaderApp直接从0x08000000开始放。修改链接脚本中的FLASH区域长度MEMORY { FLASH (rx) : ORIGIN 0x08000000, LENGTH 64K RAM (rwx) : ORIGIN 0x20000000, LENGTH 16K }同时要确保代码里没有引用Bootloader相关的Flash地址操作。这里必须提个醒如果你修改了Flash起始地址但代码里还保持着从0x08000000处读固件版本号或从Flash固定地址读配置的逻辑那就得同步改否则程序能跑但功能异常非常容易让人误判为硬件问题。4.6 缩小固件体积的具体招数64KB的Flash装一个带USB协议栈和CAN驱动的固件理论上是有余量的但前提是别开优化等级为-O0。把Makefile里的优化选项从-O0改成-Os优化体积能减少约20%~30%的固件体积。如果你还嫌大可以关掉固件里用不到的调试打印功能这类功能在嵌入式项目里往往是体积大户。编译成功后用arm-none-eabi-size查看一下固件大小只要不超过64KB就可以放心烧录。5. 烧录验证从BOOT配置到实际收发CAN报文软件部分改完终于到了烧录验证阶段。这里既有坑也有惊喜。5.1 烧录方式与BOOT引脚设置APM32F072支持SWD调试接口和串口ISP烧录。我手头有ST-Link和J-Link但APM32F072的SWD协议与ST-Link兼容性不错直接用ST-Link就能连上。如果你没有调试器也可以用串口ISP。先把BOOT0引脚拉高到3.3V然后复位芯片芯片就会进入Bootloader模式此时通过串口1PA9/PA10就能用原厂的烧录工具下载固件。烧完之后BOOT0拉低复位即可运行。烧录App固件时我建议用ST-Link直接烧录到0x08000000地址。如果你选择不刷Bootloader这个地址就是全部Flash的起点。5.2 USB枚举验证与设备识别烧录完成后先别急着接CAN总线先用USB线把设备连接到电脑。Linux下直接执行dmesg | tail如果能看到类似这样的信息usb 1-1: New USB device found, idVendor1d50, idProduct606f usb 1-1: New USB device strings: Mfr1, Product2, SerialNumber0 usb 1-1: Product: USB-CAN Analyzer cdc_acm 1-1:1.0: ttyACM0: USB ACM device说明USB枚举成功系统把设备识别成了标准USB设备。如果你改了VID/PID这里显示的就是你自定义的值。Windows下打开设备管理器如果看到通用串行总线设备或者端口下面出现新设备且没有黄色感叹号说明驱动安装成功。moonglow设备在Windows下会被识别为COM口设备可以直接用串口助手发AT指令测试如果你的固件实现了AT命令集。5.3 CAN回环测试与总线实测USB枚举正常只是第一步我们要的是能收发CAN报文。如果硬件板上有CAN收发器先别接入真实总线跑一次回环测试最稳妥。把CAN控制器的回环模式打开寄存器里有个SILM静默和LBKM回环位然后自发自收。回环测试通过说明CAN控制器本身配置没问题问题只会出现在外部收发器或线束上。回环测试的方法可以在PC端工具或Linux SocketCAN里直接操作。在Linux下把USB-CAN设备接入SocketCAN子系统sudo ip link set can0 up type can bitrate 500000 candump can0 cansend can0 123#DEADBEEF如果candump收到了自己发的123#DEADBEEF说明CAN收发路径完全打通。回环没问题后把设备接入真实总线。注意终端电阻CAN总线两端必须各有一个120欧姆终端电阻否则信号反射会导致报文错误。很多新手把设备并联到总线上却没注意终端电阻结果通信总是不稳定一个个排查到最后才发现是匹配电阻问题。6. 移植过程中的典型故障完整排查链路与最终处理移植过程不可能一帆风顺。我遇到的几个坑具有一定的代表性这里完整复盘一下希望能帮你省掉几个小时的排查时间。6.1 故障一USB枚举不到设备现象刷完固件插上电脑lsusb看不到任何新设备dmesg也没有任何输出。排查过程先量USB D引脚电平。正常情况下上电后D应该被拉高Full-Speed设备的上拉特征这是USB主机检测到设备插入的依据。用示波器或万用表量到D一直是低电平说明USB内部上拉电阻没有使能。查代码里的USB初始化流程发现固件在系统初始化时调用了USB连接配置函数但它在等待某个时钟标志位置位时超时退出导致后面的步骤没执行。再查这个时钟标志位发现它正是HSI48的就绪标志。而APM32F072压根没有HSI48它需要从PLL输出引时钟到USB所以这个标志位永远不会置位。解决重写系统时钟初始化把USB时钟配置从等待HSI48就绪改为等待PLL就绪后直接使能USB时钟。问题随之解决D正常拉高系统枚举成功。这个坑的教训是芯片兼容不等于代码兼容凡是涉及系统时钟和低层时钟源的代码必须查手册确认。6.2 故障二CAN报文发送失败现象USB枚举成功上位机工具里配置好波特率发送CAN报文但一直返回发送失败。CAN总线也监测不到任何波形。排查过程先用回环模式测试。回环模式并没有经过外部收发器而是CAN控制器内部逻辑直接回环。回环模式下发送成功说明CAN控制器本身没毛病。那么问题就出在外部收发器通路或引脚配置。用万用表量CAN_TX引脚和CAN_RX引脚的电压发现CAN_TX没有波形。查看GPIO配置发现CAN_TX引脚被配置成了普通推挽输出而不是复用功能推挽输出。在STM32和APM32上外设引脚必须配置为复用模式AF模式外设信号才能从引脚输出。标准库函数里两个模式都有改成一模一样就能用但代码里有一处初始化的顺序问题导致复用功能被后覆盖了。重新初始化GPIO为复用模式报文正常发出。这个坑的教训是GPIO复用配置的优先级和顺序容易被忽视尤其是在标准外设库风格的代码中多个外设初始化时后执行的GPIO配置可能会把前一个外设的引脚配置覆盖掉务必检查初始化顺序。6.3 故障三通信速率异常现象设备能枚举CAN报文能收发但上位机上配置500K波特率实际却跟总线上的其他节点对不上整车通信失败。排查过程这个问题的根源几乎可以肯定是CAN控制器的波特率分频配置。CAN波特率的计算公式是波特率 外设时钟 / (预分频器值 * (同步段 传播段 相位段1 相位段2))STM32F072的CAN外设时钟来自APB1APB1时钟最大36MHz芯片跑48MHz时APB1分配器需要设为2。如果代码里直接用了STM32的默认配置假设APB1也是48MHz不分频但实际上APM32F072的APB1分频器在PLL输出48MHz后默认是1分频也就是APB1是48MHz。如果把APB1当成36MHz来计算分频值算出来的波特率就会偏离目标值15%左右。解决方式确认APB1时钟频率重新计算CAN预分频值和时间段参数写进CAN初始化结构体。你说为什么回环测试没发现问题因为回环模式是环路自测收发双方用的是同一个CAN控制器哪怕波特率不对只要收发参数一致还能勉强通信。一旦接入真正的总线与别的节点通信波特率偏差就暴露了。6.4 顺带说说移植的边界思维很多人遇到芯片型号不同第一反应是直接烧写试试。这在引脚完全兼容的情况下确实可以快速验证却容易踩到时钟、外设映射这类隐性差异的坑。我的建议是第一步快速验证直接烧录原版固件看能否枚举USB这能在5分钟内判断福气和运气。第二步仔细对手册如果第一步失败不要急着怀疑芯片是坏的先查时钟配置再查外设映射。第三步稳定复现跑一遍完整的收发测试并且接上真实总线或用另外一台设备对测别只依赖回环测试。7. 再往下走这套固件还能怎么玩移植成功只是开始。仔细想想这个项目可以延伸出很多有价值的玩法不然就浪费了APM32F072这个芯片和moonglow固件这套还不错的组合。7.1 把这套方案做成量产产品如果你只是想给自己做一个调试工具那移植到这里就算彻底完成了。但如果想把它做成小批量产品比如公司内部用甚至小规模售卖那有几个点需要补全外壳与结构PCB板卡尺寸、USB座位置、CAN接口的接线方式要做成方便用户使用的成品需要重新规划。CAN收发器的选型常见的是TJA1050/TJA1042工业级可以用带隔离的CAN收发器比如CTM1050模块带电隔离抗干扰能力更强也更安全。固件升级通道除了SWD想办法把USB IAP跑通。moonglow的Bootloader就支持这个能力我在64KB Flash上放弃了它但如果你用的是128KB版本芯片强烈建议把它玩起来后续升级就完全不用拆壳子接调试器了。7.2 拿去对接其他开源生态moonglow设备在Linux下是标准的gs_usb设备可以直接接入Linux的SocketCAN生态。这意味着你可以在树莓派、Jetson Nano这类Linux开发板上把它当作一个原生CAN接口使用跑candump、cansend、can-utils甚至直接跑AVB/ROS2的CAN驱动。Windows下也有WinUSB API或者canable相关工具可用。如果你自己写上位机有一个开源的协议文档可以参考实现自定义的控制面板并不难。甚至有人把moonglow固件刷进设备后配合开源的CANopen协议栈直接把它变成了一个USB-CANopen调试工具。7.3 往其他芯片上移植的通用思路这次踩完APM32F072的坑我心里对换芯片移植固件这件事有了更清晰的路线图。如果你的需求场景中主控芯片换成了别的型号比如AT32F413、GD32F303或者STM32F103那么移植思路是通用的核对硬件外设资源USB、CAN、GPIO、时钟源是否齐全引脚是否有冲突。梳理时钟树USB和CAN各自需要多大的时钟从哪个PLL输出得到。替换低层驱动把标准外设库函数换成对应芯片厂商的SDK函数不要试图跨厂商直接复用寄存器操作除非你有十足把握。调整中断向量IRQ编号、中断优先级分组、ISR入口函数名都要与芯片一致。仔细核对链接脚本Flash和RAM容量、Bootloader和App的地址分配。验证连接先用回环测CAN再用USB枚举测USB最后用真实总线全流程验证。按这个思路换芯片其实没有想象中那么玄乎。真正的门槛不是什么高深的技术而是仔细对照手册这个老生常谈但永远有人跳过的步骤。有一点我说下个人体会刷固件之前最好先确认手上芯片的具体型号后缀Flash多大、是F072还是更精简的F042核。有些标称F072的芯片实际Flash只有32KB那移植路径就完全不同了。用st-info --probe或者J-Flash读一下芯片ID和Flash大小是最稳妥的一步。APM32F072能用我觉得其他类似国产芯片也大有可为。如果你手头也有同方案或者打算做USB-CAN欢迎交流。
返回列表