GD32芯片开发系列问题

本节主要讲一下IO配置问题引起的管脚无法正常工作问题和解决过程的思路

文章目录

  • GD32芯片开发系列问题
  • 前言
  • 一、BOOT0引脚引起的无法初始化时钟树
  • 二、CAN无法正常收发
    • 1.GD32F105V_PB8/PB9配置为CAN0
    • 2.配置CAN0的模式和滤波器
  • 三.IO无法正常推挽输出
  • 总结

前言

上一篇文章讲了一下,如果阅读和配置GD32芯片的时钟树,以及更改晶振和修改系统主频的目标下,如何修改代码的思路。接下来在继续讲一下如果在配置完IO后,如果发现IO无法正常工作该如何找问题。

其实在没有成熟的对照代码和硬件下,想判断问题到底是出在代码上还是硬件电路上,还是需要开发者有较为深厚的嵌入式开发深度,已经对软硬件了解的知识面广度。在查找问题时候,分别列出导致问题的风险点,使用示波器,万用表,CAN上位机,在线调试等工具协助一个个风险点排除,同时也要对芯片的基本功能有快速查阅能力和较深的了解程度。


先来讲一下我本次项目遇到的三个坑吧。

一、BOOT0引脚引起的无法初始化时钟树

事故现象:烧录最初版本的代码后,系统未能进入main函数,所有的外设均无动作。
解决过程:
1,进入在线调试,从start.s文件开始查,发现甚至系统时钟树都没有被初始化。
2,最初怀疑是晶振未能起震,通过示波器测量晶振确实没起震。
3,但是晶振还没用过就坏了可能性也很小的啊,继续查找代码,通过在线调试发现system_clock_init(配置是时钟树的函数根本就没进去)。
4,所以确认msp指针根本就没有进入flash的内存区,根本没法执行我烧录进去的代码,而且通过读取单片机内存单元,是可以看到代码是烧进去了的。
5,查看原理图,发现原理图设计人员把BOOT0脚当成普通的IO设置成推挽输出了,这无疑是让芯片错误判断从SRAM启动了啊,这样子肯定会出大问题的。
以下是关于BOOT的描述,就是让芯片选择从哪儿启动代码。

二、CAN无法正常收发

1.GD32F105V_PB8/PB9配置为CAN0

核心代码如下(示例):
1,先打开CAN0的时钟。
2,配置收发IO的模式和速率
3,打开复用的管脚的映射功能

    /* enable can clock */rcu_periph_clock_enable(RCU_CAN0);rcu_periph_clock_enable(RCU_GPIOB);/* configure CAN0 GPIO, CAN0_TX(PD1) and CAN0_RX(PD0) */gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CAN_PIN_TX);gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, CAN_PIN_RX);gpio_pin_remap_config(GPIO_CAN0_FULL_REMAP, ENABLE);

2.配置CAN0的模式和滤波器

核心代码如下(示例):
1,设置波特率(先了解CAN外设所在的总线地址APB2的主频是多少,再用这个主频计算分频倍数)
2,滤波器可以不管。
3,选择接收的FIFO和打开接收中断。

/*!\brief      initialize CAN and filter\param[in]  none\param[out] none\retval     nonebaudrate 125Kbps - APB2 = 54MHz
*/
void can_networking_init(void)
{can_parameter_struct can_parameter;can_filter_parameter_struct can_filter;/* initialize CAN register */can_deinit(SYS_CAN);/* initialize CAN */can_parameter.time_triggered = DISABLE;can_parameter.auto_bus_off_recovery = DISABLE;can_parameter.auto_wake_up = DISABLE;can_parameter.no_auto_retrans = DISABLE;can_parameter.rec_fifo_overwrite = DISABLE;can_parameter.trans_fifo_order = DISABLE;can_parameter.working_mode = CAN_NORMAL_MODE;can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;can_parameter.time_segment_2 = CAN_BT_BS2_3TQ;/* baudrate 125kbps = 54M/48*(1+(5+3))*/can_parameter.prescaler = 48;can_init(SYS_CAN, &can_parameter);/* initialize filter *//* CAN0 filter number */can_filter.filter_number = 0;/* initialize filter */    can_filter.filter_mode = CAN_FILTERMODE_MASK;can_filter.filter_bits = CAN_FILTERBITS_32BIT;can_filter.filter_list_high = 0x0000;can_filter.filter_list_low = 0x0000;can_filter.filter_mask_high = 0x0000;can_filter.filter_mask_low = 0x0000;  can_filter.filter_fifo_number = CAN_FIFO0;can_filter.filter_enable = ENABLE;can_filter_init(&can_filter);/* enable CAN receive FIFO0 not empty interrupt */can_interrupt_enable(SYS_CAN, CAN_INT_RFNE0);
}

解决过程:
1,先使用CAN上位机进行收发测试,发现没有任何数据,且上位机发送后显示发送失败(CAN总线根本就没有连接)。
2,最初怀疑匹配电阻问题,通过跳帽接入引入了120ohms电阻。

3,将匹配电阻调节到60ohms后,CAN收发依然和上述现象一致。
4,继续查找CAN电路的接线问题,通过示波器勾选找芯片两侧的通信口,在电脑端不断发送报文来查看两端是否出现CAN波形。

5,示波器显示CAN芯片能够正常解析CAN信号,电路接线没有问题。
6,排除电路问题后,继续查找代码问题。代码主要问题在与CAN和IO的配置问题。
7,首先是排查PB8/PB9用作于CAN0还是CAN1,通过查阅芯片手册发现这两个脚只能用作于CAN1的收发,于是赶紧改了配置:

    /* enable can clock */rcu_periph_clock_enable(RCU_CAN0);rcu_periph_clock_enable(RCU_GPIOB);/* configure CAN0 GPIO, CAN0_TX(PD1) and CAN0_RX(PD0) */gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CAN_PIN_TX);gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, CAN_PIN_RX);gpio_pin_remap_config(GPIO_CAN1_REMAP, ENABLE);

8,改了CAN配置依旧没有任何改善,还是无法收发数据,此时就有点绝望了。
9,接下来没有其他的解决思路了,找不到芯片厂商的技术支持,于是自己开始了仔细研究该款芯片的芯片手册。
10,重新下载一个详细的芯片手册,里面有各种控制寄存器的功能描述,通过大量时间查阅芯片发现有一个地方和上一份芯片介绍手册有矛盾地方(果然是小厂做出来的东西),这个里面说PB8/PB9作为CAN口只能做CAN0映射。

11,于是又把上面的代码映射改为CAN0,不过问题来了 : 我一开始用的就是用CAN0映射的啊,没有用的。
12,于是CAN0_REMAP寄存器便引起了我的注意,上图有三种映射方式,有三组IO可以映射到CAN0上,系统只是默认是PA11/PA12脚而已。
13,接下来想办法修改CAN0_REMAP寄存器,将PB8/PB9映射上去就好了。


14,在代码中改变映射方式,将PB8/PB9映射到CAN0上去。

    /* enable can clock */rcu_periph_clock_enable(RCU_CAN0);rcu_periph_clock_enable(RCU_GPIOB);/* configure CAN0 GPIO, CAN0_TX(PD1) and CAN0_RX(PD0) */gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CAN_PIN_TX);gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, CAN_PIN_RX);gpio_pin_remap_config(GPIO_CAN0_PARTIAL_REMAP, ENABLE);

14,不幸的是,依旧没有CAN报文收发,不过好消息是,通过CAN上位机发送报文数据后,不再提示“发送失败”,说明CAN总线是连接上了的。
15,最后比对官网上下载的demo代码,发现APB2时钟没打开,导致PB8/PB9都没法工作,接下来设置下APB2的时钟RCU_AF寄存器就好了。

    /* enable APB2 clock */rcu_periph_clock_enable(RCU_AF);//APB2时钟没打开,GPIOB怎么输出/* enable can clock */rcu_periph_clock_enable(RCU_CAN0);rcu_periph_clock_enable(RCU_GPIOB);/* configure CAN0 GPIO, CAN0_TX(PD1) and CAN0_RX(PD0) */gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, CAN_PIN_TX);gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, CAN_PIN_RX);gpio_pin_remap_config(GPIO_CAN0_PARTIAL_REMAP, ENABLE);

15,CAN0调试结束,期间设计了CAN电路设计,CAN波特率计算方式,FIFO选择,三个发送邮箱选择,IO复用寄存器设置,APB2时钟。

三.IO无法正常推挽输出

核心代码如下(示例):
1,这个部分就不介绍了,抄一抄就行了。
2,总共配置了20个io,只有3个无法正常输出

    char i;/* enable the led clock */rcu_periph_clock_enable(RCU_GPIOE);//rcu_periph_clock_enable(RCU_GPIOD);//rcu_periph_clock_enable(RCU_GPIOC);//rcu_periph_clock_enable(RCU_GPIOB);//rcu_periph_clock_enable(RCU_GPIOA);///* configure led GPIO port */ for(i=0;i<RLYn;i++){gpio_init(GPIO_PORT[i], GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN[i]);}

解决过程:
1,直接在代码里面把这三个IO拉高输出,使用万用表测量不出3.3V电压。
2,进入在线调试状态,直接设置PA15管脚输出高电平,依然无法输出,且设置后立即被取消设置了。
3,将单板返回给硬件组同事,让他去确认下PCB图,是不是把IO对照搞错了。
4,硬件组同事确认后,板子没有问题,我这儿继续调试下。
5,继续查阅芯片手册,看些这三个脚有没有什么特殊的,通过对PDF全局搜索PA15关键词发现:PA15默认是JTAG的调试JTDI口。
6,查找芯片关闭JTAG调试方法,可以通过设置映射寄存器,将PA15默认映射到JTAG的给关闭掉。

7,和刚才配置映射寄存器的接口一样,实现代码如下:

    gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP,ENABLE);

总结

没什么总结的,贴一下上一篇博文地址,也是这个项目的,不过是关于系统时钟树配置和阅读的。

GD芯片开发时钟树配置及修改指导

