Обсуждаем контроллеры компании Atmel.
Ответить

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

Пт янв 07, 2022 14:42:42

BOB51, вот честно. Мне проще взять МК потолще и написать на Си, нежели считать байты флеша и писать на ассемблере. Просто быстрее выходит.
Но знание асма и архитектуры АВРки позволяет критичные участки писать на си аккуратно. И не наступать на грабли с атомарностью, например.

А с I2C - повторюсь, достаточно проверить АСК при отправке адреса. А дальше проверки не нужны. Ведомый отозвался - ура, работаем на ожиданиях. Не отозвался - показать пользователю ЕГГОГ.

a1000, для DS18B20 тоже делайте на ожиданиях, не забыв запретить прерывания на период чтения/записи одного бита и отсчитывания таймингов.
Тайминги сделайте на циклах. 15 мкс получится на однобайтовом цикле - это 240 тактов при 16 мгц (я выше кидал примерный алгоритм цикла). Стартовое значение счетчика цикла либо посчитать по тактам, либо подобрать в эмуляторе студии. 45 мкс - три раза дернуть задержку 15 мкс. 480 мкс - 32 раза по 15 мкс.
Обратите внимание - сброс-пауза-ожидание presence должно быть атомарным блоком, т.е. перед сбросом запретить прерывания, а разрешить только после проверки presence.
Чтение/запись бита тоже должно быть атомарным - запретить прерывания, прижать линию на 15/45 мкс (при записи) или на 15 мкс, отсчитать 45 и посмотреть что на линии (при чтении), потом разрешить прерывания.

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

Пт янв 07, 2022 15:04:05

GoldenAndy писал(а):Ведомый отозвался - ура, работаем на ожиданиях.
я очень дико извиняюсь - о каких ожиданиях вы тут говорите? если я правильно помню, то в и2ц после того, как сделал нужный фронт SCL, можно сразу читать SDA - задержки там будут настолько малые, что ожидания не потребуется. возможно, один NOP... и то не уверен, что на самом деле необходимо. (давно с и2ц работал, пишу по воспоминаниям)

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

Пт янв 07, 2022 15:23:07

ARV, сформировали старт, подождали , пока в статусном регистре старт не подтвердится. Это быстро.
А вот чтение/запись данных - тут надо ждать, ибо формирование SCL, чтение/запись SDA делает блок TWI самостоятельно. Все 8 бит.
Т.е. отправили байт адреса - ждем, пока он отправится и прилетит/не прилетит АСК.
Это 9 тактов несущей i2c. для 400 кГц - это 22.5 мкс. Вот эти 22.5 мкс можно протупить в ожидании или заняться своими делами.

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

Пт янв 07, 2022 15:28:53

I2C штука медленная - 100/400 кГц поэтому и вставляем задержки.
Одна из версий программного лаподрыга с учетом возможных ошибок (из старых коллекций библиотечек-заготовок)
Спойлер
Код:
;
;     "av_i2c.txt"  файл обработчика шины I2C
;    лаподрыг под AVR при системной частоте 1МГц
;       (0,000001S/одноцикловая команда)
;
;----------
;      заготовка программного модуля
; для обработки кристаллов с интерфейсом I2C
; асинхронный режим обмена,
; вплоть до полного останова в процессе работы.
; линии данных и строба настроены на вход с Z
; при внешнем подтягивающем резисторе
; (статус МК по умолчанию после сброса при подаче питания)
;
; ---------- константы/флаги ----------
;
 .equ i2c_sda = 7 ; позиционный номер линии SDA
 .equ i2c_scl = 6 ; позиционный номер линии SCL
 .equ i2c_sqw = 2 ; позиционный номер линии SQVOUT
 .equ f_Ai2c = 0 ; интерпритатор статуса сигнала ACK
 .equ f_Ei2c = 1 ; флаг ошибки обмена
 .equ i2c_t4 = 8 ; интервал задержки
      ; 1/4 длительности строб-импульса приема/передачи
 .equ i2c_dcte = 5 ;0x5F ; константа для счетчика интервала ошибок
;
;----------
;
;таблица обьявленных имен - переназначение регистров РОН
 #ifndef disposit
;
;             принята базовая модель:
; область ограниченного функционала
; .def mfr0 = r0  ;(математика и обмен с ПЗУ/самопрограммирование)
; .def mfr1 = r1  ;(математика и обмен с ПЗУ/самопрограммирование)
; .def s_sreg = r2 ; зеркало SREG(ограниченный функционал)
; .def sys_flag = r3 ; системные флаги(ограниченный функционал)
; .def  = r4 ;(ограниченный функционал)
; .def  = r5 ;(ограниченный функционал)
; .def  = r6 ;(ограниченный функционал)
; .def  = r7 ;(ограниченный функционал)
;
; .def  = r8 ;(ограниченный функционал)
; .def  = r9 ;(ограниченный функционал)
; .def  = r10 ;(ограниченный функционал)
; .def  = r11 ;(ограниченный функционал)
; .def  = r12 ;(ограниченный функционал)
; .def  = r13 ;(ограниченный функционал)
; .def  = r14 ;(ограниченный функционал)
; .def  = r15 ;(ограниченный функционал)
;
; область полного функционала
 .def tmp0 = r16 ; рабочий регистр(полный функционал)
 .def tmp1 = r17 ; рабочий регистр(полный функционал)
 .def tmp2 = r18 ; рабочий регистр(полный функционал)
 .def tmp3 = r19 ; рабочий регистр(полный функционал)
 .def tmp4 = r20 ; рабочий регистр(полный функционал)
 .def tmp5 = r21 ; рабочий регистр(полный функционал)
 .def tmp6 = r22 ; рабочий регистр(полный функционал)
 .def tmp7 = r23 ; рабочий регистр полный функционал)
;
 .def Bl = r24 ; "указатель базы"(полный функционал)
 .def Bh = r25 ; "указатель базы"(полный функционал)
;     Xl = r26 ; адрес сегмента Х (полный функционал)
;     Xh = r27 ; адрес сегмента Х (полный функционал)
;     Yl = r28 ; адрес сегмента Y (полный функционал)
;     Yh = r29 ; адрес сегмента Y (полный функционал)
;     Zl = r30 ; адрес сегмента Z (полный функционал ПЗУ/самопрограммирование)
;     Zh = r31 ; адрес сегмента Z (полный функционал ПЗУ/самопрограммирование)
; регистры Xh:Xl, Yh:Yl, Zh:Zl определены в дефайне изготовителя и в системе команд
; изменение их имени хотя и возможно, но нежелательно -
; возникает путаница с интегрированной абревиатурой системы команд
;  в случае с "малой моделью" допускающей/достаточной для размещения ВСЕХ
; используемых ВСЕМИ подпрограммами регистров в области СОЗУ регистрового
; файла одновременно (без "подкачки" наборов параметров через ОЗУ)
; рекомендовано переназначение индивидуальных имен регистров
; согласно текущей задачи
;
 #endif
;
;----------
; секция переназначения регистров или портов РСФ
;
;----------
; !!! порты требуется указать в соответствии с конкретной схемой !!!
;
 #define i2c_ddr DDRB ; переприсвоение регистра режима порта DDRх
 #define i2c_port PORTB ; переприсвоение регистра порта PORTх
 #define i2c_pin PINB ; переприсвоение регистра выводов порта PINх
;----------
 #define i2c_dat tmp0 ; буфер ввода/вывода данных
 #define i2c_cntb tmp1 ; счетчик бит ввода/вывода
 #define i2c_tm tmp2 ; счетчик задержки 1/4 стробимпульса
 #define i2c_cnte tmp3 ; счетчик ошибок обмена/ожидания ответа
 #define i2c_flag tmp4 ; флаги протокола обмена
; #define i2c_adrl tmp5 ; буфер младшей части начального/целевого адреса
;
;----------
;
; ----- собственно утилиты -----
;
 .CSEG
;----------
; отработка интервала 1/4 длительности
; строб-импульса приема/передачи
;
tm4i:
  ldi i2c_tm,i2c_t4 ;
l_tm4i:
  dec i2c_tm ;
  brne l_tm4i
  ret
;
;----------
; stop2 - п/п генерации стоп-условия для шины и2с
; эта же программа при необходимости выполняет функционал
; "горячей переинициализации" (reinit)
;
;вызов acall stop2 , используемый регистр tm2i, передаваемых
;параметров нет, при входе:
; i2c_sda=?
; i2c_scl=0
; по выходу i2c_sda=i2c_scl=Z&1
;
stop2:
  sbi i2c_ddr,i2c_sda ; line i2c_sda=0 страховка
  rcall tm4i ;
  cbi i2c_ddr,i2c_scl ; line i2c_scl=Z&1
  rcall tm4i ;
  rcall tm4i ;
  cbi i2c_ddr,i2c_sda ; line i2c_sda=Z&1
  rcall tm4i ;
  ret
;
;----------
; restar - "повторный старт" (Sr-условие) протокола I2C
;
;(желательно разместить в блоке п/п работы
; с I2C, чтобы избежать "длинные"
; вызовы для субблоков strob)
;
restar:
  cbi i2c_ddr,i2c_sda ;line i2c_sda=Z&1 ; страховка
  rcall tm4i ;
 lwait:
  sbis i2c_pin,i2c_sda ; ждем подтверждение ведомого
  rjmp lwait ; line i2c_sda=1
  rcall tm4i ;
  cbi i2c_ddr,i2c_scl ; line i2c_scl=Z&1
  rcall tm4i ;
;----------
; start2 - п/п генерации старт-условия для шины и2с
; является завершающей частью подпрограммы restar
;вызов rcall start2 , используемый регистр i2c_tm, передаваемых
;параметров нет, по умолчанию исходно:
; i2c_ddr.i2c_sda = 0
; i2c_port.i2c_sda = 0
; line i2c_sda = Z&1
; i2c_ddr.i2c_scl = 0
; i2c_port.i2c_scl = 0
; line i2c_scl = Z&1
; по выходу line i2c_sda = line i2c_scl = 0
;
start2:
  rcall tm4i ;
  sbi i2c_ddr,i2c_sda ;line i2c_sda=0
  rcall tm4i ;
  rcall tm4i ;
  sbi i2c_ddr,i2c_scl ;line i2c_scl=0
  rcall tm4i ;
  ret
;
;----------
;  ---- strob SCL ----
;
strob2i:
  rcall tm4i ;acall tm4i
  cbi i2c_ddr,i2c_scl ; line i2c_scl=Z&1
  rcall tm4i ;acall tm4i
  rcall tm4i ;acall tm4i
  sbi i2c_ddr,i2c_scl ; line i2c_scl=0
  rcall tm4i ;acall tm4i
 ret
;
;----------
; rxb2 - программа для приема байта по протоколу и2с
;
; вызов = rcall rxb2
; статус ACK=0 генерируется в случае,
; если перед вызовом rxb2 был установлен
; f_Ai2c=1 (последний в текущем пакете rxb2
; устанавливает статус ACK=1(NO_ACK) при f_Ai2c=0 )
; по выходу
; i2c_dat = принятый байт
; i2c_sda=Z&1(1), i2c_scl=0
;
rxb2:
  ldi i2c_cntb,8 ; загрузить счетчик бит приемника
  cbi i2c_ddr,i2c_sda ; ориентировать line i2c_sda(как вход)=Z&1
  nop ;
  nop ;
loopr2:
  rcall tm4i ;acall tm4i ; задержка в 1/4 строб-импульса
  cbi i2c_ddr,i2c_scl ; line i2c_scl=Z&1 начало строб-импульса
  rcall tm4i ; задержка в 1/4 строб-импульса
  sbis i2c_pin,i2c_sda ; читать текущий статус line i2c_sda
  clc
  sbic i2c_pin,i2c_sda
  sec
  rol i2c_dat ; продвижка i2c_dat влево
  rcall tm4i ; задержка в 1/4 строб-импульса
  sbi i2c_ddr,i2c_scl ; конец строб-импульса line i2c_sda остается=Z&1
  rcall tm4i ; задержка в 1/4 строб-импульса
  dec i2c_cntb ; счетчик бит ввода/вывода -1
  brne loopr2 ; повторять до исчерпания i2c_cntb
  sbrc i2c_flag,f_Ai2c ; если i2c_flag.f_Ai2c=0 продолжить от noack
  rjmp off0 ; если i2c_flag.f_Ai2c=1 то переход на off0
noack:
  rcall tm4i ; задержка в 1/4 строб-импульса
  rcall strob2i ; выполнить строб на line i2c_scl
  rcall tm4i ; задержка в 1/4 строб-импульса
 ret
off0:
  cbr i2c_flag,1<<f_Ai2c ; сбросить f_Ai2c
  sbi i2c_ddr,i2c_sda ; установить line i2c_sda=0
  rcall tm4i ; задержка в 1/4 строб-импульса
  rcall strob2i ; выполнить строб на line i2c_scl
  rcall tm4i ; задержка в 1/4 строб-импульса
  rcall tm4i ; задержка в 1/4 строб-импульса
  cbi i2c_ddr,i2c_sda ; установить line i2c_sda=Z&1
  nop ;
  nop ;
 ret
;
;----------
; txb2 - программа для передачи байта по протоколу и2с
;
; вызов = rcall txb2
; перед вызовом txb2 разместить
; в i2c_dat пересылаемый байт
; фрагмент "контроль 1" по завершению ACK слэйва не
; проводится в случае, если была передана команда
; чтения данных - перед вызовом rcall txb2 был установлен
; флаг i2c_flag.f_Ai2c=1
; по выходу
; i2c_dat=0
; i2c_sda=Z&1(1), i2c_scl=0
; i2c_flag.f_Ai2c=0, i2c_flag.f_Ei2c=??
; (i2c_flag.f_Ei2c=1 в случае ошибки обмена
;   типа "ведомый не отвечает")
;
txb2:
  cbr i2c_flag,1<<f_Ei2c ; очистка f_Ei2c =0
  ldi i2c_cnte,i2c_dcte ; загрузка счетчика интервала ошибок
  ldi i2c_cntb,8 ; загрузить счетчик бит передатчика
  nop ;
  nop ;
loopt2:
  sbi i2c_ddr,i2c_sda ; установить line i2c_sda=0 (0)
  lsl i2c_dat ; текущий бит данных в СY
  brcc loopt21 ; если СY=0 оставить line i2c_sda=0
  cbi i2c_ddr,i2c_sda ; иначе установить line i2c_sda=Z&1 (1)
loopt21:
  rcall strob2i ; тело строба передачи
  dec i2c_cntb ; счетчик бит ввода/вывода -1
  brne loopt2 ; повторять до исчерпания i2c_cntb
askont:
  cbi i2c_ddr,i2c_sda ; установить line i2c_sda=Z&1(как вход)
lpask1:
  rcall tm4i ; задержка в 1/4 строб-импульса
  sbis i2c_pin,i2c_sda ; проверка на ответ ведомого (SDA=0)
  rjmp eask ;jnc eask ; продолжать при line i2c_sda=0 от eask
  dec i2c_cnte ; счетчик интервала ошибок -1
  brne lpask1 ; продолжать от lpask1 до исчерпания с-ка повторов
 extbof:
  sbr i2c_flag,1<<f_Ei2c ; установить флаг ошибки обмена f_Ei2c=1
 txbof:
  cbr i2c_flag,1<<f_Ai2c ; контрольный сброс f_Ai2c=0
  rcall tm4i ; задержка в 1/4 строб-импульса
  ret ; по выходу i2c_sda=1, i2c_scl=0
 eask:
  ldi i2c_cnte,i2c_dcte ; перезагрузить счетчик ошибок
  rcall strob2i ; тело 9-го строба передачи (поддержки сигнала AСK)
  sbrc i2c_flag,f_Ai2c ; при f_Ai2c=1 проверка на ответ ведомого (SDA=1)
  ; НЕ ПРОВОДИТСЯ!
  rjmp txbof ; переход мимо анализа ответной 1
lpask2:
  rcall tm4i ; задержка в 1/4 строб-импульса
  sbic i2c_pin,i2c_sda ; проверка на ответ ведомого(SDA=1)
  rjmp txbof ; при нормальном завершении продолжить от TXBOFF
  dec i2c_cnte ; счетчик интервала ошибок -1
  brne lpask2 ; продолжать от lpask2 до исчерпания с-ка повторов
  rjmp extbof ; при ошибке ответа ведомого продолжить от ETXBOF
;
;----------

:sleep:

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

Пт янв 07, 2022 15:29:50

Мне в этом плане нравится либа ДиХальта (не знаю, есть ли она на асме) i2c ultimate. Там скармливается режим, объем данных и адрес буфера. И подается старт. А дальше оно в фоне на прерываниях само отработает и выдаст коллбеком результат.

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

Пт янв 07, 2022 15:32:06

Это уже забота обработчика.
У меня там только минимальный драйвер приема-передачи.
8)

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

Пт янв 07, 2022 16:46:38

GoldenAndy писал(а):А вот чтение/запись данных - тут надо ждать, ибо формирование SCL, чтение/запись SDA делает блок TWI самостоятельно.
вот сроду TWI не применял, даже не пробовал, всегда хватало программного дрыгонога

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

Пт янв 07, 2022 21:16:13

ARV, ну мне наоборот, проще аппаратный TWI использовать. Хотя в каком то проектике пришлось программный i2c делать.там да, тупой ногодрыг на задержках.

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

Сб янв 08, 2022 11:08:14

Не у всех МК (тем более "устаревших" или малолапых да из других семейств) имеется аппаратный TWI.
Дополнительные минусы - практически обязательное наличие еррат и, как результат, необходимость детального изучения конкретного модуля в конкретной версии выбранного МК, невозможность переброса выводов для более удобной разводки монтажа.
Так что алгоритмы и библиотеки с программным ногодрыгом всегда актуальными будут.
8)

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

Пн янв 10, 2022 18:07:31

что касается последних сообщений, касающихся LD, то меня просто возмущает отсутствие желания у вопрошающего прочитать о системе команд AVR.

Злой ты какой то... :)
Изображение
Да я знаю что я ленивая свинья. Но свинья с чувством юмора,могущая посмеяться над собой
и над обстоятельствами.И способная, и с интеллектом выше среднего.Да если хотите знать,я самая лучшая в мире свинья! 8) :))
Последний раз редактировалось главный колбасист Пн янв 10, 2022 20:58:46, всего редактировалось 1 раз.

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

Пн янв 10, 2022 19:44:56

Не злой, а солидный (учёный КОТЯРА)!
Положено мелких КОТЯТОК носом в миску тыкать.
8)

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

Пн янв 10, 2022 20:30:57

BOB51, оффтопик.
У нас есть кошка.
Когда ей было 7 лет - взяли еще одну кошку-подростка. Уличную бандитку 6-7 месяцев.
Когда это малолетнее, отпихнув старшую, полезло в ее миску - старшая сделала просто. Лапой эту молодую мордой в миску - и держала. Хватило одного раза, что бы малая не лезла.

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

Пн янв 10, 2022 21:30:46

