基于STM32/GD32的双CAN、一路485开发板
双CAN开发板
- 双CAN、一路485开发板的设计
- 开发板配置
- 器件选型
- CAN设计
- 硬件设计
- 软件设计
- 485设计
- 硬件设计
- 软件设计
- 其他设计
- LED硬件
- 按键硬件
- PCB板子和实物图
- 开发板测试视频
- 其他资料
双CAN、一路485开发板的设计
最近工作经常会出现一些小问题。就想设计一款带CAN的开发板用来测试代码,于是就设计了一款双CAN带一路485的开发板。 此篇文章是关于开发板的设计方案。
开发板配置
- 双路CAN通信
- 一路485通信(两路串口可选)
- 一个EEPROM存储
- 三个LED指示灯
- 三个按键
- 其余所有IO口引出
器件选型
主控采用了国产兆易的GD互联型芯片,有两路CAN通信,CAN采用目前比较流程TJA1057方案。以下是主要的器件选型:
- 主控MCU :GD32F105RBT6;
- CAN芯片:TJA1057T;
- 485芯片:MAX3485ESA;
- EEPROM芯片:AT24C128;
- 电源芯片芯片:ASM1117-3.3V;
CAN设计
硬件设计
CAN设计采用TJA1057T设计,由于TJA1057T是5V芯片,需要在Rx到单片机采用一个电压转换电路。为了节省成本,我们采用一个分压电阻,将电压调试到3.3V。设计还并联了一个120欧的匹配电阻,和一个跳线帽串联起来,用户可以通过跳线帽先择是否接入120电阻。这题设计如图所示。

软件设计
CAN波特率计算:波特率 = APB1频率 / CAN分频 / (BS1 + BS2 +1);
这里初始化采用的是掩码模式,掩码中设置的为1时,报文ID为必须匹配,掩码为0时报文ID为无关紧要。例如ID为:0x18FF1111。当掩码设置为0x1FFF FFFF时。只有接收到0x18FF1111才会通过滤波进入CAN接收中断。当掩码设置为0x1FFFFFFE时,可以接收到0x18FF1110和0x18FF1111。
void SysInit_CAN(void)
{/* CANs configuration */CAN_Config();/* IT Configuration for CAN1 */can_interrupt_enable(CAN0, ENABLE);can_interrupt_enable(CAN1, ENABLE);
}
/*CAN初始化*/
void CAN_Config(void)
{uint32_t id ;can_parameter_struct CAN_InitStructure;can_filter_parameter_struct CAN_FilterInitStructure;rcu_periph_clock_enable(RCU_GPIOA);rcu_periph_clock_enable(RCU_GPIOB);rcu_periph_clock_enable(RCU_CAN0);rcu_periph_clock_enable(RCU_CAN1);rcu_periph_clock_enable(RCU_AF);/* Configure CAN1 RX pin */gpio_pin_remap_config(GPIO_CAN0_PARTIAL_REMAP, ENABLE);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_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_10MHZ, GPIO_PIN_12);gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_13);/* Configure CAN1 TX pin *//* CAN1 and CAN2 register init */can_deinit(CAN0);can_deinit(CAN1);/* initialize CAN */CAN_InitStructure.time_triggered = DISABLE;CAN_InitStructure.auto_bus_off_recovery = ENABLE;CAN_InitStructure.auto_wake_up = DISABLE;CAN_InitStructure.auto_retrans = DISABLE;CAN_InitStructure.rec_fifo_overwrite = DISABLE;CAN_InitStructure.trans_fifo_order = DISABLE;CAN_InitStructure.working_mode = CAN_NORMAL_MODE;CAN_InitStructure.resync_jump_width = CAN_BT_SJW_1TQ;CAN_InitStructure.time_segment_1 = CAN_BT_BS1_6TQ;CAN_InitStructure.time_segment_2 = CAN_BT_BS2_1TQ;/* baudrate 250K bps */CAN_InitStructure.prescaler = 6;can_init(CAN0, &CAN_InitStructure);CAN_InitStructure.prescaler = 6;can_init(CAN1, &CAN_InitStructure);/* initialize filter */id = 0x18ffffff;//需过滤的EXT_ID/* CAN0 filter number */CAN_FilterInitStructure.filter_number = 0;/* initialize filter */CAN_FilterInitStructure.filter_mode = CAN_FILTERMODE_MASK;CAN_FilterInitStructure.filter_bits = CAN_FILTERBITS_32BIT;CAN_FilterInitStructure.filter_list_high = (((u32)id <<3)&0xFFFF0000)>>16;;CAN_FilterInitStructure.filter_list_low = (((u32)id <<3)|CAN_FF_STANDARD|CAN_FF_EXTENDED)&0xFFFF;;CAN_FilterInitStructure.filter_mask_high = 0x0000;CAN_FilterInitStructure.filter_mask_low = 0x0000;CAN_FilterInitStructure.filter_fifo_number = CAN_FIFO0;CAN_FilterInitStructure.filter_enable = ENABLE;can_filter_init(&CAN_FilterInitStructure);/* initialize filter */id = 0x18ffffff;//需过滤的EXT_ID/* CAN0 filter number */CAN_FilterInitStructure.filter_number = 15;/* initialize filter */CAN_FilterInitStructure.filter_mode = CAN_FILTERMODE_MASK;CAN_FilterInitStructure.filter_bits = CAN_FILTERBITS_32BIT;CAN_FilterInitStructure.filter_list_high = (((u32)id <<3)&0xFFFF0000)>>16;;CAN_FilterInitStructure.filter_list_low = (((u32)id <<3)|CAN_FF_STANDARD|CAN_FF_EXTENDED)&0xFFFF;;CAN_FilterInitStructure.filter_mask_high = 0x0000;CAN_FilterInitStructure.filter_mask_low = 0x0000;CAN_FilterInitStructure.filter_fifo_number = CAN_FIFO0;CAN_FilterInitStructure.filter_enable = ENABLE;can_filter_init(&CAN_FilterInitStructure);can_interrupt_enable(CAN0, CAN_INT_RFNE0);can_interrupt_enable(CAN1, CAN_INT_RFNE0);
}
/*CAN0接收中断*/
void CAN0_RX0_IRQHandler(void)
{Init_RxMes(&RxMessage);can_message_receive(CAN0, CAN_FIFO0, &RxMessage);CAN0_RXData();
}
/*CAN1接收中断*/
void CAN1_RX0_IRQHandler(void)
{Init_RxMes(&RxMessage);can_message_receive(CAN1, CAN_FIFO0, &RxMessage);CAN1_RXData();
}
485设计
485硬件设计采用了自动收发报文的设计。具体实现方案可以自行百度搜索。
硬件设计

软件设计
软件就是一般的串口初始化。
/*IO口初始化*/
void usart_init(void)
{rcu_periph_clock_enable(RCU_GPIOA);rcu_periph_clock_enable(RCU_AF);rcu_periph_clock_enable(RCU_USART0);gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);usart_deinit(USART0);usart_baudrate_set(USART0, 9600);usart_word_length_set(USART0, USART_WL_8BIT);usart_stop_bit_set(USART0, USART_STB_1BIT);usart_parity_config(USART0, USART_PM_NONE);usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);usart_receive_config(USART0, USART_RECEIVE_ENABLE);usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);usart_enable(USART0);usart_interrupt_enable(USART0, USART_INT_RBNE);nvic_irq_enable(USART0_IRQn,1,2);
}/* retarget the C library printf function to the usart */
int fputc(int ch, FILE *f)
{usart_data_transmit(USART0, (uint8_t) ch);while (RESET == usart_flag_get(USART0, USART_FLAG_TBE));return ch;
}
/*串口0接收中断*/
void USART0_IRQHandler(void)
{uint16_t data;if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)){/* receive data */data = usart_data_receive(USART0);usart_data_receive(USART0);}
}
其他设计
LED硬件
硬件LED采用的是共阴极,IO口驱动的话输出高电平LED点亮。
按键硬件
硬件按键采用的是监测地。配置IO口时要配置为上拉输入。当IO口监测到低电平时表示按键按下。

PCB板子和实物图


开发板测试视频
板子焊接好后,按照如图所示插上相应的跳线帽,通过5VType-C口给模块供电。测试代码固件烧录进去之后,三个LED点亮,其中一个LED0.5HZ频率闪烁。按下按键后,相应的LED灯切换状态。串口波特率为9600,并且每1秒输出
Shiboven PCB-018 测试固件 V1.0 CAN测试请使用5VUSB供电。两路CAN波特率都为250k。两路CAN都是250K波特率并每1秒输出一路为:ID0x12345678,另一路为0x17654321。
注意:CANH、CANL别接反了。485A、485B也别接反了!!!
双CAN+一路485演示视频演示视频
其他资料
资料包中有硬件软件源码及其他资料。包括一堆CAN资料包。
相关文章:
基于STM32/GD32的双CAN、一路485开发板
双CAN开发板 双CAN、一路485开发板的设计开发板配置器件选型CAN设计硬件设计软件设计 485设计硬件设计软件设计 其他设计LED硬件按键硬件 PCB板子和实物图开发板测试视频其他资料 双CAN、一路485开发板的设计 最近工作经常会出现一些小问题。就想设计一款带CAN的开发板用来测试…...
快排/堆排/归并/冒泡/
常见的内排序算法 插入排序 直接插入排序 原理:相当于扑克牌变成有序,先拿第一张,把他调节成有序,再拿第二张,与第一张相比找到第二张的位置,再继续拿第三张,以此类推。 void InsertSort(in…...
React基础教程(08):state体验
文章目录 7、state再体验7.1 异步更新状态7.2 同步更新状态方式17.3 同步更新状态方式27.4 betterScroll7.5 列表案例7、state再体验 7.1 异步更新状态 完整代码 import React from "react";export default class App extends React.Component{state = {count:1,}…...
Win10 创建新的桌面2,并实现桌面切换
1. Win10 创建新的桌面2 Win - Tab 2. Win10 桌面切换 Ctrl - Win - ←/→ 我们下期见,拜拜!...
MySQL数据库介绍及基础操作
目录: 一.数据库介绍 二.数据库分类 三. 数据库的操作 四. 常用数据类型 五. 表的操作 一.数据库介绍 1.文件保存数据有以下几个缺点: 1.1文件的安全性问题 1.2文件不利于数据查询和管理 1.3文件不利于存储海量数据 1.4文件在程序中控制不方便 为了解决上述问题&…...
【C语言篇】C语言常考及易错题整理DAY2
文章目录 C语言常考及易错题整理选择题编程题至少是其他数字两倍的最大数两个数组的交集图片整理寻找数组的中心下标多数元素除自身以外数组的乘积不使用加减乘除求两个数的加法 C语言常考及易错题整理 选择题 下列 for 循环的次数为( ) for(int i 0…...
javase入门
最近在学习大数据,学到flume拦截器的时候发现自定义拦截器需要使用java编写,现在开始学一些java入门的东西. 一. java相关组成 path环境变量: 环境变量用于记住程序路径,方便在命令行窗口任意目录启动程序. 二 java中的变量 变量要先定义在使用. int age 15 定义变量要定义其…...
Wireshark显示过滤器大全:快速定位网络流量中的关键数据包
文章目录 一、简介二、wireshark中的逻辑运算符三、过滤示例集合3.1 过滤指定日期和时间3.2 过滤指定协议3.2.1 例:仅显示SMTP(端口 25)和ICMP流量:3.2.2 例如:Windows 客户端 - DC 交换 3.3 过滤指定网段(…...
OOP笔记4----抽象类、接口、枚举
抽象类 简介 父类可以封装不同子类的共同特征或者共同行为.而有的时候,父类中封装的方法无法具体完成子类中需要的逻辑,因此我们可以将此方法设计成抽象方法,即使用关键字abstract进行修饰。而有抽象方法的类,也必须使用abstract…...
MySQL面试题全解析:准备面试所需的关键知识点和实战经验
MySQL有哪几种数据存储引擎?有什么区别? MySQL支持多种数据存储引擎,其中最常见的是MyISAM和InnoDB引擎。可以通过使用"show engines"命令查看MySQL支持的存储引擎。 存储方式:MyISAM引擎将数据和索引分别存储在两个不…...
01_Electron 跨平台桌面应用开发介绍
Electron 跨平台桌面应用开发介绍 一、Electron 的介绍二、关于 NW.js 和 Electron 介绍三、搭建 Electron 的环境1、准备工作:2、安装 electron 环境3、查看 electron 的版本,electron -v 一、Electron 的介绍 Electron 是由 Github 开发的一个跨平台的…...
【C语言-扫雷游戏】mineweeper【未完成】
编程小白如何成为大神?大学新生的最佳入门攻略 编程已成为当代大学生的必备技能,但面对众多编程语言和学习资源,新生们常常感到迷茫。如何选择适合自己的编程语言?如何制定有效的学习计划?如何避免常见的学习陷阱&…...
psychopy stroop 实验设计
斯特鲁stroop实验就是色词一致/不一致实验。 设计步骤如下: 1. 先去设置中将Input改为PsychToolbox, 2. 然后左上角File-New新建一个 3. 右键trial,rename改名 改成自己想要的名字即可,比如欢迎界面welcome。 4. 接下来添加提示语…...
c++精品小游戏(无错畅玩版)
一、俄罗斯方块 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #include <conio.h> #include <windows.h>#ifdef _MSC_VER // M$的编译器要给予特殊照顾 #if _MSC_VER < 1200 // VC6及以下版本 #err…...
应急响应-主机安全之系统及进程排查相关命令(Linux操作系统-初级篇)
目录 概述lscpu-显示有关CPU架构的信息uname-查看系统信息lsmod-输出加载的所有模块lastb-输出最后登录失败的用户last-展示用户最近登录信息lastlog-展示所有用户最后的登录时间systemctl-系统服务,开机自启排查crontab-计划任务选项 history-查看历史命令选项常用…...
java中RSA分段加解密及Data must not be longer than异常处理
谈到RSA非对称加密,作为开发的我们第一想到的是安全,几乎不会被破解,以及公钥加密,私钥解密这些。在Java代码中,我们常使用一些现成的工具类如hutool中提供的工具类、网上在线的或者博客上的RSAUtils工具类来实现公钥私…...
MySQL数据分析进阶(十二)设计数据库——PART3
※食用指南:文章内容为‘CodeWithMosh’SQL进阶教程系列学习笔记,笔记整理比较粗糙,主要目的自存为主,记录完整的学习过程。(图片超级多,慎看!) 【中字】SQL进阶教程 | 史上最易懂S…...
Kubernetes-1.22.0 可视化部署
目录 Kubeadm方式部署3master,2work集群(Kubernetes-1.22.0)-CSDN博客 1. 官方Dashboard 2. Kuboard 部署 3. Rainbond 部署 4. Kubesphere 部署 1. 官方Dashboard kubectl apply -f https://kuboard.cn/install-script/k8s-dashboard/v2…...
在 vue3 中动态路由问题记录
第一种 如果这样子的话需要加上 /* vite-ignore / ,但是在这样用这行部署服务器上跳转会有问题 component: () > import(/ vite-ignore */ ../views/ e.component .vue) 第二种 // 解决跳转问题const modeules imporet.meta.glob(/views/**/**.vue)component: modules…...
进程编程及其函数的使用
1. 创建进程 创建进程的核心操作是使用 fork() 系统调用。 1.1 fork() 系统调用 fork() 创建一个新进程(子进程),新进程几乎是父进程的完整拷贝。fork() 返回两次: 在父进程中,返回子进程的 PID。在子进程中&#…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
前端高频面试题2:浏览器/计算机网络
本专栏相关链接 前端高频面试题1:HTML/CSS 前端高频面试题2:浏览器/计算机网络 前端高频面试题3:JavaScript 1.什么是强缓存、协商缓存? 强缓存: 当浏览器请求资源时,首先检查本地缓存是否命中。如果命…...
QT开发技术【ffmpeg + QAudioOutput】音乐播放器
一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下,音视频内容犹如璀璨繁星,点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频,到在线课堂中知识渊博的专家授课,再到影视平台上扣人心弦的高清大片,音…...
机器学习的数学基础:线性模型
线性模型 线性模型的基本形式为: f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法,得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章 摘要: 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言,受限于 C 语言本身的内存安全和并发安全问题,开发复杂模块极易引入难以…...
React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?
系列回顾: 在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒&#…...
【技巧】dify前端源代码修改第一弹-增加tab页
回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码,在知识库增加一个tab页"HELLO WORLD",完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...

