Запрет прерывания
Добавлено: Вт фев 19, 2013 21:28:03
Вот код с CodeVisioonAVR по обработке прерывания прихода символа в USART:
так вот в курсе 123авр фрагмент
#asm("cli")
--rx_counter;
#asm("sei")
описан, но я его в корне не пойму....зачем и смысл останавлиать прерывания потом его заново запускать....непойму...
так тут написано что прерывания блокируются из за того что...
Код: Выделить всё
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer[rx_wr_index]=data;
if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
rx_buffer_overflow=1;
};
};
}
#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif
так вот в курсе 123авр фрагмент
#asm("cli")
--rx_counter;
#asm("sei")
описан, но я его в корне не пойму....зачем и смысл останавлиать прерывания потом его заново запускать....непойму...
так тут написано что прерывания блокируются из за того что...
....получается, что они останавливают прерывания только для того чтоб не помешать декременту....но а смысл если когда произойдет прерывание то по его окончанию все равно декремент выполнится, ведь прерывание не портит функции --rx_counter если выполняется в тот же моментТак как мы считали символ из буфера нужно уменьшить число символов в нем подлежащих считыванию.
#asm("cli") // запретить прерывания глобально
--rx_counter; // вычесть 1 из rx_counter
#asm("sei") // разрешить прерывания глобально
Обратите внимание что перед декрементом мы запрещаем прерывания, а после прерывания включаем опять.
Зачем ? Вот фо ??? воскликнул бы англоязычный читатель ...
А затем, что в обработчике прерывания есть инкремент rx_counter - и если на декременте возникнет прерывание мы можем зациклится в этом месте программы и получить ошибку в числе символов в буфере.