|
Новичок
Регистрация: 13.04.2023
Сообщений: 1
Репутация: 10
![]() |
Прошу помощи с Algorithm Builder. Я новичёк в этом. Надо обрабатывать прерывания по изменению входов PCINT0...5
В Algorithm Builder есть прерывание Pin_Change Даю ATtiny2313 разрешения в PCMSK на один вход, PCIE и глобальному прерыванию, но никакой реакции на изменение состояния входа не происходит. Есть у кого опыт работы с этими прерываниями? |
||
|
Оценка
|
|
Специалист
Регистрация: 22.09.2010
Адрес: г. Донецк
Сообщений: 873
Репутация: 382
![]() ![]() ![]() ![]() |
Цитата:
Код:
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
Репутация: 382
![]() ![]() ![]() ![]() |
А вот более короткий пример из другого проекта, где на три входа подаются импульсы с датчиков перехода 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
Сообщений: 101
Репутация: 33
![]() |
|
||
|
Оценка
|
|
Специалист
Регистрация: 22.09.2010
Адрес: г. Донецк
Сообщений: 873
Репутация: 382
![]() ![]() ![]() ![]() |
Вы ошибаетесь, посмотрите даташит на ATtiny2313, страница 58.
Впрочем, ТС уже решил задачу на другом форуме. Судя по всему ему не хватало общего понимания работы External Interrupts на AVR.
__________________
Atmel, STM32, ESP32, RTOS, OS-less, C, C++, C#, Visual Studio, IAR, Altium, Micro-Cap, Maple, MatLab, etc. |
||
|
Оценка
|
| Обратная связь РадиоЛоцман Вверх |