GD32双路CAN踩坑记录

GD32双路CAN踩坑记录

目录

  • GD32双路CAN踩坑记录
    • 1 问题描述
    • 2 原因分析
    • 3 解决办法
    • 4 CAN配置参考代码

1 问题描述

GD32的CAN1无法进入接收中断,收不到数据。
注:MCU使用的是GD32E50x,其他型号不确定是否一样,本文只以GD32E50x举例说明。

2 原因分析

GD32的CAN过滤器总共有28个,通过过滤器控制寄存器(CAN_FCTL)打开或关闭,具体如下:

在这里插入图片描述

其中问题就出现在上图的HBC1F上面,CAN0使用的是过滤器编号0到编号(HBC1F-1),CAN1使用的是过滤器编号(HBC1F)到27,而这个默认值是0xE(14),也就是说CAN0默认使用的是编号为0-13的过滤器,CAN1默认使用的是编号为0-27的过滤器,因此,在初始化CAN1的时候,过滤器编号要在这个范围内才能被正确使用,否则是接收不到CAN数据的。

3 解决办法

1、使用编号为15-28的过滤器
2、通过修改CAN_FCTL寄存器的HBC1F,调整过滤器编号的分配
其中GD32固件库有封装函数可以修改HBC1F,函数原形如下:

/*!\brief      set CAN1 fliter start bank number\param[in]  start_bank: CAN1 start bank numberonly one parameter can be selected which is shown as below:\arg        (1..27)\param[out] none\retval     none
*/
void can1_filter_start_bank(uint8_t start_bank)
{/* filter lock disable */CAN_FCTL(CAN0) |= CAN_FCTL_FLD;/* set CAN1 filter start number */CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F;CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank);/* filter lock enable */CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
}

4 CAN配置参考代码

#include "main.h"
#include "stdio.h"can_trasnmit_message_struct can0_tx_message;
can_trasnmit_message_struct can1_tx_message;
can_receive_message_struct can0_rx_message;
can_receive_message_struct can1_rx_message;void can0_gpio_config(void)
{/* enable CAN0 clock */rcu_periph_clock_enable(RCU_CAN0);rcu_periph_clock_enable(RCU_GPIOB);rcu_periph_clock_enable(RCU_AF);/* configure CAN0 GPIO */gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_8);gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);gpio_pin_remap_config(GPIO_CAN0_PARTIAL_REMAP, ENABLE);
}void can0_config(void)
{can_parameter_struct can_parameter;can_fdframe_struct can_fd_parameter;can_fd_tdc_struct can_fd_tdc_parameter;can_filter_parameter_struct can_filter;can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);/* initialize CAN register */can_deinit(CAN0);#if 1  // CAN配置/* initialize CAN parameters */can_parameter.time_triggered = DISABLE;can_parameter.auto_bus_off_recovery = DISABLE;can_parameter.auto_wake_up = DISABLE;can_parameter.auto_retrans = DISABLE;can_parameter.rec_fifo_overwrite = DISABLE;can_parameter.trans_fifo_order = DISABLE;can_parameter.working_mode = CAN_NORMAL_MODE;/* CAN波特率 = 时钟频率 / 分频系数 / (1 + TSG1 + TSG2) *//* 仲裁段波特率 = 90M / 9 / (1 + 7 + 2) = 1M *//* configure CAN baud rate 1MBps, sample point at 80% */can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;can_parameter.time_segment_1 = CAN_BT_BS1_7TQ;  // TSG1can_parameter.time_segment_2 = CAN_BT_BS2_2TQ;  // TSG2can_parameter.prescaler = 9U;                   // 分频系数/* initialize CAN */can_init(CAN0, &can_parameter);
#else  // CANFD配置/* initialize CAN parameters */can_parameter.time_triggered = DISABLE;can_parameter.auto_bus_off_recovery = DISABLE;can_parameter.auto_wake_up = DISABLE;can_parameter.auto_retrans = ENABLE;can_parameter.rec_fifo_overwrite = ENABLE;can_parameter.trans_fifo_order = ENABLE;can_parameter.working_mode = CAN_NORMAL_MODE;/* baudrate 1Mbps, sample piont at 80% */can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;can_parameter.time_segment_1 = CAN_BT_BS1_7TQ;can_parameter.time_segment_2 = CAN_BT_BS2_2TQ;can_parameter.prescaler = 9U;/* initialize CAN */can_init(CAN0, &can_parameter);can_struct_para_init(CAN_FD_FRAME_STRUCT, &can_fd_parameter);can_fd_parameter.fd_frame = ENABLE;can_fd_parameter.excp_event_detect = ENABLE;can_fd_parameter.delay_compensation = ENABLE;can_fd_tdc_parameter.tdc_filter = 0x04U;can_fd_tdc_parameter.tdc_mode = CAN_TDCMOD_CALC_AND_OFFSET;can_fd_tdc_parameter.tdc_offset = 0x04U;can_fd_parameter.p_delay_compensation = &can_fd_tdc_parameter;can_fd_parameter.iso_bosch = CAN_FDMOD_ISO;can_fd_parameter.esi_mode = CAN_ESIMOD_HARDWARE;/* CAN波特率 = 时钟频率 / 分频系数 / (1 + TSG1 + TSG2) *//* 数据段波特率 = 90M / 3 / (1 + 4 + 1) = 5M */can_fd_parameter.data_resync_jump_width = CAN_BT_SJW_1TQ;can_fd_parameter.data_time_segment_1 = CAN_BT_BS1_4TQ;  // TSG1can_fd_parameter.data_time_segment_2 = CAN_BT_BS2_1TQ;  // TSG2/* CAN-FD data segement prescaler should be the same as non-data segement prescaler */can_fd_parameter.data_prescaler = 3;                    // 分频系数/* initialize CAN-FD */can_fd_init(CAN0, &can_fd_parameter);
#endif/* initialize filter *//* configure filter mode */can_filter.filter_mode = CAN_FILTERMODE_MASK;can_filter.filter_bits = CAN_FILTERBITS_32BIT;/* configure filter ID */can_filter.filter_list_high = 0x0000U;can_filter.filter_list_low = 0x0000U;/* configure filter mask */can_filter.filter_mask_high = 0x0000U;can_filter.filter_mask_low = 0x0000U;/* select receiver fifo */can_filter.filter_fifo_number = CAN_FIFO0;can_filter.filter_number = 0U;can_filter.filter_enable = ENABLE;can_filter_init(CAN0, &can_filter);/* configure CAN0 NVIC */nvic_irq_enable(CAN0_RX0_IRQn, 0U, 0U);/* enable can receive FIFO0 not empty interrupt */can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
}int can0_send_message(void)
{uint8_t i;uint16_t id = 1;can0_tx_message.tx_sfid = id;can0_tx_message.fd_flag = 0;can0_tx_message.fd_brs = 0;can0_tx_message.fd_esi = 0;can0_tx_message.tx_dlen = 8;for(i = 0; i < 8; i++) {can0_tx_message.tx_data[i] = i;}
#if 0printf("\r\n can0 transmit data(id: 0x%x): ", can0_tx_message.tx_sfid);for(i = 0U; i < can0_tx_message.tx_dlen; i++) {printf(" %02x", can0_tx_message.tx_data[i]);}
#endif/* transmit message */if(can_message_transmit(CAN0, &can0_tx_message) != CAN_NOMAILBOX){return 1;}return 0;
}void CAN0_RX0_IRQHandler(void)
{/* check the receive message */can_message_receive(CAN0, CAN_FIFO0, &can0_rx_message);LOG("\r\n can0 receive(id=0x%X) data: ", can0_rx_message.rx_sfid);for(int i = 0U; i < can0_rx_message.rx_dlen; i++) {LOG(" %02x", can0_rx_message.rx_data[i]);}
}void can1_gpio_config(void)
{/* enable CAN1 clock */rcu_periph_clock_enable(RCU_CAN1);rcu_periph_clock_enable(RCU_GPIOB);rcu_periph_clock_enable(RCU_AF);/* configure CAN1 GPIO */gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_5);gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);gpio_pin_remap_config(GPIO_CAN1_REMAP, ENABLE);
}void can1_config(void)
{can_parameter_struct can_parameter;can_fdframe_struct can_fd_parameter;can_fd_tdc_struct can_fd_tdc_parameter;can_filter_parameter_struct can_filter;can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);/* initialize CAN register */can_deinit(CAN1);/* initialize CAN parameters */can_parameter.time_triggered = DISABLE;can_parameter.auto_bus_off_recovery = DISABLE;can_parameter.auto_wake_up = DISABLE;can_parameter.auto_retrans = ENABLE;                 // TODO 自动重传是否需要使能can_parameter.rec_fifo_overwrite = ENABLE;   can_parameter.trans_fifo_order = ENABLE;can_parameter.working_mode = CAN_NORMAL_MODE;/* CAN波特率 = 时钟频率 / 分频系数 / (1 + TSG1 + TSG2) *//* 仲裁段波特率 = 90M / 9 / (1 + 7 + 2) = 1M *//* baudrate 1Mbps, sample piont at 80% */can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;can_parameter.time_segment_1 = CAN_BT_BS1_7TQ;  // TSG1can_parameter.time_segment_2 = CAN_BT_BS2_2TQ;  // TSG2can_parameter.prescaler = 9U;                   // 分频系数/* initialize CAN */can_init(CAN1, &can_parameter);can_struct_para_init(CAN_FD_FRAME_STRUCT, &can_fd_parameter);can_fd_parameter.fd_frame = ENABLE;can_fd_parameter.excp_event_detect = ENABLE;can_fd_parameter.delay_compensation = ENABLE;can_fd_tdc_parameter.tdc_filter = 0x04U;can_fd_tdc_parameter.tdc_mode = CAN_TDCMOD_CALC_AND_OFFSET;can_fd_tdc_parameter.tdc_offset = 0x04U;can_fd_parameter.p_delay_compensation = &can_fd_tdc_parameter;can_fd_parameter.iso_bosch = CAN_FDMOD_ISO;can_fd_parameter.esi_mode = CAN_ESIMOD_HARDWARE;/* CAN波特率 = 时钟频率 / 分频系数 / (1 + TSG1 + TSG2) *//* 数据段波特率 = 90M / 3 / (1 + 4 + 1) = 5M */can_fd_parameter.data_resync_jump_width = CAN_BT_SJW_1TQ;can_fd_parameter.data_time_segment_1 = CAN_BT_BS1_4TQ;  // TSG1can_fd_parameter.data_time_segment_2 = CAN_BT_BS2_1TQ;  // TSG2/* CAN-FD data segement prescaler should be the same as non-data segement prescaler */can_fd_parameter.data_prescaler = 3;                    // 分频系数/* initialize CAN-FD */can_fd_init(CAN1, &can_fd_parameter);/* initialize filter *//* configure filter mode */can_filter.filter_mode = CAN_FILTERMODE_MASK;can_filter.filter_bits = CAN_FILTERBITS_32BIT;/* configure filter ID */can_filter.filter_list_high = 0x0000U;can_filter.filter_list_low = 0x0000U;/* configure filter mask */can_filter.filter_mask_high = 0x0000U;can_filter.filter_mask_low = 0x0000U;/* select receiver fifo */can_filter.filter_fifo_number = CAN_FIFO1;  can_filter.filter_number = 15U;  // CAN_FCTL默认定义了CAN0和CAN1过滤器序号的分配数量,CAN0使用0-13序号,CAN1使用14-27,可以通过can1_filter_start_bank()修改can_filter.filter_enable = ENABLE;can_filter_init(CAN1, &can_filter);/* configure CAN1 NVIC */nvic_irq_enable(CAN1_RX1_IRQn, 1U, 1U);/* enable can receive FIFO0 not empty interrupt */can_interrupt_enable(CAN1, CAN_INTEN_RFNEIE1);
}int can1_send_message(void)
{uint8_t i;uint16_t id = 2;can1_tx_message.tx_sfid = id;can1_tx_message.fd_flag = 1;can1_tx_message.fd_brs = 1;can1_tx_message.fd_esi = 0;can1_tx_message.tx_dlen = 8;for(i = 0; i < 8; i++) {can1_tx_message.tx_data[i] = i;}
#if 0printf("\r\n can1 transmit data(id: 0x%x): ", can1_tx_message.tx_sfid);for(i = 0U; i < can1_tx_message.tx_dlen; i++) {printf(" %02x", can1_tx_message.tx_data[i]);}
#endif/* transmit message */if(can_message_transmit(CAN1, &can1_tx_message) != CAN_NOMAILBOX){return 1;}return 0;
}void CAN1_RX1_IRQHandler(void)
{/* check the receive message */can_message_receive(CAN1, CAN_FIFO1, &can1_rx_message);printf("\r\n can1 receive(id=0x%X) data: ", can1_rx_message.rx_sfid);for(int i = 0U; i < can1_rx_message.rx_dlen; i++) {printf(" %02x", can1_rx_message.rx_data[i]);}
}void can_user_init(void)
{// CAN0 initcan0_gpio_config();can0_config();/* initialize can0 transmit message */can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &can0_tx_message);/* initialize can0 receive message */can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &can0_rx_message);// CAN1 initcan1_gpio_config();can1_config();/* initialize can1 transmit message */can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &can1_tx_message);/* initialize can1 receive message */can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &can1_rx_message);printf("can init success\r\n");
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/405657.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CTF中的换表类Crypto题目

目录 [安洵杯 2019]JustBase[SWPUCTF 2021 新生赛]traditional字符替换解密 [BJDCTF 2020]base??字符替换 --》 base64解密 [安洵杯 2019]JustBase VGhlIGdlbxvZ#kgbYgdGhlIEVhcnRoJ#Mgc#VyZmFjZSBpcyBkb!pbmF)ZWQgYnkgdGhlIHBhcnRpY#VsYXIgcHJvcGVydGllcyBvZiB#YXRlci$gUHJ…

计量自动化终端上行通信规约

物理层 TCP 和 UDP 的传输接口 该类接口的登录链接和心跳检测采用链路测试服务&#xff0c;链路测试周期可设定。 参见 TCP/IP 协议规范。 串行通信传输接口 字节传输按异步方式进行&#xff0c;它包含 8 个数据位、1 个起始位“0”、1 个偶校验位 P 和 1 个停止位“1”。 …

测试流程自动化实践!

测试流程自动化的最佳实践涉及多个方面&#xff0c;旨在提高测试效率、确保测试质量&#xff0c;并降低测试成本。以下是一些关键的实践方法&#xff1a; 1. 明确测试目标 确定测试范围&#xff1a;在开始自动化测试之前&#xff0c;需要明确哪些功能、模块或场景需要被测试。…

共享内存及网络通信

共享内存 ------ 最高效的进程间通信 一个内核预留的空间&#xff0c;两进程绑定同一块共享空间 避免了用户空间 到 内核空间的数据拷贝 IPC 操作流程 key值 > 申请 >读写 >关闭 >卸载 1,产生key值 函数ftok key_t ftok(const char *pathname, int proj_id);…

Python 设置Excel工作表页边距、纸张大小/方向、打印区域、缩放比例

在使用Excel进行数据分析或报告制作时&#xff0c;页面设置是确保最终输出效果专业、美观的关键步骤。合理的页面设置不仅能够优化打印效果&#xff0c;还能提升数据的可读性。本文将详细介绍如何使用Python操作Excel中的各项页面设置功能。 目录 Python 设置Excel工作表页边…

调用大模型API-文心一言

一、准备工作 进入百度智能云千帆大模型平台&#xff0c;点击应用接入-创建应用&#xff1b;按提默认完成创建 二、开始使用 单轮调用 进入API列表 - ModelBuilder以第一个ERNIE-4.0-8K为例&#xff0c;选择“HTTP请求调用”&#xff0c;把第一步创建应用的 应用API Key、应…

汽车服务管理系统 _od8kr

TOC springboot580汽车服务管理系统 _od8kr--论文 系统概述 该系统由个人管理员和员工管理&#xff0c;用户三部分组成。其中&#xff1a;用户进入系统首页可以实现首页&#xff0c;热销汽车&#xff0c;汽车配件&#xff0c;汽车资讯&#xff0c;后台管理&#xff0c;在线客…

微服务的基本理解和使用

目录​​​​​​​ 一、微服务基础知识 1、系统架构的演变 &#xff08;1&#xff09;单体应用架构 &#xff08;2&#xff09;垂直应用架构 &#xff08;3&#xff09;分布式SOA架构 &#xff08;4&#xff09;微服务架构 &#xff08;5&#xff09;SOA与微服务的关系…

什么是UDP?

UDP是工作在OSI&#xff08;开放系统互连&#xff0c;Open Systems Interconnection&#xff09;模型中传输层的协议。它使用IP作为底层协议&#xff0c;是为应用程序提供一种以最少的协议机制向其他程序发送消息的协议。其主要特点是无连接&#xff0c;不保证可靠传输和面向报…

[机器学习]--线性回归算法

线性回归算法原理 线性关系在生活中有很多案例: 摄氏度和华氏度的转化: F C ⋅ 9 5 32 F C \cdot\frac{9}{5}32 FC⋅59​32学科最终成绩的计算: 最终成绩 0.3 \times 平时成绩 0.7 \times 期末成绩 线性回归(Linear regression)就是利用回归函数对一个或多个自变量…

Qt中英文支持

目的 就是想让QT编的软件支持中英文。 情况 1、首先配置项目的pro文件&#xff1a; 这样就会生成相应的翻译配置文件&#xff0c;当前是&#xff1a; translate1_cn.ts&#xff1a;中文的配置文件&#xff0c;因为一般默认就是中文&#xff0c;所以一般中文的翻译文件是不需…

小程序商城被盗刷,使用SCDN安全加速有用吗?

在电子商务蓬勃发展的今天&#xff0c;小程序商城因其便捷性和灵活性成为商家和消费者的新宠。然而&#xff0c;随着其普及&#xff0c;小程序商城的安全问题也日益凸显&#xff0c;尤其是盗刷现象频发&#xff0c;给商家和用户带来了巨大损失。面对这一挑战&#xff0c;是否可…

虚拟机安装centos7-桥接模式

1、打开虚拟机&#xff0c;点击文件&#xff0c;选择新建虚拟机 2、选择典型&#xff0c;点击下一步 3、选择稍后安装操作系统&#xff0c;点击下一步 4、选择系统类型及版本&#xff0c;点击下一步&#xff0c;因centos7是Linux操作系统&#xff0c;且是64位的&#xff0c;所以…

主存编址例题

知识点 存储单元个数最大地址-最小地址1 存储单元个数BFFFFH-80000H13FFFFH140000H 这是个十六进制&#xff0c;转换为十进制4*16^44*2^4^44*2^164*2^6*2^10字节 1kb1024字节2^10字节 因此可以转换为4*2^6kb256kb 1byte8bit&#xff0c;1个字节8比特 16k*4bit16*1024*0.5…

高性能web服务器

目录 一、简介 &#xff08;一&#xff09;nginx-高性能的web服务端 &#xff08;二&#xff09;用户访问体验 二、I/O模型 &#xff08;一&#xff09;概念 &#xff08;二&#xff09;网络I/O模型 &#xff08;三&#xff09;阻塞型 I/O 模型 &#xff08;四&#xf…

数据库MySQL之事务、索引

目录 1.概述 2.事务 3.索引 3.1索引结构 3.2操作语法 1.概述 场景&#xff1a;假如我们需要解散教学部&#xff0c;那么该部门下的所有员工都需要删除。如果教学部成功删除了&#xff0c;但员工出于某些原因(比如SQL语句写错了等)并没有删除&#xff0c;此时就会出现数据…

Unity Dots学习 (一)

先学习怎么使用&#xff0c;再研究底层代码。Dots大家都有所耳闻。一直没时间研究&#xff0c;最近研究一下 看上图可知&#xff0c;哪怕是CPU的第三级缓存也比内存要快2-5倍。 资料&#xff1a; 《DOTS之路》第零节——前导课(1)——DOTS的5W1H问题_哔哩哔哩_bilibili 《DOT…

保姆级-C#与Halcon的窗体界面展示阈值分割图像教程(机器视觉保姆级教程)

经历上一篇《零基础小白实现C#调用halcon dll的过程&#xff0c;并测试程序证明C#halcon联合开发成功》的发布已经过去三天啦&#xff0c; 零基础小白实现C#调用halcon dll的过程&#xff0c;并测试程序证明C#halcon联合开发成功-CSDN博客 在友友的催更下&#xff0c;我将用我…

人脸识别设计

总体思路 人脸识别使用的算法思路为&#xff1a;首先&#xff0c;定位一张图像中所有的人脸位置&#xff1b;其次&#xff0c;对于同一张脸&#xff0c;当光线改变或者朝向方位改变时&#xff0c;算法还能判断是同一张脸&#xff1b;然后找到每一张脸不同于其他脸的独特之处&a…

【秋招笔试】8.18大疆秋招(第一套)-后端岗

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 编程一对一辅导 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收…