Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
eufs
Опытный кот
Сообщения: 772
Зарегистрирован: Вс апр 10, 2011 02:24:06
Откуда: г.Северодонецк

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение eufs »

eufs писал(а):Если непонятно - пиши, поясню на примере. Все получается не очень компактно(из-за таблицы), но очень быстро и просто и без условных переходв.

Тогда таблицу придётся делать для всех возможных комбинаций, т.е. 2^4 = 16 байт для хранения, по сути, всего двух бит (0 или ±1). Как-то нерационально, а бешеная скорость мне не нужна: по даташиту максимальная скорость вращения энкодера 100 об/мин.

Да. 16 байт. Но не только для хранения 2 бит. Таблица дает возможность исключить всевозможные проверки и условные переходы, а это тоже место. А 16 байт - это 8 команд(всего лишь). Попробуй, напиши с таблицей и без, тогда поговорим о длине кода и затем о рациональности.
C0FFEE=‭12648430‬
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

eufs писал(а):Да. 16 байт. Но не только для хранения 2 бит. Таблица дает возможность исключить всевозможные проверки и условные переходы, а это тоже место. А 16 байт - это 8 команд(всего лишь). Попробуй, напиши с таблицей и без, тогда поговорим о длине кода и затем о рациональности.

Ну, я не говорил, что совсем отказываюсь от таблицы :) К тому же, у меня есть подозрение что с таблицей будет проще организовать обработку двух энкодеров.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение DX168B »

Вот и я суда с вопросом.
Подскажите, как можно разделить 8-битное число на 2? Сдвигом вправо?
I am DX168B and this is my favourite forum on internet!
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

DX168B писал(а):Подскажите, как можно разделить 8-битное число на 2? Сдвигом вправо?

ДА :) По кр. мере, положительное.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
DX168B
Друг Кота
Сообщения: 4468
Зарегистрирован: Вс янв 24, 2010 19:19:52
Откуда: Главный Улей России (Moscow)
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение DX168B »

Знаковое или нет, там не играет роли.
Мне нужно было поделить число пополам, отвечающее за частоту ШИМ,
чтобы его вставить в регистр сравнения.
TINY26L, TIMER1
OCR1C - число n+1 (частота ШИМ)
OCR1A - число n\2 (длинна периода)
Разрабатываю кодер\декодер сигнатур для радиосвязи. :)
Спасибо :) :beer:
I am DX168B and this is my favourite forum on internet!
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение coredumped »

Gudd-Head писал(а):Как с помощью МК определить направление вращения энкодера, покрасивее и покомпактнее?
Энкодер двухбитный в коде Грея, т.е. последовательность 00-10-11-01 в одну сторону и 00-01-11-10 в другую.
Пока в голову не приходит ничего лучше, чем сравнивать прошлые 2 бита и новые 2 бита с константами (CPI с последующим BREQ на каждую константу) "0010", "1011", "1101" и "0100" в случае инкремента (условно); "0001", "0111", "1110" и "1000" в случае декремента.

Можно с помощью аппаратного прерывания по положительному фронту. Подаете первую ногу энкодера, например, на INT0. В обработчике считываете вторую ногу. Если 0 - то одно направление, если 1 - другое. Можно замутить внешний детектор на одном D-триггере. Полет фантазии безграничен :)
Все будет только лучше, в крайнем случае - хуже.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

coredumped писал(а):Можно с помощью аппаратного прерывания по положительному фронту. Подаете первую ногу энкодера, например, на INT0. В обработчике считываете вторую ногу. Если 0 - то одно направление, если 1 - другое. Можно замутить внешний детектор на одном D-триггере. Полет фантазии безграничен :)

Во-первых, не хочется делать это в прерывании. Во-вторых, такой алгоритм даст всего одно прерывание на 4 изменения положения энкодера. Ну и в-третьих, только внешнего D-триггера мне и не хватало, когда есть МК.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение coredumped »

moza-mult писал(а):Период импульса Т 1100 машинных циклов (305 мкс*)
Длительность импульса t 340 машинных циклов (94 мкс*)
Источники прерывания
Запрос на прерывание от внешнего источника INT0
Запрос на прерывание от внутреннего источника INT1
исходник добавил... но не могу понять как он работает... и работает ли... проверить на анализаторе его временно не могу... поэтому если есть возможность ответьте плиз :)

Не хочу читать нотаций, просто в паузах, пока компилится проект на ARM (минут 10) скучно... А тут какраз плата с 16й мегой валялась :)))

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

#include <avr/io.h> 
#include <stdio.h>
#include <stdlib.h>
#include <avr/interrupt.h>

volatile unsigned char INT0_count = 0;
volatile unsigned char INT1_count = 0;
volatile unsigned char phase = 0;

ISR(INT0_vect)
{
   TCCR1B = 0; //Stop timer 1

   INT0_count++;
   if(INT0_count == 6) GICR &= ~(1<<INT0); //disable INT0

   TCCR1B = 1; //Start timer 1, prescaler=1
}

ISR(INT1_vect)
{
   TCCR1B = 0; //Stop timer 1

   INT1_count++;
   if(INT1_count == 6) GICR &= ~(1<<INT1); //disable INT1

   TCCR1B = 1; //Start timer 1, prescaler=1
}

ISR(TIMER1_OVF_vect)
{
   if(phase == 0)
   {
      TCNT1 += 0xffff - 340; //One phase
      PORTA = 1; // set PA=1;
      phase = 1;
   }
   else
   {
      TCNT1 += 0xffff - (1100 - 340); // Zero phase
      PORTA = 0; // set PA=0;
      phase = 0;
   }
}



int main( void )
{

   DDRA = 0x01; //PA1 - output
   PORTA = 0;
      
   TIMSK |= (1<<TOIE1); //timer1 overflow interrupt enable
   TCNT1 = 0xffff - (1100 - 340); // Zero phase

   TCCR1B = 1; //Start timer 1, prescaler=1

    MCUCR = (1<<ISC00) | (1<<ISC01) | (1<ISC10) | (1<ISC11); //interrupts INT0,INT1 on rising edge
   GICR |= (1<<INT0) | (1<<INT1);  //enable INT0 and INT1
   sei(); //global interrupts enable
   for(;;); //main loop
   
   return 0;
}

Импульсы наблюдаются на PA0. Кварц под рукой был тока на 4МГц, поэтому время слегка отличается
tek00001.png
(5.47 КБ) 390 скачиваний
Все будет только лучше, в крайнем случае - хуже.
eufs
Опытный кот
Сообщения: 772
Зарегистрирован: Вс апр 10, 2011 02:24:06
Откуда: г.Северодонецк

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение eufs »

coredumped писал(а):
Gudd-Head писал(а):Как с помощью МК определить направление вращения энкодера, покрасивее и покомпактнее?
Энкодер двухбитный в коде Грея, т.е. последовательность 00-10-11-01 в одну сторону и 00-01-11-10 в другую.
Пока в голову не приходит ничего лучше, чем сравнивать прошлые 2 бита и новые 2 бита с константами (CPI с последующим BREQ на каждую константу) "0010", "1011", "1101" и "0100" в случае инкремента (условно); "0001", "0111", "1110" и "1000" в случае декремента.

Можно с помощью аппаратного прерывания по положительному фронту. Подаете первую ногу энкодера, например, на INT0. В обработчике считываете вторую ногу. Если 0 - то одно направление, если 1 - другое. Можно замутить внешний детектор на одном D-триггере. Полет фантазии безграничен :)

Чуть изношеный энкодер дает дребезг по фронтам, поэтому так делать нельзя. С аппаратным триггером на входе-это получится, но нужен еще один корпус. Так что для полетов не так и много места.
C0FFEE=‭12648430‬
Karusel
Родился
Сообщения: 5
Зарегистрирован: Вс фев 20, 2011 23:48:02

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Karusel »

Добрый день ребята :tea: ! Я к вам за помощью и советами-вот с утра вожусь со SPI интерфейсом на MEGA16 :sleep: ,никак не хочет нормально работать зараза. Собственно идея в том,чтобы передать сигналы 'A' и 'B' с одного МК на другой и переключать соответствующие светодиоды на ведомом МК-зеленый и желтый,т.е. нажимаешь одну кнопку-горит соответствующий светодиод,а другой светодиод выключается,нажимаещь другую-наоборот. :dont_know: где я ошибаюсь-не понимаю. Прикрепляю исходные коды и схему в ПРОТЕУСЕ. Заранее благодарю!
Вложения
SPI.zip
(45.71 КБ) 154 скачивания
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3868
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Engineer_Keen »

Во-первых у вас портD подтянут к +

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

ldi temp,0xFF
out PORTD,temp

И как тогда контроллер сообразит что кнопка нажата, если кнопки подключены тоже к +? Так что кнопки сажаем на землю и меняем sbic на sbis.
Ну и еще про антидребезг не забываем...
Karusel
Родился
Сообщения: 5
Зарегистрирован: Вс фев 20, 2011 23:48:02

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Karusel »

Engineer_Keen писал(а):Во-первых у вас портD подтянут к +

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

ldi temp,0xFF
out PORTD,temp

И как тогда контроллер сообразит что кнопка нажата, если кнопки подключены тоже к +? Так что кнопки сажаем на землю и меняем sbic на sbis.
Ну и еще про антидребезг не забываем...

Спасибо большое,щас исправим! :kill:
Аватара пользователя
teist
Открыл глаза
Сообщения: 61
Зарегистрирован: Пт янв 01, 2010 20:43:32
Откуда: cccp

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение teist »

подскажите пожалуйста насчет антидребезга, я так понял что бороться с ним
надо задержкой. а какую лучше выбрать. Например 0,1с подойдет?
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение coredumped »

teist писал(а):подскажите пожалуйста насчет антидребезга, я так понял что бороться с ним
надо задержкой. а какую лучше выбрать. Например 0,1с подойдет?

методов много, я использую следующий - читаем порт с задержкой 3 раза, если все 3 раза прочиталось одно и тоже, значит считаем, что событие произошло (нажатие кнопки или чего-то там еще дребезжащего). Задержку нужно выбирать в зависимости от кнопки. Обычно достаточно 10-50мкс. А Вы хотите в 10000 раз больше - это слишком "эстонское" устройство может получиться :) Поставьте 10 мкс, если будут ложные срабатывания, увеличьте.
Все будет только лучше, в крайнем случае - хуже.
Аватара пользователя
asteroid7
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 18, 2009 21:12:49

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение asteroid7 »

teist писал(а):... а какую лучше выбрать. Например 0,1с подойдет?

100 мс многовато.
12...14 мс - один опрос (удобно также для динамической индикации). 3 раза = истина.
eufs
Опытный кот
Сообщения: 772
Зарегистрирован: Вс апр 10, 2011 02:24:06
Откуда: г.Северодонецк

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение eufs »

Время подавления дребезга контактов умные дядьки рекомендуют делать некратным длительности периода сети и не менее 100мс. То есть ближайшее значение 110мс, затем 130, 150,170. А вот более 200 мс рекомендуют делать для узлов управления с повышенными внешними помехами. Например в автомобилях.
Я, как правило, делаю 150 мс. Если в течении этого времени активный уровень от контакта стабильный - контакт замкнутый.
C0FFEE=‭12648430‬
Аватара пользователя
VirZh
Встал на лапы
Сообщения: 86
Зарегистрирован: Вс фев 27, 2011 01:01:11
Откуда: Республика Крым

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение VirZh »

eufs писал(а):Время подавления дребезга контактов умные дядьки рекомендуют делать некратным длительности периода сети и не менее 100мс. То есть ближайшее значение 110мс, затем 130, 150,170. А вот более 200 мс рекомендуют делать для узлов управления с повышенными внешними помехами. Например в автомобилях.
Я, как правило, делаю 150 мс. Если в течении этого времени активный уровень от контакта стабильный - контакт замкнутый.


дребезг контактов - это время, за которое при нажатии на кнопку установится стабильное соединение (разъединение) контактов. Все зависит от самой кнопки, Например, подпружиненные срабатывают немного быстрее обычных. Как правило 20 мс хватает для всех случаев. 100-150 мс, как на мой взгляд, долговато. Здесь уже можно успеть нажать и отпустить кнопку, успешно приняв сигнал за дребезг... :) Борьба с помехами-это несколько другая ситуация, и тут надо смотреть в каждом случае отдельно...
Опыт и мудрость приходят с годами... К некоторым годы приходят одни...
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение coredumped »

eufs писал(а):Время подавления дребезга контактов умные дядьки рекомендуют делать некратным длительности периода сети и не менее 100мс. То есть ближайшее значение 110мс, затем 130, 150,170. А вот более 200 мс рекомендуют делать для узлов

Это кто рекомендует? Умные дядьки что курят? Че за бред? За секунду кнопку 10 раз нажать можно, ну ладно, любой и каждый 5 раз нажмет, а это 5 нажатий и 5 отпусканий. С таким подходом Ваш контроллер посчитает это дребезгом. Или Вы спутали милисекунды и микросекунды? Включите здравый смысл :)
Все будет только лучше, в крайнем случае - хуже.
eufs
Опытный кот
Сообщения: 772
Зарегистрирован: Вс апр 10, 2011 02:24:06
Откуда: г.Северодонецк

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение eufs »

VirZh писал(а):дребезг контактов - это время, за которое при нажатии на кнопку установится стабильное соединение (разъединение) контактов. Все зависит от самой кнопки, Например, подпружиненные срабатывают немного быстрее обычных. Как правило 20 мс хватает для всех случаев. 100-150 мс, как на мой взгляд, долговато. Здесь уже можно успеть нажать и отпустить кнопку, успешно приняв сигнал за дребезг... :) Борьба с помехами-это несколько другая ситуация, и тут надо смотреть в каждом случае отдельно...


20 мс, это очень мало. Да и не к чему. 50 раз в секунду никто кнопки нажимать не будет, а помехоустойчивость выше. Это я в руководстве по программированию МК лет 10 назад еще читал (еще для 51,но суть дела не меняет). Там очень тесно связывалась моторика и физиология человека с подобными вещами. Приводились выкладки зачем и почему выбираются те или иные интервалы.

Для Вас специально привожу пример, который запомнился оттуда же. Подготовленная реакция человека на событие (зажигается например светодиод и этого человек пристально ждет) лежит в диапазоне 100-150мс, а неподготовленная, то есть та, которая происходит внезапно - 300-500мс, а если пьяный, то до 2 сек доходит. Можете проверить это каким либо образом на себе. я убежден, что цифры правильные.
А теперь скажите, зачем делать подавление дребезга 20мс, если все равно никаких действий, чаще чем 10 раз в секунду (100мс) Вы все равно пальцами сделать не сможете, а даже если у вас это получится - все равно отреагировать на каждое нажатие неполучится. Проще и грамотнее делать автоповтор нажатия на кнопку.
По поводу нажал-отпустил за 100мс - аргумент еще проще - нафига было нажимать. Мы же заботимся об эргономике и помехоподавлении, а не об играх с кнопками.

http://www.navoprosotveta.net/03/03_2882.htm
http://2po.eu/blog/vremya-reakcii-i-kibersport/
C0FFEE=‭12648430‬
eufs
Опытный кот
Сообщения: 772
Зарегистрирован: Вс апр 10, 2011 02:24:06
Откуда: г.Северодонецк

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение eufs »

coredumped писал(а):
eufs писал(а):Время подавления дребезга контактов умные дядьки рекомендуют делать некратным длительности периода сети и не менее 100мс. То есть ближайшее значение 110мс, затем 130, 150,170. А вот более 200 мс рекомендуют делать для узлов

Это кто рекомендует? Умные дядьки что курят? Че за бред? За секунду кнопку 10 раз нажать можно, ну ладно, любой и каждый 5 раз нажмет, а это 5 нажатий и 5 отпусканий. С таким подходом Ваш контроллер посчитает это дребезгом. Или Вы спутали милисекунды и микросекунды? Включите здравый смысл :)

С таким подходом к школьному курсу физики Ваш контроллер вообще ничего не посчитает...Сколько в секунде миллисекунд?
C0FFEE=‭12648430‬
Ответить

Вернуться в «AVR»