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

Обсуждаем контроллеры компании Atmel.
Ответить
Друг Кота
Аватара пользователя
Сообщения: 4966
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Сообщение Seriyvolk »

Да, всё работает! Все 32 байтика шлются по ИК как в аптеке!
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

Поздравляю! :)
Docendo discimus
Контактная информация:
Реклама
Открыл глаза
Аватара пользователя
Сообщения: 52
Зарегистрирован: Пн май 27, 2013 17:02:32

Сообщение BlYur »

Здравствуйте.
В моей программе для ATMega8 таблица векторов прерываний выглядит следующим образом:

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

.cseg 				
         .ORG $000 
         RJMP   Init	; (RESET) Внешний сброс, сброс при подаче питания, сброс при недопустимом снижении питания, сброс сторожевым таймером
         .ORG $001
         RJMP INT0Intr  ; (INT0) Запрос на внешнее прерывание 0
         .ORG $002
         RETI           ; (INT1) Запрос на внешнее прерывание 1
         .ORG $003
         RETI		    ; (TIMER2 COMP) Срабатывание компаратора таймера-счетчика 2
         .ORG $004
         RJMP Tim2OVF   ; (TIMER2 OVF) Переполнение таймера-счетчика 2
         .ORG $005
         RETI		    ; (TIMER1 CAPT) Захват фронта таймером-счетчиком 1
         .ORG $006
         RETI           ; (TIMER1 COMPA) Срабатывание компаратора А таймера-счетчика 1
         .ORG $007
         RETI           ; (TIMER1 COMPB) Срабатывание компаратора В таймера-счетчика 1
         .ORG $008
         RETI           ; (TIMER1 OVF) Переполнение таймера-счетчика 1
         .ORG $009
         RETI           ; (TIMER0 OVF) Переполнение таймера-счетчика 0
         .ORG $00A
         RETI           ; (SPI,STC) Завершение последовательной передачи интерфейсом SPI
         .ORG $00B
         RETI           ; (USART,RXC) Завершение приема УСАПП
         .ORG $00C
         RETI           ; (USART,UDRE) UРегистр данных УСАПП свободен
         .ORG $00D
         RETI           ; (USART,TXC) Завершение передачи УСАПП
         .ORG $00E
         RETI		    ; (ADC) Завершение преобразования АЦП
         .ORG $00F
         RETI           ; (EE_RDY) Готовность EEPROM
         .ORG $010
         RETI           ; (ANA_COMP) Аналоговый компаратор
         .ORG $011
         RETI           ; (TWI) Двухпроводный Последовательный интерфейс
         .ORG $012
         RETI           ; (SPM_RDY) Готовность записи Памяти программ
          
	 .ORG   INT_VECTORS_SIZE      	; Конец таблицы прерываний
Обязательно ли в программе указывать эти ОРГи с адресами?
Ведь адреса следуют друг за другом в порядке возрастания без пропусков...
Друг Кота
Сообщения: 6014
Зарегистрирован: Чт ноя 26, 2009 11:16:50
Откуда: Москва

Сообщение SmarTrunk »

Конечно, необязательно, для АТмега8. Просто тут сделано все максимально "строго".
Без "оргов", если пропущена одна строчка, то будут проблемы - таблица сместится.

Вот для АТмега32, например, там операторы JMP и RETI имеют разную длину (32 и 16 бит), так что просто убрать "орги" не выйдет.

RETI тоже не обязательны, и написаны "на всякий случай" (которого не произойдет, в грамотно написанной программе).

.cseg тоже необязательно писать, т.к. по-умолчанию это так и есть. Нужно, только если перед этим было .dseg или типа того.

Вообще все это необязательно, если ни одного прерывания не используется. Просто начинаем писать программу с первой строчки.
Реклама
Эиком - электронные компоненты и радиодетали
Мудрый кот
Аватара пользователя
Сообщения: 1812
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Не обязательно. Но вдруг вы очепатку сделаете и напишете "JMP Tim2OVF" и у вас есть обработчик "TIMER1 CAPT". С org-ами компилятор ругнётся, а без вы будете париться искать ошибку...
Уже обсуждалось и не раз. Вот, например http://radiokot.ru/forum/viewtopic.php?f=57&t=72364
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4966
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Сообщение Seriyvolk »

Парни, привет всем опять! Нуждаюсь в толчке в нужном направлении. Опять-же протокол NEC, на этот раз нужно организовать его приём по ИК. Описание протокола я скидывал чуть выше, повторяться не буду.
Может кто-то подскажет, как это сделать красиво, и лучше бы на живом примере. :)
Сам дошёл до того, что по прерыванию сравниваю время паузы меду импульсами от большего к меньшему и по итогам сравнения уже идёт какое-либо действие (запись 1/0 в регистр и его сдвиг), но прерывание выходит очень громоздким, некрасиво как-то... Надеюсь на помощь. :)
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

Главный критерий - работоспособность. А что до
Seriyvolk писал(а):некрасиво как-то
на вкус и цвет товарищей, как известно, нет.
Docendo discimus
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

Тут http://radiokot.ru/forum/viewtopic.php?f=61&t=87127 я как то выкладывал свой вариант читалки на Си, думаю перевернуть для асма, проблем не составит...
Если сам не сможеш, помогу, как чуть время появится......
Друг Кота
Аватара пользователя
Сообщения: 4966
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Сообщение Seriyvolk »

pyzhman - главный критерий - аккуратность во всём, иначе я просто бы начал изучение МК с Си.
А то, что прерывание занимает больше, чем остальной код - хорошего ничего в этом нет.
shads, сейчас у меня нечто похожее и есть, но выглядит оно не сильно здорово, согласись.
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
akl
Друг Кота
Сообщения: 4473
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Seriyvolk писал(а):по прерыванию сравниваю время паузы меду импульсами от большего к меньшему и по итогам сравнения уже идёт какое-либо действие (запись 1/0 в регистр и его сдвиг)
По мне, определение длительности паузы приводит к необходимости двух разных типов прерываний - по фронту и по спаду. А вот если определять длительность посылки между двумя фронтами, то получается проще. Вот попробовал написать в предположении, что входной сигнал подается на вход INT0 и инвертирован по отношению к протоколу.
Спойлер

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

;TEST_Seriyvolk
      .include "tn13def.inc"   ; Используем Tiny13
   
.set   Fo=9600000 ; встроенный генератор 9.6MHz

;//////////////////////////////////////////////////////////////////////////////
;////////////                      ПЕРЕМЕННЫЕ                     /////////////
;//////////////////////////////////////////////////////////////////////////////
   .CSEG

;/////////////////////////////////////////////////////////
;//////////// ПРЕРЫВАНИЯ /////////////
;/////////////////////////////////////////////////////////
   RJMP   START
   IJMP         ; обслуживание прерывания посылки
   RETI
TIME_OVER:
   ADIW    XH:XL,1

   CP      R19,XL
   CPC      R18,XH
   BRLO   START
   RETI
;***********************************
ISR_INT_BEG:
   CLR	XH
   CLR	XL

   LDI   ZL,LOW(ISR_INT_END)

   RETI
ISR_INT_END:
   SET
   RET
;/////////////////////////////////////////////////////////
;//////////// ИНИЦИАЛИЗАЦИЯ /////////////
;/////////////////////////////////////////////////////////         
Start:
   LDI   R16,RAMEND
   OUT   SPL,R16

   CLR   ZH

   CLR   XH
   CLR   XL

   LDI   R16,0b00000010
   OUT   PORTB,R16
   OUT   DDRB,R16
   NOP
   OUT   DDRB,ZH

   LDI	R18,HIGH(120000/(1000000/(Fo/256))) ;порог для определения отсутствия
   LDI	R19,LOW (120000/(1000000/(Fo/256))) ;операций

   LDI	R20,HIGH(13000/(1000000/(Fo/256)))   ; длительность синхропосылки
   LDI	R21,LOW (13000/(1000000/(Fo/256)))   ; минус защитный интервал

   LDI   R16,0b00100010
   OUT   MCUCR,R16   ; разрешение прерывания по спаду INT0

   LDI   R16,$40
   OUT   GIMSK,R16   ; разрешение прерывания INT0

   LDI   R16,0b00000010
   OUT   TIMSK0,R16

   SER   R16
   OUT   TIFR0,R16
   OUT   GIFR,R16

   LDI   ZL,LOW(ISR_INT_BEG)
   LDI   R16,1
   OUT   TCCR0B,R16

   CLT
   SEI
WAIT_SINHRO:
   SLEEP
   BRTC   WAIT_SINHRO
   CLT

   CP      XL,R21
   CPC     XH,R20
   BRLO   START      ; не, это не синхропосылка
; принята синхропосылка
RESEIVE_CODE_BEGIN:

	CLR	R10
	CLR	R11
	CLR	R12
	CLR	R13		;очистить регистры приёма

	LDI	R22,32	; счётчик битов

GO_RESEIVE:

   CLR   XH
   CLR   XL

   LDI	R20,HIGH(1680/(1000000/(Fo/256))) ;порог для определения 1 или 0
   LDI	R21,LOW (16800/(1000000/(Fo/256))) ;

   SER   R16
   OUT   TIFR0,R16
   OUT   GIFR,R16

   LDI   ZL,LOW(ISR_INT_END)

   LDI   R16,1
   OUT   TCCR0B,R16

   CLT
   SEI
WAIT_CODE:
   SLEEP
   BRTC   WAIT_CODE
   CLT
; принят очередной бит

   CP      XL,R21
   CPC     XH,R20
   BRLO   SET_0      ; 
SET_1:
	SEC
	RJMP	SET_GND
SET_0:
	CLC
SET_GND:
	ROR	R10
	ROR	R11
	ROR	R12
	ROR	R13

	DEC	R22
	BRNE	GO_RESEIVE
; принят адрес и код команды
;
;
	RJMP   GO_RESEIVE
;	RJMP	START
;   END

18:30 Нашел ошибку при сравнении. :oops: Заменил код.
Последний раз редактировалось akl Вс янв 19, 2014 18:30:48, всего редактировалось 1 раз.
Друг Кота
Аватара пользователя
Сообщения: 4966
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Сообщение Seriyvolk »

Да, длительность посылки вполне реально определять между фронтами, а поскольку с ИК приёмника сигнал идёт инвертированным - фронты спадающие.
Идею почти понял, ща немного раскурю этот кусок кода и попробую воплотить его в жизнь :)
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

Seriyvolk писал(а):pyzhman - главный критерий - аккуратность во всём, иначе я просто бы начал изучение МК с Си.
Хотите сказать, что на Си не возможно писать аккуратно?
Seriyvolk писал(а):А то, что прерывание занимает больше, чем остальной код - хорошего ничего в этом нет.
Вообще то большой код в прерывании, совсем не означает, что оно выполняется долго (я так понял вы именно это имели ввиду)...
На сам деле, обычно туда включено много (коротких и быстрых) ветвей алгоритма... и именно поэтому код может кажется громоздким.....
Seriyvolk писал(а):Да, длительность посылки вполне реально определять между фронтами
В целом, вот как я решил у себя http://radiokot.ru/forum/viewtopic.php? ... 6#p1623176
Друг Кота
Аватара пользователя
Сообщения: 4966
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Сообщение Seriyvolk »

shads писал(а):В целом, вот как я решил у себя http://radiokot.ru/forum/viewtopic.php? ... 6#p1623176
В целом, на данный момент я имею крайне схожее решение, но оно мне не нравится.
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

Seriyvolk писал(а):
shads писал(а):В целом, вот как я решил у себя http://radiokot.ru/forum/viewtopic.php? ... 6#p1623176
В целом, на данный момент я имею крайне схожее решение, но оно мне не нравится.
Чем?
Друг Кота
Аватара пользователя
Сообщения: 4966
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Сообщение Seriyvolk »

Алгоритмом, вестимо. Так же вся борода обрабатывается в прерывании. Много сравнений/переходов и всяких других действий.
Хотите сказать, что на Си не возможно писать аккуратно?
Да, без знания основ - невозможно.
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

Seriyvolk писал(а):вся борода обрабатывается в прерывании.
И что из за этого у вас в программе страдает?
Seriyvolk писал(а):Много сравнений/переходов и всяких других действий.
По другому у вас получится калека, а не декодер...
Seriyvolk писал(а):Да, без знания основ - невозможно.
Согласен... основы не помешают :).....
Открыл глаза
Аватара пользователя
Сообщения: 52
Зарегистрирован: Пн май 27, 2013 17:02:32

Сообщение BlYur »

Здравствуй, РадиоКот.
Ты меня пока ни разу не подводил.
Уверен, что не подведёшь и сейчас.
Помоги мне, пожалуйста, а то я уже голову сломал.
Пишу часики на ассме.
Для ATMega16 всё написано, просимулировано, работает отлично, посмотреть можно тут.
Но решил я впихнуть свои часики в ATMega8, ибо жирновато им быть в 16-й Меге.
И тут появились траблы.
Во-первых, Протеус не может симулировать в реальном времени, ругается, что чрезмерная загрузка проца.
Во-вторых, 9-й и 10-й выводы контроллера походу работают в режиме GPIO (PB6, PB7), хотя настроены на работу с часовым кварцем.
Блин, но в проекте для ATMega16 таких проблем не возникало!!!
Где искать баги???
Ну и собстно прилагаю сам код, из которого вырезал всё лишнее, оставил только индикацию для одного семисегментника.
7segATmega8.rar
(33.5 КБ) 160 скачиваний
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

По-моему, Вы слишком рано выключаете разряд, нужно немного попозже, примерно одну четверть времени от полного цикла вывода всех четырех разрядов.

P.S. Организация дисплея конечно не очень. Посмотрите в протеусе, есть хороший пример с драйвером для семисегментника на асме, в папке C:\Program Files\Labcenter Electronics\Proteus 7 Professional\SAMPLES\VSM for AVR\AVR Tiny15 Demo, главное поймите как это работает
Последний раз редактировалось zero648 Чт янв 23, 2014 23:41:35, всего редактировалось 1 раз.
Мучитель микросхем
Аватара пользователя
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

Сообщение unalex »

BlYur писал(а):Протеус не может симулировать в реальном времени
в протеусе в свойствах контроллера указать CKSEL fuses - внешний кварц, и указать частоту кварца
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Друг Кота
Аватара пользователя
Сообщения: 4966
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Сообщение Seriyvolk »

Эт снова я! :)) По старой доброй традиции опять с проблемой...
Суть её такова: В регистре (допустим R25) имею число в диапазоне от нуля до 99 по десятичной системе. Мне это число нужно вывести на дисплей 44780, и всего-то.
Для вывода пользуюсь функцией, в переменную которой (R17) нужно загружать код символа перед выводом.
Т.е. примерно так:
LDI R17,0b00100000
DATA_WR //Вывели на дисплей пробел
DATA_WR //Вывели ещё один пробел
Может кто скажет, как это проще делается?
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Ответить

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