Сергей Борщ 140 8 января, 2007 Опубликовано 8 января, 2007 · Жалоба Переход по вектору прерывания от передатчика автоматически сбрасывает флаг вызова прерывания.Да, про это я забыл, каюсь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 5 мая, 2008 Опубликовано 5 мая, 2008 · Жалоба Вот мой код... Пытаясь выжать (вдруг я чего-то не понимаю, чего другие понимают :( )из простейшего UART-а MSP430 все возможное, набрел на эту старую тему. По поводу твоего кода, Сергей, перемудрил ты несколько с voltile и c масками. Можно проще, например, передача: #define TX_BUFF_SIZE 16 // must be power of two #define TX_BUFF_MASK (TX_BUFF_SIZE-1) char TxBuffer[TX_BUFF_SIZE]; uint8_t volatile TxTail; uint8_t TxHead; #pragma vector = USART0TX_VECTOR __interrupt void Tx232(void) { U0TXBUF = TxBuffer[TxTail++ & TX_BUFF_MASK]; if( TxTail == TxHead ) // buffer empty IE1 &= ~UTXIE0; // disable tx int } void putchar(int symbol) { while( TxHead - TxTail >= TX_BUFF_SIZE ); // wait while buffer full TxBuffer[TxHead++ & TX_BUFF_MASK] = symbol; IE1 |= UTXIE0; // enable tx int } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 6 мая, 2008 Опубликовано 6 мая, 2008 · Жалоба Можно проще Правильно ли я понял, что вы сэкономили одно слово volatile и две (вроде бы) операции &=TX_BUFF_MASK? Или же здесь что-то более концептуальное? :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 6 мая, 2008 Опубликовано 6 мая, 2008 · Жалоба Можно проще, например, передача: void putchar(int symbol) { while( TxHead - TxTail >= TX_BUFF_SIZE ); // wait while buffer full TxBuffer[TxHead++ & TX_BUFF_MASK] = symbol; IE1 |= UTXIE0; // enable tx int } Для инициации передачи UART недостаточно просто разрешить прерывание. Желательно принудительно (программно) установить флаг UTXIFGx. Иначе нельзя быть на 100% уверенным, что прерывание действительно возникнет. Флаг может быть оказаться сброшен после вызова "лишнего" прерывания при неудачном стечении (программных) обстоятельств. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 27 7 мая, 2008 Опубликовано 7 мая, 2008 · Жалоба Для инициации передачи UART недостаточно просто разрешить прерывание. Желательно принудительно (программно) установить флаг UTXIFGx. Иначе нельзя быть на 100% уверенным, что прерывание действительно возникнет. Флаг может быть оказаться сброшен после вызова "лишнего" прерывания при неудачном стечении (программных) обстоятельств. А я вообще не понимаю, зачем запрещать и разрешать прерывания по TX. :wassat: Может просветите? Я вот так делаю //------------------------------------------------------------------------------ #pragma vector = UART0TX_VECTOR __interrupt void uart0_write_interrupt_handler(void) { IFG1 &= ~UTXIFG0; // clear flag TXD0 if(MessLen0--)U0TXBUF=*cTXbuf0ptr++; } //------------------------------------------------------------------------------ Закончили передачу сообщения - просто не кидаем в буфер ничего и прерывание не возникнет. Зачем же его тогда запрещать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 7 мая, 2008 Опубликовано 7 мая, 2008 · Жалоба Я вот так делаю Тогда при отсутствии передачи надо первый символ кидать не в буфер, а в U0TXBUF, а то прерывание вообще не возникнет. То есть, нужен какой-то флажок, который отслеживает наличие символа в передатчике. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 27 7 мая, 2008 Опубликовано 7 мая, 2008 · Жалоба Тогда при отсутствии передачи надо первый символ кидать не в буфер, а в U0TXBUF, а то прерывание вообще не возникнет. То есть, нужен какой-то флажок, который отслеживает наличие символа в передатчике. ну да, если надо чё-то передать, ставим указатель на нужный буфер, длину сообщения кидаем в MessLen0 и первый байт в U0TXBUF. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 7 мая, 2008 Опубликовано 7 мая, 2008 · Жалоба ну да, если надо чё-то передать, ставим указатель на нужный буфер, длину сообщения кидаем в MessLen0 и первый байт в U0TXBUF. И не проверяешь перед этим, не идёт ли передача предыдущего блока? :-))) Такой подход хорош для передачи блоков данных. Для putchar(), который может вызываться в произвольные моменты времени, это не подходит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kurt 0 7 мая, 2008 Опубликовано 7 мая, 2008 · Жалоба вопрос действительно уже не раз поднимавшийся и в этот раз я тыркну сцылку )) http://kurt.embedders.org/wiki/sources:uart1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 7 мая, 2008 Опубликовано 7 мая, 2008 · Жалоба Или же здесь что-то более концептуальное? :-) Абсолютно ничего концептуального - правки исключительно в рамках заданной Сергеем концепции. Просто проходя мимо взглядом зацепился. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 140 7 мая, 2008 Опубликовано 7 мая, 2008 · Жалоба Просто проходя мимо взглядом зацепился.Да, согласен. Так лучше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 7 мая, 2008 Опубликовано 7 мая, 2008 · Жалоба А я вообще не понимаю, зачем запрещать и разрешать прерывания по TX. :wassat: Может просветите? При пакетной передаче я тоже не запрещаю. Потому как в прерывании анализируется состояние буфера передачи (количество символов в очереди). Но для посимвольной передачи прерывание запрещать нужно прямо на выходе из прерывания. Иначе может иметь быть место какое-нибудь дублирование символов. Я вот так делаю Закончили передачу сообщения - просто не кидаем в буфер ничего и прерывание не возникнет.Дык это у вас как раз случай буферизированной пакетной передачи. Выше же про putchar речь идет, где посимвольная передача. Тогда при отсутствии передачи надо первый символ кидать не в буфер, а в U0TXBUF, а то прерывание вообще не возникнет. То есть, нужен какой-то флажок, который отслеживает наличие символа в передатчике.Флажки все есть UTXIFGx и EPT, нужно только не забывать их проверять. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 140 7 мая, 2008 Опубликовано 7 мая, 2008 · Жалоба Флажки все есть UTXIFGx и EPT, нужно только не забывать их проверять.Да, флажки есть. Но проверка их - лишний код. Приведенный мной код заменой имен регистров и флагов переносится на мегу и AT91SAM7, где флаг сбросить нельзя - он железно связан с признаком пустоты буфера. Зачем мне под каждый процессор специально заточенные алгоритмы, если этот работает так же? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DogPawlowa 0 20 сентября, 2014 Опубликовано 20 сентября, 2014 · Жалоба Оппа... Понадобилось перевести передачу на прерывания, не работает так как надо. У меня особенность - в циклический буфер добавляются байты (или строки) если - передача идет - если передача стоит Если оперировать только разрешением прерывания, как у zltigo, то передача после первого байта блокируется. Это понятно - нет фронта флага, он повис. Если дергать (устанавливать) флаг готовности передачи в момент добавления в буфер очередного символа, то символы пропадают - тоже понятно - срабатывает прерывание по передаче, когда передача еще идет. Я конечно найду решение до понедельника, но если кто имеет решение, прошу поделиться. Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 20 сентября, 2014 Опубликовано 20 сентября, 2014 · Жалоба После добавления чего-то в буфер вызвать (запретив прерывания) обычную функцию проверки готовности и разрешения прерывания - первый байт выйдет по опросу, остальные пойдут по прерываниям. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться