简体   繁体   English

无法建立正确的RS485通讯

[英]Cannot establish proper RS485 communication

I was trying serial communication using ATmega32 . 我正在尝试使用ATmega32串行通信。 First i used RS232, using USB-to-RS232 to establish receive and transmit using serial terminal(in my case tera term). 首先,我使用RS232,使用USB-to-RS232通过串行终端(在我的情况下为术语)建立接收和发送。 Whatever i send from serial terminal Atmega32 echo it back. 我从串行终端Atmega32发送的任何内容都将其回显。

for eg. 例如 i send Hello\\r and i receive 'Hello\\r' 我发送Hello\\r ,我收到“ Hello \\ r”

It is working fine. 一切正常。

Then i used RS485, using USB-to-RS485 to establish communication with ATmega32 but i only get 1st character in return. 然后我使用RS485,使用USB-to-RS485与ATmega32建立通信,但我只得到第一个字符。

for eg. 例如 if i send Hello i get back H . 如果我发送Hello我将返回H if i send planets i get only p in return. 如果我送出planets我只能得到p的回报。

Here is the code: 这是代码:

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 != '\0')
    {
        *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] = '\0';
            USART_Transmit_String("\r\n");
            USART_Transmit_String(uartBuff);
            USART_Transmit_String("\r\n");
            Clear_Buffer(uartBuff);
            datapos = 0;
            eos = 0;
            RE_DE_Low();
        }

    }
}

Why this type of abnormality? 为什么会出现这种异常?

How to rectify this error? 如何纠正此错误?

Any suggestions will be helpful. 任何建议都会有所帮助。

Thanks in advance 提前致谢

Getting a bit confused on who is transmitting what in reviewing this post so have the following comments: 对于谁在转发此帖子时传递的内容有些困惑,因此有以下评论:

1) simplify the Atmel code to only stream out "Hello World %d" + CR and keep incrementing the line #. 1)简化Atmel代码,使其仅输出“ Hello World%d” + CR,并继续增加行号。 For now, keep com speed @ 9600 baud. 现在,保持通讯速度为9600波特。 Does this traffic from the Atmel to the USB RS485 dongle get received with 100% success? 从Atmel到USB RS485加密狗的流量能否成功获得100%的接收? Do not continue till this does. 在此之前不要继续。

2) Which RS485 transceiver are you using in this design for the Atmel side? 2)在本设计中,您在Atmel侧使用哪个RS485收发器? There is a lot of garbage on the market and not all transceivers are created equal. 市场上有很多垃圾,并非所有收发器都是一样的。

3) Which USB RS485 dongle are you using? 3)您正在使用哪个USB RS485加密狗? As per (2), only few are reliable. 根据(2),只有极少数是可靠的。 If using the clear FTDI USB RS485 dongle then review very carefully on which RS485 transceiver is embossed inside the plastic. 如果使用透明的FTDI USB RS485加密狗,请非常仔细地检查在塑料内部压印了哪个RS485收发器。 FTDI has admitted they put out some flaky dongle cables based on the Sipex transceiver. FTDI承认他们推出了一些基于Sipex收发器的易碎加密狗电缆。 From our brief review, believe the design was at fault and not the transceiver. 从我们的简要回顾中,我们相信设计是错误的,而不是收发器。 However, regardless, now that the dongle is sealed, the same buggy dongle cannot be corrected. 但是,无论如何,由于加密狗已密封,因此无法修正同一越野车加密狗。

We build some solid adapters but do not wish to turn this into an ad so let us see if we can debug your case. 我们构建了一些可靠的适配器,但不希望将其转换为广告,因此让我们看看是否可以调试您的情况。 Post more details to continue. 发布更多详细信息以继续。

Wish to add that on your RS485 receiver pin, be sure there is a local pull-up resistor to +3v3. 希望在RS485接收器引脚上添加该引脚,请确保在+ 3v3处有一个本地上拉电阻。 This is required to have a high state on the Atmel receive of the UART when the RS485 receiver is DISABLED. 当RS485接收器被禁用时,要求在UART的Atmel接收上具有高状态。 That is, when the RS485 receiver is disabled, the RX pin is high-z. 也就是说,当禁用RS485接收器时,RX引脚为高阻态。 A value of 10k is known to be good and the value is not critical but the pull-up is recommended. 已知10k的值不错,该值并不严格,但建议上拉。

Update 更新

I think I understand the point of view of your project. 我想我了解您的项目观点。 Please correct if I am wrong. 如果我错了,请更正。 Are you attempting to use Teraterm + USB RS485 dongle to send out text to the Atmel over RS485 and wish to have the Atmel send back the data to your Teraterm? 您是否正在尝试使用Teraterm + USB RS485加密狗通过RS485将文本发送到Atmel,并希望Atmel将数据发送回Teraterm? If yes, then the results are logical if you are typing this data in Teraterm. 如果是,那么如果您在Teraterm中键入此数据,则结果是合乎逻辑的。 Please confirm this setup. 请确认此设置。

That is, are you typing "Hello world" and expecting to receive this text back? 也就是说,您是否键入“ Hello world”并希望收到此文本?

The issue with this idea is that the PC is sending out the data faster than you can type. 这个想法的问题是PC发送数据的速度快于您键入的速度。 Instead, review on how you can use Teraterm to send out in a macro form the entire string in a block. 相反,请查看如何使用Teraterm以宏形式将一个块中的整个字符串发送出去。 Only this method will work for your idea. 只有这种方法才能满足您的想法。 When you are typing, Teraterm is sending out (aka flushing the tx buffer) the "H" over the RS485 interface, etc. so you will not receive the entire string in a single block receive. 键入时,Teraterm通过RS485接口等发送(也刷新Tx缓冲区)“ H”,因此您不会在单个块接收中接收到整个字符串。

Consider a macro with Teraterm to send out "Planets", etc. in a single send. 考虑使用Teraterm宏以一次发送“行星”等。 The key point is not delay between each character that you wish to send. 关键是要发送的每个字符之间不要延迟。

485 requires precise line control when transmitting the data. 485在传输数据时需要精确的线路控制。 UDRE means the data can be loaded. UDRE表示可以加载数据。 TXC means the data has been sent. TXC表示数据已发送。 The line should released only after the last bit has been transmitted. 仅在传输完最后一位后,才应释放该行。 I believe this is the reason it works in rs232 and fails in rs485. 我相信这是它在rs232中工作而在rs485中失败的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM