Отговори на тема  [ 4 мнения ] 
RQ: ATMega външни прекъсвания - странност 
Автор Съобщение
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Съб Сеп 25, 2004 10:32 pm
Мнения: 710
Мнение RQ: ATMega външни прекъсвания - странност
RQ: ATMega външни прекъсвания - странност, която не мога да си обясня.

Кодът е дълъг за пример, но е спретнат и еднотипен :).

(В атачнатия файл сорсът е заедно с проектни файлове за AvrStudio 4 и 5 и Протеус симулация)

Та по същество:
Въпреки, че всичко е абсолютно еднакво за външни прекъсвания от 4 до 7, бит 7 се държи различно от останалите - сработва при отпускане на бутона, а не при натискане.
Дори след инициализация (след глобалното разрешаване на прекъсванията - реда "sei();") състоянието на изхода, "свързан" към SIG_INTERRUPT7 е различно от останалите.
(Ако не разреша прекъсванията, т.е. ако sei() е в коментар - състоянията са еднакви).

Някъде не доглеждам нещо (или не съм дочел някоя особеност).


Код:
#include <avr/io.h>
#include <avr/interrupt.h>

volatile uint8_t LedIsOn[4]      = {0, 0, 0, 0};
volatile uint8_t LedPortB[4]   = {PORTB4, PORTB5, PORTB6, PORTB7};
   
volatile uint8_t bit_DDE[4]      = {DDE4, DDE5, DDE6, DDE7};
volatile uint8_t bit_PortE[4]   = {PORTE4, PORTE5, PORTE6, PORTE7};
volatile uint8_t bit_ISC0[4]   = {ISC40, ISC50, ISC60, ISC70};
volatile uint8_t bit_ISC1[4]   = {ISC41, ISC51, ISC61, ISC71};
volatile uint8_t bit_INT[4]      = {INT4, INT5, INT6, INT7};

// Обработчик прерывания.
void Interrupt_Ext( uint8_t aInd){
   LedIsOn[ aInd] ^= 1;
   if ( LedIsOn[ aInd])  {
      PORTB |= (1 << LedPortB[ aInd]);   // Включаем светодиод.
   } else {
      PORTB &= ~(1 << LedPortB[ aInd]);  // Выключаем светодиод
   }
}
SIGNAL(SIG_INTERRUPT4){
   Interrupt_Ext( 0);
}
SIGNAL(SIG_INTERRUPT5){
   Interrupt_Ext( 1);
}
SIGNAL(SIG_INTERRUPT6){
   Interrupt_Ext( 2);
}
SIGNAL(SIG_INTERRUPT7){
   Interrupt_Ext( 3);
}

int main(void){
            void xInit_Inp( uint8_t aInd){
            // Настраиваем порт на котором висят кнопки
               DDRE  &= ~(1 << bit_DDE[ aInd]);                     // Port direction: input
               PORTE |=  (1 << bit_PortE[ aInd]);                     // PulUp: On
               EICRB =   (1 << bit_ISC0[ aInd]) | (1 << bit_ISC1[ aInd]);   // Прерывание по возрастающий фронту сигнала.
               EIMSK |=  (1 << bit_INT[ aInd]);                     // Разрешаем внешнее прерывание, заведенное на порт кнопки.
            }
   
  // Конфигурируем порт на выход.
  DDRB |= (1 << DDB7) | (1 << DDB6) | (1 << DDB5) | (1 << DDB4) | (0 << DDB3) | (0 << DDB2) | (0 << DDB1) | (1 << DDB0);
  PORTB = 0;
  // Настраиваем порт на котором висят кнопки
  xInit_Inp( 0);
  xInit_Inp( 1);
  xInit_Inp( 2);
  xInit_Inp( 3);
 
  sei(); // Глобальное разрешение прерываний.

/* !!! */
 
  // Бесконечный цикл.
  while(1) {
    uint16_t i;
    for(i = 65535; i != 0; i--);
    PORTB &= ~(1 << PORTB0);  // Выключаем светодиод 1.
    for(i = 65535; i != 0; i--);
    PORTB |= (1 << PORTB0);   // Включаем светодиод 1.
  }
/*  */
}


Прикачени файлове:
Коментар на файл: сорсът е заедно с проектни файлове за AvrStudio 4 и 5 и Протеус симулация
InterruptsExt.rar [47.53 KiB]
135 пъти


Последна промяна NikB на Пет Мар 18, 2011 2:19 pm, променена общо 1 път

Пет Мар 18, 2011 2:03 pm
Профил ICQ WWW
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Съб Сеп 25, 2004 10:32 pm
Мнения: 710
Мнение 
Да сложа и картинка


Прикачени файлове:
Test.JPG
Test.JPG [ 38.86 KiB | Прегледано 1143 пъти ]
Пет Мар 18, 2011 2:06 pm
Профил ICQ WWW
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Сря Юли 11, 2007 10:16 am
Мнения: 1730
Мнение 
Това което на пръв поглед виждам е, че си изпуснал един "OR"
Код:
EICRB =   (1 << bit_ISC0[ aInd]) | (1 << bit_ISC1[ aInd]);

според мен трябва да е
Код:
EICRB  |=   (1 << bit_ISC0[ aInd]) | (1 << bit_ISC1[ aInd]);

Защото, на всяко конфигуриране на пин, се записва само неговите сенс конфигурационни битове, и свяко следващо презаписва предходната конфигурация


Пет Мар 18, 2011 2:54 pm
Профил
Ранг: Почетен член
Ранг: Почетен член
Аватар

Регистриран на: Съб Сеп 25, 2004 10:32 pm
Мнения: 710
Мнение 
Не съм го изпуснал, ами съм го "подредил" (вероятно съм го изтрил, докато съм се опитвал да "подредя" сорса).

И без него - в EICRB остава само това, което е за bit7 (щото се инициализира последен)

МНОГО благодаря
(въобще не мио мина през ума, че може да е такава грешката, за да проверя, а е било доста логично)
(а сега си мисля, че докато съм се чудел е можело да разместя битовете, за диагностика :))

Благодаря!


Пет Мар 18, 2011 3:09 pm
Профил ICQ WWW
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 4 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 6 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни