Модераторы: PILOT, ManiaK, Mazzi
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> не работает флаг нешних прерываний GIFR 
V
    Опции темы
supercelt
Дата 29.8.2015, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



Код


#define F_CPU 8000000

#include <avr/io.h>
#include <string.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <stdio.h>

unsigned char cycle_counter;
unsigned char bit_counter;
unsigned char byte_counter;
unsigned char crc_counter;
unsigned char RFID_buffer[6];
unsigned char system;
//system//
//bit 0 - для обозначения что приняли либо 0 либо 1

//Macros######################################################################
#define SetBit(reg, bit)        reg |= (1 << bit)
#define ClearBit(reg, bit)        reg &= ~(1 << bit)
#define BitIsSet(reg, bit)        ((reg & (1 << bit)) != 0)
#define BitIsClear(reg, bit)    ((reg & (1 << bit)) == 0)
#define ShiftBitRight(reg)        reg >>= 1
#define CalculateCRC(reg, bit)    reg ^= (1 << bit)
//############################################################################

ISR(TIMER2_COMP_vect){
        
}

ISR(INT0_vect){
        if(BitIsClear(MCUCR, 0) && BitIsSet(MCUCR, 1)){ //падающий фронт
                ClearBit(system, 0);
                SetBit(MCUCR, 0);
                SetBit(MCUCR, 1);
        }else{ //растущий фронт
                SetBit(system, 0);
                ClearBit(MCUCR, 0);
                SetBit(MCUCR, 1);
        }
        GIFR = 64;
}

int main(void){
        SetBit(DDRD, 7);
        ClearBit(DDRD, 2);
        SetBit(PORTD, 2);
        OCR2 = 31;
        SetBit(TCCR2, 0);
        SetBit(TCCR2, 3);
        SetBit(TCCR2, 4);
        SetBit(TIMSK, 7);
        SetBit(GICR, 6);
        SetBit(MCUCR, 1);
        asm("sei");
        GIFR = 64;
        while(1){
                asm("nop");
        }
}


Суть такова. В прерывании по совпадению я хочу отследить было ли хотя бы одно прерывание внешнее. Непонятки с флагом INTF0 регистра GIFR. Я так понял что исходное состояние (когда флаг сброшен, т.е. прерываний не было) у него 1. А когда наступает внешнее прерывание, то он сбрасывается в 0. А потом в векторе нужно опять его сбросить, именно ЗАПИСАВ в него 1. В дебаггере atmel studio 6 при прохождении инициализаций туда 1 не записывается. Цикл пашет, во флаге - 0. Зато как только меняю состояние порта где внешнее прерывание висит - тут же флажок становится красным, и при следующем нажатии F11 снова белый. Далее заход в вектор, и в векторе запись 1 во флаг тоже не работает. Как отследить то что было прерывание? Помогите пожалуйста.

Это сообщение отредактировал(а) supercelt - 29.8.2015, 00:08
PM   Вверх
bass
Дата 29.8.2015, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 315
Регистрация: 5.8.2007

Репутация: нет
Всего: 2



Цитата(supercelt @ 29.8.2015,  00:07)
Код


#define F_CPU 8000000

#include <avr/io.h>
#include <string.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <stdio.h>

unsigned char cycle_counter;
unsigned char bit_counter;
unsigned char byte_counter;
unsigned char crc_counter;
unsigned char RFID_buffer[6];
unsigned char system;
//system//
//bit 0 - для обозначения что приняли либо 0 либо 1

//Macros######################################################################
#define SetBit(reg, bit)        reg |= (1 << bit)
#define ClearBit(reg, bit)        reg &= ~(1 << bit)
#define BitIsSet(reg, bit)        ((reg & (1 << bit)) != 0)
#define BitIsClear(reg, bit)    ((reg & (1 << bit)) == 0)
#define ShiftBitRight(reg)        reg >>= 1
#define CalculateCRC(reg, bit)    reg ^= (1 << bit)
//############################################################################

ISR(TIMER2_COMP_vect){
        
}

ISR(INT0_vect){
        if(BitIsClear(MCUCR, 0) && BitIsSet(MCUCR, 1)){ //падающий фронт
                ClearBit(system, 0);
                SetBit(MCUCR, 0);
                SetBit(MCUCR, 1);
        }else{ //растущий фронт
                SetBit(system, 0);
                ClearBit(MCUCR, 0);
                SetBit(MCUCR, 1);
        }
        GIFR = 64;
}

int main(void){
        SetBit(DDRD, 7);
        ClearBit(DDRD, 2);
        SetBit(PORTD, 2);
        OCR2 = 31;
        SetBit(TCCR2, 0);
        SetBit(TCCR2, 3);
        SetBit(TCCR2, 4);
        SetBit(TIMSK, 7);
        SetBit(GICR, 6);
        SetBit(MCUCR, 1);
        asm("sei");
        GIFR = 64;
        while(1){
                asm("nop");
        }
}


Суть такова. В прерывании по совпадению я хочу отследить было ли хотя бы одно прерывание внешнее. Непонятки с флагом INTF0 регистра GIFR. Я так понял что исходное состояние (когда флаг сброшен, т.е. прерываний не было) у него 1. А когда наступает внешнее прерывание, то он сбрасывается в 0. А потом в векторе нужно опять его сбросить, именно ЗАПИСАВ в него 1. В дебаггере atmel studio 6 при прохождении инициализаций туда 1 не записывается. Цикл пашет, во флаге - 0. Зато как только меняю состояние порта где внешнее прерывание висит - тут же флажок становится красным, и при следующем нажатии F11 снова белый. Далее заход в вектор, и в векторе запись 1 во флаг тоже не работает. Как отследить то что было прерывание? Помогите пожалуйста.

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

