Я работаю над проектом, в котором участвуют два микроконтроллера ATMEGA328p, обменивающиеся данными на большом расстоянии (между двумя этажами здания). Один хозяин, а другой раб. Мастер всегда инициирует связь, отправляя пользовательские AT-команды, которые имеют возврат каретки '\r' и перевод строки '\n' в качестве терминаторов в конце.
Я использую UART (9600 бит/с с четностью). Вот что я заметил: При использовании прямого UART все работает как положено. Но когда я заменил канал связи очень длинным проводом (около 5-10 м), UART начал вызывать проблемы.
Поэтому мне пришлось использовать модули RS-485 по понятным причинам.
Проблема, которую я вижу, заключается в том, что вся AT-команда передается по пути RS-485, но два кода ASCII «\ r» и «\ n» вообще не принимаются. Я проверил с помощью клона FTDI, что вход в модуль на стороне передатчика RS-485 имеет CR и LF, как и ожидалось, но на приемном конце (после преобразования RS485 в UART) принимается вся команда, кроме CR и LF.
Пожалуйста, предложите мне, что делать, поскольку весь мой программный код зависит от обнаружения CR и LF как протокола. Я просмотрел множество блогов/QA, но не смог решить свою проблему. Похоже, что модуль RS-485 не отправляет CR и LF.
Это две функции UART, которые работают на самом низком уровне. Я проверил, что мой код всегда передает 1 в качестве аргумента 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
}
Обновление: я изменил код, заменив CR на @ и заменил LF на $. Тем не менее теряются только символы завершения, остальная часть команды (длинная или короткая) передается нормально. Я чувствую, что есть некоторая проблема, связанная с синхронизацией, поскольку оператор if (trm == 1) заставляет микросхему RS-485 отбрасывать последующие символы.
Не уверен на 100%, что это решит вашу проблему, но что-то нужно проверить:
согласно таблице данных Atmel, непосредственно перед передачей байтов вы должны дождаться бита UDREn, что означает, что регистр UDRn пуст и может принять новый байт.
UDRen отличается от бита TXCn, который вы, похоже, используете (но неясно, как вы определили эту маску).
В любом случае, TXCn предназначен для after , а не before . Другие отличия: UDREn происходит до того, как байт будет полностью передан, и TXCn может не очищаться автоматически так же, как UDRen.
Используйте UDRen при подаче пакета данных для передачи в блоке, используйте TXCn при ожидании завершения последнего байта, если это имеет значение.
браханы
Родо
Маниш Верма
Маниш Верма
Маниш Верма
Питер Беннет
Маниш Верма
Родо
Маниш Верма
Миту Радж
Картман
Маниш Верма
Миту Радж
Лундин
Лундин