Правильно ли настроены два внешних дополнительных прерывания?

Roman2344
Offline
Зарегистрирован: 09.09.2015

Подскажите правильно ли я настроил два внешних дополнительных прерывания

void _PCINT9Enable() {
    PCMSK1 |= _BV(PCINT9);
    PCICR  |= _BV(PCIE1);
}

void _PCINT10Enable() {
    PCMSK1 |= _BV(PCINT10);
    PCICR  |= _BV(PCIE1);
}
int motor = 6;
int zaliv = 14;//PCINT10
int razrab = 15;//PCINT9
int i=0;
int a=0;
void setup() {
_PCINT9Enable();// разрешение дополнительных прерываний
_PCINT10Enable();
pinMode(zaliv, INPUT);
pinMode(razrab, INPUT);
pinMode(motor, OUTPUT);
}

void loop() {
  if(digitalRead(zaliv)==1){
    while(i<1){
      digitalWrite(motor,0);
      i++;
      a=0;
}
delay(3000);
digitalWrite(motor,1);
}


else if(digitalRead(razrab)==1){
    while(i<a){
      digitalWrite(motor,1);
      i=0;
      a++;
}
delay(3000);
digitalWrite(motor,0);
}


}


ISR(PCINT9_vect) 
{static unsigned long millis_prev;
  if(millis()-100 > millis_prev)  
  millis_prev = millis();  // задержка
a=0;
}


ISR(PCINT10_vect) 

{static unsigned long millis_prev;
  if(millis()-100 > millis_prev)  
  millis_prev = millis(); 
i=0;
}

 

Roman2344
Offline
Зарегистрирован: 09.09.2015

Ардуино Мега 2560 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

не правильно.

вот цитата из датаШита:

Bit 1 – PCIE1: Pin Change Interrupt Enable 1

When the PCIE1 bit is set (one) and the I-bit in the Status Register (SREG) is set (one), pin change interrupt 1 is enabled. Any change on anyenabled PCINT[14:8] pin will cause an interrupt. The correspondinginterrupt of Pin Change Interrupt Request is executed from the PCI1 Interrupt Vector. PCINT[14:8] pins are enabled individually by the PCMSK1 Register

===========================

то есть разрешил ты их вначале правильно, но аглицким по белому написано, что блок ПинЧейндж прерываний с 8 по 14 обслуживаются вектором PCI1.

векторов PCINT9_vect и PCINT10_vect не существует (!!!!) в библиотеке avr/interrupt.h.

Нужно определять PCINT1_vect и в нем просто прочитать пины диджитал инпутом, если Вы кул-хацкер - то можете прочитать их битовыми операциями.

Roman2344
Offline
Зарегистрирован: 09.09.2015

Так? И как сделать что бы PCINT 8,11,12,13,14 не работали?

void _PCINT9Enable() {
    PCMSK1 |= _BV(PCINT9);
    PCICR  |= _BV(PCIE1);
}

void _PCINT10Enable() {
    PCMSK1 |= _BV(PCINT10);
    PCICR  |= _BV(PCIE1);
}
int motor = 6;
int zaliv = 14;//PCINT10
int razrab = 15;//PCINT9
int i=0;
int a=0;
void setup() {
_PCINT9Enable();// разрешение дополнительных прерываний
_PCINT10Enable();
pinMode(zaliv, INPUT);
pinMode(razrab, INPUT);
pinMode(motor, OUTPUT);
}

void loop() {
  if(digitalRead(zaliv)==1){
    while(i<1){
      digitalWrite(motor,0);
      i++;
      a=0;
}
delay(3000);
digitalWrite(motor,1);
}


else if(digitalRead(razrab)==1){
    while(i<a){
      digitalWrite(motor,1);
      i=0;
      a++;
}
delay(3000);
digitalWrite(motor,0);
}


}


ISR(PCINT9_vect) 
{static unsigned long millis_prev;
  if(millis()-100 > millis_prev)  
  millis_prev = millis();  // задержка

if(digitalRead(razrab)==1){

a=0;}//PCINT9


if(digitalRead(zaliv)==1){

i=0;}//PCINT10

}

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

типа того,

только ты опять, вместо PCINT1_vect написал PCINT9_vect.

Про 8,11,12,13,14 - ты же сам в первых строках маску пишешь в PCMSK1, или ты просто чей-то код копировал, не разбираясь? вот там ты и разрешаешь только 9 и 10, а остальные - по умолчанию запрещены.

Roman2344
Offline
Зарегистрирован: 09.09.2015

Спасибо, код сам писал, и нстройку дополнительных прерываний по даташиту делал

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Roman2344,  как то вы очень размашисто пишите. Вместо 1...9 и 16,17 достаточно пары фраз: PCICR=1<<PCIE1; PCMSK1=(1<<PCINT9)|(1<<PCINT10); Всё равно нигде кроме сетапа эти функции не задействованы.

Roman2344
Offline
Зарегистрирован: 09.09.2015

А как лучше запретить прерывания, есть просто условие для датчика потом это условие стоит 10часов и в это время нужно запретить все внешние прерывания как оссновные так и дополнительные. Думаю что лучше noInterrupts(); или detachInterrupt();(нужно ли в скобках указывать название каждого прерывания?) или EIFR = 0xFF;?  Вообщем нужен пример, прерывания потом нужно будет опять включить, нужно что - то типа этого:

if(digitalRead(datchik)==1)          
{
  noInterrupts();// запрет прерываний INT0-INT5
				
_PCINT9Disable();//  запрет дополнительных прерываний PCINT9, PCINT10

_PCINT10Disable();

				// что-то тут делаем

_PCINT9Enable();// разрешение дополнительных прерываний PCINT9, PCINT10
_PCINT10Enable();
			
  interrupts();разрешение прерываний INT0-INT5
}

 

Прерывания что основные что дополнительные сконфигурированы в Setup. Меня интересует только как включать выключать в void loop

Roman2344
Offline
Зарегистрирован: 09.09.2015

dimax Спасибо.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Roman2344, noInterrupts() запретит абсолютно все прерывания, времяиспользующие  арудуиновские функции (delay,millis) тоже перестанут работать. Так что лучше с ним поосторожнее. Отключить прерывания INT1,INT0:   EIMSK=0; Отключить все прерывания PCINT: PCICR=0; Включать обратно -так же как операции с этими двумя регистрами в сетапе.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

вообще, имею сказать следующее:

Прошу прощения за занудство, но мне 46 лет - можно простить, ИМХО.

Прочтите датаШит на Атмеловский кристал на сайте Атмел. Можно прочесть одно описание - например на 328 или 168 - не принципиально, да хоть на тиньку13.

Очень много вопросов пропадут сами собой.

Описание - на простом, почти "школьном" аглицком. Там даже словарь не потребуется, если в школе хотя бы "3" по английскому была.

============================

Ведь скеч на IDE это прога на частичном gcc-avr. Просто, для удобства програмиста, некоторые вещи скрыты. Это не значит, что все "кул-хацкеры" должны писать только в атмел-студии, ни в коем разе. В ИДЕ можно пользоваться низким уровнем там, где нужно, если припекло. А в остальном - писать средствами ИДЕ. Но ЛЮБОЙ скетч на ИДЕ - это нормальная прога, компилируемая gcc-avr, то есть работает все, что можно прочесть в датаШите на кристал и РОВНО так, как в датаШите написано.

=================================

если вдруг, кто-то из "гуру" начнет "правду-матку" рубить, то поясню, что gcc это Gnu C Compiler. В IDE он входит основным,  а в Атмел-Студии можно выбрать любой. Но по факту использования на просторах подлунного мира - gcc - основной компилятор, в процентах использования для avr архитектуры.

Roman2344
Offline
Зарегистрирован: 09.09.2015

Спасибо всем завтра попробую с отключениями прерываний