макрос задержки на Таймере

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 7
Зарегистрирован: Ср окт 12, 2011 21:52:06

Сообщение krup »

Здравствуйте, решил создать на ассемблере макрос задержки на 1 таймере тини2313. И не могу понять почему в протеусе 1 задержка срабатывает, все остальные нет... вот сам макрос

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

; Delay задержка на 16 битовом таймере без обработки прерываний
.macro delay ;1-старший регистр 2 младший регистр 3-делитель частоты
		output OCR1AH,@0 ;закидываю старший бит для сравнения 
		output OCR1AL,@1 ;младший

		clr R16
		out TCNT1H,R16 ;очищаю счетный регистр
		out TCNT1L,R16
		output TCCR1B,@2; запуск таймера1 при делиели @2
	cikl:
		in R16,TIFR ;в хожу в цикл и жду срабатывания флага в регистре TIFR 
		sbrs R16,6
		rjmp cikl

		sbr  r16,64    ;сбрасываю 6 бит!запись 1 в бит!!!!!!! вот моя ошибка здесь была
		out TIFR,r16
		output TCCR1B,0; вырубил таймер
.endm
а это в основном цикле для проверки:

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

main:
			sbi PORTB,0
			delay 0xf4,0x24,3 ;частота 8мгц делитель 64 число 62500 для 0.5 сек

			cbi PORTB,0
			delay 0xf4,0x24,3
			rjmp main
а вот что в протеусе получилось:
Вложения
Безымянный.jpg
(80.78 КБ) 608 скачиваний
Последний раз редактировалось krup Пн янв 13, 2014 17:43:59, всего редактировалось 2 раза.
Реклама
Держит паяльник хвостом
Аватара пользователя
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Сообщение Goodefine »

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

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

clr  r16    ;сбрасываю регистр
      out TIFR,r16
Соответственно, флаг остается, и при последующем входе в макрос, задержка

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

cikl:
      in R16,TIFR ;в хожу в цикл и жду срабатывания флага в регистре TIFR
      sbrs R16,6
      rjmp cikl
не срабатывает, поскольку флаг все еще стоит, с первого запуска
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Реклама
Родился
Сообщения: 7
Зарегистрирован: Ср окт 12, 2011 21:52:06

Сообщение krup »

круто, работает спс большое! :)) шапку исправлю может комуто пригодится
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

Сообщение nirq »

"Самурай с мечо банальное зацикливание с употреблением таймера подобно банальному зацикливанию без употребления таймера, но только с употреблением таймера".

Получилось не "программисты шутят", не "ногой ухо чесать", не колхоз и даже не индусский подход, а изврат ради потому что нууу... ну ведь работает же!
И (самое главное): так короче писать. Потому что макрос. Профи юзают макросы.


Независимо от:

- magic numbers;
- high(), low().
Реклама
Эиком - электронные компоненты и радиодетали
akl
Друг Кота
Сообщения: 4468
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

krup
Замечу. Командой

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

  sbr  r16,128    ;сбрасываю 6 бит!запись 1 в бит!!!!!!! вот моя ошибка здесь была
      out TIFR,r16
      output TCCR1B,0; вырубил таймер
будет очищен флаг переполнения TOV1; OCF1A сбрасывается командой

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

  sbr  r16,64
      out TIFR,r16    ;сбрасываю 6 бит!запись 1 в бит!!!!!!! вот моя ошибка здесь была
---------------------

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

      output TCCR1B,0; вырубил таймер
:dont_know: Мечта, а не команда.
Реклама
Родился
Сообщения: 7
Зарегистрирован: Ср окт 12, 2011 21:52:06

Сообщение krup »

nirq, если есть что то лучше циклов, поделись пожалуйста. Мне показался макрос удобным потому, что я раньше все задержки циклами писал, высчитывал....
akl, да посчитав на пальцах :)) понял ошибку в маске :)) , но протеус показывал то, что я хотел. И я думал если пред делитель равен 0 , таймер вырубается?
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15752
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Различие макроса и подпрограммы - макрос всегда прописывается кодами, где бы и сколько раз не вставлялся (нет экономии ПЗУ), подпрограмма прописывается кодами только один раз, а вызывается сколь угодно командой CALL name.
Второе - задержка набирается из системной сетки "тиков" задаваемых таймером (режим ожидания флага переполнения/тика) коротко и без излишних перезагрузок. Другое дело, если надо различные интервалы считать. Но тогда режим таймера надо более приятный подобрать, например "сброс по совпадению"...
Родился
Сообщения: 7
Зарегистрирован: Ср окт 12, 2011 21:52:06

Сообщение krup »

то есть пишу похожую подпрограмму, а вызов подпрограммы с аргументами пишу в макросе?
Вымогатель припоя
Сообщения: 506
Зарегистрирован: Пн авг 31, 2009 22:10:50
Откуда: СК

Сообщение Шурики »

Посмотрите файл листинга после компиляции, всё станет понятно.
Ну не зря же это удобство для программиста сделали...
Друг Кота
Аватара пользователя
Сообщения: 15752
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

krup писал(а):то есть пишу похожую подпрограмму, а вызов подпрограммы с аргументами пишу в макросе?
Можно и так, только вот таймеры сколь угодно много на ячейках ОЗУ делаются, а их значения по надобности меняются системным тиком и набором служебных флагов. ТИК один а таймеров/событий много. :sleep:
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

Сообщение nirq »

krup писал(а):лучше циклов
Прерывания (interrupt).
Обратить внимание на слово "приоритет", помедитировать карандашом на бумажке: квадратики, стрелочки... можно даже в виде "официальной" блок-схемы.

Ход мысли: в сколь-нибудь интересной системе действия выполняются не линейно по кругу "от печки до забора, повторить" - а как бы в виде дерева с ветвями.

"Обновляем дисплей в цикле / пришёл импульс на вход, всё бросаем срочно обрабатываем пришедший импульс / обработали импульс, продолжаем обновлять дисплей / закончена передача байта на выход, всё бросаем, готовим и отправляем следующий байт / пришел ещё один импульс на вход, надо и его тоже срочно обработать, но мы заняты отправкой байта, а импульс будет обработан чуть позже либо пропущен / опять появилось свободное время, возвращаемся к обновлению дисплея, но он (дисплей) неравномерно мерцает / пользователь нажал кнопку и сразу отпустил / пользователь нажал кнопку и держит / энкодер..." - параллельные процессы.
Но микросхема не может выполнять две команды одновременно - в любой момент времени выполняется ровно одна команда. А процессы параллельные. И одно действие нельзя задерживать, и другое событие нельзя пропускать.
Ответить

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