roboforum.ru

Технический форум по робототехнике.

Глюки во время прерывания

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

Глюки во время прерывания

Сообщение Hagrael » 14 авг 2011, 15:59

Здравствуйте, товарищи программисты. Я написал код, который прекрасно работает в цикле и выводит цифры 010 на индикатор, но когда я вставил его в главное прерывание, то он начал выводить всего лишь 0, причем расположенный слева, в то время как начинается "рисование" справа. Отчего это происходит, и как это вылечить?

Заранее благодарен.
Аватара пользователя
Hagrael
 
Сообщения: 18
Зарегистрирован: 14 авг 2011, 15:42

Re: Глюки во время прерывания

Сообщение Angel71 » 14 авг 2011, 17:47

посмотреть внимательно в код, перепроверить фьюзы и если нужно переписать код.
Аватара пользователя
Angel71
 
Сообщения: 10668
Зарегистрирован: 18 апр 2009, 22:18
Предупреждения: -1

Re: Глюки во время прерывания

Сообщение Grem » 14 авг 2011, 18:25

После словосочетания "главное прерывание" у меня аж слезы потекли :D
Код покажите чтоли.
"There is nothing better than sliding down snow and flying through the air" (с) Shane McConkey.
Lieber ein Brett am Fuß als eins vorm Kopf, aber lieber ein Brett vorm Kopf als zwei am Fuß.
Аватара пользователя
Grem
 
Сообщения: 1530
Зарегистрирован: 16 май 2009, 12:50
Откуда: Россия
прог. языки: Java, C

Re: Глюки во время прерывания

Сообщение NeON79 » 14 авг 2011, 19:28

Топикстартеру: тута форум роботостроителей, а не телепатов. Тут тока Дядя Мур телепат, но он щас занят, видимо. Потому придётся код-таки рассекретить.
Я бы предложил перевесить на неглавное прерывание, но не знаю как..Я вообще прерывания так и не осилил пока(((. Жду комплектуху для экспериментов.
Никогда не бойся делать то, что ты не умеешь. Ковчег был сооружен любителем. Профессионалы построили “Титаник“
2:5020/2140.1979@fidonet
Аватара пользователя
NeON79
 
Сообщения: 536
Зарегистрирован: 09 май 2011, 16:43
Откуда: Украина, Киев
прог. языки: Нецензурный
ФИО: Евгений НеОН

Re: Глюки во время прерывания

Сообщение k01 » 15 авг 2011, 00:13

Если индикация динамическая на 7-сегментный дисплей, то можно предположить что при вызове прерывания правая и центральная цифра загораются на очень короткое время, а левая продолжает гореть до следующего вызова. Исправить это можно если в прерывании выводить по одной цифре.
k01
 
Сообщения: 3
Зарегистрирован: 08 апр 2011, 19:14
Откуда: Санкт-Петербург
Skype: k580ik80
прог. языки: C/C++, assembler
ФИО: Кирилл Дмитриев

Re: Глюки во время прерывания

Сообщение Hagrael » 15 авг 2011, 16:45

Извините, что сразу не выложил код. Просто я использовал API. Пришлось его "разбиблиотечить". Вот нынешний код:
Код: Выделить всёРазвернуть
// стандартные библиотеки
#include <mega8.h>
#include <delay.h>
#include <stdbool.h>

// обозначение портов индикатора
#define IND_PORT_A PORTD.2
#define IND_PORT_B PORTD.3
#define IND_PORT_C PORTD.4
#define IND_PORT_D PORTD.5
#define IND_PORT_E PORTD.6
#define IND_PORT_F PORTD.7
#define IND_PORT_G PORTC.1
#define IND_PORT_DP PORTC.2
#define IND_PORT_1 PORTC.3
#define IND_PORT_2 PORTC.4
#define IND_PORT_3 PORTC.5

int current = 1;
bool inited = false;

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void) {

if (!inited) return;

if (current == 1) {
   
    IND_PORT_3 = 0;
    IND_PORT_A = 0;
    IND_PORT_B = 0;
    IND_PORT_C = 0;
    IND_PORT_D = 0;
    IND_PORT_E = 0;
    IND_PORT_F = 0;
    IND_PORT_G = 1;
    IND_PORT_1 = 1;
    IND_PORT_1 = 0;
   
} else if (current == 2) {

    IND_PORT_1 = 0;
    IND_PORT_A = 1;
    IND_PORT_B = 0;
    IND_PORT_C = 0;
    IND_PORT_D = 1;
    IND_PORT_E = 1;
    IND_PORT_F = 1;
    IND_PORT_G = 1;
    IND_PORT_2 = 1;
   
} else if (current == 3) {

    IND_PORT_2 = 0;   
    IND_PORT_A = 0;
    IND_PORT_B = 0;
    IND_PORT_C = 0;
    IND_PORT_D = 0;
    IND_PORT_E = 0;
    IND_PORT_F = 0;
    IND_PORT_G = 1;
    IND_PORT_3 = 1;
   
}

}

void main() {

    #include "init_mc.c"

    IND_PORT_1 = 0;
    IND_PORT_2 = 0;
    IND_PORT_3 = 0;

    while (1) {
   
       
   
    }
   
    inited = true;

}


Цифры даже не горят. Архив с проектом прикреплен.
Вложения
Копия interrupts.rar
(77.23 КиБ) Скачиваний: 0
Аватара пользователя
Hagrael
 
Сообщения: 18
Зарегистрирован: 14 авг 2011, 15:42

Re: Глюки во время прерывания

Сообщение Michael_K » 15 авг 2011, 17:05

Инициализация таймера и прерывания где-то спрятана?
inited никогда не станет true, потому что мейн в цикле висит?
current, очевидно, где-то в прерывании должен меняться?
ну и вообще :)
Аватара пользователя
Michael_K
 
Сообщения: 6028
Зарегистрирован: 07 окт 2009, 00:29
Откуда: СПб

Re: Глюки во время прерывания

Сообщение k01 » 15 авг 2011, 17:47

IND_PORT_1 = 1;
IND_PORT_1 = 0;

индикатор включается и сразу гаснет =)

инициализация в файле init_mc.c ?
k01
 
Сообщения: 3
Зарегистрирован: 08 апр 2011, 19:14
Откуда: Санкт-Петербург
Skype: k580ik80
прог. языки: C/C++, assembler
ФИО: Кирилл Дмитриев

Re: Глюки во время прерывания

Сообщение Hagrael » 15 авг 2011, 19:30

Ну до чего глупая была ошибка! Строчку
Код: Выделить всёРазвернуть
inited = true

поместил после главного цикла! Но почему-то не хочет работать первый индикатор
Да, инициализация в файле init_mc.c:
Код: Выделить всёРазвернуть
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2 State1 State0
PORTB=0x07;
DDRB=0x00;

// Port C initialization
// Func6=In Func5ut Func4ut Func3ut Func2ut Func1ut Func0=In
// State6=T State5=1 State4=1 State3=1 State2 State1 State0=T
PORTC=0x38;
DDRC=0x3E;

// Port D initialization
// Func7ut Func6ut Func5ut Func4ut Func3ut Func2ut Func1=In Func0=In
// State7 State6 State5 State4 State3 State2 State1=T State0=T
PORTD=0x00;
DDRD=0xFC;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 3,906 kHz
TCCR0=0x05;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// USART initialization
// USART disabled
UCSRB=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

// Global enable interrupts
#asm("sei")

Вот код сейчас:
Код: Выделить всёРазвернуть
interrupt [TIM0_OVF] void timer0_ovf_isr(void) {

if (!inited) return;

if (current == 1) {
   
    IND_PORT_3 = 0;
    IND_PORT_A = 0;
    IND_PORT_B = 0;
    IND_PORT_C = 0;
    IND_PORT_D = 0;
    IND_PORT_E = 0;
    IND_PORT_F = 0;
    IND_PORT_G = 1;
    IND_PORT_1 = 1;
    IND_PORT_1 = 0;
    //delay_ms (100);
    current = 2;
   
} else if (current == 2) {

    IND_PORT_1 = 0;
    IND_PORT_A = 1;
    IND_PORT_B = 0;
    IND_PORT_C = 0;
    IND_PORT_D = 1;
    IND_PORT_E = 1;
    IND_PORT_F = 1;
    IND_PORT_G = 1;
    IND_PORT_2 = 1;
    //delay_ms (100);
    current = 3;
   
} else if (current == 3) {

    IND_PORT_2 = 0;
    IND_PORT_A = 0;
    IND_PORT_B = 0;
    IND_PORT_C = 0;
    IND_PORT_D = 0;
    IND_PORT_E = 0;
    IND_PORT_F = 0;
    IND_PORT_G = 1;
    IND_PORT_3 = 1;
    //delay_ms (100);
    current = 1;
   
}

}
Аватара пользователя
Hagrael
 
Сообщения: 18
Зарегистрирован: 14 авг 2011, 15:42

Re: Глюки во время прерывания

Сообщение k01 » 15 авг 2011, 19:56

>Но почему-то не хочет работать первый индикатор

Потому что IND_PORT_1 в первой ветке сначала устанавливается в 1, потом сразу сбрасывается в 0 =)
k01
 
Сообщения: 3
Зарегистрирован: 08 апр 2011, 19:14
Откуда: Санкт-Петербург
Skype: k580ik80
прог. языки: C/C++, assembler
ФИО: Кирилл Дмитриев

Re: Глюки во время прерывания

Сообщение Hagrael » 16 авг 2011, 07:53

*FACEPALM* Во дела...

Большое спасибо всем, кто помогал, проблема решена!
Аватара пользователя
Hagrael
 
Сообщения: 18
Зарегистрирован: 14 авг 2011, 15:42

Re: Глюки во время прерывания

Сообщение MasterWizard » 28 сен 2011, 15:42

Хоть трабл и решен, вставлю свои пять копеек:
лично я стараюсь никогда не вставлять в обработчик прерываний собственно код - в обработчике взвожу глобальную перменную-флаг и быстренько из обработчика вываливаюсь. А потом в мэйн смотрю за флагом и делаю то или иное. Многих глюков удается избежать.
MasterWizard
 
Сообщения: 4
Зарегистрирован: 28 сен 2011, 13:54
Откуда: Украина
Skype: rea.in.ua
прог. языки: C, C++


Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

cron