ARTICLE DETAIL

资讯详情

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

从STM32F103到AT32F403A的嵌入式移植实战笔记

从STM32F103到AT32F403A的嵌入式移植实战笔记 1. 为什么我会从STM32F103换到AT32F403A近两年做几个带屏显和通信的产品主力芯片一直是STM32F103系列。说实话这颗芯片确实皮实耐用资料多、生态成熟哪怕是刚入门的新手网上随便一搜都能找到完整例程。但是做产品不是搞学习板成本、供货、性能这几个因素一旦叠加起来F103的优势就没有那么绝对了。先说说我换芯片的具体背景。当时手头有一个项目需要同时跑1.5寸TFT屏幕刷新、两路UART串口通信其中一路是GPS数据解析波特率115200数据量还不小、一路SPI接口的外部ADC采样外加一个定时器输出PWM控制加热器。功能不算复杂但逻辑耦合比较重在F103上跑起来总有些捉襟见肘的感觉——倒不是说跑不动而是CPU占用率动不动就飙到60%以上后续想加功能就得精打细算。后来朋友推荐了雅特力的AT32F403A说这颗芯片性价比很高主频能跑到240MHzFlash执行速度也快关键是引脚和F103高度兼容。于是我就拿了一颗AT32F403AVGT7来试水做了个小批量验证。整趟移植下来从最初的半信半疑到后面的“真香”中间确实踩了不少坑也实实在在体会到了一些F103给不了的爽快感。这篇笔记我会把整个移植过程完整记录下来包括芯片选型对比、工程迁移步骤、外设驱动适配、踩坑记录和性能收益尽量写得实操一点。如果你也在纠结要不要从F103换到AT32或者已经在迁移路上遇到问题这篇内容应该能帮你省不少时间。2. 移植前的硬件与选型分析2.1 AT32F403A和STM32F103的核心差异很多人刚开始接触AT32的时候第一反应是“这不就是国产ST吗”。从引脚定义和寄存器结构来看AT32F403A确实做了大量兼容设计但它并不是F103的简单仿制内部架构差别还是很大的。我整理了一张对比表列出两颗芯片的关键差异点对比项STM32F103以F103VET6为例AT32F403A以AT32F403AVGT7为例最高主频72MHz240MHzFlash容量512KB256KB另有403ACV系列支持大容量SRAM64KB96KB内核Cortex-M3Cortex-M4带FPUFlash加速普通预取内置Flash读加速单元工作电压2.0~3.6V2.6~3.6V独立运放无有部分型号USBFS DeviceFS Device OTG价格参考中高明显更低最核心的差异是主频。F103锁在72MHz而AT32F403A可以跑到240MHz这意味着CPU算力直接翻了三倍还多。刚开始我觉得这颗芯片内部肯定有大坑不然怎么敢标这么高主频后来查了架构资料才发现AT32F403A的Flash读取不是简单的预取缓存而是有个独立的读加速单元可以做到Flash零等待执行所以跑高频时不用像F103那样等着Flash取指。还有一个容易忽略的点AT32F403A的内核是Cortex-M4带了硬件FPU。如果你的代码里有浮点运算比如PID控制、传感器数据滤波用M4的FPU计算速度会有数量级提升。这就不仅仅是“够用”了而是“好用”了。2.2 引脚兼容性到底有多高我最初换芯片最担心的就是引脚兼容性——如果PCB得重画那整个迁移成本就太大了。实测下来常规的LQFP100、LQFP64封装AT32F403A的引脚定义和F103基本上是通用的大多数功能引脚号都能对上。以我用LQFP100封装的经验来说把F103VET6的板子直接把芯片换成AT32F403AVGT7焊接完就能用。但有几个地方需要特别注意电源引脚部分AT32的VDD范围要确认是否在你的供电范围内3.3V系统没有问题。BOOT引脚逻辑上兼容但上拉下拉电阻的推荐值不同我建议仔细看下AT32的AN003说明。OSC32K引脚如果接的是32768晶振AT32F403A用了内部低速时钟校准后会有些差异后面我会细说。我第一版验证板就是直接在原有F103的PCB上换了芯片顺带改了几路电源滤波电容的容值总共改动不到10个器件能跑起来。这个兼容性确实做得可以。2.3 开发环境的重新搭建AT32的开发环境支持Keil MDK、IAR、GCC。我用的是Keil MDK步骤很简单去雅特力官网at32官网下载AT32F403A/403AC的固件库包含标准外设库和例程包然后安装Device Pack就能在Keil里看到AT32F403A的器件选项了。建议把官网的AT32F403A_StdPeriph_Lib整个下载下来里面不仅包含标准外设库还有一个充满示例代码的Project文件夹。USB虚拟串口例程、CAN通信例程、SPI DMA例程都是现成的移植的时候直接参考比自己摸黑写强太多。这里有个小经验Keil安装完器件支持包后记得在魔术棒Options for Target里把Device选中为AT32F403AVGT7在Target标签页里选择正确的芯片型号这样编译链接脚本才会自动选对。3. 工程迁移的核心步骤与操作细节3.1 从STM32标准库到AT32固件库的适配思路我原来的工程是基于STM32F103标准库写的没错就是那个经典的StdPeriph_Lib不是HAL库。从ST标准库切到AT32标准库表面上看起来API名字很像但实际改的时候不能想当然因为很多函数的参数定义、结构体成员、寄存器位定义都有细微差别。这次移植我没有用逐行替换的方式而是采取了一个比较有效的思路先确认功能模块清单把UART、SPI、I2C、TIM、ADC、GPIO用到的接口全部列出来。对照AT32固件库里对应的外设驱动文件逐个检查函数原型和参数定义。建立一个统一的外设封装层把应用层代码和底层芯片驱动剥离开。前两步是这个项目里必做的工作第三步是我吃过亏之后总结出来的。如果你的代码只是demo级直接改驱动层调用就行但如果是完整产品代码强烈建议加一层封装不然后续芯片型号再变或者ST库版本再升级又是一把辛酸泪。3.2 启动文件、链接脚本和时钟树配置是重头戏从F103工程切到AT32不是简单换一个Device就完事。整个底层启动过程差别很大主要体现在启动文件、链接脚本和时钟配置三个方面。启动文件ST的F103用的是startup_stm32f10x_hd.sAT32F403A要用startup_at32f403a_7.s记得确认自己的Flash容量和封装对应哪个启动文件这里有坑选错会莫名其妙跑飞。中断向量表名字也有变化比如SysTick异常向量的命名风格不同汇编文件里做好区分就行。链接脚本Keil里按Device自动生成就好了不用手改但要额外注意Flash和RAM的大小设置是否和实际芯片型号匹配。时钟树配置这里是重头戏。F103的外部高速时钟HSE默认配8MHz晶振系统时钟最高72MHz。AT32F403A的时钟树结构复杂一些我用的是8MHz外部晶振配合PLL倍频到240MHz。AT32的PLL配置寄存器有很多细分参数除了倍频系数还有分频系数、PLL范围选择等。固件库提供了plm_clock_setup函数可以参考例程直接用。我在调试时钟的时候踩过一个坑AT32F403A的PLL配置允许的倍频范围和F103不一样F103的倍频系数写习惯了直接照抄结果系统时钟实际只有80MHz后面的通信、定时全不对。排查了很久才发现是PLL配置超出了芯片要求的范围导致PLL工作异常。后来我重新按照AT32例程里的参数一步步设置并用SystemCoreClock变量打印出来确认是240MHz后才继续往下走。3.3 GPIO和基础外设的迁移比想象中简单GPIO是最基础的部分也是移植量最大的部分。F103标准库里的GPIO_InitTypeDef和AT32固件库里的gpio_init_type结构体成员基本一致只是有些模式Mode的枚举值不同。我建议直接全局搜索替换关键函数名然后编译看报错再逐一修正参数。大致对应关系如下GPIO_Init→gpio_initGPIO_WriteBit→gpio_bits_writeGPIO_ReadInputDataBit→gpio_input_data_bit_read不过要注意函数前缀虽然像但GPIO模式定义比如复用推挽、开漏最好对照头文件确认一遍别上来就编译通过就以为完事了。时序上有时候会和你预想不一样得测试确认。3.4 UART串口和DMA中断接收发送适配这块是很多工程师换芯片后最头疼的地方因为串口通信涉及中断、DMA通道、空闲帧检测等多个环节任何一个没对应上通信就乱套。先说基础串口配置。AT32F403A的UARTUSART外设库函数和ST标准库相似程度很高初始化结构体名字从USART_InitTypeDef变成了usart_init_type但成员含义基本一致。串口参数设置这块迁移成本不大。真正需要仔细改的是DMA部分。AT32F403A的DMA控制器虽然也叫DMA但通道映射和F103有区别。F103里USART1_TX固定在DMA1_Channel4USART1_RX固定在DMA1_Channel5AT32F403A的DMA通道分配不是和F103一一对应的必须查数据手册的DMA请求映射表。我一开始没仔细查直接把F103的DMA通道号搬过去了结果串口上位机收不到数据最后翻了AT32的参考手册才搞定。UART的DMA中断接收发送通信这块我建议直接参考AT32固件库自带的USART_DMA例程。AT32的例程里给了非常完整的中断处理逻辑包括空闲帧IDLE中断检测一帧数据接收完毕、DMA传输完成中断处理以及发送完的清除逻辑。实测下来稳定性很不错115200波特率下长时间跑数据不丢包。3.5 SPI通过DMA方式读取外部芯片数据项目中用到了一路SPI接口连接外部ADC类似AD7190做数据采集。F103上我用的是硬件SPI配合DMA传输移植到AT32后SPI的功能接口变化不大但有几个细节需要特别注意。SPI1/SPI2的引脚映射基本兼容我用的PA5、PA6、PA7三个脚AT32F403A和F103定义的复用功能一致直接配置即可。SPI初始化结构体里SPI_CPOL、SPI_CPHA这些参数定义是一样的照搬没问题。DMA这块又是个坑。F103的SPI1_RX在DMA1_Channel2SPI1_TX在DMA1_Channel3AT32F403A的SPI1 DMA请求映射到了DMA1的不同通道需要查表确认。我建议直接用AT32固件库里的DMA通道宏定义不要硬编码数字通道号这样就算映射不同也能在编译期看出来。另外一个非常关键的点是SPI通信速率的调整。因为AT32F403A的主频大幅提高SPI外设时钟源的选择要和分频系数配合好不然SPI时钟频率可能超出从机芯片的最大允许值。比如AD7190的最大SCLK频率是5MHz你的SPI时钟必须分频后低于这个值。在F103上PCLK1最大36MHz分频系数选8就是4.5MHz到AT32上如果PCLK1能跑到60MHz以上还选分频系数8就变成7.5MHz这会直接超出ADC的时序要求。这个一定要在移植后实测SCLK波形确认。3.6 定时器PWM输出、I2C和内部温度采集注意点定时器PWM这块我原先用的TIM3输出两路PWM来控制加热器。AT32的定时器外设兼容性出奇地好TIM初始化结构体和F103基本一致PWM模式、极性、比较值设置都能直接对应改起来非常轻松。唯一注意的就是定时器时钟源频率变了所以PWM输出频率需要重新校准——比如目标20kHz的PWM重算ARR和CCR的值别直接沿用老参数。I2C这一块的迁移体验比较复杂。F103标准库的硬I2C在社区里口碑不太好很多人都劝用软件模拟I2C。我原来的老项目里就是用的软件模拟I2C读取MLX90614红外测温芯片所以移植到AT32时这部分反而最简单IO配置换一下就完事。后来我尝试在AT32上用硬件I2C发现它的I2C外设是重新设计过的带超时检测和错误中断稳定性比F103的硬I2C好很多。如果你是从F103过来的人我强烈建议在AT32上重新评估一下硬件I2C说不定能省掉一个软件模拟的负担。内部温度采集在F103上说实话精度一般我只用来做参考。AT32F403A也有内部温度传感器代码逻辑差不多通过ADC的通道17采样。值得注意的是AT32的温度传感器校准值和ST不同数据手册有专门说明直接换算温度时要用AT32的公式参数。4. 移植过程中踩过的坑和排查思路4.1 踩坑记录从启动失败到外设Deadlock整个移植过程不是一帆风顺的我踩了几个印象很深的坑这里记录下来希望能帮你绕过去。第一个坑启动文件选错导致上电跑飞。这属于最底层的错误。AT32F403AVGT7是256KB Flash我却选了403A_4512KB版本的启动文件结果上电后程序莫名跑飞调试器都连不上。后来把所有启动文件挨个试了一遍才发现容量版本和启动文件不匹配会导致异常。后来我直接到官网核对型号后缀确认是VGT7后选对启动文件。第二个坑PLL配置不完全导致USB枚举失败。USB虚拟串口这个功能是我项目里较早调的部分。F103时代我用官方USB V4.0库改的虚拟串口在AT32上想沿用F103的USB枚举逻辑结果设备插上电脑后一直提示“无法识别的USB设备”。排查了一整天最后定位到原因是系统时钟不是标准的240MHz导致USB外设需要的48MHz时钟产生了偏差。也就是说PLL配置中的USB时钟分频设置错误48MHz不准确USB枚举自然失败。这个问题的排查思路很简单先检查时钟树用示波器量MCO引脚输出的系统时钟频率确认主频正确后再去调试USB。第三个坑AT32的DMA中断标志清除方式不同。原来的F103代码里DMA传输完成中断的清除方式是读SR寄存器后写CR清除这套写法在ST标准库上用了好多年没啥问题。但AT32的DMA控制器中断标志清除逻辑有变化如果沿用老写法会陷入中断反复触发或者清不掉标志的怪圈。我当时UART DMA接收一进中断就死循环怀疑是标志位没清干净。后来对比AT32的例程才发现它用的是显式的DMA_ClearInterruptFlag需要单独调用中断标志清除函数。这个改动虽然小但极其关键。第四个坑外部中断线映射的差异。外部中断/事件控制器在F103上每条EXTI线对应一个IO口比如EXTI0只能挂在PA0/PB0/PC0中的一个但AT32F403A的EXTI配置略有不同。我有个按键扫描是EXti中断唤醒一开始图省事直接用F103的配置写法结果中断完全触发不了。这个问题在AT32的参考手册里有明确说明需要修改SYSCFG的EXTICR配置方式。其实也不难就是得认真查手册别想当然。4.2 排查利器调试器和示波器的合理使用换芯片调底层的时候我对排查工具的使用建议是优先用调试器单步跟踪再用示波器验证波形最后用逻辑分析仪抓协议时序。调试器方面AT32F403A支持SWD调试和ST-Link完全兼容这点很方便。但需要注意AT32在低功耗模式下SWD调试口会被关闭如果你进入了睡眠模式调试器就连不上了。我当时遇到一次芯片调试连不上以为芯片烧了后来才知道是程序跑进了睡眠模式。示波器是修时钟问题的关键。我的习惯是先用MCO引脚把系统时钟引出来测一下主频是否准确再去测外设时钟。如果主频不对后面的PWM频率、波特率统统不对查起来越查越乱。逻辑分析仪在排查SPI和I2C时序时很好用。我调试SPI通过DMA读ADC数据时就是靠逻辑分析仪发现SCLK频率超了把分频系数调大后才正常读取数据。4.3 AT32F403A硬件设计上的注意事项软件移植之外硬件设计上也有几个点值得留意。电源滤波上AT32F403A的VDD引脚建议每个引脚都加0.1uF去耦电容电源入口再加一个大容值电容。严格来说这是所有MCU的通用要求但AT32的DVDD和AVDD分离更细模拟电源引脚需要额外干净。复位电路上AT32F403A的NRST引脚内部有上拉和滤波外部电容推荐值参考数据手册我用的是0.1uF实测稳定。这边不要直接沿用F103的1uF有些批次可能引起复位时序问题。时钟电路上AT32F403A的OSC_IN/OSC_OUT外接8MHz晶振负载电容选择要根据晶振规格来。建议参考官方AN003应用笔记做匹配。OSC32K如果我之前说的直接用内部低速时钟不必外接32768晶振AT32的LDO和内部RC校准做得还可以一般场景够用。5. 移植完成后我切实感受到的“爽点”代码全部迁移完、各类测试跑通之后说说让我觉得这次换芯片值得的几个地方。算力提升是最明显的。原来F103在72MHz下跑完整的显示刷新通信解析控制算法CPU负载经常过半。现在AT32F403A跑到240MHz同样的代码逻辑CPU占用率直接跌破15%。这意味着后续产品加功能的空间大了很多不用再为“加个功能会不会影响实时性”发愁。Flash执行速度快这点也让人舒心。有些F103程序在Flash里运行遇到大量分支跳转时会卡顿AT32有独立读加速单元从Flash取指几乎不拖后腿。虽然说不出来具体数字提升了几倍但体感明显——比如同样做浮点PID计算F103上偶尔会有微妙级的反应延迟AT32这边实时性稳得一批。USB虚拟串口的体验也超出预期。AT32F403A的USB模块内置了更完善的时钟恢复逻辑配合外部晶振虚拟串口长时间大数据量通信不容易掉线。之前F103如果USB线接触不良或者主机负载高偶尔会蓝屏或者设备掉线在AT32上这个情况大大减少。再有就是成本和供货的放松。这是做产品的人最现实的考量。同等级别的引脚数、容量、性能AT32的BOM成本能省一个档位而且雅特力的供货比ST稳定很多缺货焦虑少多了。对我这种小团队来说这比单纯的主频提升更重要。6. 常见问题速查与避坑建议清单移植过程中遇到的所有问题我整理成一个速查表方便你对照排查。现象可能原因处理方式上电后程序跑飞无法连接调试器启动文件选择错误核对芯片具体型号换对应的启动文件程序运行但主频不对串口波特率不对、定时器时间不对PLL倍频配置错误按AT32例程核对PLL参数用MCO输出实测主频串口收不到数据或数据乱码DMA通道或波特率时钟错误查DMA请求映射表确认UART时钟源和分频参数DMA中断进入后死循环中断标志清除方式不同改用AT32库提供的显式中断标志清除函数USB设备无法枚举USB时钟频率不对确认系统时钟为240MHz再检查USB分频配置I2C通信异常沿用F103的软件I2C时序或硬I2C配置不匹配检查I2C时序匹配建议用AT32硬件I2C重新初始化定时器PWM频率和预期不符定时器时钟源频率不同根据当前外设时钟重算ARR/CCR和分频系数外部中断无法触发EXTI映射配置不同按AT32参考手册改EXTICR配置还有几条避坑建议属于吃过亏后总结出来的习惯移植时先保留F103原工程不动新建一个AT32工程来做适配。两个版本同时存在方便对比寄存器和逻辑差异。外设底层驱动尽量都用宏定义做封装换芯片时只改底层头文件应用层代码不动。这次我深刻体会到“写封装一时爽一直封装一直爽”。每次修改底层配置后优先验证时钟主频是否正确验证通过后再继续下一步。时钟不稳后面全是坑。善用AT32官方例程包。官网里的例程虽然有些小瑕疵但整体质量不错尤其是USB、DMA这些复杂外设官方实现比你自己摸索要省太多时间。7. 从升级中学到的移植方法论这次从F103换到AT32F403A表面上看是一次芯片替换实际上让我对嵌入式项目迁移有了更多理解。芯片迁移的最大成本不在代码本身而在“惯性思维”。我们习惯了ST的库函数风格、时序节奏和寄存器布局换到新芯片时会下意识地拿老经验套新硬件结果就是问题一个接一个。AT32的库兼容性做得很好了但最后还是得静下心来看数据手册看参考手册按官方例程的方式配置。我自己这次的移植步骤简单来说分成五步查芯片数据手册确认硬件外设差异搭好最小系统验证时钟树逐个移植基础外设GPIO、UART、SPI、I2C、TIM、ADC适配复杂外设DMA、USB最后做整机压力测试和稳定性验证。整个过程大概花了两周时间其中大半时间花在时钟和DMA的坑里。在STM32F103上积累了那么多年的经验到了AT32F403A上当然没有白费但也不能完全照搬。作为一个工程师比掌握某个芯片更重要的是学会快速适应不同芯片的节奏。这个能力是用一次次踩坑换来的希望这篇笔记能让你少踩几个坑。
返回列表