Easyelectronics.ru

Электроника для всех
Текущее время: 23 янв 2021, 00:09

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 63 ]  На страницу 1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 05 май 2020, 13:13 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
Всем доброго!
Измеряю длительность положительного импульса поступающим на INT1 от ультразвукового датчика SRF-04. В цикле FOR делаются 6 измерений и и вычисляется среднее. По моей задумке, при неисправности датчика SRF-04 TMR1 должен переполниться и уйти в прерывание по переполнению где делаются определенные действия и программа не выходит из прерывания по exit(0); Датчик снят, на INT1 висит 0 (перемычкой), условия прерывания на INT1 нарастающий фронт, Start = 1, Stop = 0. В while (status == START) ожидаю завершение двух прерываний - по нарастающему и спадающему фронтам и если их нет(status == START), то TMR1 должен уйти в прерывание по переполнению - не уходит зараза и все!!! Уже моск кипит! В Proteus 8.4 все нормально работает, а железе нет! Ткните носом плиз, где мой косяк? Пробовал тупо заставлять его уходить в прерывание с задержкой - уходит. При моей частоте 7372800 и делителе прескалера 8 он должен уходить через 71,11 мс. Заранее благодарен!

Код:
EICRA = (1<<ISC11)|(1<<ISC10);                           //Прерывание по нарастающему фронту на INT1

    for ( n = 1; n < 7; n++) {
      
   TIMSK = (1 << TOIE1);                        //разрешение прерывания по переполнению TMR1
   EIMSK = (1<<INT1);                        //разрешение прерывания на INT1
   TCCR1B = (1 << CS11);                     //TMR1 включен, делитель на 8
   SFIOR = (1 << PSR321);                     //сброс прескалера
   status = START;   
   asm volatile("sei" : :);
   
     Eho_PORT |= (1<<TRIG);                     //запускаем триггер сонара.
     _delay_us(15);
     Eho_PORT &= ~(1 << TRIG);
    
       while (status == START)                     //ожидание окончания измерения
       {asm volatile("nop" : :);}
         
     EIMSK &= ~(1 << INT1);                     //запрешение прерывания на INT1
     TIMSK &= ~(1<<TOIE1);                     //запрещение прерывания по переполнению TMR1
     TCCR1B &= ~(1 << CS11);                     //TMR1 остановлен
     asm volatile("cli" : :);
     data -= 4;                           //коррекция измерений 
     distance = ((data * 1.085)/S) * 5.0;               //растояние (мм).
     summ += distance;

     _delay_ms(50);   
    }//for

    distance = summ / 6;                        //среднеарифметическое растояние до уровня воды   

   }//if
      return Temp_L;
}



Код:
// Обработчик прерывания по любому изменению на INT1
ISR(INT1_vect)
{
    if(Eho_PIN & (1 << EHO)) {                           //пришла единица, сбрасывам таймер
                                                   //и ставим состояние старта преобразования
      Reg = SREG;                  
      TCNT1 = 0x00;
      EICRA &= ~(1 << ISC10);                           //прерывание INT1 по низпадающему фронту
      SREG = Reg;
    }
    else {                                          //пришел ноль, значит звук вернулся.
      Reg = SREG;
       data = TCNT1;
       status = STOP;
      EICRA |= (1 << ISC10);                           //прерывание INT1 по нарастающему фронту
      SREG = Reg;
    }
}

//Обработчик прерывания по переполнению TMR1
ISR (TIMER1_OVF_vect)                                 
{                                                
    PORT_I_O &= ~(1 << CH1);                           //выключаем VALVE               
    PORT_I_O &= ~(1 << CH2);                           //выключаем PUMP0
    PORT_I_O &= ~(1 << CH3);                           //выключаем PUMP1
    LCDclr();
    CopyStringtoLCD(TEXT26,0,1);                        //" SONAR SRF-04 ERROR "
    exit(0);   
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 05 май 2020, 16:17 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 3051
Если в проетусе работает, а в железе нет, скорее всего дело в железе. Дребезг какой может. Если status = STOP; убрать временно из прерывания INT1 - будет уходить в ошибку по переполнению таймера?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 05 май 2020, 16:40 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
Цитата:
Датчик снят, на INT1 висит 0 (перемычкой)
(cостояние STOP)
Цитата:
, ....... Start = 1, Stop = 0. В while (status == START) ожидаю завершение двух прерываний - по нарастающему и спадающему фронтам и если их нет
(status == START==1),
Цитата:
то TMR1 должен уйти в прерывание по переполнению - не уходит зараза и все!!!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 05 май 2020, 16:49 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 3051
ILYAUL, у него вначале в коде прерывание настроено по возрастающему фронту. Если перемычка на землю до старта висит, то этого условия не случится и в прерывание INT1 оно по идее никогда не войдет в принципе.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 02:51 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
Разъем для датчика 4-х штырьковый и вход INT1 рядом с GND, поэтому на них стоит обычный джампер имитируя состояние покоя датчика. Если джампер снять (на INT1 висит 1) - ничего не меняется. В Proteus между сигналом ЭХО датчика и INT1 стоит джампер, если его снять, то уходит в прерывание(на INT1 1). Может не пропай ножки INT1? Но когда подключаю датчик вроде все работает - произвожу (условную) калибровку емкости с водой и после чего все показывает в % уровня емкости как и задумано. Попробую пропаять ножку INT1 и за комментировать status = STOP. Здесь Proteus уже не помощник, придется пере заливать железо. По результатам отпишусь.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 13:34 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
За комментировал status = STOP в обработке прерывания INT1 - в Proteus уходит по переполнению, а в железе нет... пропаял ножку INT1, не помогло.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 14:08 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
Бред какой то, даже вот так не уходит

Код:
EICRA = (1<<ISC11)|(1<<ISC10);                           //Прерывание по нарастающему фронту на INT1

    for ( n = 1; n < 7; n++) {
      
   TIMSK = (1 << TOIE1);                              //разрешение прерывания по переполнению TMR1
   EIMSK &= ~(1<<INT1);                                 //разрешение прерывания на INT1
   TCCR1B = (1 << CS11);                              //TMR1 включен, делитель на 8
   //SFIOR = (1 << PSR321);                              //сброс прескалера
   //status = START;   
   asm volatile("sei" : :);
   
    _delay_ms(4000);
   
     Eho_PORT |= (1<<TRIG);                           //запускаем триггер сонара.
     _delay_us(15);
     Eho_PORT &= ~(1 << TRIG);
    
       while (status == START)                           //ожидание окончания измерения
       {asm volatile("nop" : :);}
         
     EIMSK &= ~(1 << INT1);                           //запрешение прерывания на INT1
     TIMSK &= ~(1<<TOIE1);                              //запрещение прерывания по переполнению TMR1
     TCCR1B &= ~(1 << CS11);                           //TMR1 остановлен
     asm volatile("cli" : :);
     data -= 4;                                    //коррекция измерений 
     distance = ((data * 1.085)/S) * 5.0;                  //растояние (мм).
     summ += distance;

     _delay_ms(50);   
    }//for

    distance = summ / 6;                              //среднеарифметическое растояние до уровня воды   

   }//if
      return Temp_L;
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 14:18 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
А вот так уходит в прерывание по переполнению... начало функции main

Код:
   
//Конфигурация порта РG
   DDRG = 0b11111110;
   PORTG = 0b00000011;
   
// Настройка АЦП канал ADC0 PORTA
   ADCSRA = 0x00;                                         
   ADMUX = 0b01000001;                                 //kанал ADC1 и Vdd опорное напряжение
   ADCSRA |= (1 << ADPS1)|                                //предделитель на 64. Работа АЦП на 115200 Гц
   (1 << ADPS2)|                                     //включение АЦП Включение преобразования вручную.
   (1 << ADEN);
   
// Инициализация LCD 
   LCDinit();
   LCDclr();
   
//Вывод заставки
    CopyStringtoLCD(TEXT11,1,1);
    CopyStringtoLCD(TEXT12,1,2);
    CopyStringtoLCD(TEXT17,11,3);
    _delay_ms(4000);
   
   TIMSK = (1 << TOIE1);                              //разрешение прерывания по переполнению TMR1
   EIMSK &= ~(1<<INT1);                                 //разрешение прерывания на INT1
   TCCR1B = (1 << CS11);                              //TMR1 включен, делитель на 8
   //SFIOR = (1 << PSR321);                              //сброс прескалера
   //status = START;
   asm volatile("sei" : :);
   
   _delay_ms(75);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 14:33 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
Не могу понять, почему TMR1 не уходит в прерывание по переполнению, если запуск на переполнение происходит в вызываемой функции и уходит, если этот запуск стоит в другом месте? Может надо запускать переполнение перед вызовом функции и выключать после возврата из нее?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 15:25 
Старожил
Аватара пользователя

Зарегистрирован: 24 апр 2014, 04:58
Сообщения: 297
Croco писал(а):
TCCR1B = (1 << CS11); //TMR1 включен, делитель на 8
SFIOR = (1 << PSR321); //сброс прескалера


TCCR1B = (1 << CS11);
TCNT1=0;

так не пробовали? :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 15:48 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
Пробовал, никаких изменений... я собственно сейчас прескалер обнуляю уже от безысходности - мне фиолетово, что у него там внутри творится. Счетчик обнуляется при входе в прерывание INT1 по нарастающему фронту.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 15:58 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
Хочу попробовать как я выше писал - запускать переполнение счетчика перед вызовом функции измерения и останавливать после возврата из нее. Но для этого надо переписать функцию измерения, т.к. до работы с сонаром идет работа с DS18B20 и там хоть и 9 бит преобразование, счетчик за это время улетит по переполнению. В общем, отделю мух от котлет и отпишусь.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 16:23 
Старожил
Аватара пользователя

Зарегистрирован: 24 апр 2014, 04:58
Сообщения: 297
Show Обработчик прерывания по любому изменению на INT1


Не пробовали заходя в прерывание по ISR (TIMER1_OVF_vect) :
отключать INT1_vect и его "друзей"
Выбросить медленные функции LCD из TIMER1_OVF_vect

Не могу понять куда "лыжи навострил" exit(0) если в pop хранится while(status ==START)


Для начала, я бы:
SFIOR не трогал, и вообще забыл бы про него
Код:
//Обработчик прерывания по переполнению TMR1
ISR (TIMER1_OVF_vect)   
{
// Не знаю что это   
PORT_I_O &= ~(1 << CH1);   //выключаем VALVE
PORT_I_O &= ~(1 << CH2);   //выключаем PUMP0
PORT_I_O &= ~(1 << CH3);   //выключаем PUMP1
// что-то подобное
status=(uint8_t)STOP;   
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 18:37 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
Попробовал - изменений нет. Такое ощущение, что при входе в функцию таймер забывает, что он включен и разрешено прерывание по переполнению


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 18:57 
Старожил
Аватара пользователя

Зарегистрирован: 24 апр 2014, 04:58
Сообщения: 297
Croco писал(а):
Попробовал - изменений нет. Такое ощущение, что при входе в функцию таймер забывает, что он включен и разрешено прерывание по переполнению

Это ваш SFIOR там воду мутит :)
Мне не нравится status ==START status ==STOP
Их следовало бы привести, если они не enum

Код:
#define START (uint8_t)0x01
#define STOP(uint8_t)0x00


или

Код:
enum SonarEnum
{
STOP,
START
}


Такая большая необходимость в сохранении SREG ?
Он у вас по умолчанию сохраняется при входе в ISR.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 19:09 
Старожил
Аватара пользователя

Зарегистрирован: 24 апр 2014, 04:58
Сообщения: 297
Croco писал(а):
при входе в функцию

Какую?
Таймер включается прескаллером, а SFIOR отключает работу таймера.
Я надеюсь, что при входе в "функцию" вы запускаете таймер?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 19:18 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
Код:
TIMSK = (1 << TOIE1);                              //разрешение прерывания по переполнению TMR1
TCCR1B = (1 << CS11);                              //TMR1 включен, делитель на 8
//SFIOR = (1 << PSR321);                              //сброс прескалера
//TCNT1 = 0x00;
//asm volatile("sei" : :);

         WaterDistans();

EIMSK &= ~(1 << INT1);                           //запрешение прерывания на INT1
TIMSK &= ~(1<<TOIE1);                              //запрещение прерывания по переполнению TMR1
TCCR1B &= ~(1 << CS11);                           //TMR1 остановлен
asm volatile("cli" : :);   



Код:
uint16_t summ = 0;
    uint8_t n;
   
   EICRA = (1<<ISC11)|(1<<ISC10);                           //Прерывание по нарастающему фронту на INT1
//TCCR1B = (1 << CS11);
//EIMSK = (1<<INT1);                                 //разрешение прерывания на INT1
asm volatile("sei" : :);
    for ( n = 1; n < 7; n++) {
      status = START;
      TCNT1 = 0x00;
   //TIMSK = (1 << TOIE1);                              //разрешение прерывания по переполнению TMR1
   //EIMSK = (1<<INT1);                                 //разрешение прерывания на INT1
   //TCCR1B = (1 << CS11);                              //TMR1 включен, делитель на 8
   //SFIOR = (1 << PSR321);                              //сброс прескалера
      
   //TCNT1 = 0x00;
   //asm volatile("sei" : :);
   

   
     Eho_PORT |= (1<<TRIG);                           //запускаем триггер сонара.
     _delay_us(15);
     Eho_PORT &= ~(1 << TRIG);
    
       while (status == START)                           //ожидание окончания измерения
       {asm volatile("nop" : :);}
         
     //EIMSK &= ~(1 << INT1);                           //запрешение прерывания на INT1
     //TIMSK &= ~(1<<TOIE1);                              //запрещение прерывания по переполнению TMR1
     //TCCR1B &= ~(1 << CS11);                           //TMR1 остановлен
     //asm volatile("cli" : :);
     data -= 4;                                    //коррекция измерений 
     distance = ((data * 1.085)/S) * 5.0;                  //растояние (мм).
     summ += distance;


SFIOR не используется уже, это я просто и его попробовал...
С START и STOP так:
#define START 1
#define STOP 0

На всех INT прерывания запрещены:
EIMSK = 0;

перед вызовом функции включаю таймер и разрешаю переполнение - нифига...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 19:52 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
В общем, перед входом в функцию разрешаю прерывание таймера по переполнению, включаю таймер и глобальное прерывание, захожу в функцию и ничего не запрещаю - нет прерывая по переполнению и хоть умри!!!
Прерывания по INT запрещены

ЖАЛЬ, ЗДЕСЬ МАТЕРИТЬСЯ НЕЛЬЗЯ!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 20:03 
Старожил
Аватара пользователя

Зарегистрирован: 24 апр 2014, 04:58
Сообщения: 297
Что-то вроде этого попробовать подцепить
Код:
cli();
TIMSK = (1 << TOIE1);                              //разрешение прерывания по переполнению TMR1
TCCR1B = (1 << CS11);                              //TMR1 включен, делитель на 8
while(!(TIFR1&(1<<TOV1)){
// Включить лед 1
}

while(!!(TIFR1&(1<<TOV1)){
// Включить лед 2
}

// должен здесь зависнуть


И конечно же
Код:
   
MCUCSR|=(1<<JTD);
MCUCSR|=(1<<JTD);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 21:23 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
Этот код нужно вставить в функцию или как? Если все запускать не в этой гребанной функции, то таймер уходит в прерывание

Код:
TIMSK = (1 << TOIE1);                              //разрешение прерывания по переполнению TMR1
   EIMSK &= ~(1<<INT1);                                 //разрешение прерывания на INT1
   TCCR1B = (1 << CS11);                              //TMR1 включен, делитель на 8
   asm volatile("sei" : :);
   
   _delay_ms(75);


Но в функции не хочет. А зачем MCUCSR|=(1<<JTD); ? У меня JTAG отключен фьюзами


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 21:34 
Старожил
Аватара пользователя

Зарегистрирован: 24 апр 2014, 04:58
Сообщения: 297
Croco писал(а):
таймер уходит в прерывание


Тогда не нужно

Jtag проверьте

и статус
Код:
    volatile uint8_t status;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 21:55 
Старожил
Аватара пользователя

Зарегистрирован: 24 апр 2014, 04:58
Сообщения: 297
Show Вдумчиво и последовательно


Взято отсюда http://www.gaw.ru/html.cgi/txt/doc/micros/avr/arh128/8.htm


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 22:01 
Заглядывает иногда

Зарегистрирован: 14 янв 2015, 19:31
Сообщения: 53
Все именно так - Jtag отключен, volatile uint8_t status;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 22:03 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
Цитата:
Also, the increased number of Interrupt Vectors might be a problem if the code uses absolute addresses.
Похоже у Вас очень правильная 64-ая и надо бы ее проверить на "вшивость". Особенно один fuse.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: В ATmega64A не могу заставить TMR1 уйти в прерывание.
СообщениеДобавлено: 06 май 2020, 22:54 
Старожил
Аватара пользователя

Зарегистрирован: 24 апр 2014, 04:58
Сообщения: 297
ILYAUL
Show Он может здесь еще сидеть


Больше негде?
Три сосны...


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 63 ]  На страницу 1, 2, 3  След.


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB