Estoy trabajando en un proyecto que involucra dos MCU ATMEGA328p que se comunican a larga distancia (entre dos pisos de un edificio). Uno es amo y el otro es esclavo. El maestro siempre inicia la comunicación mediante el envío de comandos AT personalizados que tienen un retorno de carro '\r' y un salto de línea '\n' como terminadores al final.
Estoy usando UART (9600 bps con paridad uniforme). Esto es lo que noté: cuando se usa UART directo, todo funciona como se esperaba. Pero cuando reemplacé la ruta de comunicación con un cable muy largo (aproximadamente 5-10 m), el UART comenzó a causar problemas.
Así que tuve que usar módulos RS-485 por razones obvias.
El problema que veo es que todo el comando AT se transmite a través de la ruta RS-485, pero los dos códigos ASCII de '\r' y '\n' no se reciben en absoluto. Verifiqué usando un clon FTDI que la entrada al módulo del lado del transmisor RS-485 tiene CR y LF como se esperaba, pero en el extremo receptor (después de la conversión de RS485 a UART), se recibe el comando completo excepto CR y LF.
Sugiérame qué hacer, ya que todo mi código de software depende de la detección de CR y LF como protocolo. Revisé muchos blogs/controles de calidad, pero no pude resolver mi problema. Parece que el módulo RS-485 no envía CR y LF.
Estas son las dos funciones UART que funcionan en el nivel más bajo. He comprobado que mi código siempre pasa 1 como argumento trm
void UART_TxSTRING (char string[], int trm) //This string function does not sends the NULL character '\0'
{
int i = 0;
while (string[i] != '\0') //Detect end of string
{
UART_TxByte(string[i]);
i++;
}
if (trm == 1) //if trm=1, terminators will be sent with string
{
UART_TxByte('\r'); //Terminator
UART_TxByte('\n'); //Terminator
}
}
void UART_TxByte(char tx_data)
{
UCSR0B &= ~RXIE; //Disable Rx interrupts while sending data
while (!(UCSR0A & TXC_FLAG)); //Check flag before transmitting
UDR0 = (tx_data & 0xFF); //Send the ASCII code
UCSR0B |= RXIE; //Enable Rx interrupts again after transmission
}
Actualización: Modifiqué el código para reemplazar CR con @ y reemplacé LF con $ Aún así, solo se pierden los caracteres de terminación, el resto del comando (largo o corto) se transmite normalmente. Siento que hay algún problema relacionado con el tiempo, ya que la declaración if (trm == 1) está causando que el IC RS-485 elimine los caracteres posteriores.
No estoy 100% seguro de que esto resuelva su problema, pero hay algo que debe verificar:
según la hoja de datos de Atmel, inmediatamente antes de transmitir bytes, debe esperar el bit UDREn, lo que significa que el registro UDRn está vacío y puede aceptar un nuevo byte.
UDREn es diferente al bit TXCn, que parece estar usando (pero no está claro cómo definió esa máscara).
De todos modos, TXCn es para después , no para antes . Otras diferencias: UDREn ocurre antes de que el byte se haya transmitido por completo, y es posible que TXCn no se borre automáticamente de la misma manera que UDREn.
Use UDREn cuando ingrese un montón de datos para transmitir en un bloque, use TXCn cuando espere que termine el último byte, en caso de que eso importe.
brahans
Rodó
manish verma
manish verma
manish verma
pedro bennett
manish verma
Rodó
manish verma
mitu raj
Kartman
manish verma
mitu raj
Lundín
Lundín