Проблема С Прерываниями Atmega8A (Codevisionavr+Proteus)

25-07-2014, 15:54 От: admin Посмотрели: 807
Доброго времени суток!

Я новичек и сейчас работаю над первым своим устройством на МК. Отлаживая в протеусе схему, столкнулся со странным поведением. В общих чертах: делаю код в CodeVisionAVR 3.12 Evaluation, пишу на С. Задача - разработать простенький электронный таймер, до 99 мин. Методом исключения выяснилось, что при разрешении прерываний командой sei программа начинает выполнятся сначала. Пошел по пути наименьшего сопротивления, просто разрешил прерывания в самом начале программы. В таком случае глобальная переменная time_sec, в которой хранится оставшееся время  или недоступна, или сбрасывается в ноль при нажатии на любую кнопку. Нагугленые варианты решения проблемы не помогли, поэтому я вернулся к исходному варианту (код которого привел). Проект в протеусе и кодвижине  прикрепил в архиве timer.rar, код также под спойлером. Я конечно понимаю, что возможно  допустил какой-то банальный косяк, но найти не могу, нужен "свежий взгляд". Прошу вашей помощи!

Примечание: я закомментировал кусок кода, так что выводиться только один разряд (минуты). Это связано с тем, что у меня протеус не успевает корректно отрисовывать зажигание разрядов семисегментника по-очереди.


Spoiler

#include <io.h>
#include <mega8.h>
#include <math.h>
#include <delay.h>

#define btn_start PINC.1
#define btn_inc PINC.2
#define btn_dec PINC.3
#define btn_res PINC.0

void start_stop();
void display_7seg();

volatile unsigned int time_sec = 0;
_Bool run = 0;

void main(void)
{
PORTC = 0xEF;
TCCR2|=(1<<CS20)|(1<<CS21)|(1<<WGM21)|(0<<COM21)| (0<<COM20); //предделитель на 32+режим сравнения
OCR2 = 0xFA; //сравниваемое число (250)
TIMSK |= ( 1<<OCIE2 ); //разрешаем прерывания по сравнению
DDRC = 0xF0;
DDRB = 0xff;
DDRD = 0xff;

while(1)
{
if ( ~btn_start )
{
start_stop();
delay_ms(400);
}

if ( ~btn_inc )
{
if ( time_sec < 5940 )
time_sec+= 60;
delay_ms(400);
}

if ( ~btn_dec )
{
if ( time_sec >= 60 )
time_sec-=60;
delay_ms(400);
}

if ( ~btn_res )
{
time_sec = 0;
run = 0;
delay_ms(400);
}
display_7seg();
}
}

void start_stop( void )
{
if ( run == 0 )
{
TCNT2 = 0x0; //обнуляем таймер
#asm("sei");
run = 1;
}
else
{
run = 0;
#asm("cli");
};
}

void display_7seg( void )
{
unsigned char bcd,low,high;
bcd = ceil(time_sec/60);
low = bcd % 10;
high = bcd/10;
/*switch (high)
{
case 0: { PORTB = 0b10110001; PORTD = 0b11100111; break;}
case 1: { PORTB = 0b11110111; PORTD = 0b11110111; break;}
case 2: { PORTB = 0b01111001; PORTD = 0b11100111; break;}
case 3: { PORTB = 0b01110011; PORTD = 0b11100111; break;}
case 4: { PORTB = 0b00110111; PORTD = 0b11110111; break;}
case 5: { PORTB = 0b00110011; PORTD = 0b11101111; break;}
case 6: { PORTB = 0b00110001; PORTD = 0b11101111; break;}
case 7: { PORTB = 0b11110111; PORTD = 0b11100111; break;}
case 8: { PORTB = 0b00110001; PORTD = 0b11100111; break;}
case 9: { PORTB = 0b00110011; PORTD = 0b11100111; break;}
}*/
switch(low)
{
case 0: { PORTB = 0b11011110; PORTD = 0b10111000; break;}
case 1: { PORTB = 0b11111111; PORTD = 0b10111110; break;}
case 2: { PORTB = 0b11011110; PORTD = 0b01111100; break;}
case 3: { PORTB = 0b11111110; PORTD = 0b00111100; break;}
case 4: { PORTB = 0b11111111; PORTD = 0b00111010; break;}
case 5: { PORTB = 0b11111110; PORTD = 0b00111001; break;}
case 6: { PORTB = 0b11011110; PORTD = 0b00111001; break;}
case 7: { PORTB = 0b11111111; PORTD = 0b10111100; break;}
case 8: { PORTB = 0b11011110; PORTD = 0b00111000; break;}
case 9: { PORTB = 0b11111110; PORTD = 0b00111000; break;}
}
}

interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
unsigned char i =0;
if(run == 1)
{
time_sec--;
}
if( time_sec == 0)
{
run = 0;
#asm("cli");
PORTC.4 = 1;
for( i = 0; 8; i++)
{
PORTD = 0xFF; PORTC = 0xFF;
delay_ms(700);
PORTD = 0x0; PORTC = 0x0;
}
}
}


Прикрепленные файлы:





  • Прикрепленный файл
     timer.rar   167,32 Кб
      2 раз скачано




Раздел: AVR

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

Обсудить на форуме


На момент добавления Проблема С Прерываниями Atmega8A (Codevisionavr+Proteus) все ссылки были рабочие.
Все публикации статей, книг и журналов, представлены на этом сайте, исключительно для ознакомления,
авторские права на эти публикации принадлежат авторам статей, книг и издательствам журналов!
Подробно тут | Жалоба
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.


Опрос

Ваши предпочтения в TRX


Одинарное преобразование
Двойное преобразование
Прямое преобразование
SDR
Другое
Мне всё равно

Популярные новости
Календарь новостей
«    Май 2024    »
ПнВтСрЧтПтСбВс
 12345
6789101112
13141516171819
20212223242526
2728293031