Re: Помогите понять, что творит оптимизатор Си AVR
Добавлено: Ср апр 06, 2016 11:03:03
См. update предыдущего поста.
Здесь можно немножко помяукать :)
https://radiokot.ru/forum/
Достаточно передать ее в функцию по указателю:В прицнципе здесь должна увеличиться или уменьшиться переменная, передаваемая из основновной программы, но как это сделать пока что не знаю
Код: Выделить всё
void Encoder(signed char *pos){ //звездочка означает указатель на переменную, а не ее значение
...
*pos = 1; //для примера, присвоим переменной значение 1, но можете проводить и другие операции.
...
}
int main(){
signed char enc_pos;
Encoder(&enc_pos); //знак '&' означает адрес переменной. Это почти указатель, только изменяться не может.
...
}Код: Выделить всё
int Encoder(){
if(1)return 1; //условно говоря, это условие, при котором значение энкодера должно увеличиться.
if(2)return 0; //значение энкодера не менялось
if(3)return -1; //значение энкодера уменьшилось
}
int main(){
int enc_pos;
enc_pos = enc_pos + Encoder();
}Это не нужно. Объявите Encoder_State как локальную статическую переменную в функции Encoder и инициализируйте ее нужным значением// Это нужно для того чтобы получить первое значение состояния энкодера при пуске
Код: Выделить всё
void Encoder(){
static char Encoder_State = PINB & 0x03;
...Лучше внутри функций таким не злоупотреблять. Она может быть вызвана когда прерывания запрещены, а она их разрешит. Да и прерывание ее работы неопасно. Пусть себе прерывания возникают где-то в середине, они не помешают.asm("cli");
...
asm("sei");
Код: Выделить всё
signed char EncTransIncs[4][4] = {
0, +1, -1, 0,
-1, 0, 0, +1,
+1, 0, 0, -1,
0, -1, +1, 0
};
signed char Encoder(){
static uint8_t last_state = PINB & 0x03; //предыдущее состояние энкодера
uint8_t cur_state = PINB & 0x03; //текущее состояние. При первом запуске они совпадают, потом last_state будет на один отсчет отставать
signed char res; //результат
res = EncTransIncs[ last_state ][ cur_state ];
last_state = cur_state;
return res;
}
int main(){
int enc_angle;
...
while(1){
enc_angle = enc_angle + Encoder();
}
}Да если бы по второму - уже раз пятый, кажется, Вы отказываетесь понять, что в коде ТСа порядок подключения каналов уже определен и менять этот порядок подключения, при подстановке Вашего кода, он разумеется не станет. А раз не станет, то очевидно, что получит противоположный своему результат.COKPOWEHEU писал(а):Начинаем по второму кругу? Без схемы подключения говорить о необходимости изменении матрицы или знака нельзя.
я обращаю внимание на несколько недочетов в ваших файликах:Мikа писал(а):Я писал я все это по полному подобию того, как вы говорили, но что-то не так.
Это вы отказываетесь понять, что у меня он НЕ определен. Как определите так и будет работать.L.O.D писал(а):Вы отказываетесь понять, что в коде ТСа порядок подключения каналов уже определен
Ну, ее смысл в получении начального значения для внутренней переменной, так что get кое-как натянуть можно. Автору, похоже, стоит ознакомиться с методом объявления переменных с их инициализацией. Ну и это не отменяет, что приставки get и set принято использовать для получения и установки какого-то значения, а не для инициализации.1. в файл заголовка нет смысла выносить функции, которые никогда не понадобятся "снаружи" модуля. у вас это функция getEncoderState
Внутри функции - точно нет, там у static'а своя область применения, а обычные локальные переменные в спецмодификаторах не нуждаются.3. локальные, т.е. востребованные только внутри модуля, функции и [глобальные] переменные должны всегда объявляться с префиксом static
А можно подробнее? А то я нормально пользовался и так и так и проблем не находил. Это вообще рекомендация по безопасности или оформлению кода?макросы cli() и sei() вместо "ассемблерных" вставок
А при чем здесь вы? Речь, напоминаю, шла о ТС, у которого этот порядок уже определен и при этом определенном порядке приведенный вами пример выдаст противоположные результаты. С чем вы никак не можете разобраться на протяжении вот уже пяти дней и семи попыток. Многовато для человека, не отягощенного чем-то, сильно отвлекающим его внимание.COKPOWEHEU писал(а):у меня он НЕ определен. Как определите так и будет работать.
я говорил о локальных переменных для МОДУЛЯ, и о локальных для МОДУЛЯ функциях, а не о локальных переменных в функцияхCOKPOWEHEU писал(а):Внутри функции - точно нет, там у static'а своя область применения, а обычные локальные переменные в спецмодификаторах не нуждаются.
дело в том, что разные версии компилятора avr-gcc по-разному обращаются с ассемблерными вставками. неоднократно было отмечено, что оптимизатор выбрасывает подобные вставки. поэтому рекомендуется как минимум писать volatile asm("cli") чтобы однозначно не попасть под раздачу багов. ну а еще лучше поступать, как я и советовал - использовать макросы, за которые avr-gcc сам "отвечает"COKPOWEHEU писал(а):А можно подробнее? А то я нормально пользовался и так и так и проблем не находил. Это вообще рекомендация по безопасности или оформлению кода?
[бьющийся головой о стену смайлик] Ладно, я не могу разобраться в своей же библиотеке. Покажите же наконец, как ее правильно использовать. Возьмите мою библиотеку (encoder.h) и подключит к проекту ТСа. после этого скажите, в ту оно сторону вращается или нет. Только очень прошу - действительно проверьте, а то пустых обвинений тут уже третья страница идет.L.O.D писал(а):А при чем здесь вы? Речь, напоминаю, шла о ТС, у которого этот порядок уже определен и при этом определенном порядке приведенный вами пример выдаст противоположные результаты. С чем вы никак не можете разобраться на протяжении вот уже пяти дней и семи попыток.COKPOWEHEU писал(а):у меня он НЕ определен. Как определите так и будет работать.
В таком случае будем считать что я несколько расширил ваш пункт, вдруг кто тоже неправильно поймет.я говорил о локальных переменных для МОДУЛЯ, и о локальных для МОДУЛЯ функциях, а не о локальных переменных в функциях
Это, кстати, странно. Ладно бы пытался оптимизировать, то есть если где-то раньше уже есть, скажем, обнуление всего SREG, то следующую asm("cli") выбрасывать. Но целую вставку просто так? Ладно, если народ наступал на такие грабли, надо поберечься.неоднократно было отмечено, что оптимизатор выбрасывает подобные вставки
В прошлый раз забыл сказать - выложите весь проект, архивом, а не только исходный код. Особенно интересует файл Default/makefile. Он автогенерированный и если у кого тут есть IDE вашей версии, проект будет полезнее. Но в крайнем случае этого файла хватит чтобы определить что и куда вы подключаете.Я рискну вернуться к теме разговора про вынос функций в отдельные файлы и попросить вас всё-же посмотреть мой проект и и подсказать, где я допускаю ошибку
Если вам еще и обвинения привиделись, то у вас не просто мало времени на этот топик, у вас его катастрофически мало. И тот же смайлик, что вы не нашли.COKPOWEHEU писал(а):а то пустых обвинений тут уже третья страница идет.
Предыдущих семи раз достаточно.COKPOWEHEU писал(а):То есть ответить по существу нечего, подтвердить слова нечем?