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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Применение Assembler в среде Bascom(-8051) » Расчёт процентов на ASM


Расчёт процентов на ASM

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

1

Расчёт процентов от байтового значения 0...255

https://upforme.ru/uploads/0000/25/b8/1217/t648334.jpg

$regfile = "m328pdef.dat"
  $crystal = 1000000
  $framesize = 32
  $hwstack = 40
  $swstack = 16

  $baud = 4800

  Dim Temp As Byte
  Dim Percent As Byte

'Функция расчёта процентов из байтового значения (0...255)
  Declare Function Calculate_percent(byval Val_byte As Byte) As Byte

Do

  Incr Temp

'Время исполнения 78 тактов
  Percent = Calculate_percent(temp)

  Print Temp ; "  " ; Percent ; "%"

Loop
End

'===============================================================================
  Function Calculate_percent(byval Val_byte As Byte) As Byte
'-------------------------------------------------------------------------------
     'Забираем данные из "Val_byte"
      !ld R16 , X
      !ldi R17 , 100       '1
      !Mul R16 , R17       '2
      !movw R16 , R0
     'Деление на 255 (сдвиг вправо на 8)
      !lsr R17
      !ror R16
      !lsr R17
      !ror R16
      !lsr R17
      !ror R16
      !lsr R17
      !ror R16
      !lsr R17
      !ror R16
      !lsr R17
      !ror R16
      !lsr R17
      !ror R16
      !lsr R17
      !ror R16
     'Забираем адрес "Calculate_percent"
      !ld R26 , Y+2
      !ld R27 , Y+3
     'Забираем готовые данные
      !st X , R16
'-------------------------------------------------------------------------------
  End Function
'===============================================================================

+3

2

Расчёт процентов от значения 0...1024

https://upforme.ru/uploads/0000/25/b8/1217/t50671.jpg


  $regfile = "m328pdef.dat"
  $crystal = 1000000
  $framesize = 32
  $hwstack = 40
  $swstack = 16

  $baud = 4800

  Dim Temp As Word
  Dim Percent As Byte

'Функция расчёта процентов из байтового значения (0...255)
  Declare Function Calculate_percent(byval Val_word As Word) As Byte

  Temp = 500

Do

  Incr Temp

'Время исполнения 115 тактов
  Percent = Calculate_percent(temp)

  Print Temp ; "  " ; Percent ; "%"

Loop
End

'===============================================================================
  Function Calculate_percent(byval Val_word As Word) As Byte
'-------------------------------------------------------------------------------
     'Забираем данные из "Val_word"
      !ld R26 , Y
      !ld R27 , Y+1
      !ld R20 , X+
      !ld R21 , X
      !ldi R22 , 100       '1
      !clr R23

     'Умножение переменных Word * Byte
      !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
     'Деление на 1024 (сдвиг вправо на 10)
      !lsr R18
      !ror R17
      !ror R16
      !lsr R18
      !ror R17
      !ror R16
      !lsr R18
      !ror R17
      !ror R16
      !lsr R18
      !ror R17
      !ror R16
      !lsr R18
      !ror R17
      !ror R16
      !lsr R18
      !ror R17
      !ror R16
      !lsr R18
      !ror R17
      !ror R16
      !lsr R18
      !ror R17
      !ror R16
      !lsr R18
      !ror R17
      !ror R16
      !lsr R18
      !ror R17
      !ror R16
     'Забираем адрес "Calculate_percent"
      !ld R26 , Y+2
      !ld R27 , Y+3
     'Забираем готовые данные
      !st X , R16
'-------------------------------------------------------------------------------
  End Function
'===============================================================================

+3

3

Универсальный вариант 255...512...1024

Вариант выбирается здесь "Const Size_percent = 255...512...1024"

Исходник

$regfile = "m328pdef.dat"
  $crystal = 1000000
  $framesize = 32
  $hwstack = 40
  $swstack = 16

  $baud = 4800

  Dim Temp As Word
  Dim Percent As Byte

'===============================================================================
'Функция расчёта процентов, возможные варианты: 255, 512, 1024
  Const Size_percent = 1024

  #if Size_percent = 255
       Const Div_size_percent = 8   '133 такта
  #endif
  #if Size_percent = 512
       Const Div_size_percent = 9       '139 тактов
  #endif
  #if Size_percent = 1024
       Const Div_size_percent = 10       '145 тактов
  #endif

  Declare Function Calculate_percent(byval Val_word As Word) As Byte
'===============================================================================

Do

  Incr Temp

'Время исполнения 133...139...145 тактов
  Percent = Calculate_percent(temp)

  Print Temp ; "  " ; Percent ; "%"

Loop
End

'===============================================================================
  Function Calculate_percent(byval Val_word As Word) As Byte
