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

Обсуждаем контроллеры компании Atmel.
Ответить
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

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

ibiza11, я имел ввиду флаг конкретного прерывания. Исходя из сказанного вами, получается, что если хочется защититься от повторного прерывания, когда выполняется первое, можно в самом конце обработчика прерывания, перед reti, записать единицы в биты регистра GIFR, которые отвечают за прерывания?

Моя программа реализована по образу и подобию того, что лежит в обучалке. Вот её часть:
Спойлер

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

START OF DYNAMIC INDICATION CYCLE

IC:    ldi Temp1, 0b0010000 ;Включаем сегмент вывода ЕДИНИЦ
	   out PortD, Temp1
	   rcall LFSSM ;Вызов дешифровщика
	   com Display1
	   out PortB, Display1 ;Выводим код числа индикатора ЕДИНИЦ
	   
	   rjmp IC ;В начало цикла

LFSSM: ldi ZL, Low(SSM*2); Загрузка кода семисегментного числа
	   ldi ZH, High(SSM*2)

	   ldi Temp1, 0
	   add ZL, Counter1
	   adc ZH, Temp1

	   lpm
	   mov Display1, R0

	   ret

END OF DYNAMIC INDICATION CYCLE

;Seven Segmet Matrix
SSM:
     ;hgfedcba    hgfedcba 
.db 0b00111111, 0b00000110 ;0,1
.db 0b01011011, 0b01001111 ;2,3
.db	0b01100110, 0b01101101 ;4,5
.db	0b01111101, 0b00000111 ;6,7
.db	0b01111111, 0b01101111 ;8,9 

INT1_IRQ: inc Counter1
		cpi Counter1, 10
		breq res
                rjmp intend   

     res: ldi Counter1, 0

   intend:ldi Temp1, 0; Задержка
             ldi Temp2, 0

Loop2:    inc Temp1
	      brne Loop2
	      inc Temp2
	      brne Loop2
		  
	      reti
Alexeyslav, я еще не разобрался с тем, что такое EEPROM, чувствую, надо уже читать :)
Последний раз редактировалось Мikа Пн апр 29, 2013 09:50:15, всего редактировалось 1 раз.
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Мikа писал(а):можно в самом конце обработчика прерывания, перед reti записать единицы в биты регистра GIFR, которые отвечают за прерывания?
Да, перед выходом из прерывания сбросить флаг прерывания.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Alexeyslav писал(а):FLASH командой LD не читается, LD имеет доступ только к регистрам, портам ввода-вывода и RAM в едином адресном пространстве. общение с EEPROM - через порт ввода-вывода, с FLASH - через команды SPM/LPM.
Смотря на каком МК. В некоторых тиньках флэш доступен в адресном пространстве данных и нет команды LPM.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Держит паяльник хвостом
Аватара пользователя
Сообщения: 920
Зарегистрирован: Сб янв 16, 2010 15:34:57
Откуда: Sevsk/Moscow

Сообщение gauss »

Вопрос по ветвлениям на индексных переходах:
Имеется такой макрос:

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

.macro load
cli
ldi N,@0
lsl N
ldi ZL,low(Table*2)
ldi ZH,high(Table*2)
ldi r17,0
ldi r16,0
add ZL,N
adc ZH,r17
lpm r16,Z+	
lpm r17,Z
movw ZH:ZL,r17:r16
sei
ijmp	
.endmacro
В коде описана таблица:

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

Table: .dw RedOn,Greenon,BlueOn
- программа сюда не попадает!
Команды, которые надо выполнять, описаны отдельно:

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

Redon: SBI PortD,7
ret
Greenon: SBI PortD,6
ret
Blueon: SBI PortD,5
ret
В коде мы запускаем макрос:

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

load 0
load 1
Почему-то первый раз макрос выполняется, а все последующие - нет! В чем причина?
:idea:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

gauss писал(а):ijmp
...
ret
Может, icall?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

А пошаговое выполнение в отладчике что говорит? Перед этим - развернуть макрос, ибо отладчик не заходит внутрь макросов...

Да, и такой большой макрос имеет ли смысл делать макросом, может лучше подпрограммой? Проигрыш по времени выполнения - считанные такты, выигрыш по месту в коде - ВАГОН.
Контактная информация:
Реклама
Держит паяльник хвостом
Аватара пользователя
Сообщения: 920
Зарегистрирован: Сб янв 16, 2010 15:34:57
Откуда: Sevsk/Moscow

Сообщение gauss »

Помогло, спасибо!!
Просто читал на вот тут
и было ijmp.
:idea:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

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

Gudd-Head писал(а):
Мikа писал(а):можно в самом конце обработчика прерывания, перед reti записать единицы в биты регистра GIFR, которые отвечают за прерывания?
Да, перед выходом из прерывания сбросить флаг прерывания.
Сейчас дописал строчки

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

ldi Temp1, 0b10000000
		  out GIFR, Temp1
		  
		  reti
Но ничего не меняется. Если 3 раза быстро нажать кнопку, выведется число на 3 больше. Будто бы сработало 3 прерывания. Но хотя бы одно из них должно же быть сброшено?
Последний регистр, имеющий отношение к внешним прерываниям, - это статусный регистр GIFR (General Interrupt Flag Register). В нем содержатся флаги, устанавливаемые в случае формирования запроса на внешнее прерывание.
Флаги сбрасываются аппаратно, когда вызывается обработчики прерываний. Также их можно сбросить программно, записав в регистр единицы.

Изображение
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Друг Кота
Аватара пользователя
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Мikа писал(а):Если 3 раза быстро нажать кнопку, выведется число на 3 больше.
На словах объясните, как вы реализуете антидребезг.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

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

или у тебя в прерывании реализована задержка в одну секунду?
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

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

Конечно, есть задержка. Точное её время я не могу сказать, тк ещё не трогал раздел частоты работы контроллера. Но так, на глазок, это примерно секунда. Цикл задержки находится в конце обработчика прерываний. Выглядит так:

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

 
intend:ldi Temp1, 0; Задержка
          ldi Temp2, 0

Loop2:inc Temp1
	  brne Loop2
	  inc Temp2
	  brne Loop2
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

А рабочая частота контроллера? Этот цикл примерно около полумилиона тактов, при частоте тактовой 1Мгц это будет пол секунды, а при большей естественно гораздо меньше.
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

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

Частота та, которая была в нём изначально. Наверное, это 1 Мгц. То есть да, задержка примерно половина секунды.
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 330
Зарегистрирован: Чт июн 23, 2011 07:55:51

Сообщение korsaj »

Антидребезг можно реализовать след образом: в прерывании от нажатия кнопки запускаем таймер на 50-100 и отключаем прерыв от нажатия. Далее спустя 50-100мс в прерывании от таймера проверяем кнопку, если нажата, ставим флаг нажатия и считаем колво прерываний от таймера пока кнопка нажата, если остается нажатой 300мс то вновь устанавливаем флаг нажатия, если в одном из прерыв от таймера кнопка будет отжата то разрешаем прерыв от кнопки и запрещаем от таймера.
А в основной проге проверяем флаг. Конечно, если кнопкой управляется одна переменная, то флаг не нужен прям переменную и изменяем в прерывании.
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Какой хороший способ довести человека который будет пользоваться схемой... 300мс на реакцию на нажатие кнопки... ужас.

Чтобы подавить дребезг вполне достаточно считывать кнопки по таймеру каждые 10мс. И либо сразу же выполнять действия, либо отражать в память для последующего использования в программе.
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 330
Зарегистрирован: Чт июн 23, 2011 07:55:51

Сообщение korsaj »

Вообще то 50-100, а вот 300 это авто повтор нажатия при удержании.
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

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

Я не вник на 100% в описанный способ антидребезга, но почему нельзя просто в самом начале обработки прерывания поставить задержку на 50 мс (могу путать число)?

********_________
Дребезг**********\/\/\/\/\/\_____________
Задержка*********|____50_мс______|

-----------------------------------------------------> T

* - типа пробелы

Или просто выключить прерывание по данному событию зная, что цикл его обработки больше времени дребезга, а в конце обработчика снова его включить? И утановить флаги фигова GIFR, установка которого, кстати, мне так ничего и не дала. Истина где-то рядом :)
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Друг Кота
Аватара пользователя
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Мikа писал(а):почему нельзя просто в самом начале обработки прерывания поставить задержку на 50 мс?
Потому что при отпускании кнопки тоже будет дребезг. А сколько будет по времени будет нажата кнопка, вы знать заранее не можете.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

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

Вот про отпускание кнопки я не подумал, спасибо!

Надо воткнуть оптопару, она дребезжать не будет :)
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Друг Кота
Аватара пользователя
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

Мikа писал(а):Надо воткнуть оптопару
А чем бездребезговым светодиод оптопары поджигать будете? :) Проще кондёров навесить.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Ответить

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