LeonY 0 3 июня, 2008 Опубликовано 3 июня, 2008 · Жалоба на самом деле 11. забыли бит четности. Если проверка на четность не включена, это ещё не значит, что бит не передаётся. Так что подкорректируем ваш результат: 105000*11/10=115500. Где-то так. Опять же, не забываем про погрешность деления частоты. Или у вас коэффициент целый получился? Можно пояснить выделенное? А то как-то не понятно: сам ваял UART-ы (неоднократно) и всегда делал так что, если не включена то и не передается. С приемом на самых разных устройствах проблем никогда не было... А когда рассогласуешь Rx/Tx по контролю на PARITY - сразу FRAMING ERRORS валятся как из рога изобилия (Tx передает PARITY, а Rx его не ожидает). Ну и еще куча всяких побочных эффектов... 11 битов могут возникать при установке 2-х STOP Bits (их может быть 1, 1.5, 2) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DpInRock 0 4 июня, 2008 Опубликовано 4 июня, 2008 · Жалоба Бит четности не передается, если четность не включена. Разумеется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
WHILE 0 4 июня, 2008 Опубликовано 4 июня, 2008 · Жалоба а зачем 2 индекса-rx_wr_index1 и rx_counter1? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
altlogic 0 4 июня, 2008 Опубликовано 4 июня, 2008 · Жалоба Там вообще три переменных под индексы: rx_wr_index1 , rx_rd_index1, rx_counter1. Таким образом реализовано безконфликтное обращение двух потоков функций к одному буферу. rx_counter1 - количество несчитанных символов в программном буфере rx_buffer1 rx_wr_index1 - индекс для записи символа из регистра UDR1 в rx_buffer1 во время прерывания rx_rd_index1 - индекс для чтения символа из rx_buffer1 функцией getchar() К слову сказать передатчик пришлось "доделать". Прерывания по DRE необходимо отключать после того, как программный буфер UART пуст. А то прерывание постоянно возникает, и не даёт работать системе. И соответственно включать его надо всякий раз при выводе символа функцией putchar. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 4 июня, 2008 Опубликовано 4 июня, 2008 · Жалоба Вот теперь встанет следующий вопрос - добиться 115 200 на приёмнике:) У меня там тоже прерывания по окончанию приёма. Пока не проверял, но боюсь и там будет та же картина. Проверку FRAMING-PARITY-OVERRUN можно смело выбросить - толку от нее никакого, а время сожрет. С приемом проблем быть не должно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 4 июня, 2008 Опубликовано 4 июня, 2008 · Жалоба Проверку FRAMING-PARITY-OVERRUN можно смело выбросить - толку от нее никакого, а время сожрет. Толк весьма существенен. Например экономия времени :) Если произошла одна из ошибок, автомат приема можно сразу перевести на ожидание нового пакета, не дожидаясь окончания приема пакета, проверки контрольной суммы и проч. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 4 июня, 2008 Опубликовано 4 июня, 2008 · Жалоба Толк весьма существенен. Например экономия времени smile.gif Если произошла одна из ошибок, автомат приема можно сразу перевести на ожидание нового пакета, не дожидаясь окончания приема пакета, проверки контрольной суммы и проч. Ага, сэкономите, как же :) Представьте: принимаем пакет из 16 байт, в 7-м Framing Error - и что делать? Считать следующий байт началом нового пакета? Кричать караул? Правильным решением будет наплевать на ошибки и принять пакет до конца - пусть верхний уровень разбирается, нормальный пришел пакет, или нет. Как раз с помощью контрольной суммы, CRC и т.п. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 4 июня, 2008 Опубликовано 4 июня, 2008 · Жалоба Ага, сэкономите, как же :) Представьте: принимаем пакет из 16 байт, в 7-м Framing Error - и что делать? Считать следующий байт началом нового пакета? Кричать караул? Правильным решением будет наплевать на ошибки и принять пакет до конца - пусть верхний уровень разбирается, нормальный пришел пакет, или нет. Как раз с помощью контрольной суммы, CRC и т.п. Я думаю, что правильное решение для каждой ситуации свое и ситуация сильно зависит от протокола. Например: - контрольная сумма простая, вероятность ее случайного совпадения достаточно велика, не контролировать паритет при приеме рискованно. Не хочется переходить на начало - можно флаг поставить. - есть протоколы, где EOT в потоке должно прекращать прием, то есть эта ветка(перехода на начало) все равно существует. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 4 июня, 2008 Опубликовано 4 июня, 2008 · Жалоба Ну, если специально придумать плохой протокол и добавить к нему передачу с контролем паритета (которую никто не использует обычно), то смысл может быть. Но это именно из разряда придумывания себе проблем, ИМХО. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
altlogic 0 4 июня, 2008 Опубликовано 4 июня, 2008 · Жалоба Проверку FRAMING-PARITY-OVERRUN можно смело выбросить - толку от нее никакого, а время сожрет. С приемом проблем быть не должно. Спасибо за замечание. У меня никакого потокола верхнего уровня нет. UART используется для обмена между мк и gsm-модемом в пределах одной платы. Поэтому я исхожу из предположения, что ошибок быть не может в принципе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DpInRock 0 5 июня, 2008 Опубликовано 5 июня, 2008 · Жалоба Протокол верхнего уровня, это когда вы принятую строку от модема анализируете. И если пришло что-то вам непонятное (в результате какой-либо ошибки)- то отвергаете с негодованием и считаете предыдущую команду невыполненной. При этом природа ошибки вас не интересует (все равно природу не изменишь и вариантов тут нет.) Ну или еще как-то... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
altlogic 0 5 июня, 2008 Опубликовано 5 июня, 2008 · Жалоба Что-то просел я с реализацией RTS/CTS протокола. Никак не могу придумать алгоритм быстрой связи. Почитал http://electronix.ru/forum/index.php?act=P...amp;qpid=133018 понял, так, что RTS/CTS не обязательно обрабатывать в режиме прерывания. Можно сделать буфер передатчика скажем байт на восемь, и не записывать в него, пока CTS равен единице(модем не готов). А вот прерывание по пустому DATA REGISTER пусть крутится, но до тех пор пока программный буфер не пуст. В общем пока что я теряю байты при передаче их модему, не могу понять где. Приведу сразу и переписанный код int COM_tx_on( void ) { UCSR0B |= ( 1 << UDRIE0 ); // Enable TX UDRE interrupt return 1; } void COM_tx_off( void ) { UCSR0B &= ~( 1 << UDRIE0 ); // Disable TX interrupt } //<! USART0_DRE - usart data register emptry interrupt [ USART0_DRE ] void usart0_UDRE_isr(void) { if ( tx_counter > 0 ) { #asm("cli") --tx_counter; //<! неделимая операция #asm("sei") UDR0 = tx_buffer[tx_rd_index]; if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0; } else { COM_tx_off(); } } int COM_putchar(unsigned char c) { char tx = 0; while( !tx ) { if( !CTS ) { if( tx_counter != TX_BUFFER_SIZE ) { tx_buffer[tx_wr_index]=c; COM_tx_on(); if (++tx_wr_index == TX_BUFFER_SIZE) { tx_wr_index=0; } #asm("cli") ++tx_counter; #asm("sei") tx = 1; //<! break from while } } } return 1; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 5 июня, 2008 Опубликовано 5 июня, 2008 · Жалоба //<! USART0_DRE - usart data register emptry interrupt [ USART0_DRE ] void usart0_UDRE_isr(void) { if ( tx_counter > 0 ) { // #asm("cli") <-- aaarrr Лишнее действие: прерывания уже запрещены --tx_counter; //<! неделимая операция // #asm("sei") <-- aaarrr А это уже просто опасно UDR0 = tx_buffer[tx_rd_index]; if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0; } else { COM_tx_off(); } } int COM_putchar(unsigned char c) { char tx = 0; while( !tx ) { if( !CTS ) { if( tx_counter != TX_BUFFER_SIZE ) { tx_buffer[tx_wr_index]=c; // COM_tx_on(); <-- aaarrr Здесь включать передатчик рано, он может тут же запретить UDR if (++tx_wr_index == TX_BUFFER_SIZE) { tx_wr_index=0; } #asm("cli") ++tx_counter; #asm("sei") COM_tx_on(); tx = 1; //<! break from while } } } return 1; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
altlogic 0 5 июня, 2008 Опубликовано 5 июня, 2008 · Жалоба Спасибо, теперь вроде ничего не теряю:) Только я не понял // #asm("cli") <-- aaarrr Лишнее действие: прерывания уже запрещены При входе в прерывание происходит глобальное запрещение прерываний? Т.е. из одного прерывания в другое меня не выбросит, если не делать так? // #asm("sei") <-- aaarrr А это уже просто опасно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 5 июня, 2008 Опубликовано 5 июня, 2008 · Жалоба Да, при входе в прерывание прерывания запрещаются глобально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться