Помогите понять, что творит оптимизатор Си AVR

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение COKPOWEHEU »

Этот вариант я писал больше для себя. Заинтересовала задача, вдруг когда буду энкодер использовать. Оказалось проще чем я думал, хотя не поздно все усложнить :-)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение ARV »

я извиняюсь, господа, но что за странные алгоритмы вы используете? матрицы какие-то, состояния... разве не проще завести с контактов энкодера две линии, по одной вызывать прерывание по спаду или фронту и смотреть в обработчике просто на уровень второй линии? если в момент прерывания на второй линии 0 - это вращение в одну сторону, если 1 - в другую... какие матрицы?! или я слишком примитивен?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
L.O.D
Встал на лапы
Сообщения: 139
Зарегистрирован: Чт фев 11, 2016 18:35:37

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение L.O.D »

COKPOWEHEU писал(а):Этот вариант я писал больше для себя.
Тогда тем более непонятно, что удивительного Вы увидели в том, что этот вариант работает наоборот, по отношению к коду Mika. Ну да ладно. :)
ARV писал(а):или я слишком примитивен?
Ну, что вы, вы страшно умный! Изображение Знаете, что существуют два метода - push и poll. Изображение
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение ARV »

L.O.D писал(а):Ну, что вы, вы страшно умный! Знаете, что существуют два метода - push и poll.
я вашего юмора не понял. потрудитесь объяснить.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
L.O.D
Встал на лапы
Сообщения: 139
Зарегистрирован: Чт фев 11, 2016 18:35:37

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение L.O.D »

Какой такой юмор? Все чистая правда - вы умный и знаете, ну, далее - по тексту.
Только для Mika эта задачка будет несвоевременной:
А в обработчике прерывания INT0 щупаем вторым выводом канал В. И дальше все элементарно!
Если там высокий уровень — делаем +1, если низкий -1 нашему счетному регистру. Кода на три строчки, мне даже писать его лень.
Конечно, можно такой метод прикрутить и на механический энкодер. Но тут надо будет заблокировать прерывания INT0 на несколько миллисекунд. И НИ В КОЕМ СЛУЧАЕ нельзя делать это в обработчике.
Последний раз редактировалось L.O.D Вт апр 05, 2016 08:12:32, всего редактировалось 2 раза.
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение ARV »

я задал конкретный вопрос, цитирую:
ARV писал(а):разве не проще завести с контактов энкодера две линии, по одной вызывать прерывание по спаду или фронту и смотреть в обработчике просто на уровень второй линии? если в момент прерывания на второй линии 0 - это вращение в одну сторону, если 1 - в другую...
и хотел бы получить ответ на него, а не на тот, на который почему-то вы отвечаете в первую очередь:
ARV писал(а):или я слишком примитивен?

если есть какие-то объективные причины, почему мой вариант хуже ваших вариантов или иных упомянутых, я хотел бы их узнать и понять.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
L.O.D
Встал на лапы
Сообщения: 139
Зарегистрирован: Чт фев 11, 2016 18:35:37

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение L.O.D »

ARV писал(а):я задал конкретный вопрос,
Вы не вопрос задали, а захотели блеснуть аффигительной ерундицией: "я извиняюсь, господа, но что за странные алгоритмы вы используете? матрицы какие-то, состояния...".
А далее все просто - каков вопрос, таков и ответ.
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение ARV »

в остроумии вы меня перещеголяли многократно - это доказанный неопровержимый факт.
а теперь не будете ли так любезны ответить по существу моего вопроса?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
L.O.D
Встал на лапы
Сообщения: 139
Зарегистрирован: Чт фев 11, 2016 18:35:37

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение L.O.D »

Читать разучились что ли? Или полагаете, что суть вопроса это только то, что вы сочтете сутью?

PS
ARV писал(а):в остроумии вы меня перещеголяли многократно - это доказанный неопровержимый факт.
Какое самомнение! Изображение
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
L.O.D
Встал на лапы
Сообщения: 139
Зарегистрирован: Чт фев 11, 2016 18:35:37

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение L.O.D »

Отлично, ARV, мне даже и доказывать ничего не надо! :)))
Ты сам продемонстрировал свое гнилое нутрецо:

Изображение


Будучи загнанным в угол, включил г***омет? Изображение
"Поздравляю вас, гражданин, ..." © Только тут не "соврамши", а кое-что похуже.
Вложения
ArvFckgSht.png
(11.33 КБ) 536 скачиваний
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение COKPOWEHEU »

Может хватит спорить чей говномет больше?
ARV, просто приведите свой вариант. Посмотрим его эффективность, объем, помехозащищенность, оформление и та далее.
Тогда тем более непонятно, что удивительного Вы увидели в том, что этот вариант работает наоборот, по отношению к коду Mika. Ну да ладно. :)
Да сколько повторять - чтобы определить работает он также или наоборот, надо собрать ту же схему и так же назначить выводы. Без этого можно говорить только работает код или нет. Вообще, я поражаюсь вашей способности телепатически определять, что если первый вывод энкодера подключен к PD0, а второй к PD1, то вращению по часовой стрелке должно соответствовать увеличение переменной. При этом не определяя понятия "первый вывод", "второй вывод", "по часовой стрелке" (у колесика мыши, например, такого понятия нет).
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение ARV »

L.O.D писал(а):Ты сам продемонстрировал свое гнилое нутрецо:

а я и раньше, и впредь буду непрофильные сообщения минусовать. ты ж угомониться сразу не смог, стал "разборки" устраивать? вот и получил минус. и за процитированное твое сообщение тоже получил. что хочешь, то и получаешь. думаю, скоро и модераторы набегут. пока ни одно твое сообщение по теме минус не получало - я умею дело от хрени отличать. успехов!

COKPOWEHEU писал(а):ARV, просто приведите свой вариант.
я даже не знаю, что можно приводить... полностью с нуля все писать как-то лень, а бегло накорябать, так или не понятно будет, или криво. я вот про декодирование RC5 пытался рассказать, как просто делать - все сказали "плохо", а аргументов практически не было, кроме неточных значений выдержки. и с универсальным кодом приема ИК-сигналов с любых пультов та же песня... боюсь, и с энкодером будет то же самое. поэтому вы бы мне на пальцах объяснили, в чем матричный способ или какой иной лучше того, о чем сказал я... хотя бы в теории.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение COKPOWEHEU »

Самые очевидные недостатки. Привязка к внешнему прерыванию. Это может затруднить разводку. Могут возникнуть проблемы если захочется опрашивать более одного энкодера. Антидребезг потребует использования задержки внутри прерывания (что в любом случае плохо), либо еще и таймера, что серьезно усложнит программу, да и таймеров частенько не хватает. Использование прерывания с высоким приоритетом ухудшает время реакции на внешние события, тем более что как раз энкодер скорости не требует. Плюс некоторое ухудшение модульности - лишняя глобальная переменная. Ну и анализ двух байт (текущего и предыдущего состояний второго вывода) займет какое-то время.
Кроме того, неизвестно, какой из подходов лучше в плане занимаемого места. Мой код, навскидку, занимает 4 байта на инициализацию, 16 байт на процедуру (без учета сохранения регистров, которое далеко не всегда нужно и с ассемблерной вставкой, потому что gcc творит непойми что) и 16 байт на таблицу. Плюс 1 байт ОЗУ. Итого 36 байт ПЗУ и 16 тактов.
Использование прерывания даже без защиты от дребезга потребует, даже без полезного кода, порядка 20 тактов. Впрочем, возможно, вам удастся упаковать лучше, было бы интересно посмотреть.
СпойлерПро ассемблерную вставку не просто так написал: gcc сгенерировал вот это

Код: Выделить всё

lds   r24, 0x0060
lsr   r24
lsr   r24
sts   0x0060, r24
  if( PIN_0( ENCODER_1 ) )state |= (1<<2); //выставляем биты текущего состояния - 2 и 3 переменной state
sbic   0x16, 0   ; 22
  rjmp   .+6         ; 0x7a <main+0x22>
ori   r24, 0x04   ; 4
sts   0x0060, r24
  if( PIN_0( ENCODER_2 ) )state |= (1<<3); //независимо от расположения выводов энкодера
sbic   0x16, 1   ; 22
  rjmp   .+10        ; 0x88 <main+0x30>
lds   r24, 0x0060
ori   r24, 0x08   ; 8
sts   0x0060, r24
  return pgm_read_byte( &encoder_arr[state] ); //переводим состояние выводов в направление вращения
lds   r30, 0x0060
ldi   r31, 0x00   ; 0
subi   r30, 0xDA   ; 218
sbci   r31, 0xFF   ; 255
lpm   r30, Z
;суммарно 28 тактов
когда достаточно было этого

Код: Выделить всё

;r30 = state
lds r30,0x0060
;state >>=2
lsr r30
lsr r30
;if( PD0 )state |= (1<<2)
sbic PIND,0
  ori r30,0x04
;if( PD1 )state |= (1<<3)
sbic PIND,1
  ori r30,0x08
;state = r30
sts 0x0060,r30
;r30 = &encoder_arr[ state ];
ldi r31,0
subi r30,0xDA
sbci r31,0xFF
;r30 = pgm_read_byte( r30 );
lpm r30,Z
;return r30
;суммарно 16 тактов

Оформление прерывания по минимуму будет выглядеть примерно так
EXT_INT0: ;4 такта на сохранение PC плюс 2 такта на прыжок с таблицы векторов
push temp ;1 такт
in temp,SREG ;1 такт
push temp ;1 такт
lds temp, 0x0060 ;2 такта
;вот тут полезный код ;неизвестно сколько
sts 0x0060,temp ;2 такта
pop temp ;1 такт
out SREG,temp ;1 такт
pop temp ;1 такт
reti ;4 такта
;суммарно как раз 20 тактов плюс полезный код
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение ARV »

благодарю за достаточно развернутый ответ, все, что я хотел, вы мне дали.
с момента, как я перешел на Си в своих поделках, я обращался к ассемблерным вставкам и ассемблеру дважды: когда утрамбовывал в attiny13 свою лампу настроения с дистанционным управлением (ассемблер понадобился для понимания, почему глобальные регистровые переменные портятся по ходу программы) и когда делал многоголосый синтезатор звука (пришлось делать обработчик прерывания полностью в S-файле, иначе не успевал). во всех остальных случаях даже не смотрю, что там GCC наделал. зачем оно вам, мне не понятно, разве что для доказательства выгодности вашего подхода.

кстати, я покопался в своих древних поделиях и нашел, как я сам обрабатывал энкодер. оказалось, почти по-вашему: без массива, но смысл тот же - предыдущее и текущее состояние битов сравнивал, прерывания не задействовал :) такая вот эпидерсия вышла...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
L.O.D
Встал на лапы
Сообщения: 139
Зарегистрирован: Чт фев 11, 2016 18:35:37

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение L.O.D »

COKPOWEHEU писал(а):Да сколько повторять - чтобы определить работает он также или наоборот, надо собрать ту же схему и так же назначить выводы. Вообще, я поражаюсь вашей способности телепатически определять, ...
Вот и я думаю - сколько мне еще нужно повторять, чтобы Вы поняли, что никакой телепатии тут не нужно - просто сравните свой код с кодом ТСа и узрите, что там, где его код выдаст +1, Ваш выдаст -1, и при том вращении, при котором раньше число на его инкаторе росло, после подстановки Вашего кода оно будет уменьшаться и наоборот. Так понятно?

ARVе:
Спойлер
ARV писал(а):ты ж ... стал "разборки" устраивать
Это твой пост:
ARV писал(а):я вашего юмора не понял. потрудитесь объяснить.
и этот тоже:
ARV писал(а):в остроумии вы меня перещеголяли многократно - это доказанный неопровержимый факт.
и т.д. Так что, подбери свой плач-ярославны и не вали с больной головы на здоровую.
ARV писал(а):я и раньше, и впредь буду непрофильные сообщения минусовать.
Договорились. Твои посты про то, какой ты хороший, а я плохой, проминусовал, как непрофильные.
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение COKPOWEHEU »

Было бы все-таки интересно глянуть на вашу реализацию на прерывании. Вдруг ТСу понравится.
Ассемблер забывать тоже не стоит. Например, как сейчас, он помогает сравнить разные подходы, посчитать занимаемое место и скорость. Ну и поофигевать иногда над тем что компилятор творит :-)
L.O.D писал(а):сравните свой код с кодом ТСа и узрите, что там, где его код выдаст +1, Ваш выдаст -1
Разве мой код можно без модификации применить в его устройстве? Я думал что нет, а тогда как можно сравнивать.
L.O.D
Встал на лапы
Сообщения: 139
Зарегистрирован: Чт фев 11, 2016 18:35:37

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение L.O.D »

COKPOWEHEU писал(а):как можно сравнивать.
Я же прямым текстом написал, что и как нужно сравнивать. Прошло не так много времени с тех пор, чтобы потерять нить, но, так и быть, напомню:
L.O.D писал(а):
COKPOWEHEU писал(а):когда я пример кода выложил
Кстати, там нужно транспонировать матрицу, на которой основан массив encoder_arr[16], так как координаты в матрице поменяны местами.


COKPOWEHEU писал(а):Было бы все-таки интересно глянуть на вашу реализацию на прерывании. Вдруг ТСу понравится.
ТС вконец запутается в такой реализации, так как там нужно на ходу включать и выключать INT на время дребезга. О чем, кстати, также уже было написано ранее. "Вы его смерти хочете?" © :))) Впрочем, по приведенной там цитате вполне уже можно было найти 'исходник', так что он уже читал, наверное. :)))
- Из овощей я больше всего люблю пельмени... © Соседский Мальчик
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Re: Помогите понять, что творит оптимизатор Си AVR

Сообщение Мikа »

Здравствуйте!

Вот это у вас холивар переходящий на личности, неожиданный расклад. Я рискну вернуться к теме разговора про вынос функций в отдельные файлы и попросить вас всё-же посмотреть мой проект и и подсказать, где я допускаю ошибку :)

Чтобы не искать, ниже под спойлером я приведу своё сообщение.

Спойлер
Мikа писал(а):С Ассемблером я знаком, я с ним часы напролет тусовался и дома и на работе :)

Я, кстати, скачал файлы, в которых реализован Энкодер от COKPOWEHEU, там мало понятного для меня, поэтому улучшение самой функции опроса энкодера оставим на потом, сейчас нужно научиться делать функции во внешних файлах :)

В общем, что и следовало ожидать - с ходу у меня ничего не получилось, но сегодня с новыми ошибками :)

При компиляции получается вот что:

Error ld returned 1 exit status
Error undefined reference to `Encoder' EncoderExternal
Error undefined reference to `getEncoderState' EncoderExternal

О чём гласит первая ошибка мне не понятно, следующие говорят о том, что не определена ссылка на эти функции, но я же написал их прототипы в .h файле, сам файл подключил в обоих .c файлах, все как было описано.

Ниже под спойлерами я продублирую содержимое файлов, также в приложении архив с проектом и скриншот того, как я добавил файлы в проект.

Итак, файл main.c
[spoiler]

Код: Выделить всё

/*
 * EncoderExternal.c
 *
 * Created: 04.04.2016 0:01:35
 * Author : Михаил
 */

#include <avr/io.h>
#include "Encoder.h"


int main(void)
{
    // Port D init
   DDRD = 0x00;
   
   
   getEncoderState(); // Получить состояние энкодера в первый раз
   
    while (1)
    {
      Encoder();
    }
}




файл Encoder.h
Спойлер

Код: Выделить всё

#ifndef  __Encoder_H__
#define  __Encoder_H__

// Здесь нет никаких переменных, потому что функция пользууется только локальными переменными

void getEncoderState(void);
void Encoder(void);

#endif


Файл Encoder.c
Спойлер

Код: Выделить всё

#include <avr/io.h>
#include "Encoder.h"

static unsigned char Encoder_State = 0;
static signed char Encoder_Summ = 0;
static unsigned char Encoder_NewState = 0;

void getEncoderState(void)      // Это нужно для того чтобы получить первое значение состояния энкодера при пуске программы
{
   Encoder_State = PIND & 0x3;
}

void Encoder(void)
{
   Encoder_NewState = PIND & 0x3;
   if(Encoder_State != Encoder_NewState)
   {

       asm("cli"); //!

      switch(Encoder_State)
      {
         case 2:
         {
            if(Encoder_NewState == 3) Encoder_Summ++;
            if(Encoder_NewState == 0) Encoder_Summ--;
            break;
         }

         case 0:
         {
            if(Encoder_NewState == 2) Encoder_Summ++;
            if(Encoder_NewState == 1) Encoder_Summ--;
            break;
         }
         case 1:
         {
            if(Encoder_NewState == 0) Encoder_Summ++;
            if(Encoder_NewState == 3) Encoder_Summ--;
            break;
         }
         case 3:
         {
            if(Encoder_NewState == 1) Encoder_Summ++;
            if(Encoder_NewState == 2) Encoder_Summ--;
            break;
         }
      }
      
      if (Encoder_Summ == 4) // Увеличение значения числа
      {
         // Выполняемое действие 1
         // В прицнципе здесь должна увеличиться или уменьшиться переменная, передаваемая из основновной программы, но как это сделать пока что не знаю
         Encoder_Summ = 0;
      }

      if (Encoder_Summ == (-4)) // Уменьшение значения числа
      {
         // Выполняемое действие 2
         // В прицнципе здесь должна увеличиться или уменьшиться переменная, передаваемая из основновной программы, но как это сделать пока что не знаю
         Encoder_Summ = 0;
      }

         Encoder_State=Encoder_NewState;
         asm("sei")
         // Код здесь выполнится в любом случаае
   }
}


Я писал я все это по полному подобию того, как вы говорили, но что-то не так.
Надеюсь, вы еще не спите :D


[/spoiler]
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.