|
Полудуплексный обмен по USART, туплю ?!? |
|
|
|
Jan 19 2009, 20:57
|

Местный
  
Группа: Участник
Сообщений: 217
Регистрация: 13-08-07
Из: Санкт-Петербург
Пользователь №: 29 745

|
Полудуплексный обмен. Два МК. Приемники/передатчики обоих МК соединены в одну линию. Туплю. Как отключить приемник во время передачи байта информации? Код #define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT)) #define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
void tx_disable( void ) { CLEARBIT(UCSR0B, TXEN); } void tx_enable( void ) { SETBIT(UCSR0B, TXEN); }
void rx_disable( void ) { CLEARBIT(UCSR0B, RXEN); // UCSR0B &= ~(1 << RXEN0); }
void rx_enable( void ) { SETBIT(UCSR0B, RXEN); // UCSR0B |= (1 << RXEN0); }
void byte_to(uint8_t byte) { rx_disable(); tx_enable();
UDR0 = byte; // while (!(UCSR0A&(1 << UDRE0))) //; while (!(UCSR0A&(1 << TXC0))) ;
tx_disable(); rx_enable(); } Этот код не работает ! Прошу вправить мне мозг!
Сообщение отредактировал Hellper - Jan 19 2009, 20:59
--------------------
|
|
|
|
|
Jan 20 2009, 00:27
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Цитата Как отключить приемник во время передачи байта информации? Достаточно очистить бит RXEN: Цитата Disabling the Receiver In contrast to the Transmitter, disabling of the Receiver will be immediate. Data from ongoing receptions will therefore be lost. When disabled (i.e., the RXEN is set to zero) the Receiver will no longer override the normal function of the RxD port pin. The receiver buffer FIFO will be flushed when the receiver is disabled. Remaining data in the buffer will be lost Может, вместо TXEN, RXEN нужно писать TXEN 0, RXEN 0? Цитата Этот код не работает ! А вместо этого следовало бы описать, что для Вас означает "не работает". Т.е. что Вы хотели получить в результате выполнения кода и что получили.
|
|
|
|
|
Jan 20 2009, 06:55
|

Местный
  
Группа: Участник
Сообщений: 217
Регистрация: 13-08-07
Из: Санкт-Петербург
Пользователь №: 29 745

|
Цитата(=GM= @ Jan 20 2009, 02:52)  Надо бы передатчик отключать, причём на другой стороне, а не приёмник. Приёмник пусть себе принимает. отключать нужно именно приемник, тк ему не следует считывать то, что сам отправил. Цитата(Александр Куличок @ Jan 20 2009, 03:27)  Достаточно очистить бит RXEN: Может, вместо TXEN, RXEN нужно писать TXEN0, RXEN0? не работает. не играет никакой роли. Код /* USART Control Register B (generic) */ #define RXCIE 7 #define TXCIE 6 #define UDRIE 5 #define RXEN 4 #define TXEN 3 #define UCSZ 2 #define UCSZ2 2 /* new name in datasheet (2467E-AVR-05/02) */ #define RXB8 1 #define TXB8 0
/* USART1 Control Register B - UCSR1B */ #define RXCIE1 7 #define TXCIE1 6 #define UDRIE1 5 #define RXEN1 4 #define TXEN1 3 #define UCSZ12 2 #define RXB81 1 #define TXB81 0
/* USART0 Control Register B - UCSR0B */ #define RXCIE0 7 #define TXCIE0 6 #define UDRIE0 5 #define RXEN0 4 #define TXEN0 3 #define UCSZ02 2 #define RXB80 1 #define TXB80 0 Цитата А вместо этого следовало бы описать, что для Вас означает "не работает". Т.е. что Вы хотели получить в результате выполнения кода и что получили. Не работает, означает, что во время передачи приемник не выключается и начинает считывать данные с линии. Цитата Надо бы передатчик отключать, причём на другой стороне, а не приёмник. Приёмник пусть себе принимает. Нужно отключать именно приемник на передающей стороне. PS Использую WinAVR-20081205
--------------------
|
|
|
|
|
Jan 20 2009, 07:49
|
Местный
  
Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101

|
Цитата(Hellper @ Jan 19 2009, 23:57)  Полудуплексный обмен. Два МК. Приемники/передатчики обоих МК соединены в одну линию. Туплю. Как отключить приемник во время передачи байта информации? Код ... void rx_disable( void ) { CLEARBIT(UCSR0B, RXEN); // UCSR0B &= ~(1 << RXEN0); }
void rx_enable( void ) { SETBIT(UCSR0B, RXEN); // UCSR0B |= (1 << RXEN0); } ... Этот код не работает ! Закомментировано, вот и не работает.
|
|
|
|
|
Jan 20 2009, 13:02
|

Местный
  
Группа: Участник
Сообщений: 217
Регистрация: 13-08-07
Из: Санкт-Петербург
Пользователь №: 29 745

|
Цитата(_Pasha @ Jan 20 2009, 13:02)  На основании чего Вы делаете такой вывод? У Вас прием в прерывании? Приведите листинг, мож там бага  То что на железке при отправке данных они возвращаются отправителю. Да, прием в прерывании. Код ISR(USART0_RX_vect) { uint8_t status; uint8_t data; status = UCSR0A; data = UDR0; if ( ( status & ( FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN ) ) == 0 ) { UDR1 = data; }; } тут все просто -- принять и переслать. Цитата P.S. Не дожидаясь окончания передачи Вы запретили передатчик (но, передача не закончилась и запрет отложен), и разрешили приёмник... Код void byte_to(uint8_t byte) { rx_disable(); Приемник отключается. Правильно ? Код tx_enable(); Передатчик включается. Да ? Код UDR0 = byte; Данные уходят в регистр передатчика. ? Код while (!(UCSR0A&(1 << TXC0))) ; Ожидаем полного выплевывания данных из сдвигового регистра. Верно ? Код tx_disable(); Отключаем передатчик. Наверно отключаем. Код rx_enable(); } Включаем приемник. НО. Переданные данные возвращаются пользователю. Добейте меня !
--------------------
|
|
|
|
|
Jan 20 2009, 14:51
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(Hellper @ Jan 20 2009, 16:02)  Добейте меня ! Вы, видно, невнимательно читаете ответы... Добиваю while (!(UCSR0A&(1 << TXC0))) ; В этой строчке Вы ожидаете пока бит TXC не станет единицей. Ну, хорошо, он стал единицей. А, кто его будет сбрасывать в ноль? Вы - это не делаете. При выводе всех последующих байт - этот оператор просвистит пулей (TXC в единице), и никакого окончания передачи Вы не ожидаете. После while Вы включаете приёмник. Приёмник ловит передаваемый байт... Что-то осталось непонятным? Кстати: бит TXC сбрасывается записью в него единицы. Это - так, напоминаю на всякий случай...
|
|
|
|
|
Jan 20 2009, 18:35
|

Местный
  
Группа: Участник
Сообщений: 217
Регистрация: 13-08-07
Из: Санкт-Петербург
Пользователь №: 29 745

|
Код void Byte_to(uint8_t byte) { rx_disable(); tx_enable();
UDR0 = byte; while (!(UCSR0A&(1 << TXC0))) ; SETBIT(UCSR0A, TXC0); tx_disable(); rx_enable(); } В первом приближении такая конструкция не заработала. Завтра перепроверю. на грани истерики. "мыши" закачиваются...
--------------------
|
|
|
|
|
Jan 21 2009, 18:57
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
А вы вот это вот Код if ( ( status & ( FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN ) ) == 0 ) уберите. Полагаю, будет нечто более интересное, чем те данные что отсылали :) PS: при отключении RX\TX USART'а соотв. нога МК становится обычным I\O портом. Как порт сконфигурирован проверьте.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|