Флаги про которые вы пишите чуть чуть для другого предназначены.......  Это обработка вложенных прерываний. По этим флагам процессор орентируется было ли прерывание в момент выполнения другого прерывания.
При входе в обработчик данный флаг сброситься.

Такая ситуация выполняется прерывание по таймеру и в данный момент пришло внешние прерывание. Флаг выставиться. В момент окончания прерывания по таймеру, вызовется обработчик внешнего прерывания и флаг сброситься.
Если в прерывание таймера сбросить флаг внешнего прерывания если оно было вызвано, обработчик внешнего прерывания не вызоветься.

Как-то так.. ))))   


PM MAIL   Вверх
supercelt
Дата 29.8.2015, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



Спасибо, буду использовать переменную)
PM   Вверх
ФедосеевПавел
Дата 29.8.2015, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: 1
Всего: 10



Я уже успел всё подзабыть за 8 лет. Поэтому просто покажу, как я обрабатывал INT1.
Основная программа (фича в использовании именованных констант вместо магических чисел).
Код
#include <stdlib.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <inttypes.h>
#include <util/delay.h>

#include <_CONST.h>
#include <ADD_PROC.h>

// Отсылаем все неиспользуемые прерывания на один RETI
EMPTY_INTERRUPT( __vector_default );

static void My_hardware_init(void)
{
  PORTB = 0x00;    //
  DDRB  = 0xFF;    // PORTB - output
  PORTD = 0x00;    //
  DDRD  = 0xFF;    // PORTD - input+R
  //разрешить INT0 и INT1 (кнопки "Пуск" и "Другой интервал")
  MCUCR = (1<<ISC11)+(1<<ISC01); // прерывания по спаду на INT0 и INT1
  EIFR  = (1<<INTF0)+(1<<INTF1); // очистка флагов прерываний
  GIMSK = (1<<INT0) +(1<<INT1);  // разрешить INT0, INT1
  //разрешить прерывания от таймера 1
  TCCR1A= 0;
  TCCR1B= 0;                      // выключение таймера
  TIFR  = (1<<TOV1);             // очистка флагов прерываний
  TIMSK = (1<<TOIE1);            // разрешить прерывание
};

void main(void)
{
  wdt_disable();
  My_hardware_init();
  TimeLimit=20;
  PORTB=Hex2Code(TL2FirstDig());
  for(;;)          // Eternal loop
  { 
  };
}

И обработчик INT1 (он нигде в main не упомянут потому, что настройки проекта были в makefile). В нём разрешается работа int0 и int1 по логике самой программы и, возможно, опечатки  smile. MCU - AtTiny2313
Код
/*
;*************************************************************************
;* A P P L I C A T I O N   F O R   T H E   A V R   F A M I L Y
;*
;* Project Name         :Timer_00
;* File Name            :"Ext_Int1.c"
;* Title                :
;* Date            :06/03/2007
;* Version        :1.00
;* Target MCU        :AT90S2313
;* Credit               :FPA
;*
;* DESCRIPTION
;* Включаемый файл из состава проекта.
;* В этот файл входит процедуры обработки прерывания (ISR) INT1
;*************************************************************************
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;@                                                          @
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;Обработчик прерывания нажатия кнопки "Другой интервал"
*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <_CONST.h>
#include <ADD_PROC.h>

ISR(INT1_vect) __attribute__ ((naked));
ISR(INT1_vect)
{ tmpSREG=SREG;
  EIFR   = (1<<INTF0)+(1<<INTF1);
  TimeLimit+=20;
  if(TimeLimit>61) TimeLimit=20;
  PORTB=Hex2Code(TL2FirstDig());
  SREG=tmpSREG;
  __asm__ volatile ("reti");

}

Копировать мой обработчик нет смысла (атрибуты, асм вставки, рукопашное сохранение и восстановление SREG) - я тогда перешёл с асма на с и пытался добиться чуть ли не идентичных асму листингов. Но хорошо видно - запись в EIFR, тело обработчика, выход.

Это сообщение отредактировал(а) ФедосеевПавел - 29.8.2015, 14:48
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

На данный раздел помимо Правил форума распространяются текже следующие правила:


  • Прежде чем создать тему воспользуйтесь поиском или посмотрите в faq. Возможно на форуме уже есть ответ на ваш или близкий к вашему вопрос.
  • В заголовке темы в квадратных скобках обозначьте используемое семейство микроконтроллера: [avr],[pic],[arm].
  • При создании темы с вопросом указывайте участок кода с ошибкой, версию компилятора, схемы подключения, fuse биты и прочие данные, которые помогут найти правильный ответ. Для форматирования текста программ используйте кнопку код.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Для флуда, просьб выполнить задание, поиска партнёров или исполнителей существуют свои разделы.
  • Если вы заметили несовместимое с правилами сообщение, то можете уведомить об этом модератора раздела нажав кнопку Репорт у соответствующего сообщения.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема »


 




[ Время генерации скрипта: 0.1130 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.