Новичок
Регистрация: 13.04.2023
Сообщений: 1
Репутация: 10
![]() |
Прошу помощи с Algorithm Builder. Я новичёк в этом. Надо обрабатывать прерывания по изменению входов PCINT0...5
В Algorithm Builder есть прерывание Pin_Change Даю ATtiny2313 разрешения в PCMSK на один вход, PCIE и глобальному прерыванию, но никакой реакции на изменение состояния входа не происходит. Есть у кого опыт работы с этими прерываниями? |
||
Оценка
|
Специалист
Регистрация: 22.09.2010
Адрес: г. Донецк
Сообщений: 873
Репутация: 381
![]() ![]() ![]() ![]() |
Цитата:
Код:
ISR(PCINT1_vect) { sleep_disable(); return; } ISR(PCINT2_vect, ISR_ALIASOF(PCINT1_vect)); void hardware_init(void) { ... // Внешние прерывания PCICR |= _BV(PCIE1)|_BV(PCIE2); PCMSK1 |= _BV(PCINT8)|_BV(PCINT9)| _BV(PCINT10)|_BV(PCINT11)|_BV(PCINT12); PCMSK2 |= _BV(PCINT16)|_BV(PCINT17)| _BV(PCINT18)|_BV(PCINT19)|_BV(PCINT20); ... } uint8_t get_column_number(void) { columns_1_rows_0(); if(!(PIND & _BV(PD1))) return 1; if(!(PIND & _BV(PD2))) return 2; if(!(PIND & _BV(PD3))) return 3; if(!(PIND & _BV(PD4))) return 4; return 0; } uint8_t get_row_number(void) { columns_0_rows_1(); if(!(PINC & _BV(PC0))) return 1; if(!(PINC & _BV(PC1))) return 2; if(!(PINC & _BV(PC2))) return 3; if(!(PINC & _BV(PC3))) return 4; if(!(PINC & _BV(PC4))) return 5; if(!(PINC & _BV(PC5))) return 6; if(!(PIND & _BV(PD0))) return 7; return 0; } void columns_0_rows_1(void) { columns_rows_to_Z(); // Столбцы PORTD &= ~(_BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD4)); DDRD |= _BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD4); // Строки PORTC |= _BV(PC0)|_BV(PC1)| _BV(PC2)|_BV(PC3)|_BV(PC4)|_BV(PC5); PORTD |= _BV(PD0); DDRC &= ~(_BV(PC0)|_BV(PC1)| _BV(PC2)|_BV(PC3)|_BV(PC4)|_BV(PC5)); DDRD &= ~_BV(PD0); } void columns_to1_rows_to0(void) { columns_rows_to_Z(); // Столбцы PORTD |= _BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD4); DDRD &= ~(_BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD4)); // Строки PORTC &= ~(_BV(PC0)|_BV(PC1)| _BV(PC2)|_BV(PC3)|_BV(PC4)|_BV(PC5)); PORTD &= ~_BV(PD0); DDRC |= _BV(PC0)|_BV(PC1)|_BV(PC2)| _BV(PC3)|_BV(PC4)|_BV(PC5); DDRD |= _BV(PD0); } void columns_rows_to_Z(void) { // Столбцы PORTD &= ~(_BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD4)); DDRD &= ~(_BV(PD1)|_BV(PD2)|_BV(PD3)|_BV(PD4)); // Строки PORTC &= ~(_BV(PC0)|_BV(PC1)| _BV(PC2)|_BV(PC3)|_BV(PC4)|_BV(PC5)); PORTD &= ~_BV(PD0); DDRC &= ~(_BV(PC0)|_BV(PC1)| _BV(PC2)|_BV(PC3)|_BV(PC4)|_BV(PC5)); DDRD &= ~(_BV(PD0)); } uint8_t get_button_number(void) { uint8_t column = 0; uint8_t row = 0; column = get_column_number(); row = get_row_number(); // Если действительно кнопка нажата if(column!=0 && row!=0) { _delay_ms(10); // Антидребезг if(column == get_column_number()) if(row == get_row_number()) // Приведение к нулевому индексу в buttons_codes_mas[] return 7*(column-1)+row; } return 0; }
__________________
Atmel, STM32, ESP32, RTOS, OS-less, C, C++, C#, Visual Studio, IAR, Altium, Micro-Cap, Maple, MatLab, etc. |
||
Оценка
|
Специалист
Регистрация: 22.09.2010
Адрес: г. Донецк
Сообщений: 873
Репутация: 381
![]() ![]() ![]() ![]() |
А вот более короткий пример из другого проекта, где на три входа подаются импульсы с датчиков перехода 3х фаз сети через 0.
Код:
inline void hardware_init(void) { ... PCICR |= _BV(PCIE0); PCMSK0 |= _BV(PCINT0); DDRD &= ~(_BV(PD0)|_BV(PD1)|_BV(PD2)); ... } ISR(PCINT2_vect) { if(PIND & _BV(PD2)) { .... } if(PIND & _BV(PD1)) { ... } if(PIND & _BV(PD0)) { ... } ... }
__________________
Atmel, STM32, ESP32, RTOS, OS-less, C, C++, C#, Visual Studio, IAR, Altium, Micro-Cap, Maple, MatLab, etc. |
||
Оценка
|
Новичок
Регистрация: 21.11.2008
Сообщений: 88
Репутация: 27
![]() |
|
||
Оценка
|
Специалист
Регистрация: 22.09.2010
Адрес: г. Донецк
Сообщений: 873
Репутация: 381
![]() ![]() ![]() ![]() |
Вы ошибаетесь, посмотрите даташит на ATtiny2313, страница 58.
Впрочем, ТС уже решил задачу на другом форуме. Судя по всему ему не хватало общего понимания работы External Interrupts на AVR.
__________________
Atmel, STM32, ESP32, RTOS, OS-less, C, C++, C#, Visual Studio, IAR, Altium, Micro-Cap, Maple, MatLab, etc. |
||
Оценка
|
Обратная связь РадиоЛоцман Вверх |