代码之家  ›  专栏  ›  技术社区  ›  Devjeet Mandal

无法建立正确的RS485通信

  •  0
  • Devjeet Mandal  · 技术社区  · 7 年前

    我试着用 ATmega32 . 首先我使用RS232,使用USB-to-RS232建立使用串行终端的接收和传输(在我的情况下是tera术语)。无论我从串行终端Atmega32发送什么,都会将其回传。

    因为我把 Hello\r 我收到“Hello\r”

    它工作得很好。

    然后我使用RS485,使用USB-to-RS485与ATmega32建立通信,但我只得到第一个字符作为回报。

    如果我派 Hello 我回来了 H . 如果我派 planets 我只得到 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 != '\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();
            }
    
        }
    }
    

    为什么会出现这种异常?

    如何纠正这个错误?

    任何建议都会有帮助的。

    提前谢谢

    2 回复  |  直到 7 年前
        1
  •  3
  •   mon2    7 年前

    在评论这篇文章时,有点搞不清谁在传递什么,所以请发表以下评论:

    1)简化Atmel代码,使其只输出“Hello World%d”+CR,并不断增加#行。目前,保持com速度为9600波特。从Atmel到USB RS485加密狗的流量是否100%成功接收?在这之前不要继续。

    2)在本次Atmel侧设计中,您使用哪一个RS485收发器?市场上有很多垃圾,并不是所有的收发器都是平等的。

    3)您在使用哪个USB RS485加密狗?根据(2),只有少数是可靠的。如果使用透明的FTDI USB RS485加密狗,请仔细检查塑料内部压印RS485收发器的位置。FTDI承认,他们推出了一些基于Sipex收发器的片状加密狗电缆。从我们的简要回顾来看,相信是设计出了问题,而不是收发器。然而,不管怎样,既然加密狗已经被密封,同样的童车加密狗就不能被纠正。

    我们构建了一些可靠的适配器,但不希望将其转换为广告,所以让我们看看是否可以调试您的案例。发布更多详细信息以继续。

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

    更新

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

    也就是说,你是在输入“Hello world”并期待收到这条短信吗?

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

    考虑一个带有terterm的宏在一次发送中发送“行星”等。关键点不是要发送的每个字符之间的延迟。

        2
  •  0
  •   hedgehog81    7 年前

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