极海单片机替换华大(极海作为备用),一路上遇到了很多问题,所以写一篇文章记录一下。

原本单片机使用的是 STM32F030C8T6,后因 STM32 芯片涨价+缺货,换成了华大,现又考虑选极海作为备选方案。当得知极海的 APM32F030C8T6 和 STM32 对应型号是软件+硬件兼容的时候,我以为极海单片机的验证会非常简单,万万没想到,整个调试过程中遇到了各种问题。

文章目录

  • 出师不利:串口不通
  • 雪上加霜:官方Demo运行没反应
  • 悬而未决:更换外部晶振
  • 渐入佳境:测试真实时钟频率
    • 库函数获取时钟频率
    • MCO 输出时钟频率
  • 举一反三:不换晶振,灵活配置系统时钟

出师不利:串口不通

第一步先更换了单片机芯片,原芯片是华大 HC32F030J8TA,和 APM32F030C8T6 (或STM32F030C8T6)只有一个脚不同,稍微改动电路后(拆了一个电阻),将单片机换上,烧录之前的 STM32 版本程序。

因为极海 APM32F030C8T6 和 STM32 对应型号软硬件兼容,所以可以直接使用 STM32 的程序和 ST-Link,烧录程序后,发现功能基本能跑通,除了串口。

雪上加霜:官方Demo运行没反应

虽然串口暂时没有工作,但程序能跑起来,还是挺让人欣慰的,这样的话后面都不需要怎么改软件了。

想着试试跑一下官方的例程,但是结果让人怀疑人生,GPIO 例程竟然连个灯都没点起来,之前我拿 STM32 的代码都能实现 GPIO 功能,这种问题属实难到了我这个新手。

悬而未决:更换外部晶振

仔细对比 STM32 版本(旧版硬件)和 当前版本的原理图,发现原来的外部主晶振时钟频率为 8MHz,而现在板子上贴的是 32MHz 的晶振。很多国产单片机都是和 STM32 软硬件兼容,而华大却做了一些小改动(也不是说这样不好,只是没其他品牌用的舒服)。

看了一下华大单片机数据手册(我所用的型号),其外部高速晶振可选频率范围为 4~32MHz,这个和其他品牌性能相仿的单片机是一样的,

但是 STM32 和其他与 STM32 软硬件兼容的单片机品牌都是推荐 8MHz 外部高速晶振,而华大默认 32MHz,这里的默认指的是官方例程里设置的外部高速晶振频率。

所以到这里,极海官方例程无法运行就是因为系统时钟不正常,有两个解决办法,一是将板子上的 32MHz 晶振换成 8MHz 晶振,二是改代码,通过适当的分频与倍频实现 48MHz 的系统时钟(该系列最大的时钟频率)。

很明显,第二个办法更加简单,但奈何我当时没想到,傻傻地去把 32MHz 晶振吹了下来,从旧板子上拆了一个 8MHz 晶振焊到测试板上(第二个办法在本文最后一章节讲到)。

换完晶振后,极海的官方例程可以跑起来了,但是串口的问题依然没解决。

渐入佳境:测试真实时钟频率

虽然换了晶振,官方 GPIO 例程也能运行,但我还是怀疑系统时钟有问题。

目前我有两种获取系统时钟的方案,一种是通过库函数,直接读取程序运行时的系统时钟值,然后通过串口(当然现在我串口还没通,就不用想了)打印,或在 Debug 模式下查看。另一种是通过 MCO(时钟输出,microcontroller clock output),将系统的时钟输出到指定的 IO。

库函数获取时钟频率

时钟控制是一个很重要的功能模块,所以单片机官方例程一般都会有一个单独的 Demo 来介绍相关库函数的使用,比如下面我所用的例程,例程名为 RCM_ClockSwitch,在调试模式下,运行相关函数,得到的数据如下,时钟源为 2 (指的是将 PLL 作为系统时钟),系统时钟频率为 48MHz。

这样看来,更换晶振后,系统时钟好像是正确的。但是串口为什么还是没用呢?难道这个打印的时钟不可信?

的确,这个结果没说服我,后来我也了解到,这里打印的时钟只是代码里进行时钟配置后的结果,并不能真正反映系统的时钟(除非你能保证程序里的时钟配置是完全按照外部晶振频率来设置的)。

这样一来,哪怕我还是用 32MHz 的晶振,这里获取到的时钟值依然会是 48MHz,但实际设置的系统时钟到了 48M 的 4 倍(32 / 8 = 4),不过该型号单片机最高支持 48MHz。官方 GPIO 例程不能运行已经说明了胡乱设置系统的时钟会影响程序正常运行。

正所谓实践出真知,上面得出的时钟频率相当于理论上的系统时钟频率,而实际的时钟频率,还需要通过实打实的测试来求出,也就是下面 MCO 时钟输出。

MCO 输出时钟频率

下图是时钟树里对 MCO 的描述:

我当前所用单片机只有一个 IO 有此功能,PA8(我发现好多不同品牌,不同型号的 MCO 都在 PA8 上):

时钟输出的配置很简单,就和普通的 GPIO 配置差类似,下面是极海官方例程中的 MCO 配置函数:

/*!* @brief       Clock output init** @param       None** @retval      None** @note*/
void ClockOutputInit()
{GPIO_Config_T gpioconfig;/**  Connect RCM Clock output */GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_8, GPIO_AF_PIN0);gpioconfig.mode    =  GPIO_MODE_AF;gpioconfig.outtype =  GPIO_OUT_TYPE_PP;gpioconfig.pin     =  GPIO_PIN_8;gpioconfig.pupd    =  GPIO_PUPD_NO;gpioconfig.speed   =  GPIO_SPEED_50MHz;GPIO_Config(GPIOA, &gpioconfig);/** set SYSCLK as COC source*/
#if defined (APM32F030) || defined (APM32F051)RCM_ConfigCOC(RCM_COC_SYSCLK);
#elseRCM_ConfigCOC(RCM_COC_SYSCLK, RCM_COC_DIV_128);
#endif}

在 main() 函数调用上面的 MCO 初始化函数,然后用示波器或逻辑分析仪测试 PA8 的输出频率:

测到这步,已经可以确定系统时钟就是 48MHz。

对比了之前贴 32MHz 外部高速晶振的时钟输出(用 STM32 代码实现的,极海的代码无法正常运行),发现在使用 32MHz 晶振时输出的系统时钟是不稳定的,一直在一个范围内变动,所以极海官方例程无法运行的问题已经找到了,就是时钟设置出错,导致系统时钟不稳定。

就在使用极海时钟管理例程时,我发现串口竟然打印了数据!!该例程的代码如下:

重新解压了一份新的官方串口例程,发现串口已经可以使用,所以之前换完 8MHz 晶振后串口依然没用是因为代码的问题(可能改太多,改出了一些隐藏的 Bug),无论如何,串口能用起来就完事了,其他的都不重要了。

举一反三:不换晶振,灵活配置系统时钟

前面提到极海官方例程默认外部高速晶振的时钟频率为 8 MHz,而我板子上贴的是 32 MHz,如果不想换晶振,也可以通过配置系统时钟来实现 48MHz (该芯片最高频率)的系统时钟。

32M 转为 48M,只需要先对 HSE (外部高速时钟频率)进行 2 分频,然后将其作为 PLL 的时钟源,PLL 3 倍频后作为系统时钟,32 / 2 * 3 = 48。

这里发现一个问题:

CFG1_B(时钟控制寄存器 1) 结构体里 PLLSRCSEL 占两个位,

而用户手册里这个值明明只占一位数据,这代码和文档有点对不上呀。

HSE 2 分频

回到时钟配置的问题,先将 HSE 进行 2 分频,这个操作可以通过将 PLLHSEPSC 置 1 来实现,这个值只占 1 位数据,所以最多实现 2 分频。

PLL 3 倍频

PLL 倍频可以通过修改 PLLMULCFG 实现,3 倍频,将其设置为 1 即可。


修改配置函数

上面这些都可以在时钟函数中进行配置,比如我所用的工程代码会通过 SystemClock48M() 来配置系统时钟,那么我就对其做了以下修改:


使用库函数获取时钟频率,只有 12MHz,但 MCO 时钟输出测得的时钟频率为 48MHz。说明 48MHz 系统时钟已经有了,只是程序代码还有没完善的地方。

修改 HSE_VALUE 就能解决上面这个问题,将原来的 8000000 改为 32000000

修改 HSE 频率值后,库函数能获取正确的系统时钟频率了。

