Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Применение Assembler в среде Bascom(-8051) » Вставки на ASM AVR (ассемблер)


Вставки на ASM AVR (ассемблер)

Сообщений 1 страница 30 из 39

1

Если нужно максимально быстро, можно использовать вставки на ASM AVR (ассемблер)

+1

2

Поставить флажок в прерывании:

силами Bascom

  on int0 обработка_прерывания_int0

  dim флаг as byte

.....

....

  обработка_прерывания_int0:

    флаг=1

  return

Итого, уложимся в:

заход в прерывание = 8 тактов
сохранение всех регистров = 32 (регистра) * 2 такта + SREG(3 такта) = 67 тактов

поднятие флага = 3 такта

восстановление всех регистров = 32 (регистра) * 2 такта + SREG(3 такта) = 67 тактов
выход из прерывания = 4 такта

8 + 67 + 3 + 67 + 4 = 149 тактов, из которых полезных всего 3 такта процессора


силами ASM AVR

  on int0 обработка_прерывания_int0 nosave

  dim флаг as byte

.....

....

  обработка_прерывания_int0:

    $asm
       push R16
       ldi R16 , 1
       sts {флаг} , R16
       pop R16
       reti
    $end asm

  return

Итого, уложимся в:

заход в прерывание = 8 тактов
сохранение всех регистров = 1 (регистр) * 2 такта  = 2 такта

поднятие флага = 3 такта

восстановление всех регистров = 1 (регистр) * 2 такта  = 2 такта
выход из прерывания = 4 такта

8 + 2 + 3 + 2 + 4 = 19 тактов

0

3

'  Аналог команды "Incr Переменная_byte"
  lds R16 , {Переменная_byte}
  inc R16
  sts {Переменная_byte} , R16

'  Аналог команды "Decr Переменная_byte"
  lds R16 , {Переменная_byte}
  dec R16
  sts {Переменная_byte} , R16

'  Аналог команды "Decr Переменная_word"
  Loadadr Переменная_word , X       ' Загрузка адреса переменной в регистровую пару R26:R27, 2 такта
  ld R30 , X+       ' Косвенная загрузка с пост-инкрементом, 2 такта
  ld R31 , X       ' Косвенная загрузка, 2 такта
  subi R30 , &H01       ' Вычитание константы, 1 такт
  sbci R31 , &H00       ' Вычитание константы с переносом, 1 такт
  st X , R31       ' Косвенное сохранение, 2 такта
  St -x , R30       ' Косвенное сохранение с пре-декрементом, 2 такта

'  Аналог команды "Incr Переменная_word"
  Loadadr Переменная_word , X       ' Загрузка адреса переменной в регистровую пару R26:R27, 2 такта
  ld R30 , X+       ' Косвенная загрузка с пост-инкрементом, 2 такта
  ld R31 , X       ' Косвенная загрузка, 2 такта
  subi R30 , &HFF       ' Вычитание константы, 1 такт
  sbci R31 , &HFF       ' Вычитание константы с переносом, 1 такт
  st X , R31       ' Косвенное сохранение, 2 такта
  St -x , R30       ' Косвенное сохранение с пре-декрементом, 2 такта

'Аналог команды "Переменная_word + 1"
'Узнаём адрес переменной
  Loadadr Переменная_word , X
' Грузим из переменной в регистры
  ld R16 , X+       ' Косвенная загрузка с пост-инкрементом, 2 такта
  ld R17 , X       ' Косвенная загрузка, 2 такта
'Загружаем нужное число (BIN; DEC; HEX)
  ldi R20 , &H01       ' число 1   Загрузить константу, 1 такт
  ldi R21 , &H00       ' число 0   Загрузить константу, 1 такт
'Плюсуем к тому, что было в переменной
  add R16 , R20       ' Суммирование без переноса, 1 такт
  adc R17 , R21       ' Суммирование с переносом, 1 такт
'Узнаём адрес переменной
  Loadadr Переменная_word , X
'Грузим обратно в переменную
  St X+ , R16       ' Косвенное сохранение, 2 такта
  st X , R17       ' Косвенное сохранение с пре-декрементом, 2 такта

$asm
'Аналог команды "Переменная_word - 1"
'Узнаём адрес переменной
  Loadadr Переменная_word , X
' Грузим из переменной в регистры
  ld R16 , X+       ' Косвенная загрузка с пост-инкрементом, 2 такта
  ld R17 , X       ' Косвенная загрузка, 2 такта
'Загружаем нужное число (BIN; DEC; HEX)
  ldi R20 , &H01       ' число 1    Загрузить константу, 1 такт
  ldi R21 , &H00       ' число 0    Загрузить константу, 1 такт
'Плюсуем к тому, что было в переменной
  Sub R16 , R20       ' Вычитание без переноса, 1 такт
  sbc R17 , R21       ' Вычитание с переносом, 1 такт
'Узнаём адрес переменной
  Loadadr Переменная_word , X
'Грузим обратно в переменную
  St X+ , R16       ' Косвенное сохранение, 2 такта
  st X , R17       ' Косвенное сохранение с пре-декрементом, 2 такта
  $end Asm

Может кому пригодится!

Incr переменная типа "Long" (только положительные значения) или "Dword" в прерывании.

Используется один регистр!

'===============================================================================
  Обработка_прерывания_timer0:
'-------------------------------------------------------------------------------
'    Incr Переменная_long_0

    !push R16       ' Время выполнения инструкции 2 такта
    !in R16 , sreg       ' Время выполнения инструкции 1 такт
    !push R16       ' Время выполнения инструкции 2 такта

    !lds  R16 , {Переменная_long_0}       ' Время выполнения инструкции 2 такта
    !SUBI R16 , (-1)       ' Время выполнения инструкции 1 такт
    !sts  {Переменная_long_0} , R16       ' Время выполнения инструкции 2 такта

    !lds  R16 , {Переменная_long_0 + 1}       ' Время выполнения инструкции 2 такта
    !SBcI R16 , (-1)             ' Время выполнения инструкции 1 такт
    !sts  {Переменная_long_0 + 1} , R16       ' Время выполнения инструкции 2 такта

    !lds  R16 , {Переменная_long_0 + 2}       ' Время выполнения инструкции 2 такта
    !SBcI R16 , (-1)     ' Время выполнения инструкции 1 такт
    !sts  {Переменная_long_0 + 2} , R16       ' Время выполнения инструкции 2 такта

    !lds  R16 , {Переменная_long_0 + 3}       ' Время выполнения инструкции 2 такта
    !SBcI R16 , (-1)       ' Время выполнения инструкции 1 такт
    !sts  {Переменная_long_0 + 3} , R16       ' Время выполнения инструкции 2 такта

    !pop R16       ' Время выполнения инструкции 2 такта
    !out sreg , R16    ' Время выполнения инструкции 1 такт
    !pop R16       ' Время выполнения инструкции 2 такта

'-------------------------------------------------------------------------------
  Return
'===============================================================================

+2

4

' Если проворачивать битики один раз, аналог (Rotate переменная типа "Word" , Right , 1)
    Rotate_right_word:
      lds R18 , {Переменная_word}       ' Забираем переменную в регистры
      lds R19 , {Переменная_word + 1}       ' Забираем переменную в регистры
      lsr R19       ' Логический сдвиг вправо
      Ror R18       ' Циклический сдвиг вправо через C
      brcc Rotate_right_word_1       ' Перейти если перенос очищен
      ori R19 , &B_1000_0000       '  Логическое ИЛИ с константой
    Rotate_right_word_1:
    ' Сохраняем результат вращения битов в переменную
      sts {Переменная_word} , R18       ' Сохраняем регистры в переменную
      sts {Переменная_word + 1} , R19       ' Сохраняем регистры в переменную
    ret

'  Крутим биты в переменной типа "Word" направо, аналог команды на Bascom - ( Rotate переменная типа "Word" , Right , число проворотов )
    Rotate_right_word:
      ldi R21 , 1       ' На сколько бит смещаем переменную типа "Word" (число проворотов)
      lds R18 , {Переменная_word}       ' Забираем переменную в регистры
      lds R19 , {Переменная_wordd + 1}       ' Забираем переменную в регистры
      cpi R21 , 0       ' Если 0, выходим
      breq Выход_rotate_Right_word       ' Перейти если равно
    Rotate_right_word_1:
      lsr R19       ' Логический сдвиг вправо
      Ror R18       ' Циклический сдвиг вправо через C
      brcc Rotate_right_word_2       ' Перейти если перенос очищен
      ori R19 , &B_1000_0000       '  Логическое ИЛИ с константой
    Rotate_right_word_2:
      dec R21       ' Декрементировать значение регистра
      brne Rotate_right_word_1       ' Если не 0, крутим битики ещё
    ' Сохраняем результат вращения битов в переменную
      sts {Переменная_word} , R18       ' Сохраняем регистры в переменную
      sts {Переменная_word + 1} , R19       ' Сохраняем регистры в переменную
    Выход_rotate_right_word:
     ret

' Если проворачивать битики один раз, аналог (Rotate переменная типа "Word" , Left , 1)
    Rotate_left_word:
      clr R20       ' Получаем нолик
      lds R18 , {Переменная_word}       ' Забираем переменную в регистры
      lds R19 , {Переменная_word + 1}       ' Забираем переменную в регистры
      lsl R18       ' Логический сдвиг влево
      Rol R19       ' Циклический сдвиг влево через C
      adc R18 , R20       '  Суммирование с переносом
     'Сохраняем результат вращения битов в переменную
      sts {Переменная_word} , R18       ' Сохраняем регистры в переменную
      sts {Переменная_word + 1} , R19       ' Сохраняем регистры в переменную
    ret

'  Крутим биты в переменной типа "Word" влево, аналог команды на Bascom - ( Rotate переменная типа "Word" , Left , число проворотов )
    Rotate_left_word:
      clr R20
      ldi R21 , 1       ' На сколько бит смещаем переменную типа "Word"
      lds R18 , {Переменная_word}       ' Забираем переменную в регистры
      lds R19 , {Переменная_word + 1}       ' Забираем переменную в регистры
    Rotate_left_word_1:
      cpi R21 , 0       ' Если 0, выходим
      breq Выход_rotate_left_word
      lsl R18       ' Логический сдвиг влево
      Rol R19       ' Циклический сдвиг влево через C
      adc R18 , R20       '  Суммирование с переносом
      dec R21       ' Декрементировать значение регистра
      brne Rotate_left_word_1       ' Если не 0, крутим битики ещё
     'Сохраняем результат вращения битов в переменную
      sts {Переменная_word} , R18       ' Сохраняем регистры в переменную
      sts {Переменная_word + 1} , R19       ' Сохраняем регистры в переменную
    Выход_rotate_left_word:
     ret

+2

5

' Аналог команды:   переменная_long = переменная_long + переменная_word

     !lds   R26  ,  {переменная_long}       ' Время выполнения инструкции 2 такта
    !lds   R27  ,  {переменная_word}       ' Время выполнения инструкции 2 такта
    !add   R26  ,  R27       ' Время выполнения инструкции 1 такт
    !sts   {переменная_long}  ,  R26       ' Время выполнения инструкции 2 такта
    !lds   R26  ,  {переменная_long + 1}       ' Время выполнения инструкции 2 такта
    !lds   R27  ,  {переменная_word + 1}       ' Время выполнения инструкции 2 такта
    !adc   R26  ,  R27       ' Время выполнения инструкции 1 такт
    !sts   {переменная_long + 1}  ,  R26       ' Время выполнения инструкции 2 такта
    !lds   R26  ,  {переменная_long + 2}       ' Время выполнения инструкции 2 такта
    !clr   R27       ' Время выполнения инструкции 1 такт
    !adc   R26  ,  R27       ' Время выполнения инструкции 1 такт
    !sts   {переменная_long + 2}  ,  R26       ' Время выполнения инструкции 2 такта
    !lds   R26  ,  {переменная_long + 3}       ' Время выполнения инструкции 2 такта
    !clr   R27       ' Время выполнения инструкции 1 такт
    !adc   R26  ,  R27       ' Время выполнения инструкции 1 такт
    !sts   {переменная_long + 3}  ,  R26       ' Время выполнения инструкции 2 такта

+2

6

Исполнение на Bascom

' Время выполнения команд 39 тактов, если меньше или равно, иначе 43 такта
   Переменная_word_3 = Переменная_word_1 + Переменная_word_2

   If Переменная_word_3 > 1024 Then
       Переменная_word_3 = 1024
   End If


Исполнение на ASM AVR

' Время выполнения команд 19 тактов, если меньше или равно, иначе 21 такт
   lds R16 , {Переменная_word_1}       ' 2 такта
   lds R17 , {Переменная_word_2}       ' 2 такта
   add R16 , R17       ' 1 такт
   lds R17 , {Переменная_word_1 + 1}       ' 2 такта
   lds R18 , {Переменная_word_2 + 1}       ' 2 такта
   adc R17 , R18       ' 1 такт
   cpi R16 , &H00       'Значение (пример &H00)       ' 1 такт Младший разряд сравниваемого значения, больше которого оно-же и остаётся
   ldi R18 , &H04       'Значение (пример &H04 (1024))       ' 1 такт Старший разряд сравниваемого значения, больше которого оно-же и остаётся
   cpc R17 , R18       ' 1 такт
   brcs Запись_в_переменную_word_3       ' 2 такта если переход, иначе 1 такт
   breq Запись_в_переменную_word_3       ' 2 такта если переход, иначе 1 такт
   ldi R16 , &H00       ' Значение (пример &H00)      ' Младший разряд сравниваемого значения, больше которого оно-же и остаётся
   ldi R17 , &H04       ' Значение (пример &H04 (1024))       ' Старший разряд сравниваемого значения, больше которого оно-же и остаётся
  Запись_в_переменную_word_3:
   STS {Переменная_word_3} , R16       ' 2 такта
   sts {Переменная_word_3 + 1} , R17       ' 2 такта

+1

7

Переход из прерывания на метки, без последствий для стека.

В архиве 2 симуляции, с "Terminal" и "COMPIM" (связь через виртуальный ComPort с железом).

У кого не настроены виртуальные порты - отключите "COMPIM" и подключите "Terminal". ! ВНИМАНИЕ ! Вместе работать не будут !

Симуляция Протеус 7.10 + мсходник Bascom 2.0.7.1 + программа терминал  + бонус для работы "COMPIM" (пароль в личку) --  скачать

http://sa.uploads.ru/t/ys3Ir.jpg http://sa.uploads.ru/t/aNskc.jpg

+2

8

Раскидываем значение переменной типа "Long" или "Dword" по разрядам 7-seg Led индикаторов

Вариант на ASM AVR  -  738 тактов процессора на 6 разрядов Led индикации

Вариант силами Bascom  -  9755 тактов процессора на 6 разрядов Led индикации

Разница скорости  ~ 13 раз !


Обсуждение темы  ---  здесь


Симуляция Протеус 7.10 + исходники Bascom 2.0.7.1 (варианты на ASM AVR и силами Bascom)   --  скачать

http://sa.uploads.ru/t/ht3LN.jpg http://sa.uploads.ru/t/EoAVa.jpg

+3

9

Раскидываем значение переменной типа "Word" по разрядам 7-seg Led индикаторов

Вариант на ASM AVR  -  409 тактов процессора на 5 разрядов Led индикации


Симуляция Протеус 7.10 + исходники Bascom 2.0.7.1 (варианты на ASM AVR и силами Bascom)   --  скачать


http://sa.uploads.ru/t/hxRGq.jpg http://sa.uploads.ru/t/y5647.jpg

+1

10

Раскидываем значение переменной типа "Byte" по разрядам 7-seg Led индикаторов

Вариант на ASM AVR  -  210 тактов процессора на 3 разряда Led индикации


Симуляция Протеус 7.10 + исходники Bascom 2.0.7.1 (варианты на ASM AVR и силами Bascom)   --  скачать


http://sa.uploads.ru/t/GOjB6.jpg http://sa.uploads.ru/t/FETZA.jpg

+1

11

Раскидываем значения двух переменных типа "Word" по разрядам 7-seg Led индикаторов

Вариант на ASM AVR  -  978 тактов процессора на 8 разрядов Led индикации


Симуляция Протеус 7.10 + исходники Bascom 2.0.7.1 (варианты на ASM AVR и силами Bascom)   --  скачать


http://sa.uploads.ru/t/Dzi8N.jpg http://sa.uploads.ru/t/4EN1V.jpg

+1

12

----------------------------------------------------

Работа с 7-seg Led индикаторами на ASM AVR

8 разрядов

Выводы МК, которые обслуживают индикаторы, можно переназначить в исходнике


Симуляция Протеус 7.10 + исходники Bascom 2.0.7.1 (варианты на ASM AVR и силами Bascom)   --  скачать


http://sa.uploads.ru/t/8pnbX.jpg

+1

13

Выборка из 128 измерений АЦП, запущенного в режиме "Free", с последующим делением на 128 (так называемое усреднение), написано на ASM AVR

Исходник

$map       ' Получаем карту распределения памяти в отчёте компиляции
  $regfile = "m328pdef.dat"       ' Используемый контроллер
  $crystal = 8000000       ' Частота работы контроллера
  $framesize = 32       ' Размер области используемой для преобразований
  $hwstack = 40       ' Размер аппаратного стека
  $swstack = 16       ' Размер программного стека

'-------------  Настройка USART  -----------------------------------------------
  $baud = 38400
  Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0

'-------------  Настройка АЦП  -------------------------------------------------
  Config Adc = Free , Prescaler = 128 , Reference = Avcc       ' Источник опорного напряжения Reference может быть: Aref – внешний источник, Avcc – напряжение питания схемы и Internal – внутренний
  On Adc Обработка_прерывания_ацп_asm Nosave

  Admux.mux0 = 1       ' Используем ADC3
  Admux.mux1 = 1       ' Используем ADC3
  Admux.adlar = 1       ' Берём 8 бит из 10, считываем только ADCH

  Dim Фоторезистор As Byte
  Dim Флаг_данные_ацп As Byte
  Dim Temp_фоторезистор As Byte
  Dim Сумма_измерений_ацп_word As Word
  Dim Счетчик_измерений_ацп As Byte

'\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
'--------------  Разрешаем работу необходимых прерываний  ----------------------
  Enable Adc : Start Adc

'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts

'-------------------------------------------------------------------------------
'Ждём первой выборки замеров АЦП
Ждем_первый_замер_ацп:
  Idle
  If Флаг_данные_ацп = 0 Then
      Goto Ждем_первый_замер_ацп
  End If
  Флаг_данные_ацп = 0

'===============================================================================
'                   Г Л А В Н Ы Й         Ц И К Л
  Главный_цикл:
'===============================================================================

   If Флаг_данные_ацп <> 0 Then
       Print Фоторезистор
       Флаг_данные_ацп = 0
       Goto Главный_цикл
   End If

   Idle       ' Отправляем МК на тихий час
'===============================================================================
  Goto Главный_цикл
End
'===============================================================================
'       П О Д К Л Ю Ч Е Н И Е     Р А Б О Ч И Х     М О Д У Л Е Й
'===============================================================================

'===============================================================================
  Обработка_прерывания_ацп_asm:
'-------------------------------------------------------------------------------
   'Сохраняем регистры, которые будем использовать и SREG
    !push R16
    !in R16 , sreg
    !push R16
    !push R30
    !push R31

   'Забираем 8 бит АЦП
    !in R16 , adch

   'Суммируем 128 измерений, для последующего усреднения
    !lds R30 ,{Сумма_измерений_ацп_word}
    !lds R31 ,{Сумма_измерений_ацп_word + 1}
    !add R30 , R16
    !ldi R16 , 0
    !adc R31 , R16
    !sts {Сумма_измерений_ацп_word} , R30
    !sts {Сумма_измерений_ацп_word + 1} , R31
    !lds R16 , {Счетчик_измерений_ацп}
    !inc R16       ' Считаем выборку из 128 измерений
    !cpi R16 , 128
    !BRNE Выход_прерывания_ацп

   'Деление на 128 (сдвиг вправо на 7)
    !ldi R16 , 7
   Сдвиг_вправо:
    !lsr R31
    !ror R30
    !dec R16
    !brne Сдвиг_вправо
   'Забираем готовые усреднённые по 128 выборкам, 8 бит данные
    !sts {Фоторезистор} , R30

   'Поднимаем флаг сигнализирующий о готовности результата измерения АЦП
    !ldi R16 , 1
    !sts {Флаг_данные_ацп} , R16

   'Готовимся к следующей выборке измерений
    !ldi R16 , 0
    !sts {Сумма_измерений_ацп_word} , R16
    !sts {Сумма_измерений_ацп_word + 1} , R16

  Выход_прерывания_ацп:
    !sts {Счетчик_измерений_ацп} , R16

   'Восстанавливаем регистры и SREG
    !pop R31
    !pop R30
    !pop R16
    !out sreg , R16
    !pop R16
'-------------------------------------------------------------------------------
  Return
'===============================================================================

0

14

Dim D(12) As Integer
  Dim W(12) As Integer

'Время выполнения фрагмента 565 тактов МК
  For I = 1 To 12
      D(i) = W(i)
  Next I

аналог, при условии, что "i" байтовое значение. Время выполнения фрагмента 254 такта МК

!clr R18 , 0
  !clr R19 , 0

Next_i:
  Loadadr W(1) , X
  !add R26 , R18
  !adc R27 , R19
  !ld R17 , X+
  !ld R16 , X

  Loadadr D(1) , X
  !add R26 , R18
  !adc R27 , R19
  !st X+ , R17
  !st X , R16

  !subi R18 , -2
  !cpi R18 , 24
  !BRSH Exit_next_i       
  !rjmp Next_i

Exit_next_i:

Но так быстрее

'Время выполнения фрагмента 554 тактов МК
  For I = 12 To 1 step -1
      D(i) = W(i)
  Next I

аналог, при условии, что "i" байтовое значение. Время выполнения фрагмента 230 тактов МК

'Время выполнения фрагмента 230 тактов МК
  !ldi R18 , 24       ' Т.к., используются двухбайтовые переменные, смещение считается по 2 байта
  !ldi r19 , 0

Next_i:
  Loadadr W(1) , X       ' Получаем адрес первой переменной в массиве
  !add R26 , R18       ' Высчитываем смещение в массиве
  !adc R27 , R19       ' Высчитываем смещение в массиве
  !ld R16 , -X       ' Забираем данные из массива
  !ld R17 , -X       ' Забираем данные из массива

  Loadadr D(1) , X       ' Получаем адрес первой переменной в массиве
  !add R26 , R18       ' Высчитываем смещение в массиве
  !adc R27 , R19       ' Высчитываем смещение в массиве
  !st -X , R16       ' Сохраняем данные в массив
  !st -X , R17       ' Сохраняем данные в массив

  !subi R18 , 2       ' Считаем смещение адреса переменных массива. Одна переменная = 2 байта
  !brne Next_i       ' Если не "0", повторяем

Exit_next_i:

Если фрагмент используется в прерывании, не забывайте сохранять используемые регистры и SREG

!push R16
  !in R16 , sreg
  !push R16
  !push R17
  !push R18
  !push R19
  !push R26
  !push R27

'Время выполнения фрагмента 230 тактов МК
  !ldi R18 , 24       ' Т.к., используются двухбайтовые переменные, смещение считается по 2 байта
  !ldi r19 , 0

Next_i:
  Loadadr W(1) , X       ' Получаем адрес первой переменной в массиве
  !add R26 , R18       ' Высчитываем смещение в массиве
  !adc R27 , R19       ' Высчитываем смещение в массиве
  !ld R16 , -X       ' Забираем данные из массива
  !ld R17 , -X       ' Забираем данные из массива

  Loadadr D(1) , X       ' Получаем адрес первой переменной в массиве
  !add R26 , R18       ' Высчитываем смещение в массиве
  !adc R27 , R19       ' Высчитываем смещение в массиве
  !st -X , R16       ' Сохраняем данные в массив
  !st -X , R17       ' Сохраняем данные в массив

  !subi R18 , 2       ' Считаем смещение адреса переменных массива. Одна переменная = 2 байта
  !brne Next_i       ' Если не "0", повторяем

Exit_next_i:

  !pop R27
  !pop R26
  !pop R19
  !pop R18
  !pop R17
  !pop R16
  !out sreg , R16
  !pop R16

Если фрагмент используется в теле программы, сохраняться нет необходимости.

0

15

Большие счетчики с помощью байтовых  ступенек