Были времена когда мы под стол пешком ходили и не знали сколько дважды два будет,не то что
подпрограммы какие то там. :shock: Над нами насмехались родители(старшие),мол какой ты тупой,че книжки
не читаешь? :) Да,лень,знаю.
Просто был переход по условию rjmp на метку,смотрю, rcall точно так же переходит ,и невдомек было
что он че то там сохраняет в стеке адрес текущей команды ,и еще в три такта,пока не начала вылазить
ошибка переполнения в симуляторе.

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

Пн янв 10, 2022 22:57:58

главный колбасист, ну вот я не верю что вы ученик 6 класса, когда информатику еще не читают. И что понятия цикл, подпрограмма, процедура/функция вам в школе не объясняли.
(Даже на микрокалькуляторах МК-61 были команды БП и ПП... Безусловный Переход и ПодПрограмма )
И мнемоники jmp (jump) и call в переводе с иноземного - прыжок и вызов - ни на что не намекают?
Учить ассемблер методом ненаучного тыка можно, но сложно. Гораздо проще прочитать какую то книжку, а их по асму АВРок вагон и тележка... Причем на русском языке...

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

Вт янв 11, 2022 10:33:41

А есть еще и хитрые
ICALL
IJMP
Да условный возврат с подстановкой адреса через стек.
(у I8080 проще было - там набор команд возврата по флагам условий)
8)

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

Чт янв 13, 2022 14:07:30

Книжек целая коллекция уже,Белов,Мортон,Ревич,Шпак,и т.д. Че то в сон тянет,через минут двадцать,вот прям напасть какая то.Ничего не могу с собой сделать.С AVR-студией чуть веселее,там активного диалога требует,но тоже через пол часа начинаешь позевывать.
А вот скажите пожалуйста,где в сервоприводе XD-15-TN и им подобных,омрон,настройки коммуникации
по rs485 ? Понимаю что не в тему.Проблема у меня с прошлой осени.В англоязычном мануале 333стр. этот раздел почему то отсутствует. Специализированные форумы не помогли. пока.

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

Чт янв 13, 2022 14:24:54

главный колбасист, вы во все темы на форуме будете пихать свой вопрос про XD-15-TN ?
В Котуинку написали, теперь тут....
Сделайте отдельную тему уже - если кто знает - в новой теме увидит быстрее...

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

Вс янв 16, 2022 21:59:56

Изображение

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

куда дели мою мадмуазель кики? :)

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

Вс янв 16, 2022 23:14:18

главный колбасист, И чито?
Примите это как маркетинговый ход и получите 16 ассемблерных мнемоник по цене 2 команд.
Не, ви таки конечно можете писать brbs/brbc, но таки вам потом тяжелее будет разобраться...

Мало того я вам открою страшную-престрашную тайну (которую из Мальчиша-Кибальчиша так и не смогли выбить Злые Буржуины)
Мнемоника установки битов в регистре SBR Rx, K и мнемоника логического ИЛИ регистра и константы ORI Rx, K - это одна и та же машинная команда!!!!!!

ORI Rx, K в машинном коде выглядит вот так: 0110 KKKK rrrr KKKK
например, для ORI R16, 0xA5 и для SBR R16, 0xA5 получается один и тот же код 0110 1010 0000 0101 = 0x6A05

То же относится и к мнемоникам сброса битов в регистре CBR Rx, K и логического И регистра и константы ANDI Rx, K.
Только компилятор в случае мнемоники CBR константу К запишет как 255-К (инверсия).
ANDI Rx, K - 0111 KKKK rrrr KKKK
для ANDI R16,0xA5 будет машинный код 0111 1010 0000 0101 = 0x7A05
а для CBR R16, 0xA5 - 0111 0101 0000 1010 = 0x750A.

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

Пн янв 17, 2022 06:49:55

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

По вопросу. Есть команды условного перехода, анализирующие до 3-х флагов одновременно. И это хорошо.
СпойлерИзображение
Вложения
AVR_INSTR_SET.PNG
(93.16 KiB) Скачиваний: 157
Ответить