Написал программу перебора по кнопке пяти различных анимаций, навесил в протеусе светодиоды, кнопку на вход INT0(кнопка не работает, поэтому её функцию выполняет одна из ног светодиода)...
Проблема в том что прерывание выглядит так:
interrupt [EXT_INT0] void ext_int0_isr(void)
{
n++;
if(n>5)
n=1;
if(n==1)
anim1();
if(n==2)
anim2();
if(n==3)
anim3();
if(n==4);
anim4();
if(n==5)
anim5();
}
anim1(),anim2() и т.д - это процедуры разных анимаций... в теле главной функции main число n присваивается нуевое значение... ПРоблема в том что, насколько я понял, число n возвращает себе значение 0 после выполнения подпрограммы так? как мне сохранить изменяющееся число n после выполнения подпрограммы? Все порты настроены правильно и прерывания разрешены!
может вы в подпрограмме его обнуляете? код подпрограммы в студию!
В прерывании лучше никаких подпрограм не вызывать.
к тому же явно присуствует дребезг контактов, на входе INT0, надо это учитывать
Вот собственно код(коментов нету сразу предупреждаю)... дребезга не должно быть, так как сигнал с ножки порта С и есть сигнал который идет на ножку INT0(конечно хитропопо, но зато после анимации включается другая, для проверки)...
#include <mega8.h>
#include <delay.h>
#include <stdio.h>
int i;
int n;
void all_light()
{
while(1)
{
PORTB=0xFF;
PORTC=0xFF;
} //все диоды горят
}
а где основной цикл while(1){} в main?
уберите их из подпрограм
вы знаете куда возвращается Program Counter после выполнения прерывания? на тоже место где прерывание возникло, т.е. в ту процедуру, которая была активна в тот момент. Надо вызывать процедуры в основном цикле, а не в прерывании. Мое мнение, ессно.
запутано все писец непонятно. Немешало бы в отладчике покрутить. но подход к написанию у вас не правильный. В прерывании просто увеличивайте "n", а в главном цикле надов зависимости от "n" запускать нужный эффект. примерно так
мне кажется, что подход не верный даже в том случае, если эффекты сделать функциями в главном цикле. проблема в том, что функция эффекта должна прекращать свою работу сразу же, как обработается прерывание, т.е. надо внутри нее анализировать флаг какой-то или число n ваше - короче, путаница какая-то.
если эффект заключается в том, что друг за другом сменяются какие-то наперед известные комбинации, то лучше каждый эффект сделать не отдельной функцией, а при помощи массива:
#define MAX_EFFEKT 5
#define MAX_STEP 16
char Kombination[MAX_EFFEKT][MAX_STEP] = {/* тут задать 5 раз по 16 констант для получения эффектов*/};
volatile int effeсt=0; // номер текущего эффекта
int main(void){
// всякая инициализация
while(1){
for(int i=0; i<MAX_STEP;i++){
PORTB = Kombination[effeсt][i]; // просто выводим комбинацию в порт
delay_ms(100);
}
}
}
ISR(INT0_vect){ // обработчик вашего прерывания
if(++effeсt == MAX_EFFECT) effect = 0;
}
естественно, сам эффект может быть сложнее простого вывода в порт, главное, чтобы его параметры извлекались из массива
предупреждаю: в моем коде есть узкое место: дребезг в обработчике прерывания никак не подавляется - но и у вас первоначально он не подавлялся! бороться с ним оставляю вам в виде развлечения
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...