Перейти к содержанию
    

Тема может быть избита. не понимаю как оргнизовать работу UART по прерывания(+)

Переход по вектору прерывания от передатчика автоматически сбрасывает флаг вызова прерывания.
Да, про это я забыл, каюсь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот мой код...

Пытаясь выжать (вдруг я чего-то не понимаю, чего другие понимают :( )из простейшего 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
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно проще

 

Правильно ли я понял, что вы сэкономили одно слово volatile и две (вроде бы) операции &=TX_BUFF_MASK?

 

Или же здесь что-то более концептуальное? :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно проще, например, передача:

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% уверенным, что прерывание действительно возникнет. Флаг может быть оказаться сброшен после вызова "лишнего" прерывания при неудачном стечении (программных) обстоятельств.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для инициации передачи 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++; 
   
}

//------------------------------------------------------------------------------

 

Закончили передачу сообщения - просто не кидаем в буфер ничего и прерывание не возникнет.

Зачем же его тогда запрещать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я вот так делаю

 

Тогда при отсутствии передачи надо первый символ кидать не в буфер, а в U0TXBUF, а то прерывание вообще не возникнет. То есть, нужен какой-то флажок, который отслеживает наличие символа в передатчике.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда при отсутствии передачи надо первый символ кидать не в буфер, а в U0TXBUF, а то прерывание вообще не возникнет. То есть, нужен какой-то флажок, который отслеживает наличие символа в передатчике.

ну да, если надо чё-то передать, ставим указатель на нужный буфер, длину сообщения кидаем в MessLen0 и первый байт в U0TXBUF.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну да, если надо чё-то передать, ставим указатель на нужный буфер, длину сообщения кидаем в MessLen0 и первый байт в U0TXBUF.

 

И не проверяешь перед этим, не идёт ли передача предыдущего блока? :-)))

 

Такой подход хорош для передачи блоков данных. Для putchar(), который может вызываться в произвольные моменты времени, это не подходит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вопрос действительно уже не раз поднимавшийся и в этот раз я тыркну сцылку ))

http://kurt.embedders.org/wiki/sources:uart1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Или же здесь что-то более концептуальное? :-)

Абсолютно ничего концептуального - правки исключительно в рамках заданной Сергеем концепции. Просто проходя мимо взглядом зацепился.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Просто проходя мимо взглядом зацепился.
Да, согласен. Так лучше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А я вообще не понимаю, зачем запрещать и разрешать прерывания по TX.

:wassat:

Может просветите?

При пакетной передаче я тоже не запрещаю. Потому как в прерывании анализируется состояние буфера передачи (количество символов в очереди). Но для посимвольной передачи прерывание запрещать нужно прямо на выходе из прерывания. Иначе может иметь быть место какое-нибудь дублирование символов.

Я вот так делаю

Закончили передачу сообщения - просто не кидаем в буфер ничего и прерывание не возникнет.
Дык это у вас как раз случай буферизированной пакетной передачи. Выше же про putchar речь идет, где посимвольная передача.

Тогда при отсутствии передачи надо первый символ кидать не в буфер, а в U0TXBUF, а то прерывание вообще не возникнет. То есть, нужен какой-то флажок, который отслеживает наличие символа в передатчике.
Флажки все есть UTXIFGx и EPT, нужно только не забывать их проверять.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Флажки все есть UTXIFGx и EPT, нужно только не забывать их проверять.
Да, флажки есть. Но проверка их - лишний код. Приведенный мной код заменой имен регистров и флагов переносится на мегу и AT91SAM7, где флаг сбросить нельзя - он железно связан с признаком пустоты буфера. Зачем мне под каждый процессор специально заточенные алгоритмы, если этот работает так же?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Оппа...

Понадобилось перевести передачу на прерывания, не работает так как надо.

У меня особенность - в циклический буфер добавляются байты (или строки) если

- передача идет

- если передача стоит

 

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

Если дергать (устанавливать) флаг готовности передачи в момент добавления в буфер очередного символа, то символы пропадают - тоже понятно - срабатывает прерывание по передаче, когда передача еще идет.

 

Я конечно найду решение до понедельника, но если кто имеет решение, прошу поделиться.

Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...