极海单片机串口调试记录

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

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

出师不利:串口不通

第一步先更换了单片机芯片,原芯片是华大 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);
#else
    RCM_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 频率值后,库函数能获取正确的系统时钟频率了。

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小辉_Super

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值