Официальный сайт компании Arduino по адресу arduino.cc
Макросы
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Ср, 30/01/2019 - 17:53
Проблема следующая!
Пытаюсь подправить библиотеку (CyberLib) чтобы можно было работать с переменными и в цыкле.
Если с D_In, D_Out, D_High, D_Low и D_Inv все нормально - подстановка происходит, что видно на прилагаемом коде, - то если запросить D_Read - выдает ошибку, хотя делал также как и с остальными.
Вопрос - Почему верхние макросы подставляют значение а последний не хочет.
(Текст Ошибки под макросом)
//Эти 2(два) макроса работают #define D_In(x) if(x==10) DDRB &=B11111011; #define D_Out(x) if (x==0) DDRD |=B00000001;\ else if (x==1) DDRD |=B00000010;\ else if (x==2) DDRD |=B00000100;\ else if (x==3) DDRD |=B00001000;\ else if (x==4) DDRD |=B00010000;\ else if (x==5) DDRD |=B00100000; //Здесь макрос тоже работает #define D_Inv(x) switch(x){\ case 0: PORTD ^=B00000001; break;\ case 1: PORTD ^=B00000010; break;\ case 2: PORTD ^=B00000100; break;\ case 3: PORTD ^=B00001000; break;\ case 4: PORTD ^=B00010000; break;\ case 5: PORTD ^=B00100000; break;\ } // А ВОТ с этим проблема хотя и сделан по ВЫШЕ подобному и который работает без ошибки. //Если раскоментировать 42_ю (buton1 = D_Read(10);) строку - идет ошибка (указана под макросом в коментарии) #define D_Read(x) switch(x){\ case 10: ((PINB & B00000100)>>2); break;\ case 11: ((PINB & B00001000)>>3); break;\ case 12: ((PINB & B00010000)>>4); break;\ case 13: ((PINB & B00100000)>>5); break;} //main.ino:42: error: expected primary-expression before 'switch' //main.ino:42: error: expected `;' before 'switch' void setup() { for(int i=2; i<6; i++) { D_Out(i); //Понимаю что правильнее DDRх - но делал для проверки работы в цыкле с переменной } } void loop() { static bool poz = 0; static bool buton1 = 0; //buton1 = D_Read(10); if(!buton1) { for(int i=3; i<6; i++) { D_Inv(i); poz = !poz; if(poz) { i--; } delay(1000); } } //D_Beep(13, 1000, 10); }
Код рабочий - ели закоментировано чтение ПИНА
Смотрел библиотеку ув.Arhat, вот что он пишет -
"При указании номера пина в переменной - этот подход НЕ РАБОТАЕТ! Макрос развернется в код, склеивающий название переменной с текстом макроса и Вы получите сообщение о синтаксических ошибках и только.
Такой подход имеет место быть, поскольку все пины Ардуино имеют жесткую привязку к своим функциям, особенно специальным и, соответственно, всегда явно известны при разработке скетчей."
Вот сижу и думаю почему приведенный ниже код работает - может это и есть ошибка.
Пока думал над вопросм, для D_Read нашол такое решение, правда сменить пин можно только по дефайну -
Хоть чтото не надо переписывать по всему коду
#define button 12 //Эти 2(два) макроса работают #define D_In(x) if(x==10) DDRB &=B11111011; #define D_Out(x) if (x==0) DDRD |=B00000001;\ else if (x==1) DDRD |=B00000010;\ else if (x==2) DDRD |=B00000100;\ else if (x==3) DDRD |=B00001000;\ else if (x==4) DDRD |=B00010000;\ else if (x==5) DDRD |=B00100000; //Здесь макрос тоже работает #define D_Inv(x) switch(x){\ case 0: PORTD ^=B00000001; break;\ case 1: PORTD ^=B00000010; break;\ case 2: PORTD ^=B00000100; break;\ case 3: PORTD ^=B00001000; break;\ case 4: PORTD ^=B00010000; break;\ case 5: PORTD ^=B00100000; break;\ } #define D_Read(x) _D_READ(x) #define _D_READ(x) dread_D##x #define dread_D10 ((PINB & B00000100)>>2) #define dread_D11 ((PINB & B00001000)>>3) #define dread_D12 ((PINB & B00010000)>>4) #define dread_D13 ((PINB & B00100000)>>5) void setup() { for(int i=2; i<6; i++) { D_Out(i); //Понимаю что правильнее DDRх - но делал для проверки работы в цыкле с переменной } D_In(button); } void loop() { static bool poz = 0; if(D_Read(button)) { for(int i=3; i<6; i++) { D_Inv(i); poz = !poz; if(poz) i--; delay(1000); } } //D_Beep(13, 1000, 10); }
Но вопрос по первому коду остается Открытым - ПОЧЕМУ?
Но, Вы же своими кейсами убили саму идею киберлиба! У Вас хоть переменная, хоть константа - одной командой не получится.
Делать надо так, чтобы при константе получалась лдна команда, а при переменной - короткое вычисление. Возмите DigitalPins - там это уже сделано
vosara - а вы попробуйте сами выполнить подстановку вместо компилятора
Вот что получается:
неудивительно, что компилятор ругается
vosara - а вы попробуйте сами выполнить подстановку вместо компилятора
Вот что получается:
неудивительно, что компилятор ругается
Смотрите как я вижу работу макроса. Возможно я ошибаюсь - поправте
[quote=vosara]
Кампилятор перед кампиляцией должен заменить эту строчку на
на
[\quote]
Неправильно. Макрос, это всего лишь текстовая подстановка, никакие блоки кода в момент подставновки не вычисляются.
На место вашего D_Read(10) будет подставлен не конкретный кэйс из свитча, а весь блок свитча целиком, и что в итоге выйдет - я написал в сообщении #2 выше
Вычисляются ПОСЛЕ подстановки. Т.е. при подстановке блок должен быть корректным.
А значит Вам тут надо использовать не switch, а тернарный оператор. Посмотрите, наконец DigitalPins, там всё это сделано.
vosara - да с чего вы взяли. что он свитч не тянет? - тянет точно так же
Замените свою строчку 24 на
и убедитесь в наличии точно той же ошибки, как в прошлом случае
Да Ошибка. Спасибо!