прерывание сбрасывает присвоенные в цикле значения элементов массива?!?!))
- Войдите на сайт для отправки комментариев
Чт, 17/08/2017 - 16:03
На панельке led 8х8 отбражается змейка. Тело змейки-массив из 10 эл-ов (5 точек с координатами Х,У). В цикле координатам её "телец" присваиваются новые значения и змейка бежит. по нажатию клавиши обрабатывается прерывание. Прерывание присваивает глобальной переменной новое значение. Исходя из одного из этих значений выбирается нужный цикл (направление движение змейки). Но вот беда... по нажатию клавиши змейка начинает свой путь из точки 0.0 .. то есть присвоенные массиву новые координаты сбрасываются(
#include "LedControl.h" #include "binary.h" #include <TM74HC595Display.h> #include <TimerOne.h> LedControl lc=LedControl(11,13,10,1); int SCLK = 7; int RCLK = 6; int DIO = 5; TM74HC595Display disp(SCLK, RCLK, DIO); int Course=0; void setup() { lc.shutdown(0,false); // выставляем яркость на среднее значение: lc.setIntensity(0,1); // очищаем дисплей: lc.clearDisplay(0); attachInterrupt(0, course(), RISING); //повышение напряжения на пин2 } //провоцирует выполнение course() int delaytime = 100; int snake[10]; void snakeY(int y){ //присваивание координаты У snake[9]=snake[7];snake[7]=snake[5]; snake[5]=snake[3];snake[3]=snake[1]; snake[1]=y; } void snakeX(int x){ //присваивание координаты Х snake[8]=snake[6];snake[6]=snake[4]; snake[4]=snake[2];snake[2]=snake[0]; snake[0]=x; } void ledsnake(){ //отображение змеи int b=1; for(int a=0; a<9; a+=2){ lc.setLed(0,snake[a],snake[b],true); b+=2; } delay(delaytime); b=1; for(int a=0; a<9; a+=2){ lc.setLed(0,snake[a],snake[b],false); b+=2; } } volatile int course(){ //направление движения по нажатию кнопки volatile int val; val=analogRead(0); if(val>760&&val<795) //лево {disp.digit4(2); Course=2;} if(val>625&&val<645) //низ {disp.digit4(0); Course=0;} if(val>525&&val<545) //право {disp.digit4(3); Course=3;} if(val>590&&val<610) //верх {disp.digit4(1); Course=1;} } void snakemove(){ //движение змеи if(Course==3){ for(int y=snake[1];y<9;y++){ snakeY(y); snakeX(snake[0]); ledsnake(); if(Course!=3) continue; if(y==7)y=-1; } } if(Course==2){ for(int y=snake[1];y>-2;y--){ snakeY(y); snakeX(snake[0]); ledsnake(); if(Course!=2) continue; if(y==0) y=8; } } if(Course==1){ for(int x=snake[0];x>-2;x--){ snakeX(x); snakeY(snake[1]); ledsnake(); if(Course!=1) continue; if(x==0) x=8; } } if(Course==0){ for(int x=snake[0];x<9;x++){ snakeX(x); snakeY(snake[1]); ledsnake(); if(Course!=0) continue; if(x==7) x=-1; } } } void loop() { snakemove(); }
у вас вправо-влево - это y -координата, а вверх-вниз - это х ? оригинально...
Вообще, в таком "слепом" и непрозрачном коде легко налепить ошибок... не пробовали писать как-то попроще? В процедурах snakeX snakeY - что за бредовое переприсваивание координат? Циклы для кого придумали?
В процедуре snakemove - в каждом цикле отработки курса в операторе for вы насильственно меняете индексную переменную. Это нарушает логику, это прямой путь к трудно отловим глюкам.
Вывод - Типичный говнокод... сорри. неудивительно, что не работает
Это, в общем, мой первый код) и он работает (когда переменной course присваивалось рандомное значение, а циклы завершались через определенные промежутки времени - змея двигалась как надо.) поэтому я думаю что дело именнно в прерываниях. Похоже прерыванием сбрасываются присвоенные значения. Объясните по поводу насильственного изменения индексной переменной
Уберите volatile из строк 44 и 45, а поставьте в строку 10. Проблему это не решит, но курей-то зачем смешить?
Объясните по поводу насильственного изменения индексной переменной
я имел в виду вот этот код
Непонятно все-таки, какое максимальное значение должен принимать x - менее 9, то есть 8 - как в заголовке цикла, или же 7, как в условии в 6-й строке? Если вы при достижении x==7 сбрасываете его до значения (-1) - почему тогда в заголовке цикла for до x<9 ?
по поводу volatile - в строке 44 вы обьявляете volatile возвращаетмое значение процедуры course() - не уверен, правильно ли это, но уверен, что это в вашем коде нафик не нужно, так как эта процедура вообще не возвращает значений. Процедуру course() надо описать как void.
Локальную перемененую val в этой же процедуре тоже незачем описывать как volatile
А вот что нужно описывать как волатильную переменную - вы не сделали. Это переменная Course
мда.. свой же подчерк не разобрал) volatile относится к переменной, а не к функции
я имел в виду вот этот код
Непонятно все-таки, какое максимальное значение должен принимать x - менее 9, то есть 8 - как в заголовке цикла, или же 7, как в условии в 6-й строке? Если вы при достижении x==7 сбрасываете его до значения (-1) - почему тогда в заголовке цикла for до x<9 ?
[/quote]
это по моему мнению - допустимая небрежность. просто использовал конструкцию цикла for, а по смыслу это while