Обработка несколько пинов в разных портах.
- Войдите на сайт для отправки комментариев
Пнд, 05/11/2018 - 20:06
Добрый день, уважаемые форумчане!
Прошу у Вас совета, кто знает, подскажите. Имеется 26 кнопок, которые подключены напрямую к ножкам МК Мега 2560. Вся проблема в том, что эти ножки расположены в разных портах.
PA0,PA4,PC1,PC4,PC5,PC6,PC7,PD4,PD5,PE2,PE3,PF7,PG1, PG2,PH2,PJ2,PJ3,PJ5,PK0,PK1,PK2,PK3,PK4,PK5,PK6,PL7
Существует ли какой-нибдуь красивый способ обработать такую конфигурацию кнопок? Если бы было матричное подключению, то проблем, собственно, бы и не было. Но как красиво обработать такой комплект? Может существуют какие-то макросы, которые позволят компактно вызвать процедуру опроса для каждого пина? Или создать свою таблицу (массив) соответствия пинов элементам таблицы (массива) и таким образом в цикле прогонять?
Заранее, спасибо!
С уважением.
Я перефразирую вопрос.
Существует ли способ, грамотно пробежать по данным пинам, находящимся в разных группах, в цикле и вызвать для каждого функцию опроса?
Например в таком виде:
for(byte i = 0; i < 26; i++) { if(isPressed(i)){ // i=0 -> PA0, i=1 -> PA4, i=2 -> PC1 и т.д. // если нажата... } else { // если нет... } }Заранее, спасибо!
Способ с массивом пинов вполне нормальный, если ищется генерализованное решение.
Спасибо за ответ! Я только-только начал изучать программирование МК, поэтому не судите строго. Решил реализовать при помощи макросов (никогда до этого их не использовал):
#define IS_PRESSED(PINx, PIN) !((PINx) & (1<<(PIN))) #define CFG_BUTTONS_DDR(DDRx, PIN) ((DDR##DDRx) |= (1<<(PIN))) #define CFG_BUTTONS_PORT(PORTx, PIN) ((PORT##PORTx) |= (1<<(PIN))) #define BUTTONS_COUNT 26 byte butPorts[] = {'A', 'A', 'C', 'C', 'C', 'C', 'C', 'D', 'D', 'E', 'E', 'F', 'G', 'G', 'H', 'J', 'J', 'J', 'K', 'K', 'K', 'K', 'K', 'K', 'K', 'L'}; byte butPins [] = {0, 4, 1, 4, 5, 6, 7, 4, 5, 2, 3, 7, 1, 2, 2, 2, 3, 5, 0, 1, 2, 3, 4, 5, 6, 7}; void setup() { cfgButtons(); } void loop() { } void cfgButtons() { for(byte i = 0; i < BUTTONS_COUNT; i++){ CFG_BUTTONS_DDR(butPorts[i], butPins[i]); CFG_BUTTONS_PORT(butPorts[i], butPins[i]); } }В результате компилятор выдает ошибку:
Ну, вы с козырей-то не заходите. Поищите картинку с распиновкой Arduino Mega2560. Там увидите соответствие выводов МК сквозной нумерации Arduino. Вот эти номера в массив сгружайте и потом уже pinMode(pins[i], INPUT) / digitalRead(pins[i])... Если этого не хватит, то уже к регистрам можно перейти. Например - хранить в массиве структур указатель на порт и битовую маску для доступа к конкретному выводу (в сущности Arduino так и делает).
А компилятор правильно ругается. ## - это не для рантайма, а для препроцессинга. Сначала решеточками строки в исходнике слепляются, а потом только уже начинается непосредственно компиляция. Ну и, естественно, что там слеплено - как функция/переменная не объявлено.
Shaman_2010, насколько я знаю, в Ардуино ИДЕ пины Мега обозначены целыми числами, типа 42 или 50. Почему бы просто не создать массив целых типа int или byte, без всяких PA1 и PB4?
Ну, вы с козырей-то не заходите. Поищите картинку с распиновкой Arduino Mega2560. Там увидите соответствие выводов МК сквозной нумерации Arduino. Вот эти номера в массив сгружайте и потом уже pinMode(pins[i], INPUT) / digitalRead(pins[i])... Если этого не хватит, то уже к регистрам можно перейти. Например - хранить в массиве структур указатель на порт и битовую маску для доступа к конкретному выводу (в сущности Arduino так и делает).
А компилятор правильно ругается. ## - это не для рантайма, а для препроцессинга. Сначала решеточками строки в исходнике слепляются, а потом только уже начинается непосредственно компиляция. Ну и, естественно, что там слеплено - как функция/переменная не объявлено.
Спасибо за ответ! Да, в том то и дело, что, по моему, не все пины, которые я привел выше, имеют сквозную нумерацию, поэтому я сразу перешел к работе с регистрами... И по макросам, да, я уже понял, что дал маху с ними, спасибо! )
Shaman_2010, насколько я знаю, в Ардуино ИДЕ пины Мега обозначены целыми числами, типа 42 или 50. Почему бы просто не создать массив целых типа int или byte, без всяких PA1 и PB4?
Дело в том, что не все пины имеют сквозную нумерацию Arduino. По моему...
Решил задачу следующим образом:
#define BUTTONS_COUNT 26 volatile uint8_t *butDDR[] = {&DDRA, &DDRA, &DDRC, &DDRC, &DDRC, &DDRC, &DDRC, &DDRD, &DDRD, &DDRE, &DDRE, &DDRF, &DDRG, &DDRG, &DDRH, &DDRJ, &DDRJ, &DDRJ, &DDRK, &DDRK, &DDRK, &DDRK, &DDRK, &DDRK, &DDRK, &DDRL}; volatile uint8_t *butPORT[] = {&PORTA, &PORTA, &PORTC, &PORTC, &PORTC, &PORTC, &PORTC, &PORTD, &PORTD, &PORTE, &PORTE, &PORTF, &PORTG, &PORTG, &PORTH, &PORTJ, &PORTJ, &PORTJ, &PORTK, &PORTK, &PORTK, &PORTK, &PORTK, &PORTK, &PORTK, &PORTL}; volatile uint8_t *butPIN[] = {&PINA, &PINA, &PINC, &PINC, &PINC, &PINC, &PINC, &PIND, &PIND, &PINE, &PINE, &PINF, &PING, &PING, &PINH, &PINJ, &PINJ, &PINJ, &PINK, &PINK, &PINK, &PINK, &PINK, &PINK, &PINK, &PINL}; byte butPins [] = {0, 4, 1, 4, 5, 6, 7, 4, 5, 2, 3, 7, 1, 2, 2, 2, 3, 5, 0, 1, 2, 3, 4, 5, 6, 7}; void setup() { Serial.begin(9600); cfgButtons(); } void loop() { delay(1000); Serial.println(isButPressed(0)); } void cfgButtons() { for(byte i = 0; i < BUTTONS_COUNT; i++){ (*(butDDR[i])) |= (1 << butPins[i]); (*(butPORT[i])) |= (1 << butPins[i]); } } bool isButPressed(byte butNum) { if(butNum >= BUTTONS_COUNT) {return false;} return ((*(butPIN[butNum])) & (1 << butPins[butNum])) ? false : true; }Громоздко выглядит, конечно, но работает. Надо будет и правда подумать на счет структур. Если есть советы по улучшению - буду признателен!
Заранее спасибо!