Полная версия этой страницы:
USART
max_mart
Jun 20 2012, 06:48
Здравствуйте.
Использую USART для общения 2 мег. Нужно объеденить RX и TX в одну линию.
Подскажите, ПОЖАЛУЙСТА, как это реализовать програмно?
Сергей Борщ
Jun 20 2012, 07:15
QUOTE (max_mart @ Jun 20 2012, 09:48)

как это реализовать програмно?
Настроить ногу TX регистром DDR на ввод. Линию подтянуть к питанию резистором. Перед передачей включать передатчик битом TXEN (при этом нога переключится на вывод автоматически), после передачи - выключать этим же битом. При желании на время передачи отключать приемник битом RXEN. На уровне протокола исключать возможность работы более одного передатчика одновременно. В протоколе же предусмотреть паузу на время передачи одного байта после включения передатчика и отсеивание принятого до включения передатчика мусора из линии.
max_mart
Jun 20 2012, 08:22
"В протоколе же предусмотреть паузу на время передачи одного байта после включения передатчика и отсеивание принятого до включения передатчика мусора из линии." -
это значит, что еще после вкл. идет передача мусора?
Navovvol
Jun 20 2012, 09:33
А че на прямую нельзя ? накрест соединить RX и TX?
Сергей Борщ
Jun 20 2012, 09:34
QUOTE (max_mart @ Jun 20 2012, 11:22)

это значит, что еще после вкл. идет передача мусора?
Нет, это значит, что приемник мог зацепиться в худшем случае за последний всплеск шума и в течении максимум одного байта продолжает принимать. Если начать передачу - приемник просто не зацепится за реальный стартовый бит.
AlexFTF
Jun 20 2012, 09:38
Цитата(max_mart @ Jun 20 2012, 13:48)

Здравствуйте.
Использую USART для общения 2 мег. Нужно объеденить RX и TX в одну линию.
Подскажите, ПОЖАЛУЙСТА, как это реализовать програмно?
Если не секрет, зачем такое усложнение?
hd44780
Jun 20 2012, 09:52
Наверное хочет 2 провода вместо 3-х ...
max_mart
Jun 20 2012, 10:43
Я уже так делал. При передаче запрещал прием, а при преме запрещал передачу.
Резистором 10 кОм подтянул к +.
При передаче после нужных мне 5 байт. Еще идет какая-то отправка(какие-то байты).
Потом я ее запрещаю. передаю с компьютеры другие 5 байт ответа - он вместо нужной команды выдает 0. А дальше вообще кашмар. Когда приходит командв на отправку, он начинает отправлять одни 0 и команды. Пока не будит истечено временем.
Реализую не по прерыванию.
3 провода: VCC, GND, DATA
3 провода: VCC, GND, DATA
AlexFTF
Jun 20 2012, 10:54
Цитата(hd44780 @ Jun 20 2012, 16:52)

Наверное хочет 2 провода вместо 3-х ...
Если работает в синхронном режиме согласен.
max_mart может было бы проще использовать USART в асинхронном режиме или I2C?
max_mart
Jun 20 2012, 11:15
А он и работает в асинхронном режиме.
А выше я написал почему 3 провода в общем
Цитата(NSTU @ Jun 20 2012, 19:38)

Если не секрет, зачем такое усложнение?

В ряде случаев это упрощение. У меня на одном порту сидят 3 процессора, плюс компьютер может подключаться (через преобразователь уровней)
max_mart
Jun 20 2012, 12:51
Ну и подскажите тогда, пожалуйста, как тогде реализовать такое упрощение?
Я думаю может быть дело в гипер терминале через, который я отлаживал(он не предусматривает одновременной работы с 2 ногами RX и TX) через max232.
просто надо связать 2 разных устройства по одному протоколу через USART.
Попробую испытать. Если не заработает, то напишу.
Сергей Борщ
Jun 20 2012, 13:15
QUOTE (max_mart @ Jun 20 2012, 15:51)

Ну и подскажите тогда, пожалуйста, как тогде реализовать такое упрощение?
Нее... Это вы показывайте свой код, а мы постараемся помочь исправить его.
QUOTE (max_mart @ Jun 20 2012, 15:51)

Я думаю может быть дело в гипер терминале через, который я отлаживал(он не предусматривает одновременной работы с 2 ногами RX и TX) через max232.
Описывайте задачу полностью. Никакого гипертерминала и max232 в вашем вопросе не было - там были 2 меги. Естественно, что поскольку max232 не умеет отключать свой выход - напрямую его подключать к такой системе нельзя. Как минимум надо развязать диодом, чтобы в паузах единица на выходе max232 не мешала работать шине.
max_mart
Jun 20 2012, 14:11
Также не работает(((
Спасибо огромное за отклики и помощь!!!
Задача следующая:
Передача данных по USART. RX и TX объединены в одну
Есть устройство(именуемое SLAVE), которое всегда находится в режиме приема, как только данные приходят оно отправляет ответ.
Есть второе устройство(именуемое MASTER), которое всегда находится в режиме передачи, как только данные отправлены оно ожидает ответ, в качестве подтверждения.
Есть специальный протокол обмена между ними:
Из MASTER в SLAVE:
Формат пакета:
[Const1] [Data] [-Data] [Const2] [CS]
где
Const1 = 0x0F
Const2 = 0x15
Data - один байт пересылаемых данных.
-Data - инвертированный предыдущий байт.
CS - контрольная сумма, вычисляемая как сумма четырех
предыдущих байт по "исключающему ИЛИ". При всех операциях
старшие биты 5,6,7 не учитываются (обнуляются).
Команда 00, 01, 02, 03 - номер включаемого режима.
(максимально до 07, но реально будет использоваться 3 или 4).
Команда 08 - запрос текущего режима.
Ответ SLAVE:
Формат пакета
[Const3] [Data] [-Data] [Const4] [CS]
где
Const3 = 0x06
Const4 = 0x12
Data = 00, 01, 02, 03 ... 07 - текущий режим.
Примеры обменов.
MAS -> SLA SLA -> MAS
-------------- --------------
0F 00 1F 15 05 - 06 00 1F 12 0B включить! режим 0 - включен режим 0
0F 01 1E 15 05 - 06 01 1E 12 0B ... 1
0F 02 1D 15 05 - 06 02 1D 12 0B ... 2
0F 03 1C 15 05 - 06 03 1C 12 0B ... 3
0F 08 17 15 05 - 06 01 1E 12 0B какой режим включен? - включен режим 1
MASTER работает 100%. Уже было проверено с другими.
Код реализацииSLAVE:
// Сначала инициализация
// USART initialization
UCSR0A=0x00;
UCSR0B=0b00001000; // transmitter enable
UCSR0C=0b00000000; // 5 bit data transmit, no parity, 1 stop
UBRR0H = (unsigned char)(MYUBRR>>8);
UBRR0L = (unsigned char)MYUBRR;
//Функции обработки данных
unsigned char receive_BYTE (void)
{
// Wait until a byte has been received
while (!(UCSR0A & (1 << RXC0)));
return UDR0;
}
unsigned char receive_USART (void)
{
unsigned char cs=0;
pos=1;
do
{
USART_RX_buf[pos] = receive_BYTE();
USART_RX_buf[pos]&=0x1F;
if (pos != 5)cs^=USART_RX_buf[pos];
pos++;
} while (pos<6);
if ((USART_RX_buf[1]==0x06)&&(USART_RX_buf[4]==0x12))
{
if (cs == USART_RX_buf[5])
{
if (USART_RX_buf[3] == ((~(USART_RX_buf[2]))&0x1F))
{
UCSR0B &= ~(1<<4); //RX
DDRD &=~(1<<0);
PORTD &=~(1<<0);
UCSR0B |= (1<<3); //TX
return USART_RX_buf[2];
}
}
}
UCSR0B &= ~(1<<4); //RX
DDRD &=~(1<<0);
PORTD &=~(1<<0);
UCSR0B |= (1<<3); //TX
return 0;
}
void send_USART (unsigned char data)
{
unsigned char cs=0;
pos=1;
if (data == economS) data=0x00;
do
{
while (!(UCSR0A & (1 << UDRE0)));
// Transmit data
if (pos == 1) {UDR0 = 0x0F;cs^=0x0F;}
if (pos == 2) {UDR0 = data&0x1F; cs^=(data&0x1F);}
if (pos == 3) {UDR0 = ((~data)&0x1F); cs^=((~data)&0x1F);}
if (pos == 4) {UDR0 = 0x15;cs^=0x15;}
if (pos == 5) UDR0=cs;
while (!(UCSR0A & (1 << TXC0)));
pos++;
}while (pos<6);
UCSR0B &= ~(1<<3); //TX
DDRD &=~(1<<1);
PORTD &=~(1<<1);
UCSR0B |= (1<<4); //RX
}
Далее просто:
send_USART(mode); // отправляет команду
u_dat=receive_USART(); // приходит подтверждение
Дальше идет событие.
Сейчас проверял. Получается так как будто он зависает в режиме приема. Потому что если приходит подтверждение, то должен гореть светодиод
Заранее благодарен.
Очень надеюсь на Вашу помощь.
Цитата(max_mart @ Jun 20 2012, 22:51)

просто надо связать 2 разных устройства по одному протоколу через USART.
В этом случае нет смысла объединять Rx и Tx. Вот если к этой связке для программирования и отладки требуется добавить компьютер (через max с диодом, совершенно верно) или еще одно устройство, то смысл появится
max_mart
Jun 20 2012, 14:21
Плата уже готовая!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Там место под RX и TX нету!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Только сверху напаивать!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Вы че хотите, чтобы я потом на каждую припаивал по отдельности????????????????????
Игрушек, то этих очень много!!!!!!!!!!!!!!!!!!!!!!!!!
Вот и попросили сделать пульт!!!!!!!!!!!!!!!!!!!!!!!
А для упрощения жизни в будущем и решил их объединить!!!
Цитата(max_mart @ Jun 20 2012, 18:19)

Плата уже готовая!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Там место под RX и TX нету!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Только сверху напаивать!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Вы че хотите, чтобы я потом на каждую припаивал по отдельности????????????????????
Игрушек, то этих очень много!!!!!!!!!!!!!!!!!!!!!!!!!
Вот и попросили сделать пульт!!!!!!!!!!!!!!!!!!!!!!!
А для упрощения жизни в будущем и решил их объединить!!!
По этому протоколу я ими управляю
Цитата(max_mart @ Jun 20 2012, 18:11)

Код реализацииSLAVE:
.....
UCSR0B=0b00001000; // transmitter enable
Насколько я понял: Slave в начале своей работы должен принять команду... Почему включаете передатчик?
max_mart
Jun 20 2012, 15:32
Ой прошу прощения за неосторожность

. Писал в торопях. это MASTER
Код программы описанный выше это MASTER.
Соединяю MASTER со SLAVE следующим образом:
питание SLAVE- 5В
питание MASTER - 3.3В.
На линии (RX и TX) ставлю преобразователь уровня на 3.3В(резистивный делитель напряжения), подтягиваю эту линию через 11кОм к 3.3В. RX и TX у мастера соединяю через 300 Ом между собой
АлексейСлав
Jun 22 2012, 18:49
Посмотри старые переходники на телефон, там шины RX-TX с компьютра мультиплексируются в один сигнал.
Эта шина в телефоне называется MBUS которая одновременно работает как RX так и TX.
Вот например схемка -
http://pinouts.ru/CellularPhonesCables/nok...us_cable2.shtml
max_mart
Jun 25 2012, 05:52
Всем спасибо!!! Но проблему я решил.
Просто надо было расставить заданной величины задержки в нужных местах и вуаля!!!)))
А так все правильно было)))
АлексейСлав
Jun 25 2012, 15:59
Возможно, ты просто замаскирвал таким образом одну ошибку другой, в результате чего они скомпенсировались.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.