极海单片机串口调试记录相关推荐

  1. PIC18F45K80单片机串口调试总结

    /****PIC18F45K80单片机串口调试总结-Sandy*********Start of file***********/     文件名:PIC18F45K80单片机串口调试总结 作者:手术 ...

  2. ucosiii使用两个串口调试记录

    使用STM32作为主机,接受从机STC89C52传过来的数据,用UART作为通讯协议.本来是件很简单的事情,偏偏弄了一天.原因在于配置STM32UART5时,初始化后,然后将LED再初始化.LED挂P ...

  3. UartAssist,串口调试助手

    UartAssist是一款功能非常强大,且实用性极高的串口调试助手,该软件不仅支持常用的110-115200bps波特率,而且不论是它的端口号.校验位.数据位.停止位等各种数据,在这里通通都可以完美的 ...

  4. 瑞芯微rockchip PX30触摸屏调试记录

    系列文章目录 瑞芯微rockchip PX30 串口调试记录 瑞芯微rockchip PX30 显示屏调试 瑞芯微rockchip PX30触摸屏调试记录 瑞芯微rockchip PX30 QT环境搭 ...

  5. AVR单片机开发6——AVR单片机串口Proteus调试注意事项

    ATmega168是基于增强的AVR RISC结构的低功耗8 位CMOS微控制器.由于其先进的指令集以及单时钟周期指令执行时间,ATmega168 的数据吞吐率高达1 MIPS/MHz,从而可以缓减系 ...

  6. 海思NNIE开发(一):海思Hi3559AV100/Hi3519AV100 NNIE深度学习模块开发与调试记录

    海思NNIE开发系列文章: 海思NNIE开发(一):海思Hi3559AV100/Hi3519AV100 NNIE深度学习模块开发与调试记录 海思NNIE开发(二):FasterRCNN在海思NNIE平 ...

  7. 华大单片机 HC32F460 串口调试

    华大单片机 HC32F460 串口调试 吐槽下,华大官方例程写到太复杂了,不熟练的一时摸不上手. #include "drvs.h" /********************** ...

  8. 关于单片机串口单步调试运行正常,全速异常

    1.今天在调试51单片机的时候发现,单片机串口发送数据的时候,接收端接收的数据全是错误的. 2.使用KEIL在线调试单步运行,发现接收端正常接收每一个字符,点击全速运行就异常了. 代码如下: 上面这个 ...

  9. 【记录】一次51单片机串口乱码问题排查

    [记录]一次51单片机串口乱码问题排查 项目场景 问题描述 原因分析 解决方案 结语 项目场景 在51串口收发仿真实验中使用两个单片机互相通信,程序设定A上电1s后通过串口以16进制给B发送AA,直到 ...

  10. arduino 停止程序_极路由1S OpenWrt开机自启程序及串口调试

    如何给openwrt添加启动项?首先在/etc/init.d中创建一个文件,在CRT终端中直接用vi命令即可,自行创建startCamera文件,如下图所示. vi编辑器中输入下图所示内容,START ...

最新文章

  1. 第一节 并发基础概念及实现、进程、线程基本概念
  2. python测试rabbitmq的消息收发
  3. Python 机器学习库 Top 10,你值得拥有!
  4. Java 技术篇-IntelliJ IDEA修改类名后运行提示找不到或无法加载主类问题解决方法
  5. winform npoi excel 样式设置
  6. iOS基础知识点总结
  7. Mozilla工程师观点:开源不赚钱,因为它不是为赚钱而设计的
  8. xcode常用快捷键_Mac及Xcode常用快捷键
  9. MySQL为什么要set names
  10. 连连看外挂消去算法分析
  11. 常见MIME类型例表
  12. 【OpenCV入门指南】第七篇 线段检测与圆检测
  13. 单片机脉冲喷吹仪c语言,C51单片机脉冲累加器(C语言程序)
  14. 掘金企服:ICP经营许可证和ICP备案的区别
  15. WMS仓储管理系统解决方案
  16. java实现电子面单pdf生成_常用快递电子面单批量打印api接口对接demo-JAVA示例
  17. 论文查重前应删掉哪些内容?
  18. 国庆节未休假的你,领到了三倍的工资吗?
  19. 基于word2vec的QA demo
  20. C语言程序设计-跳马问题

热门文章

  1. Python与企业微信-3
  2. 扫雷游戏(保姆式教程)
  3. Vulnhub-Tiki
  4. vue中的attribute 和 property 是什么意思
  5. 【学习笔记】多目标优化问题分解成若干简单多目标子问题--MOEA/D-M2M
  6. 《自控力》读书笔记思维导图
  7. 极客快讯第 5 期:袁隆平对抖音账号不知情,抖音回应;百度宣布组建智能汽车公司;北京滴滴和花小猪将于一周内完成司机疫苗接种;
  8. [论文笔记]Rob-GAN: Generator, Discriminator, and Adversarial Attacker
  9. vue3使用keep-alive页面切换时报错:TypeError: parentComponent.ctx.deactivate is not a function
  10. Springboot 注解最全详解