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
}
}




