не, начинал задолго, когда под микронтроллеры Си вообще не существовало. И вообще когда микроконтроллеров было в магазине не купить только К580ИК80 или потом Z80 и то с подполы, Альтернатив не было - только асм. Когда для PIC появился Хайтеч Си и под AT89C51 Кейл с удовольствием перешел на Си, что резко упростило... То же самое видно по проектам Чена - сначала чисто асемблер АВР, потом ГСС АВР причем зачастую в сочетании с ассемблером. Там у него на сайте и АРМы затронуты на Си. "Писанина скриптов и маке-файлов" в итоге намного упрощает работу - их и писать не надо, полно готовых, AVRStudio например сама генерирует, куб для STM32 тоже генерирует. Достаточно почитать и разобраться уже в готовом. Поискал проекты для WS-ок с таким класическим решением фиксированых адресов, не нашел - думаю это чисто доморощенный вариант (не класический). Зато видел такое: Спойлер
Код:
#define ClearOutBit PORTC &= ~(1<<1) //0 на выход #define SetOutBit PORTC |= 1<<1 //1 на выход
void Set0( void ) //Выставляем в правую линию ноль ~0.4 мкс { SetOutBit; asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); ClearOutBit; //После этого временной интервал немного увеличен, в связи с выполнением циклов, но диоды сигнал ловят исправно }
void Set1( void ) //Выставляем в правую линию единицу ~0.85 мкс { SetOutBit; asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); ClearOutBit; //После этого временной интервал немного увеличен, в связи с выполнением циклов, но диоды сигнал ловят исправно } unsigned long int mas[30]; //32 битный массив из 30 значений
void setMas( void ) //выставление всего массива в линию { unsigned long int a; unsigned int j,i;
for (j=0; j<30; j++) { //количество светодиодов 30 a = 0x1000000; //первым выставляется G (Hi->Low), потом R и B for (i=0;i<24;i++){ //три байта G,R,B a=a>>1; if ((mas[j]&a)==0x00000000) { Set0(); //ноль } else { Set1(); //единица } } } }
Для более-менее приличной работы под ассемблером простого "линейного" (одиночного) файла явно маловато. А "по фэншую" надо при использовании нескольких *.asm файлов в одном проекте их в строке запуска приписывать ( да ещё и линкер добавлять, ежли компилятор не однофайловый). Если несколько разных семейств - это уже большая проблема, чем удрать на Си. Мне удалось соорудить вариант слэнга для организации многофайловиков под ассемблером (одинаково работающий в рамках всех трёх семейств - mcs51/avr/pic). Собственно посему и переход далее уже не под "чистый Си", а к тому " слэнгу", что в ардуиноIDE употребляется. Не классический подход, однако весьма удачный с точки зрения "продвинутого пользователя".
А "по фэншую" надо при использовании нескольких *.asm файлов в одном проекте их в строке запуска приписывать ( да ещё и линкер добавлять, ежли компилятор не однофайловый).
зачем? Ведь ранее "класично" в конце основного файла добавить типа:
Код:
;----------; ; Other modules
.include "mpc_mon.asm" ; System monitor .include "mpc_play.asm" ; Playback control .include "mpc_fs.asm" ; File System .include "mpc_sm.asm" ; Medium access .include "mpc_iic.asm" ; IIC functions .include "mpc_comm.asm" ; Communications .include "mpc_eep.asm" ; EEPROM functions .include "mpc_mess.asm" ; Constants
Потому что для добавления файлов частенько простого ".include имя файла" недостаточно. Тем более, что приведенная Вами, oleg110592, цитата на практике равноценна именно "слэнговому" подключению простейшего *.txt файла. И действует лишь как простое последовательное суммирование текстов перечисленных файлов. По фэншую нужно каждый файл указать отдельно в строчке запуска компилятора, да еще и добавить опции линкера, также для каждого из обрабаиываемых файлов... Ведь рассматривается не только компилятор ассемблера АВР, но и компиляторы PIC и MCS51. А у 51-й помимо c51asm.exe от атмеля существует и классика от кейла и многокомпонентный от AD2500... Там уже правила запуска посложнее (благо этим мастер проекта в IDE автоматически занимается для основного файла). Помимо прочего у "слэнга" еще дополнительные особенности по оформлению участка объявления констант/данных всех включенных в проект файлов - это уже из собственного опыта. Кстати... Я ввел *.txt именно по причине того, что вариант .include это именно "слэнг", а не "фэншуй". Дабы не вводить народ в заблуждение. Простое подключение будет аналогично ручной установке фрагмента исходника в соответствующем месте. Компилятор будет обрабатывать такой файл последовательно всего лишь как единый текст. А вот запуск с командной строки с указанием перечня файлов и опций их обработки дает совсем иной результат. В то же время если все *.asm файлы размещены в папке проекта, и если используется именно IDE, а не командная строка, процесс генерации строки запуска помогает сделать мастер проекта. Так и у ПИКов в мпасм и у аврок в авр студии. Но опять же трогать те настройки дело достаточно муторное и у каждоо компилятора со своей спецификой.
Последний раз редактировалось BOB51 Сб мар 21, 2020 18:42:50, всего редактировалось 1 раз.
Потому что для добавления файлов частенько простого ".include имя файла" недостаточно
простите мою необразованность - почему? почему "слэнговому" - тоже непонятно - не видел в документации к ассемблеру слова слэнг. "простейшего *.txt файла" тоже не годится - не будет подсветки синтаксиса цветом в редакторе, что неудобно для разработки. "Ведь рассматривается не только компилятор ассемблера АВР, но и компиляторы PIC и MCS51" - у каждого компилятора своя документация - под одну гребенку не причешешь. Вот Си - он и в Африке Си - практически все однообразно не считая костылей.
Да... Потеря подсветки синтаксиса - это оплата за единообразие подхода к написанию... Это вполне приемлемая плата. Почему простой .iclude *.asm не подходит - у разных компиляторов разное к ним отношение, а предпочтительно иметь однотипные оформления текстов и установок обработки. Чтоб меньше излишней мозготрепки... Уже не помню на чем в прошлом облом получил - когда удалось получить удачное работоспособное решение просто копать глубже не стал. Вопросы многофайловых проектов под ассемблером достаточно редко и слабо рассматриваются... Как только до этого доходит - сразу начинается миграция на ЯВУ. Именно "слэнг" , причем с применением некоторых ограничений по директивам и подборке компиляторов/IDE и позволил получить практически одинаковую методику написания проектов как для MCS51, так и для AVR и PIC10/12/16. Да и написание текстовок можно выполнять в одном редакторе с последующей подстановкой в конкретный проект. Ограничения получают директивы имеющие различное толкование. Основа - три распечатки с "заметками на полях". Собственно расширение *.txt помимо прочего не нервирует автоматику мастера проектов IDE. Результат меня весьма удовлетворяет.
Решил малость повыделываться над прожкой, что ранее (https://radiokot.ru/forum/download/file.php?id=345868 ) выложил... Попробуем изменить содержимое файла trd2812_m таким образом, чтобы он стал "частично перемещаемым" - там разве что "дырка" от 1 до 256 слов возникнуть может. И сделаем это СРЕДСТВАМИ ПРЕПРОЦЕССОРА компилятора ассемблера. Итак подрихтуем: в начале файла поставим опорную метку
Код:
bptr0: nop
далее вычисляемое препроцессором относительно данной точки смещение для начала размещения табличного декодера
Код:
.org (bptr0 + (256 - (bptr0 & 0x00FF))) slot0:
позиционку в самой программе делаем также как адрес начала предыдущего фрагмента +16... И заменяем в slot 7
Код:
;sbr zl,(1<<6)
на
Код:
sbr zl,(1<<5)
теперь вроде бы у нас стартовое значение slot0 должно быть всегда 0хNN00 .... Спойлер
Код:
; ; ; trd2812_ma.txt ; ; файл обработчика передачи массива ; из буфера вывода в линейку на основе WS2812B ; базовый МК из линейки АТМЕЛ при тактовой частоте ; от 16 Мегагерц ( 0,000000062 S) ; ; требуемые интервалы по даташиту WS2812B ; ;Data transfer time( TH+TL=1.25µs±600ns) ; T0H 0 code ,high voltage time 0.4us ±150ns ; T1H 1 code ,high voltage time 0.8us ±150ns ; T0L 0 code ,low voltage time 0.85us ±150ns ; T1L 1 code ,low voltage time 0.45us ±150ns ; RES low voltage time Above 50µs ; исходный уровень линии связи = 0 ; данные передаются пакетами из трех байт на точку ; старшими битами вперед в последовательности ; соответствующей G - R - B цветам точки ; количество блоков должно соответствовать ; количеству точек в ленте ; ; реальные данные согласно тест - отладки дебаггером (версия1!) ; авр-студио 4.19 ; ; Data transfer time( TH+TL=1.38µs -10ns) ; T0H 0 code ,high voltage time 0.44us ±10ns ; T1H 1 code ,high voltage time 0.88us ±10ns ; T0L 0 code ,low voltage time 0.94us ±10ns ; T1L 1 code ,low voltage time 0.50us ±10ns ; RES low voltage time 192,88uS (Above 50µs) ; ; длина прерывания с пакетом загрузки (x60*3) = 2175uS (0.002175) ; интервал между прерываниями (irq t/c0) = 0.004S (4000uS) ; ; define datas ; .equ port_out = PORTB ; порт вывода (по усмотрению) ; .equ out_line = 0 ; линия вывода данных ; .equ bufout = SRAM_START ; начальный адрес буфера вывода ; .equ pixel = 60 ; количество точек в линейке/ленте ; .equ bufout_size = (pixel * 3) ; не может быть более объема ОЗУ - стек!!!
.cseg bptr0: nop .org (bptr0 + (256 - (bptr0 & 0x00FF))) slot0: ; 6/14 (6-4=2 посему роль остатка выполняет CBI) cbi port_out,out_line ; 2 цикла nop nop nop nop nop nop nop nop nop ret ; 4 цикла .org (slot0+16) slot1: nop ; 13/7 (13-4=9) nop nop nop nop nop nop cbi port_out,out_line ; 2 цикла nop nop ret ; 4 цикла ;.org 0x0060 .org (slot1+16) xslot0: ; 6/14 (6-5=1 посему роль остатка выполняет CBI с избытком в 1 nop) cbi port_out,out_line ; 2 цикла cbr zl,(1<<6) ; модификация указателя 1 цикл nop nop nop nop nop nop ; -2 цикла на ld tmp0,x+ dec tmp1 ; 1 цикл brbs SREG_Z,ends_trd ; 1 цикл при неисполнении (в цикле) rjmp trasstt ; 2 цикла .org (xslot0+16) xslot1: nop ; 13/7 (13-5=8) cbr zl,(1<<6) ; модификация указателя 1 цикл nop nop nop nop nop cbi port_out,out_line ; 2 цикла ; -2 цикла на ld tmp0,x+ dec tmp1 ; 1 цикл brbs SREG_Z,ends_trd ; 1 цикл при неисполнении (в цикле) rjmp trasstt ; 2 цикла ; ends_trd: pop tmp0 pop tmp1 pop xl pop xh pop zl pop zh ; восстановить рабочую область из стека ret ;---------- ; ; предварительно: ; линия out_line настроена на вывод ; исходный уровень out_line =0 ; указатель стека усатновлен на RAMEND ; массив данных (bufout:bufout_size) предварительно загружен ; флаг готовности массива данных установлен ; mass_trm: push zh push zl push xh push xl push tmp1 push tmp0 ; храним рабочую область в стеке res_line: ldi tmp0,4 ser tmp1 cbi port_out,out_line res_time: dec tmp1 brne res_time dec tmp0 brne res_time ; =>50uS time out ldi xh,high (bufout) ldi xl,low (bufout) ; загрузка начального адреса массива ; в указатель ldi tmp1,bufout_size ldiw z,slot0 ; адрес начала таблицы в указателе ;---------- trasstt: ld tmp0,x+ ; 2 цикла slot_0: sbi port_out,out_line ; 2 цикла реально до установки 3 цикла bst tmp0,7 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла = 4 цикла от out_line=1 ;---------- slot_1: sbi port_out,out_line bst tmp0,6 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла ;---------- slot_2: sbi port_out,out_line bst tmp0,5 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла ;---------- slot_3: sbi port_out,out_line bst tmp0,4 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла ;---------- slot_4: sbi port_out,out_line bst tmp0,3 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла ;---------- slot_5: sbi port_out,out_line bst tmp0,2 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла ;---------- slot_6: sbi port_out,out_line bst tmp0,1 ; 1 цикл bld zl,4 ; 1 цикл icall ; 3 цикла ;---------- slot_7: sbi port_out,out_line ;sbr zl,(1<<6) ; модификация указателя под завершающий фрагмент sbr zl,(1<<5) ; 1 цикл bst tmp0,0 ; 1 цикл bld zl,4 ; 1 цикл ijmp ; 3 цикла ;----------
Только вот... при создании "перемещаемой таблицы" потребовалось введение опорной контрольной точки
Код:
bptr0: nop
внутри файла... Да размер окна задать не в 32 слова, а в 256... (размер "компонентов" задан как 16 слов)
А там в проекте сразу оговорка имела место - частота МК16 МГц! Посему и ставилась для проекта аттини45. Или иные АВРки с частотой 16МГц и выше. Касательно переноса алгоритма - при достаточной скорости исполнения команд можно и посмотреть. Например под STC (mcs51 имеющих исполнение команды за один такт)... ПИКушки разве что из "энхансед" с PLL (чаще в 18 серии встречаются). То при желании/необходимости не так уж и сложно... Как вариант однотипного алгоритма на двух семействах под ассемблером можно глянуть ранее выкладывавшийся https://radiokot.ru/forum/viewtopic.php ... 1#p3472041 Там протокол последовательного обмена с побитовой синхронизацией для MCS51 и Attiny2313 проект kotuino\upgm\PGX051\librus\ файл trbspi_mb1.txt - это для MCS51 Спойлер
Код:
; ; trbspi_mb1.txt ; ; файл протокола приемопередатчика проекта UPGM ; для блока управления KOTUINO (PGX051) ; /master board/ ; ;---------- ; ; bus_dtr equ 2 ; шина данных/запроса доступа ; по reset вход с внешней подтяжкой к +5 вольт ; при запросе выход с активным уровнем 0 ; при обмене соответственно или вход или выход ; с данными в прямом коде ; bus_clc equ 3 ; тактовый строб обмена данными ; по reset/cold init вход с внешней подтяжкой к +5 вольт ; при обмене соответственно вход(прием) или выход(передача) ; активный уровень 0 ; bus_qt equ 4 ; шина квитирования ; по reset/cold init вход с внешней подтяжкой к +5 вольт ; активный уровень 0 ; вход для передатчика, выход для приемника ; ;---------- ; ; модуль передачи ; ; .equ bits_ct = 8 ; константа для cntbit_t ; .define cntbit_t (rbt0+2) ; r2 rb0 счетчик бит ; .define cnt_tm (rbt0+3) ; r3 rb0 счетчик таймера заержки ; .define data_t (rbt0+7) ; r7 rb0 байт буфера данных
; data_key: .dbit 1 ; флаг типа данные/команда ; data_key=0 - байт с данными ; data_key=1 - байт с командой
; ;---------- ; ; собственно передача data_key и байта данных ; перед вызовом программы данные должны быть загружены в ; data_t (r7) ; и установлен в соответствие флаг data_key ;(data_key=0 - байт с данными ; data_key=1 - байт с командой) ; программа использует регистровый банк 0 ; ; pspi_txd: push cntbit_t push cnt_tm ; копировать временно используемый ресурс в стек orl P1,#(1<<bus_dtr || 1<<bus_clc || 1<<bus_qt) ; настройка порта ; за исключением at89s52 возможно потребуется настройка портов ; bus_dtr=bus_clc=bus_qt=ВХОД tx_on: mov r2,#bits_ct ; mov cntbit_t,#bits_ct mov c,data_key acall strob ; бит типа данных передан data_tx: xch a,r7 rrc a ; предсдвиг значения данных xch a,r7 acall strob ; бит данных передан djnz cntbit_t,data_tx tx_off: setb P1.bus_dtr ; страховое закрытие bus_dtr ; за исключением at89s52 возможно потребуется настройка портов ; шины bus_dtr=bus_clcbus_qt=ВХОД ; и bus_dtr=bus_clcbus_qt=1 pop cnt_tm pop cntbit_t ret ;---------- strob: mov P1.bus_dtr,c ; выдать бит data_key на bus_dtr acall time ; задержка установки данных clr P1.bus_clc ; активируем запрос синхронизации acall time ; задержка установки данных tx_tp0: mov a,P1 ; читаем входные линии Р1 в А jb ACC.bus_qt,tx_tp0 ; ожидание ответа приемника (bus_qt=0) setb P1.bus_clc ; деактивируем запрос синхронизации acall time ; задержка установки данных tx_tp1: mov a,P1 ; читаем входные линии Р1 в А jnb ACC.bus_qt,tx_tp1 ; ожидание ответа приемника (bus_qt=1) acall time ; задержка установки данных ret ;---------- time: mov r3,#10 ; интервал ~40uS период = 0,00004*5= ~0,0002 бита/секунду ttime: nop ; nop djnz r3,ttime ; cnt_tm = R3 ret ;---------- ;
; ;---------- ; ; модуль приема ; ; не имеет защиты от превышения ожидания длительности строба ; сопровождения исходя из предположения, что обмен между модулями ; является основной частью программы в промежутках между исполнением ; команд ; т.е. допускается полный останов обмена ; ; pspi_rxd: push cntbit_t push cnt_tm ; копировать временно используемый ресурс в стек mov r2,#bits_ct ; загрузить счетчик бит cntbit_t =r2 orl P1,#(1<<bus_dtr || 1<<bus_clc || 1<<bus_qt) ; настройка порта ; за исключением at89s52 возможно потребуется настройка портов ; /bus_dtr=bus_clc=ВХОД, bus_qt=ВЫХОД/ ; bus_dtr=bus_clc=bus_qt=ВХОД ; bus_dtr=bus_clc=bus_qt=1 rx_on: acall strobinp mov a,r7 rlc a mov data_key,c data_rx: acall strobinp djnz r2,data_rx pop cnt_tm pop cntbit_t ; ret ;---------- strobinp: mov a,P1 jb ACC.bus_clc,strobinp ; простой в ожидании rx_tp0: acall time ; задержка установки данных mov a,P1 mov c,ACC.bus_dtr xch a,r7 ; mov a,data_t rrc a xch a,r7 clr P1.bus_qt ; актвировать строб квитирования acall time ; задержка установки данных rx_tp1: mov a,P1 jnb ACC.bus_clc,rx_tp1 ; ждем ответ передатчика setb P1.bus_qt ; деактвировать строб квитирования acall time ; задержка установки данных ret ;---------- ; по выходу ; в data_key значение в соответствии с принятым (0 или 1) ; в R7 (data_t) принятые данные в прямом коде прямой последовательности ;----------
и вторая половинка kotuino\upgm\PAVR\librus\ файл trbspi_sb1.txt это для АВР Спойлер
Код:
; ; trbspi_sb1.txt ; ; файл протокола приемопередатчика проекта UPGM ; для блока подчиненной периферии(PAVR) ; /slave board/ ; ; ;---------- ; ; .equ bus_dtr = 0 ; шина данных/запроса доступа ; локализация в PORTA PAVR ; по reset вход с внешней подтяжкой к +5 вольт ; при запросе выход с активным уровнем 0 ; при обмене соответственно или вход или выход ; с данными в прямом коде ; .equ bus_clc = 1 ; тактовый строб обмена данными ; локализация в PORTA PAVR ; по reset/cold init вход с внешней подтяжкой к +5 вольт ; при обмене соответственно вход(прием) или выход(передача) ; активный уровень 0 ; .equ bus_qt = 0 ; шина квитирования ; локализация в PORTD PAVR ; по reset/cold init вход с внешней подтяжкой к +5 вольт ; активный уровень 0 ; вход для передатчика, выход для приемника ; ;---------- ; ; .def data_t = r11 ; регистр (урезан) данные данных trbspi_sb ; ;---------- ; ; данные флаги размещены в регистре РСФ GPIOR0 ; или по псевдониму доступа через ОЗУ (GPIOR0+0x20) ; ; .equ data_key = 0 ; (GPIOR0) флаг типа данные/команда ; data_key=0 - байт с данными ; data_key=1 - байт с командой ; ; ; ;---------- ; ; тактовая частота системного генератора 8МГц ; ;---------- ; ; настройки портов относительно PSPI ; ; исходно по reset ; DDRA=00000000 ; PORTA=00000000 ; входы с Z-состоянием ; DDRB=00000000 ; POTTB=00000000 ; входы с Z-состоянием ; DDRD=00000000 ; POTTD=00000000 ; входы с Z-состоянием ; В init проводим отключение подтягивающих резисторов ; MCUCR.PUD=1 ; и устанавливаем PORTD.ptr_clc = 0 DDRD.ptr_clc = ВЫХОД (1) ; ;---------- ; ; модуль передачи ; ; собственно передача data_key и байта данных ; перед вызовом программы ; данные должны быть загружены в ; data_t (r11) ; и установлен в соответствие флаг data_key ;(data_key=0 - байт с данными ; data_key=0 - байт с командой) ; ; pspi_txd: push tmp0 ; служебный буфер-времянка push tmp1 ; счетчик бит push tmp2 ; счетчик таймера интервалов cbi DDRA,bus_dtr cbi DDRA,bus_clc cbi DDRD,bus_qt ; предварительно настроено ; bus_dtr=bus_clc=bus_qt=ВХОД (через внешнюю ; подтяжку = 1) cbi PORTA,bus_dtr ; подготовлено к выдаче bus_dtr=0 ; вывод bus_dtr=1 cbi PORTA,bus_clc ; подготовлено к выдаче bus_clc=0 ; вывод bus_clc=1 cbi PORTD,bus_qt ; подготовлено к выдаче bus_qt=0 ; вывод bus_qt=1 tx_on: ldi tmp1,8 ; счетчик бит загружен in tmp0,GPIOR0 ; читаем флаг data_key rcall strob ; бит типа данных передан data_tx: mov tmp0,data_t rcall strob ; бит данных передан lsr tmp0 ; постсдвиг значения данных mov data_t,tmp0 ; используется вывод данных из tmp0.0 dec tmp1 brne data_tx tx_off: pop tmp2 pop tmp1 pop tmp0 ret ;---------- strob: sbrs tmp0,0 sbi DDRA,bus_dtr ; if tmp0,0=0 --> вывод bus_dtr=0 sbrc tmp0,0 cbi DDRA,bus_dtr ; if tmp0,0=1 --> вывод bus_dtr=1 ; вывод в соответствии нулевого бита из tmp0,0 ; на PORTA,bus_dtr rcall time ; задержка установки данных sbi DDRA,bus_clc ; активируем запрос синхронизации ; ранее в PORTA.bus_clc установлен 0 rcall time ; задержка установки данных tx_tp0: sbic PIND,bus_qt rjmp tx_tp0 ; ожидание ответа приемника (bus_qt=0) cbi DDRA,bus_clc ; деактивируем запрос синхронизации ; bus_clc=ВХОД ; единица на bus_clc формируется за счет внешнего ; подтягивающего резистора cbi DDRA,bus_dtr ; вывод bus_dtr=1 ; разворот шины данных на ВХОД rcall time ; задержка установки данных tx_tp1: sbis PIND,bus_qt rjmp tx_tp1 ; ожидание ответа приемника (bus_qt=1) rcall time ; задержка установки данных ret ;---------- time: ldi tmp2,10 ; интервал ~40uS период = 0,00004*5= ~0,0002 бита/секунду ttime: nop ; dec tmp2 brne ttime ret ;---------- ;
; ;---------- ; ; модуль приема ; ; не имеет защиты от превышения ожидания длительности строба ; сопровождения исходя из предположения, что обмен между модулями ; является основной частью программы в промежутках между исполнением ; команд ; т.е. допускается полный останов обмена ; ; при выходе ; ; в data_t принятые данные в прямом коде ; флаг GPIOR0.data_key=1 принята команда ; флаг GPIOR0.data_key=0 приняты данные ; ; pspi_rxd: push tmp0 ; буфер обмена push tmp1 ; счетчик бит push tmp2 ; счетчик таймера интервалов cbi DDRA,bus_dtr cbi DDRA,bus_clc cbi DDRD,bus_qt ; предварительно настроено на ; шины bus_dtr=bus_clc=bus_qt=ВХОД, bus_dtr=bus_clc=bus_qt1=1 cbi PORTA,bus_dtr ; подготовлено к выдаче bus_dtr=0 ; вывод bus_dtr=1 cbi PORTA,bus_clc ; подготовлено к выдаче bus_clc=0 ; вывод bus_clc=1 cbi PORTD,bus_qt ; подготовлено к выдаче bus_qt=0 ; вывод bus_qt=1 rx_on: rcall strobinp ; флаг типа данных получен sbrs tmp0,7 cbi GPIOR0,data_key sbrc tmp0,7 sbi GPIOR0,data_key ; флаг типа данных размещен ldi tmp1,8 ; загрузить счетчик бит data_rx: rcall strobinp ; текущий бит данных получен dec tmp1 brne data_rx mov data_t,tmp0 ; данные переданы в data_t pop tmp2 pop tmp1 pop tmp0 ret ;---------- strobinp: sbic PINA,bus_clc ; простой в ожидании PORTA.bus_clc=0 ; ***!!! выполняется БЕЗ ОГРАНИЧЕНИЯ НА ВРЕМЯ ОЖИДАНИЯ !!!*** rjmp strobinp rcall time ; задержка установки данных sbis PINA,bus_dtr clc sbic PINA,bus_dtr sec ror tmp0 ; заносим значение текущего PINA.bus_dtr в старший бит tmp0 sbi DDRD,bus_qt ; актвировать строб квитирования ; bus_qt=ВЫХОД с предварительно заданным ; (cbi PORTD,bus_qt) значением =0 rcall time ; задержка установки данных rx_tp1: sbis PINA,bus_clc ; простой в ожидании PORTA.bus_clc=1 ; ***!!! выполняется БЕЗ ОГРАНИЧЕНИЯ НА ВРЕМЯ ОЖИДАНИЯ !!!*** rjmp rx_tp1 cbi DDRD,bus_qt ; деактвировать строб квитирования ; bus_qt=ВХОД, единица устанавливается за счет внешнего ; подтягивающего резистора rcall time ; задержка установки данных ret ; ;---------- ;
Переносится алгоритм с учетом специфики ядра и системы команд.
А там в проекте сразу оговорка имела место - частота МК16 МГц! Посему и ставилась для проекта аттини45. Или иные АВРки с частотой 16МГц и выше.
Ну так.. на то и ассемблер, чтоб подобные вопросы решать(c) - не у всех в сундучке тини45. Тут релизация на тини13 9.6МГц http://www.getchip.net/posts/120-adjust ... #more-4589 фиксированых адресов нет, как и ответа ЗАЧЕМ оные:
У WS2812 два варианта скорости обмена - я выставлял прожку под максимально жесткие условия. Дополнительно ставилось требование как можно более высокой стабильности и равенства интервалов обработки условного перехода как для нулевого слота так и для слота передачи 1. Дабы не накапливалась ошибка при увеличении количества пакетов. Это чисто мой собственный интерес - что можно из МК ногодрыгом корректно выжать. Так что вполне реально и иное решение. Насчет 16 МГц - практически любая МЕГА на такой частоте с внешним кварцем работает.
Это чисто мой собственный интерес - что можно из МК ногодрыгом корректно выжать. Насчет 16 МГц - практически любая МЕГА на такой частоте с внешним кварцем работает.
опять 25 - "практически любая МЕГА" имеет UART и SPI, а PIC16F628 имеет UART, и AT89C51 имеет UART - при наличии аппаратного управления светодиодами какой смысл жопытному разработчику ногодрых. Вот на тини13 выжать - это уже царь-разработчик. з.ы. И где тут "позволил получить практически одинаковую методику написания проектов как для MCS51, так и для AVR и PIC10/12/16" - проще в итоге писать каждый раз по правилам конкретного семейства.
Аппаратные модули и для более соответствующих их назначению задач пригодятся. Особой надобности в таком решении для того, что и "дрыголап" выполняет как-то ЖАБОДАВНО применять. Относительно того "для каждого в его правилах"... По компилятору отличие лишь в командах. Да в некоторых специфических директивах, свойственных только конкретному семейству (директивы по перемещаемому коду у ПИКовых к примеру). Это вполне оперативно парируется картами команд и распечатками по компилятору (плюс распечатка системы команд для сложных случаев). Структуру и особенности конкретного МК при работе под ассемблером все равно необходимо по проработанному заранее даташиту отслеживать. Так что особой разницы не будет наблюдаться. Единственно по мере роста объёма аппаратных модулей мороки все больше.
BOB51, может пора перестать изобреДать и хотя бы начать смотреть как это сделано у вменяемых людей? http://elm-chan.org/works/sd8p/report.html Это я о долгобретятине с "слэнгом" и "многофайловости". Насчет :
Цитата:
Аппаратные модули и для более соответствующих их назначению задач пригодятся. Особой надобности в таком решении для того, что и "дрыголап" выполняет как-то ЖАБОДАВНО применять.
пиши как есть и проще - "у меня не взлетело"...
Последний раз редактировалось dosikus Пн мар 23, 2020 14:43:42, всего редактировалось 1 раз.
ну вот и вернулись на круги своя. В итоге задачка управления светодиодами все ж решается на Си изредка со "вставками" - все сводится к написанию ТОЛЬКО драйверов светодиодов под разные семейства или даже разные драйвера внутри семейств. Основной костяк программы для ВСЕХ семейств один и тот же - чисто на СИ. Что считаю крайне удобно для разработчика. И не надо для этой задачи чисто ассемблера и так называемых "классических" фиксированных адресов.
Последний раз редактировалось oleg110592 Пн мар 23, 2020 14:46:08, всего редактировалось 1 раз.
dosikus Приветствую! Да все прекрасно работает, ежли требуется. Я ж приводил пример ПО ПРОСЬБЕ показать, что не всякий *.asm файл легко вписывается в проект под СИ. Определяя место ассемблера в проектах под Си как максимум работу с краткими вставками. Хотя со мной и спорили, однако к такому подходу и вернулись: "...В итоге задачка управления светодиодами все ж решается на Си изредка со "вставками" - все сводится к написанию ТОЛЬКО драйверов светодиодов под разные семейства или даже разные драйвера внутри семейств. ..." Т.е. для любителя действует правило - пишем или на ассемблере или на Си или на ином ЯВУ. Не злоупотребляя в рамках одного проекта смесью. Насчет многомодульности - вопрос определяется или в рамках конкретного компилятора для конкретного семейства или методом выборки обобщенных для нескольких компиляторов ассемблера приемов. Можно и так и так - только в одном случае "по фэншую" и только в рамках одного семейства, в другом - "слэнг", но одинаково работающий на любом из используемых компиляторов. Естественно с соответствующими отступлениями от "чистокровного" построения проекта.
Конечно - можно ДРУГИМ заменить. Только я специально привел один из возможных вариантов, когда вставка ассемблерного файла по каким-либо причинам может быть неудачной.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 46
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения