最近做一个项目使用到ADM2587E,为了解决公司历史遗留的问题(ADM2587E芯片发烫,容易烧毁,485设备只能手拉手连接三四个,就通信不正常现象),认真阅读了Datasheet和官网LayOut的一些设计文档,在此做个总结。
ADM2587E是ADI公司推出的集成了iCoupler数字隔离的隔离型RS485/422收发器,输入/输出引脚具备±15kV静电放电(ESD)保护功能,适用于高速通信的多点传输线。ADM2582E/ADM2587E还内置了隔离的DC-DC电源,摒弃了外部DC-DC隔离模块的需求。
主要特色:
(1)隔离式RS485、RS422收发器,可设置半双工、全双工两种模式。
(2)内部封装了 isoPower隔离型DC-DC转换器,无需外部连接DC-DC电源芯片。
(3)DC5V或3.3V电源供电(使用3.3V功耗更小)。
(4)通信速率500kb/s,支持波特率115200。
(5)强大的保护功能,比如热关断保护、高共模瞬变抗扰度:>25 kV/μs等。
下载芯片的Datasheet ADM2587E | 隔离式 RS-485 接口 | 亚德诺(ADI)半导体
【注意:这个芯片一定要看Datasheet,一定要看Datasheet,一定要看Datasheet,重要事情说三遍,一切导致芯片发烫,通信不正常,串联设备数量不够,都是芯片使用错误导致!!!】
由Datasheet可知芯片引脚图如下:
其引脚定义为:
翻译:
Pin No. | Mnemonic | Description |
1 | GND1 | 地,逻辑侧地 |
2 | VCC | 逻辑侧电源。建议在引脚2和引脚1之间安装一个0.1µF和一个0.01 µF的分流电容 |
3 | GND1 | 地,逻辑侧地 |
4 | RXD | 接收器输出数据。(注意:此引脚和主芯片的RX引脚连接) |
5 | \RE | 接收器使能输入。低电平时,输入有效 |
6 | DE | 发送器使能输入。高电平时,输出有效 |
7 | TXD | 驱动器输入数据(注意:此引脚和主芯片的TX引脚连接) |
8 | VCC | 逻辑侧电源。建议在引脚 8 和引脚 9 之间放置一个 0.1 µF 和一个 10 µF 的分流电容 |
9 | GND1 | 地,逻辑侧地 |
10 | GND1 | 地,逻辑侧地 |
11、14 | GND2 | 隔离式DC-DC转换器的GND,建议通过一个磁珠将引脚 11 和引脚 14 连接到 PCB 地线上 |
12 | VISOOUT | VISOOUT,隔离电源输出。必须外部连接到 VISOIN。建议在引脚 12 和引脚 11 之间放置一个 10 µF 的储备电容和一个 0.1 µF 的分流电容 |
13 | Y | 驱动器的非反相输出 |
15 | Z | 驱动器的反相输出 |
16 | GND2 | 地线,总线侧。不要将此引脚连直接接到引脚 14 和引脚 11 |
17 | B | 接收器的反相输入 |
18 | A | 接收器的非反相输入 |
19 | VISOIN | 隔离电源输入。必须外部连接到 VISOOUT。建议在引脚 19 和引脚 20 之间放置一个 0.1 µF 和一个 0.01 µF 的分流电容。通过磁珠将此引脚连接到 VISOOUT |
20 | GND2 | 地线,总线侧 |
其典型电路(半双工RS485)如图所示:
图中,左侧为公共GND,右侧为信号GND。磁珠L1和L2型号为BLM15HD182SN1D
0402封装,阻抗1.8kΩ@100MHz。TVS型号为P6KE6.8A。
原理图主要是要注意如下:
(1)引脚4和引脚7和主芯片连接不能接错,不能看到引脚4名称为RXD,就和主控芯片的TXD连接,引脚7同理。
(2)引脚12必须和引脚19连接,这个是芯片内部DC-DC,提供3.3V电压。有的工程师,参考网上电路,将引脚12和19连接后,又外接了5V或者3.3V外部电源,由于外部电源不够稳定,极易造成芯片发烫,甚至烧毁。
(3)瞬态电压抑制管我是建议接上的,特别在室外长距离传输,不接容易损坏芯片。
(4)L1、L2磁珠,可以选择性连接,试验了,问题不大,但是应该会使通信干扰增加。
(5)GND2和GND1共地,问题不大,但是会失去隔离芯片最大的隔离特性。
(6)输出A、B两根线也行,不引入信号地,通信没问题。
(7)RS485跨接的120Ω,如果多设备连接,手拉手接在设备的末端即可。
由datasheet可知,需要注意的是:
为了抑制噪声,需要低感抗、高频率的电容;而为了抑制纹波并保持稳压,需要较大容值的电容。电源侧的电容连接在引脚 1(GND1)与引脚 2(VCC),以及引脚 8(VCC)与引脚 9(GND1)。 VISOIN 和 VISOOUT 电容器分别连接在引脚 11(GND2)与引脚 12(VISOOUT),以及引脚 19(VISOIN)与引脚 20(GND2)。
为了实现噪声抑制和纹波减小,并联的电容容值较小的电容应该靠近芯片。电容值推荐为:
(1)引脚 11 和引脚 12 处的 VISOOUT 分别为 0.1 µF 和 10 µF
(2)引脚 8 和引脚 9 处的 VCC 分别为 0.1 µF 和 0.01 µF。
(3)引脚 19 和引脚 20 处的 VISOIN,引脚 1 和引脚 2 处的 VCC,电容值分别为 0.01 µF 和 0.1 µF。
(4) 拼接电容尽可能靠近GND1(引脚9和引脚10)以及GND2(引脚11)。
(5) 为了降低PCB走线的电感效应,最好避免使用很窄和很长的走线。
(6)为使拼接电容有效,必须将电容直接连到引脚11,即GND2(器件引脚和铁氧体磁珠之间)
(7)引脚11和引脚14上的GND2连接先通过PCB走线连在一起,然后连接到铁氧体磁珠。为了降低辐射,必须确保这两个GND2引脚先通过铁氧体磁珠连接,再连接到PCB GND2和GND2(引脚16和引脚20)。
(8)Layout时,电容器引线总长度与输入电源引脚之间的距离不应超过 10 mm。
Datasheet推荐引脚电容和磁珠连接图如下:
Datasheet推荐引脚电容放置图和PCB布局如下:
GD32F103ZET6的UART3和ADM2587E程序设计(半双工),引脚PC10(连接 ADM2587E的引脚7)和PC11(连接 ADM2587E的引脚4),PD3和ADM2587E的使能引脚5、6连接。
【注意:GD32F103ZET6是国产芯片,平替STM32F103ZET6,故STM32F103可以直接参考(也可以参考我之前STM32串口通信文章)】
1、初始化UART3
//!----------------------------------------------------------
//!-------------------> Local Defines <----------------------
//!----------------------------------------------------------
#define USART_DATA_LEN 64
//!----------------------------------------------------------
//!--------------------> Local Variables <-------------------
//!----------------------------------------------------------
volatile uint16_t usart3_rx_cnt = 0;
uint16_t usart3_rx_buf[USART_DATA_LEN] = {0};
/*!
================================================================================
@Brief
USART3 config(void).
@Param
null
@Return
null
-------------------------------------------------------------------------------
*/
void USART3_Config(void)
{
rcu_periph_clock_enable(RCU_GPIOC); // 使能GPIO时钟
rcu_periph_clock_enable(RCU_UART3); // 使能串口时钟
gpio_init(GPIOC, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10); // 发送引脚初始化 TX
gpio_init(GPIOC, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11); // 接收引脚初始化 RX
usart_deinit(UART3); // 串口复位
usart_word_length_set(UART3, USART_WL_8BIT); // 字长
usart_stop_bit_set(UART3, USART_STB_1BIT); // 停止位
usart_parity_config(UART3, USART_PM_NONE);
usart_baudrate_set(UART3, 9600U); // 波特率
usart_receive_config(UART3, USART_RECEIVE_ENABLE); // 接收使能
usart_transmit_config(UART3, USART_TRANSMIT_ENABLE); // 发送使能
usart_hardware_flow_rts_config(UART3, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(UART3, USART_CTS_DISABLE);
usart_enable(UART3); // 串口使能
nvic_irq_enable(UART3_IRQn, 0, 0);//使能UART3中断
usart_interrupt_flag_clear(UART3, USART_INT_RBNE);//接收缓冲区非空中断
usart_interrupt_flag_clear(UART3, USART_INT_IDLE);//接收空闲中断打开
usart_interrupt_enable(UART3, USART_INT_RBNE);//接收缓冲区非空中断
usart_interrupt_enable(UART3, USART_INT_IDLE);//接收空闲中断打开
}
/*!
================================================================================
@Brief
USART3 enable(void).
@Param
null
@Return
null
-------------------------------------------------------------------------------
*/
void USART3_RX_Enable(void)
{
gpio_init(GPIOD, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3); // UART3 Enable:PD3 OUTPUT
gpio_bit_reset(GPIOD, GPIO_PIN_3); // PIN Low:Rx; High:Tx
}
/*!
================================================================================
@Brief
USART3 enable(void).
@Param
null
@Return
null
-------------------------------------------------------------------------------
*/
void USART3_TX_Enable(void)
{
gpio_init(GPIOD, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3); // UART3 Enable:PD3 OUTPUT
gpio_bit_set(GPIOD, GPIO_PIN_3); // PIN Low:Rx; High:Tx
}
/*!
================================================================================
@Brief
UART3 Interrupt receive. (PC)
@Param
null
@Return
null
-------------------------------------------------------------------------------
*/
void UART3_IRQHandler(void)
{
if(RESET != usart_interrupt_flag_get(UART3, USART_INT_FLAG_RBNE))
{
usart3_rx_buf[usart3_rx_cnt++] = usart_data_receive(UART3); // 接收串口数据
}
else if(RESET != usart_interrupt_flag_get(UART3, USART_INT_FLAG_IDLE))
{
usart_data_receive(UART3); //清除空闲中断标志
//USART_SendData(UART3,usart3_rx_buf, usart3_rx_cnt);
//控制逻辑在此添加
usart3_rx_cnt = 0;
memset(usart3_rx_buf, 0, sizeof(usart3_rx_buf));
}
}
PS,全双工,简易电路如下: