Да напишите уже, что хотите чтобы вам написали код. Все сразу отправят вас в "закажу проект", престанут флудить и будут ждать когда объявится альтруистичный рыцарь.
Код мне не нужен, Я спросил как поймать нажатие кнопки, Мне ответили, что нужно больше учить и заниматься программированием, с нуля писать правильный код. Если я научусь правильно писать код у меня Не останутся вопросы по работе с кнопкой,
поймать то можно по прерыванию или по таймеру. но как уже раньше написали - надо его еще и обработать, а если цикл занимает кучу времени, то толку будет немного
разве это плохо? - по мне так двойной выигрыш - и проблему решите, и новому научитесь А насчет прерываний... Поскольку Вы нам не верите - проведите эксперимент, посадите кнопку на прерывание. Вы переживаете, что у вас не хватит прерываний на все кнопки - так сделайте для начала только одну.. Мой опыт говорит мне, что вам это никак не поможет убыстрить отклик на нажатие - но вдруг я ошибаюсь. Пробуйте. тестируйте, это же интересно...
Я не могу использовать аппаратные прерывания, так как даже если будет работать то на примере одной кнопки у меня их 7+датчики, это направление значит не подходит. Остается прерывание/опрос по таймеру, Значит буду капать в этом направлении и удивительно что этой функции нет в библиотеках работы с кнопками, в которых основной упор делается на дребезг, но он устраняется тем же таймером. Я считаю что если код компилируется и выполняет свои функции значит он написан правильно, и не стоит вгонять нубов в рамки которые вы себе установили, не существует правил которые определяют время выполнения кода, я указал что код длится 150мс это по моим личным ощущениям а как вы определили, что он длится больше 10мс?
чтоб еще больше вас запутать - даже в Уно аппаратные прерывания есть на всех пинах. А у вас. как я вижу. Мега... а вам не приходит в голову. что если в стольких библиотеках работы с кнопками нет опроса по таймеру - тут что-то не так? может он и не нужен. если все обходятся без него?
там прерывание даёт регистр порта, а не отдельный пин. это всё от того, что создатели ардруины не предусмотрели такую возможность. К тому же опрос матричной клавиатуры возможен только по таймеру.
чей-та? Кто тебе запрещает в ардуине опрашивать кнопки по таймеру? - да опрашивай запросто. Другой вопрос. что проблемы ТС это не решит,
что любопытно - вы так старательно отметаете любые пути, не ведущие напрямую к немедленному решению, как будто вы вакцину против вируса создаете и нет ни секунды лишней. а не поделку выходного дня. Учиться писать хороший код вы отказались - это вас не ведет к решению Аппаратные прерывания отмели, ибо "их все равно мало". Даже если аппаратные прерывания вам в итоге не подойдут - пробуя их вы бы многому научились. Путь обучения - это пробовать разные варианты и сравнивать. А так даже если вы и соберете свою поделку кое-как - все равно останетесь неучем.
просто невнимательно читаете. В вашей же ссылке, а разделе "внешние прерывания" сказано. что прерывания есть двух типов - те что рассмотрены в этой методичке, их всего два. Но есть и другие - их в разы больше.
Так а что нужно то? Я делаю так: Код (C++): #define PIN_READ_TO 10L // 10 ms периодичность проверки входов. Оптимальным является интервал 5-10мс. соответственно в результате сигнал о нажатии будет получен через 20-40мс (в данном случае 40мс) #define PIN_IN_NUMB 4 // количество используемых входов значение от 1 до 8. //------------------ ФУНКЦИЯ УСТР. ДРЕБЕЗГА -------------------------------------- // Глобальные переменные // биты в байтах ниже взводятся обработчике дребезга, можно в в прерывании от таймера и сбрасываются программой обработчиком событий byte LATCH_ON = 0; // вход перешел в 1 //byte LATCH_OFF = 0; // вход вернулся в 0 uint8_t vc_debounce(uint8_t SWKEYS) // Verical_Couners_debounce, вызывается каждые 10 мсек, можно из таймера { // в SWKEYS состояние вводов static uint8_t SLATCH = 0; // текущее устоявшееся значение входов после устранения дребезга static uint8_t VCBIT0 = 0; // счетчик бит 0 static uint8_t VCBIT1 = 0; // счетчик бит 1 uint8_t vcmask = 0; // Маска uint8_t vctemp = 0; // vcmask = SWKEYS ^ SLATCH; // скинем счетчики для установившихся и неактивных значений VCBIT0 &= vcmask; VCBIT1 &= vcmask; // Каждая '1' в SLATCH представляет установившееся значение // каждый '0' установившееся нулевое значение SLATCH ^= (vctemp = vcmask & VCBIT0 & VCBIT1); if( vctemp ) // есть изменения входов, взведем флаги { LATCH_ON |= vctemp & SWKEYS; // взведем биты нажатых кнопок и сработавших входов. // LATCH_OFF |= vctemp & ~SWKEYS; // Биты сбрасываются в обработчиках. } VCBIT1 ^= (vcmask & VCBIT0); // инкрементируем счетчик. VCBIT0 ^= (vcmask); } void setup() { DDRC &= ~((1<<0)|(1<<1)|(1<<2)|(1<<3)); //A0 A1 A2 A3 вход } void Input_On(byte number) { // выполним действие по нажатию на кнопку. номер кнопку в переменной "number" } /* void Input_Off(byte number) { // ЕСЛИ НУЖНО! выполним действие по отпусканию кнопки. номер кнопку в переменной "number" } */ void loop() { static uint32_t LastPinReadMs = 0 ; // переменная для сохранения времени, когда были считаны значения с цифорвых входов uint8_t current_state; // переменная для текущего состояние по кнопкам byte j,i; if ((millis() - LastPinReadMs) > PIN_READ_TO) // выполняется каждые 10мс (PIN_READ_TO) { //----------------------- current_state= PINC & ((1<<0)|(1<<1)|(1<<2)|(1<<3)); // читаем значение vc_debounce(current_state); // 2) отбросим дребезг по всем входам, на основании предыдущих проверок (игнорируем состояния, держащиеся на входе менее 4 проверок подряд) LastPinReadMs = millis(); // запомним время // if (LATCH_ON != 0 || LATCH_OFF != 0 ) // Если есть изменения на входах - обработаем. if (LATCH_ON != 0 ) // Если есть изменения на входах - обработаем. { for (i=1,j=0; j < PIN_IN_NUMB; j++,i=i<<1) // пробежимся по всем входам { if (LATCH_ON & i) // Если копка была нажата или вход перешел в ON { Input_On(j); LATCH_ON &= ~i; // Обязательно сбросим бит, так как данное событие обработано } /* if (LATCH_OFF & i) // Если копка была отпущена или вход перешел в OFF ЕСЛИ НУЖНО. { Input_Off(j); LATCH_OFF &= ~i; // Обязательно сбросим бит, так как данное событие обработано } */ } } } // --------------------- // ваш код.... }
вот прерывания для attiny841 Код (C++): /* Interrupt vectors */ /* Vector 0 is the reset vector */ /* External Interrupt Request 0 */ #define INT0_vect _VECTOR(1) #define INT0_vect_num 1 /* Pin Change Interrupt Request 0 */ #define PCINT0_vect _VECTOR(2) #define PCINT0_vect_num 2 /* Pin Change Interrupt Request 1 */ #define PCINT1_vect _VECTOR(3) #define PCINT1_vect_num 3 /* Watchdog Time-out Interrupt */ #define WDT_vect _VECTOR(4) #define WDT_vect_num 4 /* Timer/Counter1 Capture Event */ #define TIMER1_CAPT_vect _VECTOR(5) #define TIMER1_CAPT_vect_num 5 /* Timer/Counter1 Compare Match A */ #define TIMER1_COMPA_vect _VECTOR(6) #define TIMER1_COMPA_vect_num 6 /* Timer/Counter1 Compare Match B */ #define TIMER1_COMPB_vect _VECTOR(7) #define TIMER1_COMPB_vect_num 7 /* Timer/Counter1 Overflow */ #define TIMER1_OVF_vect _VECTOR(8) #define TIMER1_OVF_vect_num 8 /* TimerCounter0 Compare Match A */ #define TIMER0_COMPA_vect _VECTOR(9) #define TIMER0_COMPA_vect_num 9 /* TimerCounter0 Compare Match B */ #define TIMER0_COMPB_vect _VECTOR(10) #define TIMER0_COMPB_vect_num 10 /* Timer/Couner0 Overflow */ #define TIMER0_OVF_vect _VECTOR(11) #define TIMER0_OVF_vect_num 11 /* Analog Comparator 0 */ #define ANA_COMP0_vect _VECTOR(12) #define ANA_COMP0_vect_num 12 /* ADC Conversion Complete */ #define ADC_vect _VECTOR(13) #define ADC_vect_num 13 /* EEPROM Ready */ #define EE_RDY_vect _VECTOR(14) #define EE_RDY_vect_num 14 /* Analog Comparator 1 */ #define ANA_COMP1_vect _VECTOR(15) #define ANA_COMP1_vect_num 15 /* Timer/Counter2 Capture Event */ #define TIMER2_CAPT_vect _VECTOR(16) #define TIMER2_CAPT_vect_num 16 /* Timer/Counter2 Compare Match A */ #define TIMER2_COMPA_vect _VECTOR(17) #define TIMER2_COMPA_vect_num 17 /* Timer/Counter2 Compare Match B */ #define TIMER2_COMPB_vect _VECTOR(18) #define TIMER2_COMPB_vect_num 18 /* Timer/Counter2 Overflow */ #define TIMER2_OVF_vect _VECTOR(19) #define TIMER2_OVF_vect_num 19 /* Serial Peripheral Interface */ #define SPI_vect _VECTOR(20) #define SPI_vect_num 20 /* USART0, Start */ #define USART0_START_vect _VECTOR(21) #define USART0_START_vect_num 21 /* USART0, Rx Complete */ #define USART0_RX_vect _VECTOR(22) #define USART0_RX_vect_num 22 /* USART0 Data Register Empty */ #define USART0_UDRE_vect _VECTOR(23) #define USART0_UDRE_vect_num 23 /* USART0, Tx Complete */ #define USART0_TX_vect _VECTOR(24) #define USART0_TX_vect_num 24 /* USART1, Start */ #define USART1_START_vect _VECTOR(25) #define USART1_START_vect_num 25 /* USART1, Rx Complete */ #define USART1_RX_vect _VECTOR(26) #define USART1_RX_vect_num 26 /* USART1 Data Register Empty */ #define USART1_UDRE_vect _VECTOR(27) #define USART1_UDRE_vect_num 27 /* USART1, Tx Complete */ #define USART1_TX_vect _VECTOR(28) #define USART1_TX_vect_num 28 /* Two-wire Serial Interface */ #define TWI_SLAVE_vect _VECTOR(29) #define TWI_SLAVE_vect_num 29