'-------------------------------------------------------------------------------
     'Забираем данные из "Val_word"
      !ld R26 , Y
      !ld R27 , Y+1
      !ld R20 , X+
      !ld R21 , X
      !ldi R22 , 100       '1
      !clr R23

     'Умножение переменных Word * Byte
      !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
     'Деление на нужный делитель  (сдвиг вправо на 8_9_10)
      !ldi R19 , Div_size_percent
     Next_calculate_percent:
      !lsr R18
      !ror R17
      !ror R16
      !dec R19
      !brne Next_calculate_percent

     'Забираем адрес "Calculate_percent"
      !ld R26 , Y+2
      !ld R27 , Y+3
     'Забираем готовые данные
      !st X , R16
'-------------------------------------------------------------------------------
  End Function
'===============================================================================

+4

4

Сверхзвуковое ускорение:

Вход = байт (нужная переменная 0...255)
Выход = байт (переменная  в процентах 0...100 %)
Время выполнения  = 7 или 15 тактов МК

Исходник

$regfile = "m328pdef.dat"
  $crystal = 1000000
  $framesize = 32
  $hwstack = 40
  $swstack = 16

  $baud = 4800

  Dim Temp As Byte
  Dim Percent As Byte

Do

  Incr Temp

'=======================================================
'Выполнение подпрограммы с входом и выходом, 15 тактов
  Gosub Calculate_perzent
'=======================================================
'А так, Ёханая Бабайка, 7 тактов
'=======================================================
   'Забираем данные из переменной (0...255)
    !lds R16  , {Temp}       '2 такта
    !ldi R17 , 100       '100%     1 такт
    !Mul R16 , R17       '2 такта
   'Забираем готовые данные (0...100 %)
    !sts {Percent} , R1       '2 такта
'=======================================================

  Print Temp ; "  " ; Percent ; "%"

Loop
End

'===============================================================================
  Calculate_perzent:
'-------------------------------------------------------------------------------
   'Забираем данные из переменной (0...255)
    !lds R16  , {Temp}
    !ldi R17 , 100       '100%
    !Mul R16 , R17
   'Забираем готовые данные (0...100 %)
    !sts {Percent} , R1
'-------------------------------------------------------------------------------
  Return
'===============================================================================

Следующий вариант: Гиперзвук, правда уже нема куда.

+3

5

sasha_1973 написал(а):

Следующий вариант: Гиперзвук, правда уже нема куда.

Ща мода на облачные вычисления.  :D

А так надо не забывать, что надо ещё сохранять флаги и используемые регистры (а это уже увеличивает количество тактов и юзает стек).

Отредактировано RDW (2022-01-21 12:51:52)

+1

6

RDW написал(а):

Ща мода на облачные вычисления.  :D

Ага, и вместо "мигающей лампочки" получаем "сервер-интернет-WiFi"
Модно, понтово, дорого ))) да и еще потребность всё это обслуживать...
Красота...

+1

7

А ещё можно использовать в виде макроса

Исходник

$regfile = "m328pdef.dat"
  $crystal = 1000000
  $framesize = 32
  $hwstack = 40
  $swstack = 16

  $baud = 4800

  Dim Temp_percent As Byte
  Dim Percent As Byte

  Macro Calculate_perzent
   'Забираем данные из переменной (0...255)
    !lds R16  , {Temp_percent}
    !ldi R17 , 100       '100%
    !Mul R16 , R17
   'Забираем готовые данные (0...100 %)
    !sts {Percent} , R1
  End Macro

Do

  Incr Temp_percent

'Выполнение макроса, 7 тактов
  Calculate_perzent

  Print Temp_percent ; "  " ; Percent ; "%"

Loop
End

+3

8

Занятная штука эти макросы, но малоприменимая...
Разве только для повышения быстродействия. ;)

0

9

Nord написал(а):

Занятная штука эти макросы, но малоприменимая...
Разве только для повышения быстродействия.

Экономия кода !

Один макрос, во многих местах.

0

10

RDW написал(а):

А так надо не забывать, что надо ещё сохранять флаги и используемые регистры (а это уже увеличивает количество тактов и юзает стек)

Если фрагмент не в прерывании, то для чего ?

0

11

sasha_1973 написал(а):

Экономия кода !
Один макрос, во многих местах.

Как, собственно и подпрограмма... ;)

Экономия кода с макросом копеечная, а вот на быстродействии сказывается заметно...
Возможно, если скорость критична, стОит отказаться от подпрограмм и т.п.

В такой редакции - 15 тактов (п/п) против 7 (макрос):

Bascom 2.0.8.5

Dim Temp_percent As Byte
Dim Percent As Byte
'=========================================

Do

Incr Temp_percent

Gosub Calc_perzent

Print Temp_percent ; "  " ; Percent ; "%"

Loop

End

'=========================================
Calc_perzent:
    !lds R16  , {Temp_percent}
    !ldi R17 , 100       '100%
    !Mul R16 , R17
   'Забираем готовые данные (0...100 %)
    !sts {Percent} , R1
Return

0

12

sasha_1973 написал(а):

Экономия кода !
Один макрос, во многих местах.

Ценой увеличения размера прошивки!
Подпрограммы в этом плане лучше.

+1

13

Пётр написал(а):

Ценой увеличения размера прошивки!
Подпрограммы в этом плане лучше.

Увы... С макросом меньше получается... ;)

В моем тесте (МК - Mega48): с макросом - 11%, с п/п - 12%...

Разумеется, что неиспользуемые при компиляции макрос или п/п, равно как и строки их вызова - закомментированы...

Я бы сказал, что с п/п - привычнее... ;)
Макросы надо размещать вначале, что несколько мешает листанию.
П/п - все в конце, как правило после END (у меня в частности ;) )...

0

14

Nord написал(а):

Увы... С макросом меньше получается...

Макрос это автоматизированное копирование участков кода. Меньше будет только если в макросе пара асм инструкций. То есть меньше чем нужно для вызова подпрограммы и возврата из нее.

0

15

Пётр написал(а):

Макрос это автоматизированное копирование участков кода.

По логике работы это так и есть, да и в Справке об этом говориться.
Только полученные цифры пока почему-то говорят другое... ;)

Пётр написал(а):

Меньше будет только если в макросе пара асм инструкций. То есть меньше чем нужно для вызова подпрограммы и возврата из нее.

Я использовал код, приведенный Александром, только МК заменил.
И в макросе и в п/п - одинаковые наборы операторов.
Результат описал... ;)

При использовании п/п добавляется 8 тактов на каждый вход/выход.
А это далеко не NOP, это время выполнения операций для сохранение/восстановление адресов входа/выхода при вызове п/п.
Возможно (!) эти операции и дают прирост размера прошивки, ведь эти адреса не вычисляются статично при компиляции, а определяются "по ходу пьесы".

ИМХО, спор пока ни о чем... ;)
Нужно наваять что-то с большим количеством макросов и (или) п/п и уже это сравнивать. ;)

0

16

Nord написал(а):

Я использовал код, приведенный Александром, только МК заменил.
И в макросе и в п/п - одинаковые наборы операторов.
Результат описал...

Данный код ни чего не показывает. И макрос, и пп вообще можно не использовать в этом коде.
Вот когда вы будете использовать макрос или пп несколько раз(соб-но для этого их и пишут) Тогда и увидите разницу.
Тот же код, сделайте вызов пп/макроса хотя бы 3 раза

+2

17

Nord написал(а):

Только полученные цифры почему-то говорят другое..

как  уже написал KIP, Вы сделали не очень верный пример, от того и цифры "с потолка".
да, сделайте хотя бы 10-12 вызовов того и другого и всё будет гораздо нагляднее.

+1

18

Не до конца дочитали ? ;)
Я про это же в #15 написал...

0

19

Добрался до "большого", поэкспериментировал...

Таки да, был неправ насчет конечного размера кода  :blush:
Пошел по пути, предложенному kip и Александр Д, с вызовом макроса или п/п 10 раз подряд.
С макросом конечный код увеличивается, с п/п - нет.

Но и прироста в скорости работы с макросом особого не заметил, хотя ожидалось...  :dontknow:
Тестировался полный цикл с приращением Temp_percent + 5:
- с макросом - 333,642 mS
- с п/п          - 333,999 mS

+1

20

Nord написал(а):

С макросом конечный код увеличивается, с п/п - нет

Логично, не правда ли? ))))

ПП: Звонок_Мужу
Вася, купи хлеба!
пока хватит

Давай Звонок_Мужу =  6 байт
Давай Звонок_Мужу =  6 байт
Давай Звонок_Мужу =  6 байт
Давай Звонок_Мужу =  6 байт
Итого: 6*4 = 24 байта

Вася, купи хлеба!
Вася, купи хлеба!
Вася, купи хлеба!
Вася, купи хлеба!
Итого: 17*4= 68 байт

---
Как бы вот ))

0

21

Александр Д. написал(а):

Логично, не правда ли? ))))

Было бы логичнее довести этот вопрос до конца еще вчера, но вечер был занят другим... ;)
Пришлось искать доказательства только спустя сутки. ;)

0


Вы здесь » Программирование ATMEL в BASCOM. » Применение Assembler в среде Bascom(-8051) » Расчёт процентов на ASM