作者之前用过GD32芯片,也成功移植过STM32代码到GD32芯片,但最近移植一份STM32代码到GD32后运行的时候发现一个问题:使用内部时钟时一切正常,一旦切换为使用外部12M时钟就启动不了。
最开始以为是时钟配置不对,但是我先移植了一份bootloader的代码到GD32,使用内部时钟、外部时钟运行都是正常的(详细配置过程请查阅我的上一篇文章:《史上最详细的gd32时钟频率设置》)。由此断定:时钟的配置绝对没有问题。
那么问题就来了,
问题1:时钟配置确实没有问题,可为什么一旦切换为外部时钟就卡死呢?
问题2:为什么烧写一次之后就无法直接再次烧写或调试?
因为这两个问题的困扰,网上查找了好多资料,最终在下面这篇文章中找到了问题2的原因所在:.html
问题2解决办法:
因为GD32与ST是pin对pin,这个板子当时是直接吹掉ST的芯片然后贴的GD芯片,实际调试发现GD的芯片在这个板子上是要把reset引脚接到JLINK上,用JLINK来使芯片复位。
至此问题2是解决了,但问题1依然毫无头绪,更严重的是:一旦我选择了外部时钟,烧录后程序起不来,想debug结果一直报错:cannot access memory,看网上说换STLINK可以,但我试了发现也不行,巧的是并不是绝对无法烧录,不停的尝试KEIL菜单栏的flash-》erase,终于把flash清除了。。。
极其艰难的把flash清除后,暂时不敢轻举妄动了。
仔细思考,为什么内部时钟可以,一切换外部时钟就无法启动,甚至影响烧录呢?因为可以确认外部时钟配置没有问题,那是不是连接外部晶振的引脚配置有问题呢?
那我就先查看引脚定义:
看数据手册发现PD0,PD1这两个引脚默认是连接外部晶振的输入输出,而我的BootLoader代码使用外部晶振在同一块板子上可以成功运行,但没有将PD0,PD1复用作为普通GPIO,使用的是他们的默认功能。因此我初步猜测,会不会是因为出问题的那份代码中复用了这两个引脚,导致只有在使用内部晶振的时候可以运行,一旦使用了外部晶振,就会因为PD0,PD1已复用作为普通GPIO,而非外部晶振的输入输出,所以没有时钟输入,也就无法启动。
于是乎,就仔细查询代码中关于PD0、PD1的配置操作,结果真的在一个函数中找到了!!!
uint8_t i;uint8_t di_status;config_t *config_info = get_config();rcu_periph_clock_enable(RCU_AF);gpio_pin_remap_config(GPIO_PD01_REMAP, ENABLE);rcu_periph_clock_enable(RCU_GPIOA | RCU_GPIOC);gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_6 | GPIO_PIN_15);if (config_info->src_type == MOT_MOD_MASTER){di_status = !gpio_input_bit_get(di_table[6].gpiox, di_table[6].port_pin);if (!di_status){ctrl_do(DO_CTRL_RELAY, 1); //上电}}else{ctrl_do(DO_CTRL_RELAY, 1); //上电}
这段代码中将PD0、PD1复用为GPIO了,也就是只能默认使用内部晶振!
rcu_periph_clock_enable(RCU_AF);
gpio_pin_remap_config(GPIO_PD01_REMAP, ENABLE);
将这两行代码屏蔽后,编译烧录,成功运行!
就是这两个小问题,前前后后耽误了三四天时间。
总结一下经验和教训吧:
1.接手别人的代码后,在重新配置时钟时,除了时钟本身文件的配置外,一定要注意在程序中时钟输入输出引脚是否被复用!
2.调试中遇到多个问题时,不要慌,用控制变量法,逐一排除,问题总归是有源头的。
3.多上CSDN。。。
以上共勉。
本文发布于:2024-02-04 13:17:26,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170708148955921.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |