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

Обсуждаем контроллеры компании Atmel.
Ответить
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

a1000, отвечал я колбасисту.
Таки да, ответ вам должен быть. А то я попутал по кучке ответов.

а код либы - да, по мотивам ДиХальта. Там половина копипасты, я там что то под себя вроде переписывал.. Заголовок, судя по всему, ДиХальтов. Может и всё его - 7 лет прошло, не помню.
Я тогда изучал АВРки и их ассемблер.
И большинство чужих либ изучал и переписывал под себя.

Добавлено after 42 minutes 58 seconds:
a1000, по обработке прерывания от i2c - у того же ДиХальта был развесистый такой алгоритм обработки прерывания в зависимости от статусного байта.
Для спортивного интересу - да, можно i2c обрабатывать прерыванием. но выигрыш от этого?
1 байт на 400 кГц передается за 8+1 тактов. Или за 2.5 мкс * 9 = 22,5 мкс.
За 22.5 мкс МК на частоте 8 МГц выполняет условно 180 команд. Это если не считать условных и безусловных переходов и двухсловных команд.
Из которых вы потратите, (если мне не изменяет память) по 4 такта на вход в прерывание и выход из него. Потом нужно сохранить SREG и какой то из регистров. Еще 3 такта. Еще сохранить ZL:ZH - это указатель для ваших сохранений данных из TWDR. Т.е. 5 тактов сохранения, 5 восстановления регистров.
Дальше реализация этапов чтения - у не думаю, что менее 20-30 тактов уйдет... Т.е. на обработку прерывания будет тратиться ну не менее 40-50 тактов. Из 180.
Т.е. при 8 МГц у вас между прерываниями будет 12-15 мкс.
Ради спортивного интереса - да, можно работать с прерыванием.
А так - я бы не заморачивался и сделал на ожиданиях. Обычно i2c-устройства - это не plug'n'play, а запаянные на плату конкретные устройства. И при исправности всех устройств обмен по шине не должен выдавать ошибки. Соответственно, цикл обработки упрощается.
В ожиданиях, если вдруг что, можно сделать не бесконечное ожидание, а конечный цикл, однобайтовый, от 0xFF до 0x00. И отдавать флаг ошибки, если цикл досчитал до 0. Ибо передача/прием байта занимают 180 или 360 тактов (8 или 16 МГц тактовой). а цикл ожидания будет длиться дольше.
Если уже параллельно процессу обмена нужно что то выполнять, то можно делить обмен по i2c на этапы - старт, отправка адреса записи, отправка стартового адреса, повстарт, отправка адреса чтения, чтение байта 1, чтение байта 2, ...., чтение байта 7, стоп.
И выполнять эти этапы раздельно, а между этапами параллельные операции.

Касательно 18B20 - я думаю, что при правильном подходе там обмен уложится байт в 200-300-400. Там же важно выдерживать только 3 тайминга - резет 480 мкс и чтение presence / чтение-запись бита - 15+45 мкс.
Опять же, если не не использовать UART, то проще всего эти задержки делать на тупых циклах.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15816
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

По практике более удачно программный вариант для I2C RTC использовать.
Если уж и аппаратно на прерываниях (а это уже "прием строки символов" в массив данных) то использовать условный возврат из прерывания по предварительно заданному адресу. Сам адрес следующего фрагмента обработчика задает текущий фрагмент обработчика массива перед своим завершением.
(собственно анализатор загрузчика хекс файла в котуинке на таком принципе построен).
8)
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18828
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

GoldenAndy писал(а):Обычно i2c-устройства - это не plug'n'play, а запаянные на плату конкретные устройства. И при исправности всех устройств обмен по шине не должен выдавать ошибки.
абсолютно верно! ни коллизий, ни потерь битов в правильно сконструированном девайсе на шине I2C быть не может! и нужды в анализе этих битов нет никакой. от слова совсем.
GoldenAndy писал(а):Если уже параллельно процессу обмена нужно что то выполнять
как я неоднократно утверждал в разных других темах, реальная необходимость действительно параллельно что-то делать в любительских проектах возникает крайне-крайне-крайне редко. более того, после реализации этой "истинной" параллельности обычно оказывается, что никакого выигрыша нет вообще, только напрасно потраченное время. но это моё мнение, оно может не совпадать с мнением редакции :)))
GoldenAndy писал(а):проще всего эти задержки делать на тупых циклах
и тут согласен на все 100%.

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

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

ARV писал(а):ни коллизий, ни потерь битов в правильно сконструированном девайсе на шине I2C быть не может!
Ну, тут нужно заложить какой то гипотетический случай на выход из строя i2c-ведомого устройства.... Но с этим прекрасно справится таймаут ожидания - делается на одном регистре и трех ассемблерных командах (пишу по памяти, но могу и криво написать, на асме очень давно не писал, в основном голый Си)
LDI reg, 0xFF
label:
SUB reg
BRNE label

Либо проверять ACK при отправке адреса. Нету ACK - ведомый сдох, несите нового раба. Если АСК есть - то устройство на шине и дальше на тупых ожиданиях работаем.
ARV писал(а):реальная необходимость действительно параллельно что-то делать в любительских проектах возникает крайне-крайне-крайне редко
У меня такое было всего один раз. Когда приходилось читать по i2c из INA219 1000 раз в сек попеременно значения тока и напряжения, класть их в буфер и обрабатывать. И это была основная задача - там действительно пришлось использовать прерывание и конечный автомат. Таймер дергал старт обмена, а конечник в прерывании i2c обрабатывал всю лог.цепочку. При этом в прерывании таймера обрабатывались значения тока и напряжения из предыдущего цикла. И это была основная задача МК. А оставшееся от всей этой кухни время - это формирование изображения для дисплея, вывод его по SPI через DMA. По второму i2c был обмен с EEPROMкой внешней, но он редкий, там настройки живут и калибровочные константы. Тут уже былл обмен на ожиданиях, ибо основная задача работает реалтаймово на прерываниях.
Ну и под это все был выбран соответствующий СТМ с частотой 72 МГц, у него 44 кб ОЗУ, что бы помнить 20 тысяч точек тока...

А про команду LD - ну слов нет... Даже в той же студии №4 есть прекрасный хелп по асму. А нет - есть курс ДиХальта, там всё русским по белому описано.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 15816
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Иногда полная проверка наоборот является источником ошибок.
Причем весьма долго "скрывающихся".
Тот же контроль на освобождение шины ведомым, когда после передачи адреса следует выдача данных с первым нулевым битом.
8)
В остальном... Глубоко лезть в возможности ассемблера обычно современные котятки не желают - сбегают на Си.
Посему многие "стандартные" приемы давно забыты.
:sleep:
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

BOB51, ну я тоже сбежал на Си. Но для АВР - начинал с ассемблера. Но на Си - тупо удобнее и быстрее. И зачастую - универсальнее.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15816
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Всего хорошо в меру и при необходимости.
Ассемблер остается базой в любом случае (в том числе и для вставок/прикладных драйверов в Си).
В то же время пользу приносит применение "заимствованных" приемов.
Другое дело оперативно перескочить с одного на другое да еще и при нескольких разных компиляторах с проектом раз в месяц/пол-года штука таки напряжная.
Там только набор "шпор" да конспектов поможет.
8)
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

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

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

a1000, для DS18B20 тоже делайте на ожиданиях, не забыв запретить прерывания на период чтения/записи одного бита и отсчитывания таймингов.
Тайминги сделайте на циклах. 15 мкс получится на однобайтовом цикле - это 240 тактов при 16 мгц (я выше кидал примерный алгоритм цикла). Стартовое значение счетчика цикла либо посчитать по тактам, либо подобрать в эмуляторе студии. 45 мкс - три раза дернуть задержку 15 мкс. 480 мкс - 32 раза по 15 мкс.
Обратите внимание - сброс-пауза-ожидание presence должно быть атомарным блоком, т.е. перед сбросом запретить прерывания, а разрешить только после проверки presence.
Чтение/запись бита тоже должно быть атомарным - запретить прерывания, прижать линию на 15/45 мкс (при записи) или на 15 мкс, отсчитать 45 и посмотреть что на линии (при чтении), потом разрешить прерывания.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18828
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

ARV, сформировали старт, подождали , пока в статусном регистре старт не подтвердится. Это быстро.
А вот чтение/запись данных - тут надо ждать, ибо формирование SCL, чтение/запись SDA делает блок TWI самостоятельно. Все 8 бит.
Т.е. отправили байт адреса - ждем, пока он отправится и прилетит/не прилетит АСК.
Это 9 тактов несущей i2c. для 400 кГц - это 22.5 мкс. Вот эти 22.5 мкс можно протупить в ожидании или заняться своими делами.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 15816
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

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:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

Мне в этом плане нравится либа ДиХальта (не знаю, есть ли она на асме) i2c ultimate. Там скармливается режим, объем данных и адрес буфера. И подается старт. А дальше оно в фоне на прерываниях само отработает и выдаст коллбеком результат.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 15816
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Это уже забота обработчика.
У меня там только минимальный драйвер приема-передачи.
8)
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18828
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

ARV, ну мне наоборот, проще аппаратный TWI использовать. Хотя в каком то проектике пришлось программный i2c делать.там да, тупой ногодрыг на задержках.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 15816
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Не у всех МК (тем более "устаревших" или малолапых да из других семейств) имеется аппаратный TWI.
Дополнительные минусы - практически обязательное наличие еррат и, как результат, необходимость детального изучения конкретного модуля в конкретной версии выбранного МК, невозможность переброса выводов для более удобной разводки монтажа.
Так что алгоритмы и библиотеки с программным ногодрыгом всегда актуальными будут.
8)
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1408
Зарегистрирован: Чт авг 21, 2014 11:11:48
Откуда: краснодарский край

Сообщение главный колбасист »

что касается последних сообщений, касающихся LD, то меня просто возмущает отсутствие желания у вопрошающего прочитать о системе команд AVR.
Злой ты какой то... :)
Изображение
Да я знаю что я ленивая свинья. Но свинья с чувством юмора,могущая посмеяться над собой
и над обстоятельствами.И способная, и с интеллектом выше среднего.Да если хотите знать,я самая лучшая в мире свинья! 8) :))
Последний раз редактировалось главный колбасист Пн янв 10, 2022 20:58:46, всего редактировалось 1 раз.
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 15816
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Не злой, а солидный (учёный КОТЯРА)!
Положено мелких КОТЯТОК носом в миску тыкать.
8)
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

BOB51, оффтопик.
У нас есть кошка.
Когда ей было 7 лет - взяли еще одну кошку-подростка. Уличную бандитку 6-7 месяцев.
Когда это малолетнее, отпихнув старшую, полезло в ее миску - старшая сделала просто. Лапой эту молодую мордой в миску - и держала. Хватило одного раза, что бы малая не лезла.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1408
Зарегистрирован: Чт авг 21, 2014 11:11:48
Откуда: краснодарский край

Сообщение главный колбасист »

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

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