Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: Котуинко

Сб мар 21, 2020 11:40:35

не, начинал задолго, когда под микронтроллеры Си вообще не существовало. И вообще когда микроконтроллеров было в магазине не купить только К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(); //единица
                     }
         }
      }
}

просто и со вкусом :lol:

Re: Котуинко

Сб мар 21, 2020 15:20:43

Для более-менее приличной работы под ассемблером простого "линейного" (одиночного) файла явно маловато.
А "по фэншую" надо при использовании нескольких *.asm файлов в одном проекте их в строке запуска приписывать ( да ещё и линкер добавлять, ежли компилятор не однофайловый).
Если несколько разных семейств - это уже большая проблема, чем удрать на Си.
Мне удалось соорудить вариант слэнга для организации многофайловиков под ассемблером (одинаково работающий в рамках всех трёх семейств - mcs51/avr/pic).
Собственно посему и переход далее уже не под "чистый Си", а к тому " слэнгу", что в ардуиноIDE употребляется.
Не классический подход, однако весьма удачный с точки зрения "продвинутого пользователя".
:beer:

Re: Котуинко

Сб мар 21, 2020 17:42:25

А "по фэншую" надо при использовании нескольких *.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     

отсюда (1999год):
http://elm-chan.org/works/mp3/report_e.html

Re: Котуинко

Сб мар 21, 2020 17:57:42

oleg110592 писал(а):зачем?
затем же, что и отедльные модули в Си: чтобы не ломать голову разными именами меток и прочих индентификаторов

Re: Котуинко

Сб мар 21, 2020 18:16:13

ну нынче ассемблеры поумнели - понимают подпрограммы - метки одинаковые могут быть:
Спойлер
Код:
include 'pic14.inc'

macro delai d
      movlw d
      call delay
end macro

green =0001'0000b
red   =0010'0000b
white =0000'0001b
black =0000'0000b

start:
   call gpinit
   call adinit
   call ledinit
   goto .a
.a:
   delai 10       ;1=from 760Hz to 25540Hz
   gpout green+red+white
   delai 100       ;1=50%
   gpout black
   goto .a
;;;;;;;;;;;;;;;;;;;;;;;;;;;
delay:
   call adsample
   movwf al
.a:
   mov ah,bl
.b:
   loop ah,.b
   loop al,.a
   return     

или даже так - метка однообразная @@ - ходим к ближайшей или назад или вперед:
Спойлер
Код:
start:
   call gpinit
   call adinit
   call ledinit
   goto @f
   nop
@@:
   delai 10       ;1=from 760Hz to 25540Hz
   gpout green+red+white
   delai 100       ;1=50%
   gpout black
   goto @b           

Re: Котуинко

Сб мар 21, 2020 18:18:17

Потому что для добавления файлов частенько простого ".include имя файла"
недостаточно.
Тем более, что приведенная Вами, oleg110592, цитата на практике равноценна именно "слэнговому" подключению простейшего *.txt файла.
И действует лишь как простое последовательное суммирование текстов перечисленных файлов.
По фэншую нужно каждый файл указать отдельно в строчке запуска компилятора, да еще и добавить опции линкера, также для каждого из обрабаиываемых файлов...
Ведь рассматривается не только компилятор ассемблера АВР, но и компиляторы PIC и MCS51.
А у 51-й помимо c51asm.exe от атмеля существует и классика от кейла и многокомпонентный от AD2500...
Там уже правила запуска посложнее (благо этим мастер проекта в IDE автоматически занимается для основного файла).
Помимо прочего у "слэнга" еще дополнительные особенности по оформлению участка объявления констант/данных всех включенных в проект файлов - это уже из собственного опыта.
8)
Кстати...
Я ввел *.txt именно по причине того, что вариант .include это именно "слэнг", а не "фэншуй".
Дабы не вводить народ в заблуждение.
:beer:
Простое подключение будет аналогично ручной установке фрагмента исходника в соответствующем месте.
Компилятор будет обрабатывать такой файл последовательно всего лишь как единый текст.
А вот запуск с командной строки с указанием перечня файлов и опций их обработки дает совсем иной результат.
:roll:
В то же время если все *.asm файлы размещены в папке проекта, и если используется именно IDE, а не командная строка, процесс генерации строки запуска помогает сделать мастер проекта.
Так и у ПИКов в мпасм и у аврок в авр студии.
Но опять же трогать те настройки дело достаточно муторное и у каждоо компилятора со своей спецификой.
:(
Последний раз редактировалось BOB51 Сб мар 21, 2020 18:42:50, всего редактировалось 1 раз.

Re: Котуинко

Сб мар 21, 2020 18:40:09

Потому что для добавления файлов частенько простого ".include имя файла" недостаточно

простите мою необразованность - почему?
почему "слэнговому" - тоже непонятно - не видел в документации к ассемблеру слова слэнг.
"простейшего *.txt файла" тоже не годится - не будет подсветки синтаксиса цветом в редакторе, что неудобно для разработки.
"Ведь рассматривается не только компилятор ассемблера АВР, но и компиляторы PIC и MCS51" - у каждого компилятора своя документация - под одну гребенку не причешешь.
Вот Си - он и в Африке Си - практически все однообразно не считая костылей.

Re: Котуинко

Сб мар 21, 2020 18:55:46

Да...
Потеря подсветки синтаксиса - это оплата за единообразие подхода к написанию...
Это вполне приемлемая плата.
8)
Почему простой .iclude *.asm не подходит - у разных компиляторов разное к ним отношение, а предпочтительно иметь однотипные оформления текстов и установок обработки. Чтоб меньше излишней мозготрепки...
Уже не помню на чем в прошлом облом получил - когда удалось получить удачное работоспособное решение просто копать глубже не стал.
:dont_know:
Вопросы многофайловых проектов под ассемблером достаточно редко и слабо рассматриваются... Как только до этого доходит - сразу начинается миграция на ЯВУ.
8)
Именно "слэнг" , причем с применением некоторых ограничений по директивам и подборке компиляторов/IDE и позволил получить практически одинаковую методику написания проектов как для MCS51, так и для AVR и PIC10/12/16.
Да и написание текстовок можно выполнять в одном редакторе с последующей подстановкой в конкретный проект.
Ограничения получают директивы имеющие различное толкование.
Основа - три распечатки с "заметками на полях".
Собственно расширение *.txt помимо прочего не нервирует автоматику мастера проектов IDE.
:roll:
Результат меня весьма удовлетворяет.
:hunger:

Решил малость повыделываться над прожкой, что ранее (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) ; не может быть более объема ОЗУ - стек!!!


;таблица обьявленных имен - переназначение регистров РОН
;
; .def name = r31 ; ZH регистр (полный)
; .def name = r30 ; ZL регистр (полный)
; .def name = r29 ; YH регистр (полный)
; .def name = r28 ; YL регистр (полный)
; .def name = r27 ; XH регистр (полный) указатель текущей ячейки массива bufout
; .def name = r26 ; XL регистр (полный) указатель текущей ячейки массива bufout
; .def name = r25 ; регистр (полный) BH
; .def name = r24 ; регистр (полный) BL
; .def name = r23 ; регистр (полный)
; .def name = r22 ; регистр (полный)
; .def name = r21 ; регистр (полный)
; .def name = r20 ; регистр (полный)
; .def name = r19 ; регистр (полный)
; .def name = r18 ; регистр (полный)
; .def tmp1 = r17 ; регистр (полный) счетчик байт вывода
; .def tmp0 = r16 ; регистр (полный) буфер выводимого байта
; .def regn = r15 ; регистр (урезан)
; .def regn = r14 ; регистр (урезан)
; .def regn = r11 ; регистр (урезан)
; .def regn = r10 ; регистр (урезан)
; .def regn = r9 ; регистр (урезан)
; .def regn = r8 ; регистр (урезан)
; .def regn = r7 ; регистр (урезан)
; .def regn = r6 ; регистр (урезан)
; .def regn = r5 ; регистр (урезан)
; .def regn = r4 ; регистр (урезан)
; .def regn = r3 ; регистр (урезан)
; .def regn = r2 ; регистр (урезан)
; .def matr = r1 ; регистр (урезан) r1 по возможности не использовать!!!
; .def madr = r0 ; регистр (урезан) r0 по возможности не использовать!!!
;
;----------
;  .macro   ;; ввод и предобработка данных
;     
;     
;    .endmacro
;
;----------
;
; определение буфера вывода в области данных
;  .dseg
;  .org bufout
;point0: .byte 3 ; g:r:b
;point1: .byte 3 ; g:r:b
;point2: .byte 3 ; g:r:b
;point3: .byte 3 ; g:r:b
;point4: .byte 3 ; g:r:b
;point5: .byte 3 ; g:r:b
;point6: .byte 3 ; g:r:b
;point7: .byte 3 ; g:r:b
;point8: .byte 3 ; g:r:b
;point9: .byte 3 ; g:r:b
;point10: .byte 3 ; g:r:b
;point11: .byte 3 ; g:r:b
;point12: .byte 3 ; g:r:b
;point13: .byte 3 ; g:r:b
;point14: .byte 3 ; g:r:b
;point15: .byte 3 ; g:r:b
;point16: .byte 3 ; g:r:b
;point17: .byte 3 ; g:r:b
;point18: .byte 3 ; g:r:b
;point19: .byte 3 ; g:r:b
;point20: .byte 3 ; g:r:b
;point21: .byte 3 ; g:r:b
;point22: .byte 3 ; g:r:b
;point23: .byte 3 ; g:r:b
;point24: .byte 3 ; g:r:b
;point25: .byte 3 ; g:r:b
;point26: .byte 3 ; g:r:b
;point27: .byte 3 ; g:r:b
;point28: .byte 3 ; g:r:b
;point29: .byte 3 ; g:r:b
;point30: .byte 3 ; g:r:b
;point31: .byte 3 ; g:r:b
;point32: .byte 3 ; g:r:b
;point33: .byte 3 ; g:r:b
;point34: .byte 3 ; g:r:b
;point35: .byte 3 ; g:r:b
;point36: .byte 3 ; g:r:b
;point37: .byte 3 ; g:r:b
;point38: .byte 3 ; g:r:b
;point39: .byte 3 ; g:r:b
;point40: .byte 3 ; g:r:b
;point41: .byte 3 ; g:r:b
;point42: .byte 3 ; g:r:b
;point43: .byte 3 ; g:r:b
;point44: .byte 3 ; g:r:b
;point45: .byte 3 ; g:r:b
;point46: .byte 3 ; g:r:b
;point47: .byte 3 ; g:r:b
;point48: .byte 3 ; g:r:b
;point49: .byte 3 ; g:r:b
;point50: .byte 3 ; g:r:b
;point51: .byte 3 ; g:r:b
;point52: .byte 3 ; g:r:b
;point53: .byte 3 ; g:r:b
;point54: .byte 3 ; g:r:b
;point55: .byte 3 ; g:r:b
;point56: .byte 3 ; g:r:b
;point57: .byte 3 ; g:r:b
;point58: .byte 3 ; g:r:b
;point59: .byte 3 ; g:r:b
;
;----------

  .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 цикла
;----------

:roll:
Только вот... при создании "перемещаемой таблицы" потребовалось введение опорной контрольной точки
Код:
bptr0:
  nop

внутри файла...
Да размер окна задать не в 32 слова, а в 256... (размер "компонентов" задан как 16 слов)
:write:

Re: Котуинко

Пн мар 23, 2020 09:33:24

и позволил получить практически одинаковую методику написания проектов как для MCS51, так и для AVR и PIC10/12/16.

ну и теперь смертельный номер - покажите как будет выглядеть файл trd2812_m для:
1)Tiny13 на 9,6Мгц
2)AT89C51 на 12МГц
3)PIC10/12/16 на 4МГц
:)))

Re: Котуинко

Пн мар 23, 2020 09:52:35

А там в проекте сразу оговорка имела место - частота МК16 МГц!
:twisted:
Посему и ставилась для проекта аттини45.
Или иные АВРки с частотой 16МГц и выше.
8)
Касательно переноса алгоритма - при достаточной скорости исполнения команд можно и посмотреть.
Например под STC (mcs51 имеющих исполнение команды за один такт)...
ПИКушки разве что из "энхансед" с PLL (чаще в 18 серии встречаются).
То при желании/необходимости не так уж и сложно...
:roll:
Как вариант однотипного алгоритма на двух семействах под ассемблером можно глянуть ранее выкладывавшийся
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
;
;----------
;

:tea:
Переносится алгоритм с учетом специфики ядра и системы команд.
:beer:

Re: Котуинко

Пн мар 23, 2020 10:10:01

А там в проекте сразу оговорка имела место - частота МК16 МГц!
:twisted:
Посему и ставилась для проекта аттини45.
Или иные АВРки с частотой 16МГц и выше.

Ну так.. на то и ассемблер, чтоб подобные вопросы решать(c) - не у всех в сундучке тини45.
Тут релизация на тини13 9.6МГц
http://www.getchip.net/posts/120-adjust ... #more-4589
фиксированых адресов нет, как и ответа ЗАЧЕМ оные:
Изображение

Re: Котуинко

Пн мар 23, 2020 10:19:08

У WS2812 два варианта скорости обмена - я выставлял прожку под максимально жесткие условия.
Дополнительно ставилось требование как можно более высокой стабильности и равенства интервалов обработки условного перехода как для нулевого слота так и для слота передачи 1. Дабы не накапливалась ошибка при увеличении количества пакетов.
Это чисто мой собственный интерес - что можно из МК ногодрыгом корректно выжать.
Так что вполне реально и иное решение.
8)
Насчет 16 МГц - практически любая МЕГА на такой частоте с внешним кварцем работает.
:wink:

Re: Котуинко

Пн мар 23, 2020 11:18:30

Это чисто мой собственный интерес - что можно из МК ногодрыгом корректно выжать.
Насчет 16 МГц - практически любая МЕГА на такой частоте с внешним кварцем работает.

опять 25 - "практически любая МЕГА" имеет UART и SPI, а PIC16F628 имеет UART, и AT89C51 имеет UART - при наличии аппаратного управления светодиодами какой смысл жопытному разработчику ногодрых. Вот на тини13 выжать - это уже царь-разработчик. :))
з.ы. И где тут "позволил получить практически одинаковую методику написания проектов как для MCS51, так и для AVR и PIC10/12/16" - проще в итоге писать каждый раз по правилам конкретного семейства.

Re: Котуинко

Пн мар 23, 2020 14:08:15

Аппаратные модули и для более соответствующих их назначению задач пригодятся.
Особой надобности в таком решении для того, что и "дрыголап" выполняет как-то ЖАБОДАВНО применять.
8)
Относительно того "для каждого в его правилах"...
По компилятору отличие лишь в командах. Да в некоторых специфических директивах, свойственных только конкретному семейству (директивы по перемещаемому коду у ПИКовых к примеру).
Это вполне оперативно парируется картами команд и распечатками по компилятору (плюс распечатка системы команд для сложных случаев).
Структуру и особенности конкретного МК при работе под ассемблером все равно необходимо по проработанному заранее даташиту отслеживать.
Так что особой разницы не будет наблюдаться.
Единственно по мере роста объёма аппаратных модулей мороки все больше.
:beer:

Re: Котуинко

Пн мар 23, 2020 14:41:30

BOB51, может пора перестать изобреДать и хотя бы начать смотреть как это сделано у вменяемых людей?
http://elm-chan.org/works/sd8p/report.html
Это я о долгобретятине с "слэнгом" и "многофайловости".
Насчет :
Аппаратные модули и для более соответствующих их назначению задач пригодятся.
Особой надобности в таком решении для того, что и "дрыголап" выполняет как-то ЖАБОДАВНО применять.

пиши как есть и проще - "у меня не взлетело"...
Последний раз редактировалось dosikus Пн мар 23, 2020 14:43:42, всего редактировалось 1 раз.

Re: Котуинко

Пн мар 23, 2020 14:43:22

ну вот и вернулись на круги своя. В итоге задачка управления светодиодами все ж решается на Си изредка со "вставками" - все сводится к написанию ТОЛЬКО драйверов светодиодов под разные семейства или даже разные драйвера внутри семейств. Основной костяк программы для ВСЕХ семейств один и тот же - чисто на СИ. Что считаю крайне удобно для разработчика. И не надо для этой задачи чисто ассемблера и так называемых "классических" фиксированных адресов.
Последний раз редактировалось oleg110592 Пн мар 23, 2020 14:46:08, всего редактировалось 1 раз.

Re: Котуинко

Пн мар 23, 2020 14:45:31

oleg110592, тем более, что ему не завезли методичек о создании и структуре модульного проекта на асмЪ ПОД АВР...

Re: Котуинко

Пн мар 23, 2020 15:12:22

dosikus
Приветствую!
Да все прекрасно работает, ежли требуется.
Я ж приводил пример ПО ПРОСЬБЕ показать, что не всякий *.asm файл легко вписывается в проект под СИ.
Определяя место ассемблера в проектах под Си как максимум работу с краткими вставками.
Хотя со мной и спорили, однако к такому подходу и вернулись:
"...В итоге задачка управления светодиодами все ж решается на Си изредка со "вставками" - все сводится к написанию ТОЛЬКО драйверов светодиодов под разные семейства или даже разные драйвера внутри семейств.
..."
Т.е. для любителя действует правило - пишем или на ассемблере или на Си или на ином ЯВУ. Не злоупотребляя в рамках одного проекта смесью.
8)
Насчет многомодульности - вопрос определяется или в рамках конкретного компилятора для конкретного семейства или методом выборки обобщенных для нескольких компиляторов ассемблера приемов.
Можно и так и так - только в одном случае "по фэншую" и только в рамках одного семейства, в другом - "слэнг", но одинаково работающий на любом из используемых компиляторов. Естественно с соответствующими отступлениями от "чистокровного" построения проекта.
8)

Re: Котуинко

Пн мар 23, 2020 15:20:37

Я ж приводил пример ПО ПРОСЬБЕ показать, что не всякий *.asm файл легко вписывается в проект под СИ.

определили ж - файл несчитовый и легко заменяется другим

Re: Котуинко

Пн мар 23, 2020 15:23:24

Конечно - можно ДРУГИМ заменить.
Только я специально привел один из возможных вариантов, когда вставка ассемблерного файла по каким-либо причинам может быть неудачной.
:beer:
Ответить