Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Полудуплексный обмен по USART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Hellper
Полудуплексный обмен. Два МК. Приемники/передатчики обоих МК соединены в одну линию.
Туплю. Как отключить приемник во время передачи байта информации?

Код
#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();          
}


Этот код не работает !
Прошу вправить мне мозг!
smile3009.gif
=GM=
Цитата(Hellper @ Jan 19 2009, 20:57) *
Как отключить приемник во время передачи байта информации?

Надо бы передатчик отключать, причём на другой стороне, а не приёмник. Приёмник пусть себе принимает.
Александр Куличок
Цитата
Как отключить приемник во время передачи байта информации?

Достаточно очистить бит 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 нужно писать TXEN0, RXEN0?

Цитата
Этот код не работает !

А вместо этого следовало бы описать, что для Вас означает "не работает". Т.е. что Вы хотели получить в результате выполнения кода и что получили.
Hellper
Цитата(=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
Maik-vs
Цитата(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);
}
...


Этот код не работает !


Закомментировано, вот и не работает. blink.gif
GDI
А это дублирующие строки закоментированы.
Палыч
Цитата(Hellper @ Jan 19 2009, 23:57) *
Этот код не работает ! Прошу вправить мне мозг!
Банально забыли очистить бит TXC0 в UCSR0A
P.S. Не дожидаясь окончания передачи Вы запретили передатчик (но, передача не закончилась и запрет отложен), и разрешили приёмник...
_Pasha
Цитата(Hellper @ Jan 20 2009, 09:55) *
Не работает, означает, что во время передачи приемник не выключается и начинает считывать данные с линии.


На основании чего Вы делаете такой вывод? У Вас прием в прерывании? Приведите листинг, мож там бага smile.gif
Палыч
Цитата(_Pasha @ Jan 20 2009, 13:02) *
У Вас прием в прерывании? Приведите листинг, мож там бага smile.gif
Да, нет... У него - передача по готовности. Но, с ошибкой!
_Pasha
Цитата(Палыч @ Jan 20 2009, 12:51) *
Не дожидаясь окончания передачи Вы запретили передатчик

+многа

Тогда первый байт пройдет, а остальные  cranky.gif Так оно еще и ничего не передает?
Палыч
Цитата(_Pasha @ Jan 20 2009, 13:25) *
Так оно еще и ничего не передает?
Передаёт. Запрет передатчика срабатывает по окончанию передачи (если сдвиговый регистр не пуст).
Hellper
Цитата(_Pasha @ Jan 20 2009, 13:02) *
На основании чего Вы делаете такой вывод? У Вас прием в прерывании? Приведите листинг, мож там бага smile.gif

То что на железке при отправке данных они возвращаются отправителю.
Да, прием в прерывании.
Код
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();          
}

Включаем приемник.

НО. Переданные данные возвращаются пользователю.

Добейте меня !
Палыч
Цитата(Hellper @ Jan 20 2009, 16:02) *
Добейте меня !

Вы, видно, невнимательно читаете ответы... Добиваю biggrin.gif
while (!(UCSR0A&(1 << TXC0))) ;
В этой строчке Вы ожидаете пока бит TXC не станет единицей. Ну, хорошо, он стал единицей. А, кто его будет сбрасывать в ноль? Вы - это не делаете. При выводе всех последующих байт - этот оператор просвистит пулей (TXC в единице), и никакого окончания передачи Вы не ожидаете. После while Вы включаете приёмник. Приёмник ловит передаваемый байт...
Что-то осталось непонятным?
Кстати: бит TXC сбрасывается записью в него единицы. Это - так, напоминаю на всякий случай...
Hellper
Код
void Byte_to(uint8_t byte)
{
    rx_disable();
    tx_enable();

       UDR0 = byte;
       while (!(UCSR0A&(1 << TXC0)))
;
    SETBIT(UCSR0A, TXC0);
    tx_disable();
    rx_enable();          
}


В первом приближении такая конструкция не заработала.
Завтра перепроверю.

на грани истерики. "мыши" закачиваются...
SysRq
А вы вот это вот
Код
if ( ( status & ( FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN ) ) == 0 )
уберите. Полагаю, будет нечто более интересное, чем те данные что отсылали :)

PS: при отключении RX\TX USART'а соотв. нога МК становится обычным I\O портом. Как порт сконфигурирован проверьте.
Hellper
Цитата(SysRq @ Jan 21 2009, 21:57) *
А вы вот это вот
Код
if ( ( status & ( FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN ) ) == 0 )
уберите. Полагаю, будет нечто более интересное, чем те данные что отсылали smile.gif

интересно что будет ? видимо если убрать контроль ошибок, то ситуация координальным образом измениться ? Если грамотно отключить приемник в прерывание по получению байта информации прыгать программе не придется.

Цитата
PS: при отключении RX\TX USART'а соотв. нога МК становится обычным I\O портом. Как порт сконфигурирован проверьте.


сконфигурированы как входы без доопределения потенциала.

вопрос актуален !
SysRq
Цитата(Hellper @ Jan 20 2009, 16:02) *
интересно что будет ?
В UDR1 посыпется весь мусор, который принимался в UDR0, без фильтрации.

Покажите весь код работы с USART... может у вас прерывание по TXC разрешено, но реализовано, и т.п. Гадать так долго будем.
Hellper
Цитата(SysRq @ Jan 22 2009, 01:02) *
Покажите весь код работы с USART... может у вас прерывание по TXC разрешено, но реализовано, и т.п. Гадать так долго будем.
Палыч
Бегло пробежал взглядом программы... В Buffer_to_comp(uint8_t * ptr, uint8_t size) вся та беда, о которой говорилось выше - не исправлена.
P.S. И в Byte_to_cable Вы всё лихо закоментировали... Приём разрешён всегда? Это не рабочий вариант? Что мы проверяем? Что должны найти?
Hellper
Цитата(Палыч @ Jan 22 2009, 12:24) *
Бегло пробежал взглядом программы... В Buffer_to_comp(uint8_t * ptr, uint8_t size) вся та беда, о которой говорилось выше - не исправлена


буффер нигде не используется.
SysRq
Цитата(Палыч @ Jan 22 2009, 12:24) *
Это не рабочий вариант? Что мы проверяем? Что должны найти?

+1.

Кроме того, тестирование проводим одного МК или двух соединенных?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.