无法建立正确的 RS485 通信

Cannot establish proper RS485 communication

我正在尝试使用 ATmega32 进行串行通信。首先,我使用 RS232,使用 USB-to-RS232 建立使用串行终端的接收和传输(在我的例子中是 tera 术语)。无论我从串行终端 Atmega32 发送什么,都会回显它。

例如。我发送 Hello\r 并收到 'Hello\r'

它工作正常。

然后我使用 RS485,使用 USB-to-RS485 与 ATmega32 建立通信,但我只得到 return 中的第一个字符。

例如。如果我发送 Hello,我会返回 H。如果我发送 planets 我在 return 中只得到 p

代码如下:

void Delay(int ms)
{
    int i;
    for (i=0;i<ms;i++)
    _delay_ms(1);

}

void UART_Init(unsigned int baud)
{
    UBRRH = (unsigned char)(baud >> 8);
    UBRRL = (unsigned char)baud;

    UCSRB = (1<<RXEN)  | (1<<TXEN) | (1<<RXCIE);
    UCSRC = (1<<URSEL) | (3<<UCSZ0);
}

void UART_Transmit(unsigned char data)
{
    UDR = data;
    while ( !( UCSRA & (1<<UDRE) ) );
}


void USART_Transmit_String( char *string)
{
    while (*string != 0)
    UART_Transmit(*string++);
}


void Clear_Buffer(char *string)
{
    while (*string != '[=10=]')
    {
        *string = 0;
        string++;
    }
}

ISR(USART_RXC_vect)
{
    uartBuff[datapos] = UDR;
    if (uartBuff[datapos] == '\r')
    {
        eos = 1;
    }
    datapos++;
    if (datapos > SIZE)
    {
        datapos = 0;
        Clear_Buffer(uartBuff);
    }
}

int main(void)
{
    _delay_ms(1000);
    UART_Init(103);
    sei();
    LED_Enable();
    LED_High();
    Delay(100);
    LED_Low();
    Delay(100);

    RE_DE_Enable();
    RE_DE_High();
    USART_Transmit_String("Hello World");
    UART_Transmit(0x0d);
    UART_Transmit('\n');
    Delay(1000);
    datapos = 0;
    eos = 0;
    RE_DE_Low();
    while (1) 
    {
        if (strstr(uartBuff,"led on\r"))
        {
            LED_High();
        }
        if (strstr(uartBuff,"led off\r"))
        {
            LED_Low();
        }

        if (eos == 1)
        {
            RE_DE_High();
            uartBuff[datapos] = '[=10=]';
            USART_Transmit_String("\r\n");
            USART_Transmit_String(uartBuff);
            USART_Transmit_String("\r\n");
            Clear_Buffer(uartBuff);
            datapos = 0;
            eos = 0;
            RE_DE_Low();
        }

    }
}

为什么会出现这种异常?

如何纠正这个错误?

任何建议都会有所帮助。

提前致谢

485传输数据时需要精确的线路控制。 UDRE 表示可以加载数据。 TXC 表示数据已发送。只有在传输完最后一位后才应释放该线路。我相信这就是它在 rs232 中工作而在 rs485 中失败的原因。

在查看这篇文章时对谁在传输什么感到有点困惑 post 所以有以下评论:

1) 简化 Atmel 代码以仅流出 "Hello World %d" + CR 并继续递增行 #。现在,保持通信速度@ 9600 波特。从 Atmel 到 USB RS485 加密狗的流量是否 100% 成功接收?在此之前不要继续。

2) 您在此设计中为 Atmel 端使用了哪个 RS485 收发器?市场上有很多垃圾,并不是所有的收发器都是一样的。

3) 您使用的是哪种 USB RS485 加密狗?根据(2),只有少数是可靠的。如果使用透明的 FTDI USB RS485 加密狗,请非常仔细地检查塑料内部压印的 RS485 收发器。 FTDI 承认他们推出了一些基于 Sipex 收发器的易碎加密狗电缆。从我们的简短审查来看,相信是设计出了问题,而不是收发器。不过不管怎样,现在dongle被封了,同款有bug的dongle是没办法改正的

我们构建了一些可靠的适配器,但不希望将其变成广告,所以让我们看看是否可以调试您的案例。 Post 更多详情待续。

希望将其添加到您的 RS485 接收器引脚上,确保有一个本地上拉电阻到 +3v3。当 RS485 接收器被禁用时,这需要在 UART 的 Atmel 接收上具有高状态。也就是说,当 RS485 接收器被禁用时,RX 引脚为高阻态。已知 10k 的值是好的,该值并不重要,但建议使用上拉。

更新

我想我理解你项目的观点。如果我错了请更正。您是否尝试使用 Teraterm + USB RS485 加密狗通过 RS485 向 Atmel 发送文本并希望 Atmel 将数据发送回您的 Teraterm?如果是,那么如果您在 Teraterm 中输入此数据,则结果是合乎逻辑的。请确认此设置。

也就是说,您是否正在输入 "Hello world" 并希望收到此文本?

这个想法的问题是 PC 发送数据的速度比您键入的速度快。相反,请查看如何使用 Teraterm 以宏形式发送块中的整个字符串。只有这种方法适用于您的想法。当您打字时,Teraterm 会通过 RS485 接口等发送(也就是刷新 tx 缓冲区)"H",因此您不会在单个接收块中收到整个字符串。

考虑使用 Teraterm 的宏在一次发送中发送 "Planets",等等。关键点是你想发送的每个字符之间没有延迟。