Обычно старый исходник читать - легче заново переписать.
а что заново писать - инклуд для определенного микроконтроллера, таблицу векторов прерываний, метки(переменные), инициализацию стека, инициализацию периферии. Дальше новая логика работы, новые подпрограммы и в конце инклуды с модулями, большинство из которых готовые, даже в других местах скопипащеные, ну может слегонца их подправить - в ассемблере особо со стилями не разгуляешься, главный принцип: работает - не трогай.
Да не всегда - перебирал недавно I2C под 1307 (адаптацию софт-ногодрыга для адуринки) - накопал ошибку "черезмерного контроля", из-за которой лишние заморочки были. Все-таки плюсик - софтовому I2C добавка. Ну и в таком духе... Где алгоритм с учетом новых знаний чуток перешерстить, где покрасивее подчистить. Шаблоны штука хорошая, только все же лучше шаблон алгоритма хранить - без конкретной привязки к какому-либо семейству - просто словесное описание. Тогда его проще быстренько хоть под ассемблер, хоть под Си (или еще какой ЯВУ) приткнуть.
Где алгоритм с учетом новых знаний чуток перешерстить, где покрасивее подчистить.
перешерстить приходится с учетом особенностей конкретного ассемблера другого семейства, вот на Си практически только копипаста. Например давно еще на PIC сделана индикация и кнопки - мигрировало практически в неизменном виде (Си) PIC->AVR->STM8->Nuvoton и прекрасно работает, на ARM по другому, есть DMA. Вот на ассемблере приходится шерстить (stm8): Спойлер
@@: ld a, (led1) and a, index jreq @f bset CAT3_DDR, #CAT2 @@: ld a, (led0) and a, index jreq @f bset CAT3_DDR, #CAT3 @@: sll index tnz index jreq @f mov index, #0x01 @@: bres TIM2_SR1, #0 ; UIF Update Interrupt Flag mask iret
STM8 я пока "задвинул" - особо возится с ним при возможности работ с адуринками и улучшенной среднемладшей от микрощипа как-то особого желания нету...
Это ёжли с точки зрения производства - там возможен интерес. Однако единственный производитель таки может в будущем и СВИНЮ подложить... А подход к работе под ассемблером с STM8 практически такой же, как и для I8088 в отношении сегментов - в других семействах с подобной методикой не работают. Вобщем "на поиграться" при наличии уже имеющегося затратно. Разве что для тех, кому сей МК в качестве первого в освоении приходится - "на пустую голову" еще смысл есть с ним возиться.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
в отношении сегментов - в других семействах с подобной методикой не работают.
это в родной STM8 среде надо всего-то segment 'ram0' segment 'rom' - разобраться несложно, документ есть.
Цитата:
Однако единственный производитель таки может в будущем и СВИНЮ
У STM8 интересен в принципе 20-ногий сверхдешевый STM8S003F4 - отличная замена тинек (у STM8 есть более полезные фишки). Насчет свиньи - тут можно не беспокоится - есть уже 3 типа микроконтроллеров разных производителей совместимых по ногам с STM8S003F4. Вот недавно делал на замену устаревшей платы с PIC16F676 - можно ставить STM8 и Nuvoton: Да и сейчас валом китайских поделок с 20-и ногими STM8/Nuvoton - почти практические ардуинки
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
На сегодня - единственный корпоративный. Микрощип таки атмел слопал, правда и сам заметно изменился... Отнюдь не в сторону "народных компонентов". Это типичный вариант развития транснационалки...
Из ПИКовых по лицензии 17-я серия "с дополнительными извратами" - в России клепается. АВРки китаяски туварищи клепают, да не в единстваенном варианте. За MCS51 лучше уж... их кто только не извращается творить и впихеривать в состав иных кристаллов. А основной рынок таки адуриноподобными на сегодня завален. В "забытьи" остались правнуки Z80 - там весьма интересные экземплярчики имеются - но ... только "на почитать" про оные.
Из ПИКовых по лицензии 17-я серия "с дополнительными извратами" - в России клепается. АВРки китаяски туварищи клепают, да не в единстваенном варианте.
сколько дебагеры программаторы для оных, вышеперечисленных стоят и где брать? Для СТМ8 - два в одном (плюс и СТМ32) программатор/дебагер =2$ в любом колбасном лотке и кучи на алике. Не говорим уж о распространенности полезных материалов в сети, особенно никак не любительская 17-я серия. Платки типа ардуино на 20и ногих СТМ8 и Нувотоне тоже совсем не дефицит.
Были - Z86 к примеру... (и частенько во "враждебной технике" попадались )... Даже книжу ДОДЭКА успели выпустить: "М.А.Гладштейн Микроконтроллеры семейства Z86 фирмы ZILOG Руководство программиста М,:ДОДЭКА, 1999 ..." Насчет отладчиков - кто с чем привык дело иметь. Тест ядра и симулятор IDE успешно выполняет, остальное - на усмотрение пользователя. За АРМ уже разговоры были - это разряд "система-на-кристалле" с которой эфективно работать предпочтительно на ЯВУ (и в рамках действующей в устройстве ОС)... Аналогия работы с ПК. Насчет STM8... там ВСЕГДА один "лишний" внешний кондер имеется... По сравнению с теми же ПИКовыми и/или АВР. Правда в виде отдельной платки "вроде как для адурино" (по сути в самой IDE не поддерживаемые так как хотя-бы те же "пилюльки") действительно валяются... Но особой разницы относительно уже имеющейся базы на сегодня как-то незаметно... Ибо то, что на платках стоит меге328й не конкурент (в смысле применения в рамках ардуинки). Другое дело - "пилюльки" - то вполне достойная компания нанкам и про-мини.
Насчет STM8... там ВСЕГДА один "лишний" внешний кондер имеется...
Будем конденсаторами меряться? Он там между 2 пинами которые рядышком. У Nuvoton не нужен. Зато у AVR надо тянуть на плате 6 пинов для внутрисхемного программирования, у PIC пять... у STM8 достаточно три, а у AVR еще и кошмарные фузы А "система-на-кристалле", это в телефонах, и называется SOC электронная схема, выполняющая функции целого устройства (например, компьютера) и размещённая на одной интегральной схеме, а STM32 в большинстве своем это обычный заурядный микроконтроллер, а STM32MP1 - новый многоядерный микропроцессор от STMicroelectronics, поддерживающий работу с Linux. А ардуинки для разработчика- ассемблериста (BOB51 из их числа считаю) имхо представляют интерес только как макетная платка с микроконтроллером, сама среда ардуино это больше для детей - нынешние дети 10-и лет у нас программирование в школе на Scratch учат - на ардуино тоже удобнее Scratch использовать.
Обеспечение режима внешнего программирования НЕ РАССМАТРИВАЕТСЯ. Ибо может быть как внутрисхемным, так и для автономного кристалла (как у всех DIP корпусов).
Я уже ранее говорил - нельзя недооценивать ардуино, исходя из массового примера школоты! Вполне мощное и надежное средство (как сама IDE, так и платки-платформы). Результат - зависит от "умения готовить".
Насчет - чего кто "в школах" учит и проччего... При нынешнем отношении к короновиреву дурдому. Как бы не пришлось в следующем году содержимым "кащеевых сундучков" пользоваться.
И почему не рассмотреть - у mega328PB нет DIP корпусов (по документации) пора забывать потихонечку. Чего нельзя сделать на ардуино, то что можно на Си или С++ или ассемблере - лишняя неудобная прослойка, сами там программы что-ли пишутся. Повторюсь - для обучения детей может и неплохо, но для разработчика среда накладывает определенные ограничения (сено в скафандре). Сплошные костыли, зачем, если сразу можно нормально на обычном языке писать. Готовь не готовь а...
Цитата:
С ростом навыков и созданием всё более глобальных проектов вы столкнётесь с тем, что “Ардуина” перестанет справляться с тем объёмом вычислений, который вы хотите от неё получить. Может банально не хватать быстродействия в расчётах, обновлении информации на дисплеях, отправки данных и прочих ресурсозатратных действий, а ещё может просто закончиться память!
https://alexgyver.ru/lessons/code-optimisation/ Насчет сундучков - у каждого свои сундучки , кто давно запасся уже новым (старое пока еще валяется в чулане). Да и лотки с комплектующими на онлайн режим только перешли. У меня самого лежат кучки PIC16F628 и tiny26 в DIP и пр. подобного - использовать пока не вижу смысла, только на случай крайнего апокалипсиса.
За те МК, что имеют режим самопрограммирования об ISP можно говорить только разве что с точки зрения загрузки бутлоадера.
Воть одно наблюдение мня больше беспокоит... Последний год -два обратило на себя внимание появление случайного мусора в ЕЕПРОМке АВРок... Даже ёжли МК с "отлежки" и/или в проекте ЕЕПРОМ не используется... Для пакости специально записывал всю область 0xFF .... Таки не часто, но после длительного лежания при считывании "мусорец" таки попадается... Может случайность ("стечение обстоятельств"), а может и нет... При обычной работе ЕЕПРОМка не часто используется, посему чего там в считанном дампе особо внимания не уделяется... Кто чего сказать может?
режим самопрограммирования об ISP можно говорить только разве что с точки зрения загрузки бутлоадера
говорилось об обычном программировании новой платы, с новеньким микро. Вчерась прошивал меги48 в TQFP - шесть ламелек выведено чтоб прошить. RESET меги48 очень неудобно тянуть к ламелькам с противоположной стороны там где MISO MOSI питание... На этом фоне лишний конденсатор меркнет. У меня пружинные контакты на переходничке в один ряд шесть штук, когда шью STM8 "лишние" пружинные контакты висят в воздухе. ЕЕПРОМ еще в давние времена была болезнь нулевой ячейки, Атмел сама признавала, потом вроде победили. Сам не использую в проектах AVR несколько начальных ячеек ЕЕПРОМ.Фуз BOD 1.8В еще помогает Было вообще о ЕЕПРОМ неоднократно, например: https://radiokot.ru/forum/viewtopic.php ... 4#p3153394
Да вот и я ту ЕЕПРОМку по факту в проектах на АВРках пока не использую... Просто при проверке кристаллов случайно внимание обратил. Потом еще несколько раз попадалось... Вместо чистенького 0хFF при чтении высыпаются случайные значения в случайных местах. Вот и интерес - либо у меня "стечение обстоятельств", либо у кого еще наблюдалось? У ПИКовых такого не замечал (специально пару раз почитал МК с хранения)... Причем для АВРок делал спецзапись области ЕЕПРОМ с программатора... вначале все как и положено...что записано, то и считано... Все равно через некоторое время снова "случайные значения" в случайном порядке... Может софт программатора чего сбоит, может сам кристалл... А может и "потроха" МК...
с EEPROM случайные значения скорее всего программатор. У меня с давних пор самосборный на основе этого http://www.tuxgraphics.org/electronics/ ... 7052.shtml Работает из родной среды AVR Studio, времянки выдержаны - частота нужная в среде, по документу выставляется - если выставить большую, то сбои. Среда тогда сама об этом говорит. Прошито довольно много мега48, некоторые работают в сварочном оборудовании. Сбоев особо не наблюдалось. Были партии где BOD сильно зависел от температуры - при холоде микроконтроллер в сбросе, пришлось BOD отключить. Было несколько экземпляров где флэш периодически слетал - помогала чисто замена микроконтроллера. EEPROM постоянно нужен для установок изменяемых пользователем. Всегда делаю проверку на правильность диапазона параметра при загрузке микроконтроллера и считывании параметров из EEPROM. Грубо говоря - если в EEPROM 0xFF, то загрузить дефолтным значением. В некоторых проектах сделано при долгом удержании определенной кнопки - установки записываются в EEPROM дефолтные.
У меня STK200 и SiProg c со стандартными софт-оболочками понькой да аврдудой... В принципе все может бысть... Пока свой не заморочить по даташиту - проверить сложно... А мутить свое расширение до КОТУИНКИ (аналогично приставке под АТ89с2051) пока ВЛООМуушкиии...
Проверка на кристалле (не в рамках адуринки, а в собственном варианте под ассемблером) - то также надо чего-то полезного замутить... Придется малость отложить в сторону с "вопросцем"... Пока чего из проектов проверить не позволит.
Набросок модуля... Это вариация на тему uLAN ногодрыгом на АВРках (у мня его для АВРок раньше не имелось). Проверено только в дебаггере на правильность кода и интервалов. Еще бы где в макете сунуть... Но то есть вторично.
Собственно суть... При однофайловом варианте/тестировании модулть является самостоятельной единицей. Поскольку дебаггер таки привязан к конкретному кристаллу - задаю ATtiny2313 как наиболее универсальный (смотреть в папке проекта test). Можно любой иной задать - не существенно для модулей, в которых только система команд да базовое ядро используется. В случае использования аппаратно-зависимых блоков МК придется и тестировать на тех МК, где аппаратный модуль применяется. Для использования в "многофайловике" имеется малая извратина - в главном фрагменте дефайнов основного файла проекта необходима добавка... Она является определяющей для "подчиненных" модулей, указывая на необходимость проведения некоторых изменений в случае "коллективной обработки". Шаблон главного файла дефайнов с "добавкой": Спойлер
Код:
; ; "defname_proto.txt" файл объявленных имен, бит и констант (шаблон) ; ;---------- ; в файле определений главного файла проекта ; следует добавить: #ifndef disposit #define disposit #endif ; в случае многофайлового проекта раскомментировать данную строку ; при однофайловом проекте ; определение disposit не требуется ; ;---------- ; variable definitions ;(таблица обьявленных имен) ;_____ ;таблица обьявленных имен - пользовательские константы ;
; ; av_mlan.asm ; ; файл-заготовка модуля обмена сети uLAN ; для МК семейства АВР при системной ; тактовой частоте 1 МГц и ; "трехпроводной" (полной) схеме ; соединительной линии ; ;_____ ;таблица обьявленных имен - пользовательские константы ; .equ m_cfg9 = 0b00011111 ; разрешение 9 бит, время преобразования 93,75 mS .equ m_cfg10 = 0b00111111 ; разрешение 10 бит, время преобразования 187,5 mS .equ m_cfg11 = 0b01011111 ; разрешение 11 бит, время преобразования 375 mS .equ m_cfg12 = 0b01111111 ; разрешение 12 бит, время преобразования 750 mS .equ mk_conv_t = 0x44 ; (CONVERT T) команда запуска преобразования температуры .equ mk_rd_spad = 0xBE ; (READ SCRATCHPAD) команда чтения "блокнота" из DS18B20 .equ mk_wr_spad = 0x4E ; (WRITE SCRATCHPAD) команда записи Th:Tl:Config в блокнот DS18B20 .equ mk_wr_eep = 0x48 ; (COPY SCRATCHPAD) команда записи Th:Tl:Config ; ; из блокнота DS18B20 в EEPROM DS18B20 .equ mk_rd_eep = 0xB8 ; (RECALL E2) команда чтения Th:Tl:Config ; ; из EEPROM DS18B20 в блокнота DS18B20 .equ mk_scip_rom = 0xCC ; (SKIP ROM) команда "не выполнять персональную адресацию" ; ; применяется преамбулой во всех блоках обмена при одиночном ; ; датчике .equ mk_read_rom = 0x33 ; (READ ROM) чтение из DS18B20 группового кода изделия ; ; и индивидуального номера ( пакет из 8 байт в составе ; ; байт family code, 6 байт serial number и байт CRC ) ; ; .equ uL_dat = 6 ; линия порта обмена #define uL_port PORTD ; имя порта вывода, используемого для uLAN #define uL_pin PIND ; имя порта ввода, используемого для uLAN #define uL_ddr DDRD ; имя порта DDR, используемого для uLAN ; .equ uL_port = PORTD ; имя порта вывода, используемого для uLAN ; .equ uL_pin = PIND ; имя порта ввода, используемого для uLAN ; .equ uL_ddr = DDRD ; имя порта DDR, используемого для uLAN ;_____ ;таблица обьявленных имен - переназначение регистров РОН #ifndef disposit ; ; принята базовая модель: ; область ограниченного функционала ; .def mfr0 = r0 ; (математика и обмен с ПЗУ/самопрограммирование) ; .def mfr1 = r1 ; (математика и обмен с ПЗУ/самопрограммирование) .def s_stk_l = r2 ; зеркало указателя стека(ограниченный функционал) .def s_stk_h = r3 ; зеркало указателя стека(ограниченный функционал) .def s_xl = r4 ; зеркало Xh:Xl(ограниченный функционал) .def s_xh = r5 ; зеркало Xh(ограниченный функционал) .def s_yl = r6 ; зеркало Yh:Yl(ограниченный функционал) .def s_yh = r7 ; зеркало Yh(ограниченный функционал) .def s_zl = r8 ; зеркало Zh:Zl(ограниченный функционал) .def s_zh = r9 ; зеркало Zh(ограниченный функционал) .def s_sreg = r10 ; зеркало SREG (ограниченный функционал) .def sys_flag = 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 data_mlan tmp0 ; РВХ данных обмена #define cntt_mlan tmp1 ; счетчик длины пакета #define cntb_mlan tmp2 ; счетчик бит приемника/передатчика байта #define cntp_mlan tmp3 ; счетчик задержки #define flag_mlan tmp4 ; оперативные флаги для m_flag #define remd_mlan tmp1 ; остаток в CRC контроле ;_____ ;таблица обьявленных имен - секция флагов пользователя ; .equ erkz_mlan = 0 ; флаг ошибки "КЗ линии mLAN" ; в области флагов ошибок .equ ernd_mlan = 1 ; флаг ошибки "линия mLAN не отвечает" ; в области флагов ошибок .equ ecrc_mlan = 2 ; флаг ошибки при проверке CRC кода пакета mLAN ; в области флагов ошибок ;_____ ;таблица обьявленных имен - секция определенных данных (ОЗУ) ; .dseg s_pad: .byte 10 ; область блокнота данных датчика 9 байт ; ; целевое именование проводится в программе обработки через: #define gradus_l s_pad ; младший байт текущей температуры #define gradus_h s_pad+1 ; старший байт текущей температуры #define th_us1 s_pad+2 ; уставка термостата максимальный порог ;/пользовательский байт #define tl_us2 s_pad+3 ; уставка термостата минимальный порог ;/пользовательский байт #define m_cfg s_pad+4 ; байт конфигурации датчика DS18B20 #define m_res0 s_pad+5 ; резерв, всегда 0xFF #define m_res1 s_pad+6 ; резерв, всегда 0x0C #define m_res2 s_pad+7 ; резерв, всегда 0x10 #define m_crc s_pad+8 ; контрольная сумма пакета #define m_flag s_pad+9 ; флаги результата обмена ; ;_____ ;таблица обьявленных имен - секция определенных данных (EEPROM) ; ; .eseg ; ; ;---------- ; local macros ; ; m_start_pak ; макрос запуска стекера пакетных блоков обмена с uLAN ; .macro m_start_pak cli push tmp0 ; РВХ данных обмена push tmp1 ; счетчик длины пакета rcall m_start .endm ; ; m_stop_pak ; макрос завершения стекера пакетных блоков обмена с uLAN ; .macro m_stop_pak rcall m_stop pop tmp1 pop tmp0 sei .endm ; ;---------- ; ; .cseg ; тестовый участок (при необходимости)
; ;---------- ; фрагмент системного init подготовки линий порта обмена ; по reset при подаче питания на МК по умолчанию ; uL_dat = вход с Z состоянием (внешняя подтяжка к 1) ; и ; uL_port.uL_dat = 0 - подготовлено к выдаче uL_dat=0 ; m_linap: cbi uL_ddr,uL_dat ; uL_dat = вход с Z состоянием (внешняя подтяжка к 1) cbi uL_port,uL_dat ; uL_port.uL_dat = 0 - подготовлено к выдаче uL_dat=0 ret ; m_t15: nop ; совместно с RCALL m_t15 обеспечивает задержку в 15uS nop nop nop m_t11: nop nop ; совместно с RCALL m_t10 обеспечивает задержку в 10uS nop nop ret ; при системной частоте 1 МГц ; m_t480: ldi cntt_mlan,32 ; 32*15=480 задержка ~480uS tl480: rcall m_t15 dec cntt_mlan brne tl480 ret ; ;---------- ; ; участок вызова функций драйвера обмена ; m_start: ; во внешней программе перед вызовом call m_start ; cli ставится при исполнении блока обмена ; - crc контроль защиту не требует pop tmp1 ; считать адрес возврата h pop tmp0 ; считать адрес возврата h push s_sreg in s_sreg,SREG push tmp2 ; счетчик бит приемника/передатчика байта push tmp3 ; счетчик задержки push tmp4 ; оперативные флаги для m_flag push Xl push Xh push tmp0 ; восстановить адрес возврата l push tmp1 ; восстановить адрес возврата h ret ; m_stop: pop tmp1 ; считать адрес возврата h pop tmp0 ; считать адрес возврата h pop Xh pop Xl pop tmp4 pop tmp3 pop tmp2 out SREG,s_sreg pop s_sreg ; во внешней программе перед вызовом call m_stop ; sei ставится в случае, если при вызове было выполнено cli push tmp0 ; восстановить адрес возврата l push tmp1 ; восстановить адрес возврата h ret ; ;---------- ; ; m_dttc - генератор импульса reset термодатчика и проверка ; импульса "присутствия" ; (начальная настройка линии обмена и резервирование ; данных уже предварительно выполнено) ; по выходу возвращает статус ошибок в регистре flag_mlan ; erkz_mlan=1 ошибка "КЗ линии mLAN" ; ernd_mlan=1 ошибка "линия mLAN не отвечает" ; или flag_mlan = 0 при благополучном завершении ; m_dttc: clr flag_mlan ; сброс флагов ошибок sbi uL_ddr,uL_dat ; uL_dat=0 rcall m_t480 cbi uL_ddr,uL_dat ; uL_dat=Z с подтяжкой к 1 ; контроль импульса присутствия через каждые 10 мкС ; с последующим ожиданием его отключения ведомым прибором ldi cntt_mlan,16 ; ~240uS ожидания l_dttc: rcall m_t15 sbis uL_pin,uL_dat ; продолжаем до исчерпания если uL_dat=1 rjmp quit_m0 ; обработка положительного ответа uL_dat=0 dec cntt_mlan brne l_dttc ldi flag_mlan,(1<<ernd_mlan) ret ; выход по ошибке "датчик не отвечает" (uL_dat=1) quit_m0: ldi cntt_mlan,16 ; ~240uS ожидания l_dttc1: rcall m_t15 sbic uL_pin,uL_dat ; продолжаем до исчерпания если uL_dat=0 rjmp quit_m1 ; обработка положительного ответа uL_dat=1 dec cntt_mlan brne l_dttc1 ldi flag_mlan,(1<<erkz_mlan) ret ; выход по ошибке "КЗ линии mLAN" (uL_dat=0) quit_m1: ldi cntt_mlan,27 l_dttc2: rcall m_t15 ; защитная задержка ~405uS dec cntt_mlan brne l_dttc2 ret ; ; ;---------- ; ; приемник байта в стандарте сетей microLAN ; вызов call m_rxb ; по выходу принятый байт в регистре data_mlan ; uL_dat = вход Z с внешней подтяжкой к 1 ; m_rxb: ldi cntb_mlan,8 m_rxb_L: nop ; интервал между слотами в 2 uS sbi uL_ddr,uL_dat ; uL_dat=0 активирован запрос слота nop ; rcall m_t11 cbi uL_ddr,uL_dat ; через 12uS снимаем запрос слота 2tci nop ; uL_dat=1 nop ; nop ; задержка установки уровня rcall m_t11 sbic uL_pin,uL_dat ; 1tci no skip, 2tci sec ; 1tci sbis uL_pin,uL_dat ; 1tci no skip, 2tci clc ; 1tci чтение данных в середине слота (~30uS) rcall m_t15 rcall m_t11 ; дорабатываем 60uS ror data_mlan ; 1tci dec cntb_mlan ; 1tci brne m_rxb_L ; 1 false 2 true ret ; 4tci ; ;---------- ; ; передатчик байта в стандарте сетей microLAN ; перед вызовом передаваемый байт разместить ; в data_mlan ; вызов call m_txb ; по выходу ; uL_dat = вход Z с внешней подтяжкой к 1 ; m_txb: ldi cntb_mlan,8 m_txb_L: nop ; интервал между слотами в 2 uS sbi uL_ddr,uL_dat ; uL_dat=0 активирован запрос слота ror data_mlan ; 1tci интервал между слотами в 2 uS rcall m_t11 brcc m_txb_i ; 1tci/2tci обход при С=0 cbi uL_ddr,uL_dat ; 1tci иначе ставим 1 m_txb_i: nop nop rcall m_t15 rcall m_t15 rcall m_t11 cbi uL_ddr,uL_dat ; 1tci иначе ставим 1 dec cntb_mlan ; 1tci brne m_txb_L ; 1 false 2 true ret ; 4tci ; ; ;---------- ; ; модуль обработки CRC8 uLAN DALLAS ; и вариант CRC7 как частный случай ; блок данных предварительно размещается в s_pad ОЗУ ; исходные данные НЕ РАЗРУШАЮТСЯ! ; обрабатывается как проверка так и генерация CRC ; с подстановкой в конце дампа пакета ; возвращает флаг "ошибка CRC" =0 или =1(при ошибке) ; при генерации байт CRC подставляется ; в m_crc области s_pad ОЗУ ; crcg7: set ldi cntp_mlan,7 rjmp crcg crcg8: set ldi cntp_mlan,8 rjmp crcg crck7: ldi cntp_mlan,8 rjmp crck crck8: ldi cntp_mlan,9 crck: clt crcg: clr flag_mlan ldi Xl,low(s_pad) ldi Xh,high(s_pad) clr remd_mlan ; результат big_lp: ld tmp0,x+ ; читаем текущий байт данных в tmp0 push tmp0 ; и копируем его же в стек ldi cntb_mlan,8 ; счетчик бит =8 low_lp: eor tmp0,remd_mlan ; xor битов 0, результат в tmp0 ror tmp0 ; результат xor битов 0 накопителя результата ; и текущих данных передан в С brbc SREG_C,crcpt0 ; в зависимости от результата по биту 0 ; или уходим в завершение crcpt0 ldi tmp0,0x18 eor remd_mlan,tmp0 ; или ксорим второй узел crcpt0: ror remd_mlan ; результат сдвигаем вправо с учетом СY pop tmp0 ; загружам исходные данные ror tmp0 ; кольцевой сдвиг исходных данных, ; что поступило в старший бит безразлично push tmp0 ; отправляем текущий результат сдвига в стек ; и оставляем в tmp0 dec cntb_mlan ; счетчик бит -1 brne low_lp pop tmp0 ; корректор указателя стека dec cntp_mlan ; счетчик байт пакета -1 brne big_lp brtc crc_k ; если Т=0 - завершаем как тест clt ; сброс Т st x,remd_mlan ; запись результата в ячейку CRC s_pad ret crc_k: tst remd_mlan ; проверка результата breq crcpt1 ; jz - norma sbr flag_mlan,(1<<ecrc_mlan) ; иначе ecrc_mlan=1 "ошибка crc" crcpt1: ret ; ; ;---------- ; ; командный пакет запуска преобразования ; term_start: m_start_pak ; храним предыдущий контент в стеке rcall m_dttc tst flag_mlan ; при flag_mlan не равном 0 brne m_error ; перейти к обработчику ошибок ldi data_mlan,mk_scip_rom rcall m_txb ldi data_mlan,mk_conv_t rcall m_txb m_stop_pak ret ; m_error: nop ; пока заблокировано rjmp m_error m_stop_pak ret ; после вывода сообщения "E 0-LAn" ; возврат до следующего запроса канала uLAN ; ( упрощенный вариант ) или переход к ; соответствующим абсолютным блокировкам системы ; по критичным параметрам ; ;---------- ; ; командный пакет чтения текущих данных блокнота ; по выходу данные в блокноте, флаг ecrc_mlan ; сохранен в m_flag области s_pad ; m_rd9: m_start_pak ; храним предыдущий контент в стеке ldi cntp_mlan,9 ; загружен счетчик байт пакета ldi Xl,low(s_pad) ldi Xh,high(s_pad) ; загружен указатель на начало блокнота rcall m_dttc tst flag_mlan ; при flag_mlan не равном 0 brne m_error ; перейти к обработчику ошибок ldi data_mlan,mk_scip_rom rcall m_txb ldi data_mlan,mk_rd_spad rcall m_txb m_rd9_L: rcall m_rxb st x+,data_mlan dec cntp_mlan brne m_rd9_L rcall crck8 st x,flag_mlan ;флаг ошибки СRC лежит в m_flag области s_pad m_stop_pak ret ; ;---------- ;
.exit ; .exit ставится только при тесте иначе закомментировать
собственно тем disposit определяется что должно быть "выкушено", а что "добавлено" в случае применения модуля в многофайловике при случае, когда модуль вставляется как .include *.* Также там и необходимость присвоения регистрам "транзитного имени" проявляется - даже в рамках одного модуля без дополнительных .undef для одного и того же регистра r17, в базовом шаблоне именованного как temp1, можно задать два символьных имени: #define cntt_mlan tmp1 ; счетчик длины пакета и #define remd_mlan tmp1 ; остаток в CRC контроле при том, что оба варианта будут правильно оттранслированы. Ну и сам проектик для тест-обкатки модуля как автономной единицы:
uLAN - гугл сдурел от поиска такой сети (Улан-Удэнская сотовая сеть) вероятно uLAN=MicroLan=1-wire
Цитата:
Можно любой иной задать - не существенно для модулей, в которых только система команд да базовое ядро используется
существенно, например для тини13 =9.6МГц/4.8МГц/1.2МГц это:
Код:
m_t15: nop ; совместно с RCALL m_t15 обеспечивает задержку в 15uS nop nop nop m_t11: nop nop ; совместно с RCALL m_t10 обеспечивает задержку в 10uS nop nop ret ; при системной частоте 1 МГц
имхо лучше поуниверсальнее, чтоб не нопами, а типа задавать задержку в циклах: Спойлер.
Код:
macro delay_cycles_2 cycles:req .set _cy_, \cycles ; up to 10 cycles can be done by 'nop' and 'rjmp .' sequence ; in less-or-equal words than loop .if _cy_ >= 11 .set _cy_, _cy_ - 1 ldi r24, lo8( _cy_ / 4 ) ldi r25, hi8( _cy_ / 4 ) sbiw r24, 1 brne .-4 .set _cy_, _cy_ % 4 .endif ; less than 11 cycles or remainder from long delay .if (_cy_ & 0x01) nop .endif .rept (_cy_ / 2) rjmp . .endr .endm
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 37
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения