Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

RQ: ATMega външни прекъсвания - странност
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=8714
Страница 1 от 1

Автор:  NikB [ Пет Мар 18, 2011 2:03 pm ]
Заглавие:  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]
136 пъти

Автор:  NikB [ Пет Мар 18, 2011 2:06 pm ]
Заглавие: 

Да сложа и картинка

Прикачени файлове:
Test.JPG
Test.JPG [ 38.86 KiB | Прегледано 1148 пъти ]

Автор:  michev [ Пет Мар 18, 2011 2:54 pm ]
Заглавие: 

Това което на пръв поглед виждам е, че си изпуснал един "OR"
Код:
EICRB =   (1 << bit_ISC0[ aInd]) | (1 << bit_ISC1[ aInd]);

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

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

Автор:  NikB [ Пет Мар 18, 2011 3:09 pm ]
Заглавие: 

Не съм го изпуснал, ами съм го "подредил" (вероятно съм го изтрил, докато съм се опитвал да "подредя" сорса).

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

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

Благодаря!

Страница 1 от 1 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/