'Считаем 4096, 2 байтовых счётчика, так быстрее
   Считаем_256:
    !lds R26 , {Счетчик_256}
    !inc R26
    !sts {Счетчик_256} , R26
   'Если = 256
    !cpi R26 , 0
    !BREQ Считаем_4096
    !rjmp Выход_прерывания

   Считаем_4096:
    !lds R26 , {Счетчик_4096}
    !inc R26
    !sts {Счетчик_4096} , R26
   'Если =16, почему 16 (16 * 256 = 4096)
    !cpi R26 , 16
    !BREQ Реакция_на_совпадение_счетчика
    !rjmp Выход_прерывания

   Реакция_на_совпадение_счетчика:
    '......
    '......
    '......

   Выход_прерывания:
    '......
    '......
    '......

   'Считаем 65536, 2 байтовых счётчика, так быстрее
   Считаем_256:
    !lds R26 , {Счетчик_256}
    !inc R26
    !sts {Счетчик_256} , R26
   'Если =256
    !cpi R26 , 0
    !BREQ Считаем_65536
    !rjmp Выход_прерывания

   Считаем_65536:
    !lds R26 , {Счетчик_65536}
    !inc R26
    !sts {Счетчик_65536} , R26
   'Если = 256, почему 256 (256 * 256 = 65536)
    !cpi R26 , 0
    !BREQ Реакция_на_совпадение_счетчика
    !rjmp Выход_прерывания

   Реакция_на_совпадение_счетчика:
    '......
    '......
    '......

   Выход_прерывания:
    '......
    '......
    '......

0

16

'Incr Переменная_word
  !lds R26 , {Переменная_word}
  !lds R27 , {Переменная_word + 1}
  !ADIW R26 , 1       ' плюс (вместо 1) нужное значение
  !sts {Переменная_word} , R26
  !sts {Переменная_word + 1} , R27



'Decr Переменная_word
  !lds R26 , {Переменная_word}
  !lds R27 , {Переменная_word + 1}
  !sbIW R26 , 1       ' минус (вместо 1) нужное значение
  !sts {Переменная_word} , R26
  !sts {Переменная_word + 1} , R27

0

17

Select Case Переменная_byte

Select Case Переменная_byte
      Case 0:
      Case 1:
      Case 2:
      Case 3:
      Case 4:
      Case 5:
  End Select

Аналог на Bascom:

  On Переменная_byte Goto Обработка_0 , Обработка_1 , Обработка_2 , Обработка_3 , Обработка_4 , Обработка_5

  Обработка_0:
   '.....
   '.....
   Goto Выход

  Обработка_1:
   '.....
   '.....
   Goto Выход

  Обработка_2:
   '.....
   '.....
   Goto Выход

  Обработка_3:
   '.....
   '.....
   Goto Выход

  Обработка_4:
   '.....
   '.....
   Goto Выход

  Выход:




Аналог на ASM:

   !lds R16 , {Переменная_byte}

   !cpi R16 , 0
   !BREQ Обработка_0       ' Перейти если равно

   !cpi R16 , 1
   !BREQ Обработка_1       ' Перейти если равно

   !cpi R16 , 2
   !BREQ Обработка_2       ' Перейти если равно

   !cpi R16 , 3
   !BREQ Обработка_3       ' Перейти если равно

   !cpi R16 , 4
   !BREQ Обработка_4       ' Перейти если равно

   !cpi R16 , 5
   !BREQ Обработка_5       ' Перейти если равно

  Обработка_0:
   '.....
   '.....
   !rjmp Выход

  Обработка_1:
   '.....
   '.....
   !rjmp Выход

  Обработка_2:
   '.....
   '.....
   !rjmp Выход

  Обработка_3:
   '.....
   '.....
   !rjmp Выход

  Обработка_4:
   '.....
   '.....
   !rjmp Выход

  Выход:

+2

18

Шустренький счётчик миллисекунд

$map
  $loadersize = 1024

  $regfile = "m328pdef.dat"
  $crystal = 8000000
  $framesize = 64
  $hwstack = 64
  $swstack = 64

'===============================================================================
            'Настройка USART
'===============================================================================
  $baud = 38400       '38400
  Config Com1 = Baud , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
' Ucsr0a.1 = 1       ' Двойная скорость работы USART, скорость трансляции = $baud * 2

'===============================================================================
            'Настройка TIMER0 для отсчёта временных интервалов
'===============================================================================
  Config Timer0 = Counter , Prescale = 64 , Compare A = Disconnect , Clear Timer = 1

  On Compare0a Обработка_прерывания_compare0a Nosave

  Stop Timer0

  Timer0 = 0

  Compare0a = 124       '1 ms

  Dim Счетчик_ms As Word

'--------------  Разрешаем работу необходимых прерываний  ----------------------

  Enable Compare0a
  Start Timer0
'------------  Разрешаем работу всех включенных прерываний  --------------------
  Enable Interrupts
'===============================================================================

'                   Г Л А В Н Ы Й         Ц И К Л
  Главный_цикл:
'===============================================================================

    nop

   Power Idle       ' Отправляем МК на тихий час
'===============================================================================
  Goto Главный_цикл
End
'===============================================================================
'       П О Д К Л Ю Ч Е Н И Е     Р А Б О Ч И Х     М О Д У Л Е Й
'===============================================================================

'===============================================================================
  Обработка_прерывания_compare0a:
'-------------------------------------------------------------------------------
    !push R16
    !in R16 , sreg
    !push R16

    !lds R16 , {Счетчик_ms}
    !SUBI R16 , -1
    !sts {Счетчик_ms} , R16
    !lds R16 , {Счетчик_ms + 1}
    !SBCI R16 , -1
    !sts {Счетчик_ms + 1} , R16

    !pop R16
    !out sreg , R16
    !pop R16

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

+2

19

Продолжение этого

Всё конечно работает и даже устраивает, но, чем больше ветка переходов, тем дольше обработка.

Пришлось искать решение проблемки. Результат = 11 тактов МК независимо от количества меток

Исходник

$map       ' Получаем карту распределения памяти компилятором Bascom
  $regfile = "m328pdef.dat"     
  $crystal = 1000000
  $framesize = 128       ' Размер области используемой и необходимой для преобразований
  $hwstack = 128       ' Размер аппаратного стека
  $swstack = 128       ' Размер программного стека

  Dim Переход As Byte

Do

    Incr Переход

    If Переход > 7 Then Переход = 0

   
   '11 тактов МК
    !lds R26 , {Переход}
    !clr R27
    !ldi R30 , low(s_0)
    !ldi R31 , high(s_0)
    !add R30 , R26
    !adc R31 , R27
    !ijmp   'Для МК < 128 kb
    !eijmp   'Для МК => 128 kb

    S_0:
        !rjmp Save_0
    S_1:
        !rjmp Save_1
    S_2:
        !rjmp Save_2
    S_3:
        !rjmp Save_3
    S_4:
        !rjmp Save_4
    S_5:
        !rjmp Save_5
    S_6:
        !rjmp Save_6
    S_7:
        !rjmp Save_7

    Save_0:
     'Делаем, что надо
     !rjmp Save_end

    Save_1:
    'Делаем, что надо
     !rjmp Save_end

    Save_2:
    'Делаем, что надо
     rjmp Save_end

    Save_3:
    'Делаем, что надо
     rjmp Save_end

    Save_4:
    'Делаем, что надо
     rjmp Save_end

    Save_5:
    'Делаем, что надо
     !rjmp Save_end

    Save_6:
    'Делаем, что надо
     !rjmp Save_end

    Save_7:
    'Делаем, что надо
     rjmp Save_end

    Save_end:

  Loop
End

+1

20

Как быстрее, брать данные из байтового массива в оперативке МК или таблицы во флеше ?

Если силами Bascom, то данные из массива забирать быстрее в ~3 раза

Если силами ASM, то разницы практически нет, 11 тактов из массива, 12 тактов из таблицы.


Данные из таблицы:

'=================================
     '41 такт МК
    '---------------------------------
      1_val_byte = Lookup(count , Data_test)
    '=================================

    аналог на ASM

    '=================================
     '12 тактов МК
    '---------------------------------
      !lds R16 , {count}
      !clr R17
      !ldi R30 , Low(Data_test * 2)
      !ldi R31 , High(Data_test * 2)

      !add R30 , R16
      !adc R31 , R17

      !lpm R18 , Z
      !sts {1_val_byte} , R18
    '=================================


Данные из байтового массива

'=================================
     '13 тактов МК
    '---------------------------------
      Val_byte = 2_val_byte(count)
    '=================================

     аналог на ASM

    '=================================
     '11 тактов МК
    '---------------------------------
      !lds R16 , {count}
      !clr R17
      Loadadr 2_val_byte(0) , Z

      !add R30 , R16
      !adc R31 , R17

      !ld R18 , Z
      !sts {Val_byte} , R18
    '=================================

0

21

Если переменная Word > 0 Decr переменная Word

разница по времени выполнения ~3 раза

'===============================================================================
  Interrupt_compare0a:
'-------------------------------------------------------------------------------
'Время выполнения 149 тактов (romsize < 128 kb), с заходом и выходом из прерывания
'Время выполнения 160 тактов (romsize = 128 kb), с заходом и выходом из прерывания
'Время выполнения 163 такта  (romsize = 256 kb), с заходом и выходом из прерывания
'     If Count_ms > 0 Then
'         Decr Count_ms
'     End If

'Время выполнения 46 тактов (romsize < 128 kb), с заходом и выходом из прерывания
'Время выполнения 55 тактов (romsize = 128 kb), с заходом и выходом из прерывания
'Время выполнения 56 такта  (romsize = 256 kb), с заходом и выходом из прерывания

    !Push R16
    !In R16 , Sreg
    !Push R16

    #if _romsize > 65535
        !in R16 , RAMPZ
        !Push R16
        !clr R16
        !out RAMPZ , R16
    #endif

    !push R30
    !push R31

    !clr R17
    !lds R30 , {Count_ms}
    !lds R31 , {Count_ms + 1}

    !cpi R31 , 0
    !cpc R30 , R16
    !brcs Exit_interrupt_compare0a
    !breq Exit_interrupt_compare0a
    !rjmp Decr_count_ms
    !rjmp Exit_interrupt_compare0a

   Decr_count_ms:
    !SBIW R30 , 1

   Save_count_ms:
    !sts {Count_ms} , R30
    !sts {Count_ms + 1} , R31

   Exit_interrupt_compare0a:
    !pop R31
    !pop R30

    #if _romsize > 65535
        !pop R16
        !out RAMPZ  , R16
    #endif

    !pop R16
    !Out Sreg , R16
    !Pop R16

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

+2

22

Умножение байтовых чисел без знака (0...255)

  Dim A As Byte
  Dim B As Byte
  Dim Result As Word

Result = A * B    '40 тактов   

11 тактов МК
  !lds R16 , {A}
  !lds R17 , {B}
  !Mul R16 , R17
  !movw R16 , R0
  !sts {Result} , R16
  !sts {Result + 1} , R17

10 тактов МК, запись из переменных в регистровую пару R0:R1 возможна только для оператора MUL
  !lds R0 , {A}
  !lds R1 , {B}
  !Mul R0 , R1
  !sts {Result} , R0
  !sts {Result + 1} , R1

+3

23

Dim A As Integer : A = 32767
  Dim B As Integer : B = -32767
  Dim Results As Long

Results = A * B       '91 такт 

'Умножение переменных типа Integer (-32767...32767)  35 тактов
!lds R20 , {A}
!lds R21 , {A + 1}
!lds R22 , {B}
!lds R23 , {B + 1}

!clr   R2
!muls  R23 , R21
!movw  R18 , R0
!mul   R22 , R20
!movw  R16 , R0
!mulsu R23 , R20
!sbc   R19 , R2
!add   R17 , R0
!adc   R18 , R1
!adc   R19 , R2
!mulsu R21 , R22
!sbc   R19 , R2
!add   R17 , R0
!adc   R18 , R1
!adc   R19 , R2

!sts {Results} , R16
!sts {Results + 1} , R17
!sts {Results + 2} , R18
!sts {Results + 3} , R19

+3

24

Dim A As Word : A = 65535
  Dim B As Word : B = 65535
  Dim Results As Dword

Results = A * B       '84 такта

'Умножение переменных типа Word (0...65535)  33 такта
!lds  R20 , {A}
!lds  R21 , {A + 1}
!lds  R22 , {B}
!lds  R23 , {B + 1}

!clr  R2
!mul  R23 , R21
!movw R18 , R0
!mul  R22 , R20
!movw R16 , R0
!mul  R23 , R20
!add  R17 , R0
!adc  R18 , R1
!adc  R19 , R2
!mul  R21 , R22
!add  R17 , R0
!adc  R18 , r1
!adc  R19 , R2

!sts {Results} , R16
!sts {Results + 1} , R17
!sts {Results + 2} , R18
!sts {Results + 3} , R19

+3

25

'Забираем данные из "Val_word"
      !ldS R20 , {Val_word}
      !ldS R21 , {Val_word + 1}
     'Забираем данные из "Val_byte"
      !lds R22 , {Val_byte}
      !clr R23

     'Умножение переменных Word * Byte, время выполнения 28 тактов МК
      !mul  R23 , R21
      !mov  R18 , R0
      !mul  R22 , R20
      !movw R16 , R0
      !mul  R23 , R20
      !add  R17 , R0
      !adc  R18 , R1
      !mul  R21 , R22
      !add  R17 , R0
      !adc  R18 , R1

      Dim Itog As Long
      Dim Itog As Double
     'Забираем в переменную типа "Long" или "Double"
      !sts {itog} , R16
      !sts {itog + 1} , R17
      !sts {itog + 2} , R18
      !clr R19
      !sts {itog + 3} , R19

+3

26

'===============================================================================
  Interrupt_handling:       '34 такта (счёт); 40 тактов (счёт + реакция на сравнение)
'-------------------------------------------------------------------------------
  'If Val_word = 0 Then
      'Stop Timer1
      'Led = On_led
    'Else
      'Decr Val_word
  'End If

    !push R16
    !in R16 , sreg
    !push R16
    !push R30
    !push R31

    !lds R30 , {Val_word}
    !lds R31 , {Val_word + 1}

    'If Val_word = 0 Then
    !clr R16
    !cpi R30 , 0
    !cpc R31 , R16
    !breq Reaction_compare_variables
    !rjmp Decrement_variable

   Reaction_compare_variables:
    'Stop Timer1
    !lds R16 , tccr1b
    !andi R16 , &B_1111_1000
    !sts tccr1b , R16

    'Set Led
    Led = On_led

    !rjmp Exit_isr_compare1a

    'Else
   Decrement_variable:
    'Decr Val_word
    !sbiw R30 , 1       ' Вычесть константу из слова

   Exit_interrupt_handling:
    !sts {Val_word} , R30
    !sts {Val_word + 1} , R31
    'End If

    !pop R31
    !pop R30
    !pop R16
    !out sreg , R16
    !pop R16

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================



'===============================================================================
  Interrupt_handling:       '41 такт (счёт); 49 тактов (счёт + реакция на сравнение)
'-------------------------------------------------------------------------------
  'Incr Переменная_word

  'If Переменная_word = Count Then
      'Stop Timer1
      'Переменная_word = 0
      'Set Led
  'End If

    !push R26
    !in R26 , sreg
    !push R26
    !push R27
    !push R30
    !push R31

    'Incr Val_word
    !lds R30 , {Val_word}
    !lds R31 , {Val_word + 1}
    !adiw R30 , 1       'Сложить константу и слово

    !lds R26 , {Count_word}
    !lds R27 , {Count_word + 1}

    'If Val_word = Count Then
    !cp R30 , R26
    !cpc R31 , R27
    !breq Reaction_compare_variables
    !rjmp Exit_isr_compare1a

   Reaction_compare_variables:
    'Stop Timer1
    !lds R30 , tccr1b
    !andi R30 , &B_1111_1000
    !sts tccr1b , R30

    'Val_word = 0
    !clr R30
    !clr R31

    'Set Led
    Led = On_led

    'End If

   Exit_interrupt_handling:
    !sts {Val_word} , R30
    !sts {Val_word + 1} , R31

    !pop R31
    !pop R30
    !pop R27
    !pop R26
    !out sreg , R26
    !pop R26

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================

+3

27

Умножение переменных с знаком для Attiny? нет аппаратного перемножения (long=Integer*Integer)

Dim A As Integer : A = -32767
  Dim B As Integer : B = 32767
  Dim Results As Long

Do

  Gosub 16_muls_16_32

Loop
End

'=====================================
  16_muls_16_32:       '509 тактов
'-------------------------------------
    !lds R16 , {A}
    !lds R17 , {A + 1}

    !bst R17 , 7       'Проверка на "-"
    !brtc 16_muls_16_32_1       'BRTC k Перейти если флаг T очищен

    !ldi R18 , 255       '$ff
    !ldi R19 , 255       '$ff
    !rjmp 16_muls_16_32_2

   16_muls_16_32_1:
    !clr R18
    !clr R19

   16_muls_16_32_2:
    !lds R20 , {B}
    !lds R21 , {B + 1}

    !bst R21 , 7       'Проверка на "-"
    !brtc 16_muls_16_32_4

   16_muls_16_32_3:
    !ldi R22 , 255       '$ff
    !ldi R23 , 255       '$ff
    !rjmp 16_muls_16_32_5

   16_muls_16_32_4:
    !clr R22
    !clr R23

   16_muls_16_32_5:
    !rcall 16_muls_16_32_6

    !sts {Results} , R16
    !sts {Results + 1} , R17
    !sts {Results + 2} , R18
    !sts {Results + 3} , R19

   !ret
'=====================================
   16_muls_16_32_6:
    !rcall 16_muls_16_32_12
    !rcall 16_muls_16_32_8
    !sbrc  R0 , 0       '$00
    !rcall 16_muls_16_32_7
   !ret

   16_muls_16_32_7:
    !rcall 16_muls_16_32_14
    !rcall 16_muls_16_32_16
   !ret

   16_muls_16_32_8:
    !mov R24 , R20
    !mov R25 , R21
    !mov R26 , R22
    !mov R27 , R23

    !clr R20
    !clr R21
    !clr R22
    !clr R23

    !ldi R31 , 33       '$21
    !clc
    !rjmp 16_muls_16_32_11

   16_muls_16_32_9:
    !brcc 16_muls_16_32_10

    !add R20 , R24
    !adc R21 , R25
    !adc R22 , R26
    !adc R23 , R27

   16_muls_16_32_10:
    !lsr R23
    !ror R22
    !ror R21
    !ror R20
    !ror R19
    !ror R18
    !ror R17
    !ror R16

    !dec R31
    !brne 16_muls_16_32_9

   !ret

   16_muls_16_32_11:
    !ror R19
    !ror R18
    !ror R17
    !ror R16

    !dec R31
    !brne 16_muls_16_32_9
   !ret

   16_muls_16_32_12:
    !clr R0
    !clt
    !sbrs R23 , 7       '$07
    !rjmp 16_muls_16_32_13
    !rcall 16_muls_16_32_14
    !set

   16_muls_16_32_13:
    !bld R0 , 0
    !rcall 16_muls_16_32_15
    !bld R1 , 0
    !eor R0 , R1
   !ret

   16_muls_16_32_14:
    !rcall 16_muls_16_32_17
    !subi R20 , 255       '$ff
    !sbci R21 , 255       '$ff
    !sbci R22 , 255       '$ff
    !sbci R23 , 255       '$ff
   !ret

   16_muls_16_32_15:
    !clt
    !sbrs R19 , 7       '$07
   !ret

   16_muls_16_32_16:
    !com R16
    !com R17
    !com R18
    !com R19
    !subi R16 , 255       '$ff
    !sbci R17 , 255       '$ff
    !sbci R18 , 255       '$ff
    !sbci R19 , 255       '$ff
    !set
   !ret

   16_muls_16_32_17:
    !com R20
    !com R21
    !com R22
    !com R23
   !ret
'==========================================================


+1

28

Умножение переменных беЗ знака для Attiny? нет аппаратного перемножения (dword=word*word)

Dim A As Word : A = 32767
  Dim B As Word : B = 65535
  Dim Results As Dword

  Dim C As String * 10

Do

  '513 тактов
  Gosub Word_mul_word

!nop

C = Str(results)

Loop
End

'=====================================
  Word_mul_word:       '509 тактов
'-------------------------------------
    !lds R16 , {A}
    !lds R17 , {A + 1}
    !clr R18
    !clr R19

    !lds R20 , {B}
    !lds R21 , {B + 1}
    !clr R22
    !clr R23

    !rcall Word_mul_word_1

    !sts {Results} , R16
    !sts {Results + 1} , R17
    !sts {Results + 2} , R18
    !sts {Results + 3} , R19
'=====================================
   !ret
'=====================================
   Word_mul_word_1:
    !mov R24 , R20
    !mov R25 , R21
    !mov R26 , R22
    !mov R27 , R23
    !clr R20
    !clr R21
    !clr R22
    !clr R23
    !ldi R31 , 33       '$21
    !clc
    !rjmp Word_mul_word_4
   Word_mul_word_2:
    !brcc Word_mul_word_3
    !add R20 , R24
    !adc R21 , R25
    !adc R22 , R26
    !adc R23 , R27
   Word_mul_word_3:
    !lsr R23
    !ror R22
    !ror R21
    !ror R20
    !ror R19
    !ror R18
    !ror R17
    !ror R16
    !dec R31
    !brne Word_mul_word_2
   !ret
   Word_mul_word_4:
    !ror R19
    !ror R18
    !ror R17
    !ror R16
    !dec R31
    !brne Word_mul_word_2
   !ret
'=====================================

+2

29

Не смог найти на форуме преобразование в ассемблер двойного FOR NEXT.
Есть код, часть которого уже преобразована. Помогите полностью перевести на ассеблер.

Код:
Dim Page_counter As Byte
Dim Page_offset As Word
Dim M_red(mem_size) , M_green(mem_size) , M_blue(mem_size) As Byte
Dim Nn1 , Nn2 , Nn3 As Word
Nn1 = 32
Nn2 = 64
Nn3 = 4

Display_refresh:
   Load Timer0 , Timer0reload
   $asm
      lds R31 , {Page_counter}                              ' Прямая загрузка  из переменной в регистр                                                    время выполнения 2 такта
      cpi R31 , 7                                           ' Сравнить регистр и константу "Количество_подсчетов"                                         1 такт
      BRCS Cnt_Plus                                         ' Перейти если меньше чем "Количество_подсчетов + 1 "                         если переход на метку тогда 2 такта иначе 1 такт
      SBI  PORTd,5                                          ' Очистить регистр                                                                                                                                      1 такт
      lds R31 , 0
      sts {Page_counter} , R31
Cnt_plus:
      inc R31                                               ' Инкрементировать содержимое регистра                                                                                                      1 такт
      sts {Page_counter} , R31                              ' Прямая загрузка  из регистра в переменную                                                                              2 такта

      !lds R0 , {Page_counter}
      !lds R1 , {nn3}
      !Mul R0 , R1
      !sts {Page_offset} , R0
      !sts {Page_offset + 1} , R1

      lds R17 , {Page_offset}
      lds R18 , {Nn1}
      add R17 , R18
      STS {L1} , R17

      lds R17 , {L1}
      lds R18 , {Nn2}
      add R17 , R18
      STS {L2} , R17
   $end Asm


   For K = 1 To 2
      For B_1 = 1 To 4

         R18 = M_red(l1)
         R19 = M_green(l1)
         R20 = M_blue(l1)
         R21 = M_red(l2)
         R22 = M_green(l2)
         R23 = M_blue(l2)

         $asm
            LDI r17,8
Loop_shift2:
            in R16, dout_port
            BST r18,7
            BLD r16,Dout_pin_r1
            BST r19,7
            bld r16,Dout_pin_g1
            BST r20,7
            bld r16,Dout_pin_b1
            BST r21,7
            BLD r16,Dout_pin_r2
            BST r22,7
            bld r16,Dout_pin_g2
            BST r23,7
            bld r16,Dout_pin_b2

            LSl r18
            LSl r19
            lsl r20
            lsl r21
            lsl r22
            lsl r23
            Out Dout_port , R16
            SBI   shift_clock_Port, shift_clock_Pin
            dec r17
            CBI   shift_clock_Port, shift_clock_Pin
            BRnE loop_shift2

            lds R16 , {L1}
            lds R17 , {L2}
            inc R16
            inc R17
            sts {L1} , R16
            sts {L2} , R17

         $end Asm
      Next B_1

      $asm
         lds R16 , {Page_offset}
         sts {L1} , R16
         lds R17 , {L1 }
         lds R18 , {Nn2}
         add R17 , R18
         STS {L2} , R17
      $end Asm

   Next

   Pwm1b = 0
   Waitus 20

   $asm
      sbi PORTb,3                                           ' установить на выводе "1"
      Cbi Portb,3                                           ' установить на выводе "0"
      sbi PORTd,3
      Cbi Portd,3
      Cbi Portd,5
   $end Asm

   Pwm1b = Br
Return

0

30

Двойные ступеньки

0


Вы здесь » Программирование ATMEL в BASCOM. » Применение Assembler в среде Bascom(-8051) » Вставки на ASM AVR (ассемблер)