Страница 1 из 1

Как убить прерывание в CV ?

Добавлено: Пт май 08, 2015 10:14:28
binarick
Доброго времени уважаемые форумчане.
Пытаюсь сделать кнопочки управления на прерывании и вроде бы всё работает но немного не так как нужно :)

Схемка в 8 протеусе:
Изображение
Проблема: При нажатии на кнопку "Right" мой счётчик kolvo должен получить ++, это и происходит, но после этого он постоянно получает ++
Тоже самое с "Left". те. после нажатия на кнопку право/лево я имею постоянно приращение единицы до предела переменной.

Что сделать чтобы по нажатии на кнопку единожды выполнялось ++ или -- ?
Предполагаю что нужно как-то остановить прерывание, но как это сделать в CVAVR не знаю

код на CodeVision AVR 3.12:

Код: Выделить всё

#include <mega8.h>
#include <alcd.h>
#include <delay.h>
#include <stdio.h>

short int pushkey=0, kolvo=0;
char lcd_buffer[33];
int kod = 0;

interrupt [EXT_INT0] void ext_int0_isr(void)
{//5 - left; 6 - right; 7 - clik
pushkey=0;
if (PINB.7==0) pushkey = 7;
if (PINB.6==0) pushkey = 6;
if (PINB.5==0) pushkey = 5;

//как убить прерывание в CV ??????? 
}

void main(void)
{
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (1<<DDB4) | (1<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0); 
PORTB=(1<<PORTB7) | (1<<PORTB6) | (1<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
DDRC=(1<<DDC6) | (1<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// INT0: On
GICR|=(0<<INT1) | (1<<INT0);
//MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC00) | (0<<ISC00);
//MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (1<<ISC00);
//MCUCR=(0<<ISC11) | (0<<ISC10) | (1<<ISC00) | (0<<ISC01);
MCUCR=(0<<ISC11) | (0<<ISC10) | (1<<ISC01) | (1<<ISC01);
GIFR=(0<<INTF1) | (1<<INTF0);

lcd_init(20);
lcd_clear();
#asm("sei")

while (1)
      {
        if(pushkey==7)  {delay_ms(10);kod='c'; pushkey=0;}
        if(pushkey==5)  {delay_ms(10);kod='l'; pushkey=0;}
        if(pushkey==6)  {delay_ms(10);kod='r'; pushkey=0;}
        switch (kod)
            {
            case  'c': { kolvo=0; break;};
            case  'l': { kolvo--; break;};
            case  'r': { kolvo++; break;};
            };
        lcd_clear();
        sprintf(lcd_buffer,"%u", kolvo);
        lcd_puts(lcd_buffer);
      };
}
Спасибо за Ваше время и ответы

Re: Как убить прерывание в CV ?

Добавлено: Пт май 08, 2015 10:32:28
Шурики
Прерывание включается командой #asm("sei"), соответственно, для выключения #asm("сli").

Прогоняет значения вверх и вниз потому что не инициализируется переменная kod в бесконечном цикле в main.

Программа написана кривовасто и выполняется точно по написанному.

Re: Как убить прерывание в CV ?

Добавлено: Пт май 08, 2015 10:37:35
binarick
Вот спасибо.... затупил малость :)

а что кривовато намекните ?

Re: Как убить прерывание в CV ?

Добавлено: Пт май 08, 2015 10:42:32
ARV
криво все. но главное - вы как 1 раз присваиваете переменной kod значение, так потом никогда его и не меняете, вот switch у вас все время и отрабатывает это значение.

Re: Как убить прерывание в CV ?

Добавлено: Пт май 08, 2015 10:46:02
binarick
ARV писал(а):криво все. но главное - вы как 1 раз присваиваете переменной kod значение, так потом никогда его и не меняете, вот switch у вас все время и отрабатывает это значение.
спасибо уже разобрался с этим выше

а что криво то ? всё это както не понятно.
или если не трудно покажите прямой код ?

Re: Как убить прерывание в CV ?

Добавлено: Пт май 08, 2015 10:54:55
ARV
1. переменные, модифицируемые в прерываниях, должны быть volatile
2. обработка кнопок - нет защиты от дребезга, обработка побитно - напрасная трата сил на переприсваивания
3. запись типа 0<< бессмысленна
4. в главном цикле очередное бессмыленное переприсваивание переменных для анализа кодов кнопок
5. многократные дублирования кода
6. фигурные скобки в switch
5. точка с запятой после }
для такой небольшой программки достаточно, чтобы назвать все кривым.

Re: Как убить прерывание в CV ?

Добавлено: Пт май 08, 2015 11:02:39
Аlex
Для того, чтобы назвать всё кривым, достаточно увидеть вот эту фразу:
//как убить прерывание в CV ???????
Убейте весь МК молотком, тогда и прерывания тоже убьются.

Re: Как убить прерывание в CV ?

Добавлено: Пт май 08, 2015 11:05:15
binarick
со многим согласен, просто быстро выдернул из основной программы потому избыточность кода наблюдается, чтото сгенерил кодевижен сам.
вот очень заинтересовал Ваш пункт 2 про защиту от дребезга

Уважаемый, может Вы подскажете как грамотные люди реализуют "дребезг" ? я только вот это выдумал.

Re: Как убить прерывание в CV ?

Добавлено: Пт май 08, 2015 11:06:29
binarick
Аlex писал(а):Для того, чтобы назвать всё кривым, достаточно увидеть вот эту фразу:
//как убить прерывание в CV ???????
Убейте весь МК молотком, тогда и прерывания тоже убьются.
ну всё запинали новичка :)))

просто хотел не скучное название :))

Re: Как убить прерывание в CV ?

Добавлено: Пт май 08, 2015 11:07:00
ARV
на форуме есть тема "помогите опросить кнопку" - там столько всего про дребезг! :)))

Re: Как убить прерывание в CV ?

Добавлено: Пт май 08, 2015 11:07:52
Аlex
Очередные вопросы про обработку кнопок. Для этого есть отдельная тема, почитайте её, там и примеры реализации есть.