RS485 CAN Shield
| |||||||||||||||||
| |||||||||||||||||
说明
产品概述
RS485 CAN Shield 是微雪电子为 NUCLEO/XNUCLEO 开发的一款的带 RS485 和 CAN 通信功能的扩展 板,具备 RS485、CAN 通信功能。
产品特点
- 基于 Arduino 标准接口设计,兼容 UNO、Leonardo、NUCLEO、XNUCLEO 开发板
- 具备 RS485 功能,收发器为 MAX3485,3.3V 供电
- 具备 CAN 功能,收发器为 SN65HVD230,3.3V 供电
注意:RS485 CAN Shield 只能使用 3.3V 供电,UNO、Leonardo等Arduino由于硬件限制,无法使用CAN功能
硬件说明
MAX3485 简介
MAX3485 接口芯片是 Maxim 公司的一种 RS-485 驱动芯片。用于 RS-485 通信的低功耗收发器。
采用单一电源+3.3 V 工作,采用半双工通讯方式。RO 和 DI 端分别为接收器的输出和驱动器的输
入端;/RE和 DE 端分别为接收和发送的使能端,当/RE为逻辑 0 时,器件处于接收状态;当 DE 为
逻辑 1 时,器件处于发送状态;A 端和 B 端分别为接收和发送的差分信号端,当 A-B>+0.2V 时,
RO 输出逻辑 1;当 A-B<-0.2V 时,RO 输出逻辑 0。A 和 B 端之间加匹配电阻,一般可选 100Ω的
电阻。
引脚 | 功能 |
RO | 接收器输出 |
/RE | 接收输出使能 |
DE | 发送输出使能 |
DI | 输出驱动器输入 |
GND | 电源地线 |
A | 差分信号正向端 |
B | 差分信号反向端 |
VCC | 电源(3.3V) |
SN65HVD230简介
SN65HVD230 是德州仪器公司生产的 3.3V CAN 收发器,该器件适用于较高通信速率、良好抗干扰
能力和高可靠性 CAN 总线的串行通信。SN65HVD230 具有高速、斜率和等待 3 种不同的工作模式。
其工作模式控制可通过 Rs 控制引脚来实现。CAN 控制器的输出引脚 Tx 接到 SN65HVD230 的数据
输入端 D,可将此 CAN 节点发送的数据传送到 CAN 网络中;而 CAN 控制器的接收引脚 Rx 和
SN65HVD230 的数据输出端 R 相连,用于接收数据。
引脚 | 功能 |
D | 驱动输入 |
GND | 电源地线 |
VCC | 电源(3.3V) |
R | 接收输出 |
Vref | 参考输出 |
CANL | 低总线输出 |
CANH | 高总线输出 |
RS | 工作模式控制端 |
使用教程
准备工作
- RS485 CAN Shield 模块两个
- STM32 开发板两个(本手册用的是微雪电子的 Xnucleo 开发板,主控芯片是 STM32F103R)
- 杜邦线若干
跳线说明
- D14(PB_9)、D15(PB_8)分别作为默认 CAN 的发送端和接收端。
注:PB_9,PB_8 作为 STM32 CAN1 管脚时编程需打开管脚重映射。
GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
- D7(PA_8)是 RS485 的发送接收使能端,高电平时为发送状态,低电平时为接收状态。
- D8(PA_9)、D2(PA_10)和 D0(PA_2)、D1(PA_3)分别是 UART1 和 UART2 的发送端和接收端。可
- 通过 485 RXD/TXD JMP 跳线帽选择 UART1 或 UART2 作为 RS485 的输出输入端。
注:Xnucleo 默认 PA_2、PA_3 作为串口转 USB 端口。若要用 D0、D1 作为 RS485 的串口,则还需变换 Xnucleo 中 JP4 相应跳线。用跳线帽将 1、3 管脚短接,2、4 管脚短接。Xuncleo原理图中 JP4 串口跳线如下图所示:
- 模块间通信,CAN 端口的 H,L 分别和另一个模块的 CAN 端口 H,L 对接。RS485 端口的 A,B 分别和另一个模块的 RS485 端口 A,B 对接。
硬件连接
Shield | STM32 | 功能 |
VCC | 3.3V | 电源输入 |
GND | GND | 电源地 |
D2 | PA10 | RS485接收端 |
D8 | PA9 | RS485发送端 |
D7 | PA8 | RS485 发送接收使能端 |
D14 | PB9 | CAN发送端 |
D15 | PB8 | CAN接收端 |
D0、D1 将信息输出到 PC 端的串口。
软件工作原理
本测试程序采用 mbed 框架+STM32 库函数的形式,分为发送程序和接收程序两个程序。
CAN:
CAN 驱动程序采用 STM32 库函数编写,封装在 CAN.cpp 和 CAN.h 两个文件中。程序开始调用 CAN
初始化函数 CAN_Config()配置相关寄存器。
发送程序将要发送的数据保存在发送邮箱(TxMessage)中,再调用驱动函数
CAN_Transmit(CAN1, &TxMessage)发送出去。
而接收程序侧调用 CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);将接收到的数据保存
在接收邮箱(RxMessage)中。
RS485:
发送端程序控制 RS485_E 为高电平,使 RS485 处于发送状态,通过 RS485.printf 函数让数据
通过 RS485 串口发送出去。而接收程序则开启接收中断,程序控制 RS485_E 为低电平,使 RS485
处于接收状态,中断服务函数通过 RS485.scanf 扫描接收到的数据。
代码简介
发送端程序说明
/*CAN:程序开始调用 CAN 初始化函数,配置相关寄存器。CAN 通信侧建立一个发送邮箱 TXMsg, 将要发送的数据保存在邮箱中,再调用驱动函数发送出去。 RS485:控制 RS485_E 为高电平,使 RS485 处于发送状态,通过连接到 RS485 的串口将数据发送 出去。*/ #include "mbed.h" #include "CAN.h" Serial pc(D1,D0); //serial print message Serial RS485(D8, D2); //RS485_TX RS485_RX DigitalOut RS485_E(D7); //RS485_E CanTxMsg TxMessage; uint8_t TransmitMailbox = 0; int i =0,j=0; int main() { CAN_Config();//CAN initialize RS485_E = 1;//The RS485 transmission status was enabled /* TxMessage */ //Set the mailbox data to be sent TxMessage.StdId = 0x10; TxMessage.ExtId = 0x1234; TxMessage.RTR=CAN_RTR_DATA; TxMessage.IDE=CAN_ID_STD; TxMessage.DLC=8; TxMessage.Data[0] = 'C'; TxMessage.Data[1] = 'A'; TxMessage.Data[2] = 'N'; TxMessage.Data[3] = ' '; TxMessage.Data[4] = 'T'; TxMessage.Data[5] = 'e'; TxMessage.Data[6] = 's'; TxMessage.Data[7] = 't'; pc.printf( "**** This is a RS485_CAN_Shield Send test program ****\r\n"); while(1) { RS485.printf("ncounter=%d ",j);//RS485 Transmit Data wait(1); TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);//CAN Transmit Data i = 0; while((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK) && (i != 0xFFF)){ i++; } if(i == 0xFFF){ pc.printf("\r\can send fail\r\n");//Failed to send the packet due to timeout. Procedure } else{ pc.printf("\r\nCAN send TxMessage successfully \r\n"); //send successful } pc.printf("\r\nRS485 send: counter=%d\r\n",j++);//Print sending content pc.printf("The CAN TxMsg: %s\r\n",TxMessage.Data); wait(1); } }
接收端程序说明
/*CAN:程序开始调用 CAN 初始化函数,配置相关寄存器。接收端查询 FIFO 中是否有数据,有的 话,则将接收到的数据保存到接收邮箱 RxMessage 中,再通过串口打印出来。 RS485:使能 RS485 接收中断函数,控制 RS485_E 为低电平,使 RS485 处于接收状态,中断服务 函数通过 RS485.scanf 扫描接收到的数据。*/ #include "mbed.h" #include "CAN.h" Serial pc(D1,D0); //serial print message Serial RS485(D8, D2); //RS485_TX RS485_RX DigitalOut RS485_E(D7); //RS485_E CanRxMsg RxMessage; //RxMessage char s[1024]; void callback()//RS485 Receive interrupt handler function {// Note: you need to actually read from the serial to clear the RX interrupt RS485.scanf("%s",s);//Save received data pc.printf("\r\nRS485 Receive:%s \r\n",s);//Print receiving information } int main() { CAN_Config();//CAN initialize RS485.attach(&callback);//Enable RS485 receiving interruption RS485_E = 0;//The receiving status was enabled pc.printf( "**** This is a can receive test program ****\r\n"); while(1) { while(CAN_MessagePending(CAN1, CAN_FIFO0) < 1)//Waiting for data to arrive { } CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//CAN Receive Data pc.printf("The CAN RxMsg: %s\r\n",RxMessage.Data);//Print received data } }