помогите разобраться с прерываниями

iopq
Offline
Зарегистрирован: 05.07.2016

нужно читать данные с устройства. соответственно решил использовать прерывания.

настраиваю так 

void setup() {
 DDRD &= ~_BV(2);       //порт на вход
 EICRA |= (1<<ISC01);   //вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW)
 EIMSK |= (1<<INT0);    //разрешить прерывания INT0
}

далее по событию вызывается функция -

ISR(INT0_vect){
 read(); 
}

которая представляет собой 

void read()
{
cli();                                                       //запретили прерывания
readByte();                                            //читаем поступающие данные в глобальную переменную
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (temp[0]  ==  0xD6){                           //если поступили ожидаемые данные
for(uint8_t i=0;i<22;i++) temp[i] =0;      //очистили глобальную переменную byte temp[22] = {};
DDRD |= (1 << 2);                                 //настроили порт на выход
writeByte(0x10);                                   //отправили байт
DDRD &= ~_BV(2);                              //настроили порт на вход               
sei();                                                     //разрешили прерывания
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (temp[0] == 0x1F){ //если поступили ожидаемые данные for(uint8_t i=0;i<22;i++) temp[i] =0; //очистили глобальную переменную byte temp[22] = {}; DDRD |= (1 << 2); //настроили порт на выход writeByte(0x20); //отправили байт DDRD &= ~_BV(2); //настроили порт на вход sei(); //разрешили прерывания }

}

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

iopq
Offline
Зарегистрирован: 05.07.2016
код исковеркался, редактировать кнопки нет дублирую-
void read()
{
cli();                                                       //запретили прерывания
readByte();                                            //читаем поступающие данные в глобальную переменную
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (temp[0]  ==  0xD6){                           //если поступили ожидаемые данные
for(uint8_t i=0;i<22;i++) temp[i] =0;      //очистили глобальную переменную byte temp[22] = {};
DDRD |= (1 << 2);                                 //настроили порт на выход
writeByte(0x10);                                   //отправили байт
DDRD &= ~_BV(2);                              //настроили порт на вход               
sei();                                                     //разрешили прерывания
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (temp[0]  ==  0x1F){                           //если поступили ожидаемые данные
for(uint8_t i=0;i<22;i++) temp[i] =0;      //очистили глобальную переменную byte temp[22] = {};
DDRD |= (1 << 2);                                 //настроили порт на выход
writeByte(0x20);                                   //отправили байт
DDRD &= ~_BV(2);                              //настроили порт на вход               
sei();                                                     //разрешили прерывания
}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Не понимаю, зачем вы засунули в обработчик прерывания чтение, запись и еще разбор данных? В прерывании максимум, что надо сделать - положить прочитанный байт в буфер. Или флаг "пора читать" поднять. А анализировать то, что нападало в буфер и рассылать данные - в лупе.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

У вас получается, что в прерывании используются sei и cli. Убирайте срочно.  Ну и обработку данных делайте по флагу, в прерывании считываете байт в буфер, по заполнении буфера выставляете флажек, а в лупе по нему работаете с накопленными данными. Можете сделать два буфера чтения данныз. Пока в один складываете данные из прерывания, другой обрабатываете.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

А препод чё говорит?