GD32F105V开发过程中的管脚配置问题记录相关推荐

  1. 移动应用开发过程中的迭代式原型设计

    \ 主要结论 \ 移动应用原型创建过程中采用迭代式快速开发方法的重要性. \ 可以从对手身上学到什么,如何从他们的失误中获益. \ 如何为你的应用定义USP,如何通过故事板(Storyboarding ...

  2. JavaFX8开发过程中的问题记录

    JAVAFX8开发过程中的问题记录 起源 上Java课的时候没有好好学,到后来自学一段时间才真正算是入门,不过听说Java不适合做桌面程序,所以对Swing这一块根本都没有看,而且也忽略了线程和文件I ...

  3. Asp.net开发过程中,我们会遇到很多Exception

    在Asp.net开发过程中,我们会遇到很多Exception,不处理这些Exception的话会出现很难看的页面. 还有一些我们未预料到的Exception,当发生Exception时,我们也必须进行 ...

  4. 项目开发过程中的收获与思考

    2013年7月,我正式毕业了,到公司入职,也就正式成为了一名菜鸟程序员.到今天,2014年1月3日,目前主要的工作是公司一个项目中的一个功能模块,到我进入项目组算起,已经过了四个月了.因此,想写点东西 ...

  5. 对复杂业务组件在实际开发过程中被调用的反思

    写这篇文章的初衷是为了记录我在修复项目中一个复杂业务组件中的bug而引起其他依赖这个组件的功能无法使用的过程中,对使用.维护复杂业务组件的一些思考 原文地址 Bug发生原因 我所在的项目组中, 有一个 ...

  6. web开发过程中经常用到的一些公共方法及操作

    进化成为程序猿也有段岁月了,所谓的经验,广度还是依旧,只不过是对于某种功能有了多种实现方式的想法.每天依旧不厌其烦的敲打着代码,每一行代码的回车似乎都有一种似曾相识的感觉.于是乎:粘贴复制,再粘贴再复 ...

  7. 软件项目开发过程中主要遇到的核心问题小结

    最近在北京组织管理某银行的现金管理系统项目的开发,对软件项目开发过程中遇到的问题进行一些心得体会小结,怕时间长了没及时写下来时间久了被遗忘了,现在趁项目还在开发过程,把体会相对深刻时,感受到的一些问题 ...

  8. mysql开发问题解决_开发过程中mysql常见问题的解决方法

    本篇文章给大家带来的内容是关于开发过程中mysql常见问题的解决方法,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 记录开发过程中遇到mysql相关的问题以及解决方法,长期更新. 远 ...

  9. 探讨如何确保对日软件外包开发过程中的质量

    2019独角兽企业重金招聘Python工程师标准>>> 摘 要:对日软件外包是目前在国内发展迅速的一个行业,但是由于国界.地域.语言.习俗等差异,导致了对日软件外包的质量得不到保证. ...

  10. ReactJS 开发过程中的一些使用心得

    ReactJS作为目前最火的构建用户界面的前端框架,为什么有那么多的前端工程师去追逐它,不仅因为它简单,而且它提供了一系列强大的API让我们摆脱以前繁琐的DOM操作,使我们的逻辑更加清晰,代码更加简单 ...

最新文章

  1. 机器学习中的标量、向量、矩阵、和张量的概念
  2. 局域网计算机中arp,在局域网中的一台计算机上使用了arp-a命令,有如下输出: C:\arp.a Interface: 192.168.0.1 0n - 赏学吧...
  3. linux tr命令书上的一个很好的例子
  4. 学习mysql中使用inner join,left join 等
  5. html中心对齐,html – 对齐内联块中心
  6. 源码分析Android Handler是如何实现线程间通信的
  7. 一站式快速实现应用现代化,IBM Cloud Pak做对了什么? | 技术公开课
  8. poj 1459-Power Network解题报告
  9. ps aux 和ps -aux和 ps -ef的选择
  10. 群晖服务器密码修改,群晖nas使用教程:重置黑群晖登陆密码 – 群晖教程
  11. 前端安全之常见漏洞及防御
  12. ClearCase的一些基本概念
  13. 业务系统+电子签章开放平台,快速构建个性化的电子签署应用
  14. 618的优惠券去哪了?
  15. 微信小助手插件WeChatTweak
  16. AS400 资料并分享面经一
  17. 基于centos8部署nextcloud+onlyoffice----2021-07-16
  18. vue3+ts+ant-vue:手把手教你实现穿梭框简易版,配源码
  19. MSTP:多生成树协议
  20. 寻宝游戏 - 利用iBeacon特性设计的iOS线下寻宝游戏 - 物联网小游戏

热门文章

  1. 格力手机2刷机 格力手机二代刷机 GREE G0215D刷机教程
  2. c# 调用Minitab18.1实现直方图、质量正态图
  3. 川大计算机考研录取率高吗,四川大学考研难不难?看完这篇你就知道了!
  4. 搭建IPv6网络环境
  5. 适用于物联网数据共享的区块链节点存储优化方案
  6. Java实现批量ping IP地址
  7. 浏览器下载Firefox os 模拟器安装教程步骤详解
  8. 【乌拉喵.教程】TestBench仿真给输出脚赋值引起的问题
  9. Day11 JaseSE File类的使用
  10. 最简单的又炫的快捷菜单....喜欢的拿起就跑