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

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

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

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



BASCOM 8051

Сообщений 91 страница 114 из 114

91

Деструктивное поведение, конечно.
В бизнесе не должно быть друзей/врагов. Если посмотреть на восточных братьев, они для всех рынок.
На западе же себе в ноги стреляют и норм.

0

92

Я вообще можно сказать внёс бабки (хотя и символические) за лицензию на устаревший продукт, в котором за год ничего не поменялось. Забронзовел Марк. Но упорные товарищи (почёт и уважение от всех пионеров планеты) уже протоптали дорожку, нужно только DAT-файлы строчить и добавлять.

0

93

жаль, не добавил Dword и прочее
ну и редактор кривой, много бяк.

0

94

64 бит конечно не дождались.

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

0

95

Я что-то не догоняю или это нормально? В XRAM можно смотреть запись в EAXFR.

Код
Код:
$regfile = "8H1K08.DAT"
$crystal = 35000000
$ramsize = 1024
$map
$large
Rstcfg = &B0100_0011
Stop Timer1
Auxr.6 = 0
P1 = 0 : P3 = 0 : P5 = 0
P1dr = &B0000_0000 : P3dr = &B1100_1111 : P5dr = &B1110_1111
P_sw2.7 = 1
'EAXFR
'*******************************************************************************
   P1ie = &B1111_1111 : P3ie = &B0011_0100 : P5ie = &B0001_0000
   P3m0.3 = 1 : P3m1.5 = 0
   P5m0.4 = 1 : P5m1.4 = 0
   Btn Alias P3.2
   'P3ie.2 = 1
   P3m1.2 = 1
   P3m0.2 = 0
   P3pu.2 = 1
   P3m0.4 = 1 : P3m1.4 = 0
'*******************************************************************************
P_sw2.7 = 0

Stop
Картинка

0

96

не понял, поясните  :dontknow:

0

97

Пишем в EAXFR и эти данные отображаются в XRAM. За границами реальной памяти (1024) конечно.

0

98

о как. Но то симулятор, а не реально устройство!

0

99

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

Так single в byte не поместится.  
Отредактировано Andrusha (2025-11-04 00:36:42)

Если значение в байт гарантированно помещается (пользователь сам это контролирует), то помещаем

SINGLE > BYTE
Код:
$regfile = "8H1K28.DAT"
$crystal = 35000000
$romstart = &H0
$ramsize = 1024
$map
$large
Dim Vs As Single
Dim Vb As Byte
Dim Tmp_a As Byte : Dim Tmp_b As Byte
Start Timer1

Do

   Tmp_a = Th1 : Tmp_b = Tmp_b + Th1 : Rotate Tmp_b , Right : If Tmp_b < 1 Then Tmp_b = 2
   Vs = Tmp_a / Tmp_b

$asm
       mov a, {Vs+3}
       mov r7, a
       mov a, {Vs+2}
       mov r6, a
       mov a, r7
       rl a
       mov a, r6
       jb acc.7, S_to_b_set_low_bit_1
       mov a, r7
       rl a
       anl a, #254
       sjmp S_to_b_exp_done
   S_to_b_set_low_bit_1:
       mov a, r7
       rl a
       orl a, #1
   S_to_b_exp_done:
       clr c
       subb a, #127
       jc S_to_b_val_too_small
       mov r2, a
       clr c
       subb a, #8
       jnc S_to_b_val_too_big
       mov a, r6
       anl a, #127
       orl a, #128
       mov r1, a
       mov a, #7
       clr c
       subb a, r2
       jz S_to_b_round_check_e7
       mov r0, a
   S_to_b_shift_final:
       clr c
       mov a, r1
       rrc a
       mov r1, a
       djnz r0, S_to_b_shift_final
       jnc S_to_b_store_result
       inc r1
       jz S_to_b_val_too_big
       sjmp S_to_b_store_result
   S_to_b_round_check_e7:
       mov a, {Vs+1}
       jnb acc.7, S_to_b_store_result
       inc r1
       jz S_to_b_val_too_big
       sjmp S_to_b_store_result
   S_to_b_val_too_small:
       cjne a, #255, S_to_b_set_zero
       mov a, {Vs+2}
       anl a, #127
       orl a, #128
       jnb acc.7, S_to_b_set_zero
       mov r1, #1
       sjmp S_to_b_store_result
   S_to_b_set_zero:
       mov r1, #0
       sjmp S_to_b_store_result
   S_to_b_val_too_big:
       mov r1, #255
   S_to_b_store_result:
       mov a, r1
       mov {Vb}, a
$end Asm

   Print "Vs=" ; Vs ; " Vb=" ; Vb
Loop
Stop

Отредактировано Кот Обормот (2026-02-20 20:31:42)

0

100

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

Да и я в АВР ни разу не применял - задачи не было ))
Один раз понадобился десятичный логарифм: а АВР есть, а в 8051 - нет, напрёгся.

Теперь немножко есть
Код:
$regfile = "8H1K08.DAT"
$crystal = 35000000
$ramsize = 1024
$map
$large

Dim Log_in As Single
Dim Log_out As Integer

Log_in = 0.0005
Do
   Gosub L10
   Print "in=" ; Log_in ; " out=" ; Log_out
   Log_in = Log_in * 1.25
Loop

L10:

   $asm
      lcall log10_unpack
      jc log10_set_zero
      lcall log10_calc_full_opt
      lcall log10_write_long
      ret
   Log10_set_zero:
      mov {Log_out+0}, #0
      mov {Log_out+1}, #0
      ret
   Log10_unpack:
      mov a, {Log_in+3}
      jb acc.7, log10_unpack_err
      mov r4, a
      mov a, {Log_in+2}
      mov r6, a
      rlc a
      mov a, r4
      rlc a
      jz log10_unpack_err
      clr c
      subb a, #127
      mov r5, a
      mov a, r6
      anl a, #127
      mov r3, a
      mov a, {Log_in+1}
      mov r2, a
      clr c
      ret
   Log10_unpack_err:
      setb c
      ret
   Log10_calc_full_opt:
      mov dptr, #log10_tab
      mov a, r3
      rl a
      add a, dpl
      mov dpl, a
      mov a, dph
      addc a, #0
      mov dph, a
      clr a
      movc a, @a+dptr
      mov r4, a
      inc dptr
      clr a
      movc a, @a+dptr
      mov r6, a
      inc dptr
      clr a
      movc a, @a+dptr
      mov r7, a
      inc dptr
      clr a
      movc a, @a+dptr
      mov r0, a
      clr c
      mov a, r7
      subb a, r4
      mov r7, a
      mov a, r0
      subb a, r6
      mov r0, a
      mov a, r2
      mov b, r7
      mul ab
      mov a, r2
      mov b, r7
      mul ab
      jnb acc.7, log10_noround
      inc b
   Log10_noround:
      mov r1, b
      mov a, r4
      add a, r1
      mov r4, a
      mov a, r6
      addc a, #0
      mov r6, a
      mov a, r5
      jnb acc.7, log10_pos_exp
      push r4
      push r6
      cpl a
      inc a
      mov b, #194
      mul ab
      mov r1, a
      mov a, b
      mov r2, #0
      xch a, r0
      mov a, r5
      cpl a
      inc a
      mov b, #11
      mul ab
      add a, r0
      mov r2, a
      mov a, r5
      cpl a
      inc a
      mov b, #3
      div ab
      mov r0, a
      clr c
      mov a, r1
      subb a, r0
      mov r1, a
      mov a, r2
      subb a, #0
      mov r2, a
      clr c
      mov a, r1
      cpl a
      add a, #1
      mov r1, a
      mov a, r2
      cpl a
      addc a, #0
      mov r2, a
      pop r6
      pop r4
      sjmp log10_sum
   Log10_pos_exp:
      mov b, #194
      mul ab
      mov r1, a
      mov a, b
      mov r2, #0
      xch a, r0
      mov a, r5
      mov b, #11
      mul ab
      add a, r0
      mov r2, a
      mov a, r5
      mov b, #3
      div ab
      add a, r1
      mov r1, a
      mov a, r2
      addc a, #0
      mov r2, a
   Log10_sum:
      mov a, r4
      add a, r1
      mov r1, a
      mov a, r6
      addc a, r2
      mov r2, a
      mov a, r5
      jb acc.7, log10_chk_neg
      mov a, r2
      jb acc.7, log10_calc_zero
      sjmp log10_calc_exit
   Log10_chk_neg:
      mov a, r2
      jnb acc.7, log10_calc_zero
      sjmp log10_calc_exit
   Log10_calc_zero:
      mov r1, #0
      mov r2, #0
   Log10_calc_exit:
      ret
   Log10_write_long:
      mov {Log_out+0}, r1
      mov {Log_out+1}, r2
      ret
   Log10_tab:
      db   0,0,  34,0,  67,0, 101,0, 134,0, 166,0, 199,0, 231,0
      db   7,1,  39,1,  71,1, 102,1, 133,1, 164,1, 195,1, 225,1
      db   0,2,  30,2,  59,2,  89,2, 119,2, 148,2, 177,2, 206,2
      db 234,2,   7,3,  35,3,  63,3,  91,3, 119,3, 146,3, 174,3
      db 201,3, 228,3, 255,3,  26,4,  52,4,  79,4, 105,4, 131,4
      db 157,4, 183,4, 208,4, 234,4,   3,5,  28,5,  53,5,  78,5
      db 103,5, 128,5, 152,5, 176,5, 201,5, 225,5, 249,5,  16,6
      db  40,6,  64,6,  87,6, 110,6, 133,6, 157,6, 179,6, 202,6
      db 225,6, 247,6,  14,7,  36,7,  58,7,  81,7, 103,7, 124,7
      db 146,7, 168,7, 189,7, 211,7, 232,7, 253,7,  19,8,  40,8
      db  61,8,  81,8, 102,8, 123,8, 143,8, 164,8, 184,8, 204,8
      db 224,8, 244,8,   8,9,  28,9,  48,9,  68,9,  87,9, 107,9
      db 126,9, 146,9, 165,9, 184,9, 203,9, 222,9, 241,9,   4,10
      db  23,10, 41,10, 60,10, 79,10, 97,10,115,10,134,10,152,10
      db 170,10,188,10,206,10,224,10,242,10,  4,11, 21,11, 39,11
      db  56,11, 74,11, 91,11,109,11,126,11,143,11,160,11,177,11
      db 194,11
   $end Asm

Return

На входе данные в Single, на выходе Integer.
Результат является домноженным на 10000.
Либо использовать как есть целочисленное, либо соответствующим образом изменить формулы с поправкой на множитель.
Если результат выходит за границы Integer, то выдаёт ноль (признак ошибки).
Расхождение с gnumeric в сотых долях процента. Вырастает до десятых при переходе функции через ноль.
Размер процедуры по бинарнику ~500 байт
Игрался с безтабличными методами - проиграл.
Если диапазон входного значения достаточно узкий (например от 2 до 8), то точность можно увеличить.

Графики абсолютных погрешностей

Если применить более сложный метод, то ожидаемые погрешности умеьшатся на порядки. В районе пересечения нуля относительная погрешность до ~7E-5 (при росте входного значения ошибка уменьшается)

Отредактировано Кот Обормот (2026-03-03 07:55:15)

+1

101

Терминал симулятора можно как-то перенаправить на вывод в файл? Нельзя (но тикет я закинул). А то там только последние ~500 строк держит. Решение

Отредактировано Кот Обормот (2026-03-02 19:24:33)

0

102

Обзор от ИИ
Для создания виртуальных COM-портов в Windows с возможностью логирования (сохранения) данных в файл используются эмуляторы, такие как
Eltima Virtual Serial Port Driver, SerialTool или TCP/COM-port splitter. Они создают пару портов (например, COM1-COM2), где данные, отправленные в один порт, можно прочитать и сохранить из другого, используя монитор порта.
Популярные решения:

    SerialTool: Позволяет создавать виртуальные порты и обеспечивает удобный интерфейс для отправки/получения данных и сохранения их в файл.
    Eltima Virtual Serial Port Driver: Надежный инструмент для создания пар виртуальных COM-портов.
    COM Port Data Emulator: Позволяет генерировать поток данных и тестировать COM-порты.

Как использовать:

    Создание: Установите программу (например, Eltima VSPD) и создайте пару виртуальных портов.
    Настройка: В вашей программе, которая работает с COM-портом, выберите один из созданных портов (например, COM1).
    Логирование: В эмуляторе (например, SerialTool) откройте второй порт (COM2) и включите функцию логирования/записи данных в файл.

Для перенаправления данных также можно использовать сетевые утилиты, превращающие COM-трафик в сетевой.

Из личного: Очень давно что-то подобное делал, но названия софта уже не помню.
А Симуляторами я не пользуюсь...

Отредактировано Александр Д. (2026-03-03 08:37:26)

0

103

Получение целочисленного sin\cos в integer

Код 657 байт
Код:
$regfile = "8H1K08.DAT"
$crystal = 35000000
$ramsize = 1024
$map
$large
Dim X As Single : X = -7.85398
Dim Result_s As Single
Dim Res_sin_i As Integer
Dim Res_cos_i As Integer
Dim I As Byte
For I = 1 To 32
   Gosub Sin16
   Result_s = Res_sin_i / 32768
   Print "óãîë=" ; X ; " sin=" ; Result_s ;
   Result_s = Res_cos_i / 32768
   Print " cos=" ; Result_s
   X = X + 0.49087375
Next N

Stop

Sin16:
   '657
   $asm

         mov a, {X+3}
         mov r7, a
         mov a, {X+2}
         mov r6, a
         mov a, {X+1}
         mov r5, a
         mov a, {X}
         mov r4, a
         mov a, r7
         jnb acc.7, sin16_pinp
         setb f0
         anl a, #127
         mov r7, a
         sjmp sin16_exexp
      sin16_pinp:
         clr f0
         sin16_exexp:
         mov a, r6
         rlc a
         mov a, r7
         rlc a
         jnz sin16_nz
         mov {&h18}, #0
         mov {&h19}, #0
         mov {&h1A}, #0
         mov {&h1E}, #0
         ljmp sin16_init
      sin16_nz:
         clr c
         subb a, #126
         mov r0, a
         mov a, r6
         anl a, #127
         orl a, #128
         mov r6, a
         mov r7, #0
         mov a, r0
         jz sin16_savn
         jnb acc.7, sin16_shl
         cpl a
         inc a
         mov r0, a
      sin16_shr:
         clr c
         mov a, r7
         rrc a
         mov r7, a
         mov a, r6
         rrc a
         mov r6, a
         mov a, r5
         rrc a
         mov r5, a
         mov a, r4
         rrc a
         mov r4, a
         djnz r0, sin16_shr
         sjmp sin16_savn
      sin16_shl:
         clr c
         mov a, r4
         rlc a
         mov r4, a
         mov a, r5
         rlc a
         mov r5, a
         mov a, r6
         rlc a
         mov r6, a
         mov a, r7
         rlc a
         mov r7, a
         djnz r0, sin16_shl
      sin16_savn:
         mov {&h18}, r4
         mov {&h19}, r5
         mov {&h1A}, r6
         mov {&h1E}, r7
         lcall sin16_scl
         clr f1
         mov a, {&h1A}
         jb acc.7, sin16_rdpi
         sjmp sin16_chpi
      sin16_rdpi:
         clr c
         mov a, {&h18}
         subb a, #0
         mov {&h18}, a
         mov a, {&h19}
         subb a, #0
         mov {&h19}, a
         mov a, {&h1A}
         subb a, #128
         mov {&h1A}, a
         cpl f0
         cpl f1
      sin16_chpi:
         mov a, {&h1A}
         jb acc.6, sin16_rhpi
         sjmp sin16_init
      sin16_rhpi:
         clr c
         mov a, #0
         subb a, {&h18}
         mov {&h18}, a
         mov a, #0
         subb a, {&h19}
         mov {&h19}, a
         mov a, #128
         subb a, {&h1A}
         mov {&h1A}, a
         cpl f1
      sin16_init:
         mov {&h08}, #64
         mov {&h09}, #186
         mov {&h0A}, #77
         mov {&h10}, #0
         mov {&h11}, #0
         mov {&h12}, #0
         mov r3, #0
      sin16_loop:
         lcall sin16_ldat
         lcall sin16_shx
         lcall sin16_shy
         lcall sin16_core
         inc r3
         mov a, r3
         cjne a, #22, sin16_loop
         ljmp sin16_fin
      sin16_scl:
         mov a, {&h19}
         mov b, #96
         mul ab
         mov r6, a
         mov r7, b
         mov a, {&h18}
         mov b, #190
         mul ab
         add a, r6
         mov a, r7
         addc a, b
         mov r4, a
         mov r6, r4
         mov r7, #0
         mov a, {&h1A}
         mov b, #96
         mul ab
         add a, r6
         mov r6, a
         mov a, b
         addc a, r7
         mov r7, a
         mov a, {&h19}
         mov b, #190
         mul ab
         add a, r6
         mov r6, a
         mov a, b
         addc a, r7
         mov r7, a
         mov a, {&h18}
         mov b, #40
         mul ab
         add a, r6
         mov r6, a
         mov a, b
         addc a, r7
         mov r4, a
         mov r6, r4
         mov r7, #0
         mov a, {&h1E}
         mov b, #96
         mul ab
         add a, r6
         mov r6, a
         mov a, b
         addc a, r7
         mov r7, a
         mov a, {&h1A}
         mov b, #190
         mul ab
         add a, r6
         mov r6, a
         mov a, b
         addc a, r7
         mov r7, a
         mov a, {&h19}
         mov b, #40
         mul ab
         add a, r6
         mov {&h18}, a
         mov a, b
         addc a, r7
         mov r4, a
         mov r6, r4
         mov r7, #0
         mov a, {&h1E}
         mov b, #190
         mul ab
         add a, r6
         mov r6, a
         mov a, b
         addc a, r7
         mov r7, a
         mov a, {&h1A}
         mov b, #40
         mul ab
         add a, r6
         mov {&h19}, a
         mov a, b
         addc a, r7
         mov r4, a
         mov r6, r4
         mov a, {&h1E}
         mov b, #40
         mul ab
         add a, r6
         mov {&h1A}, a
         ret
      sin16_ldat:
         mov dptr, #sin16_tab
         mov a, r3
         mov b, #3
         mul ab
         add a, dpl
         mov dpl, a
         mov a, dph
         addc a, #0
         mov dph, a
         clr a
         movc a, @a+dptr
         mov {&h1B}, a
         inc dptr
         clr a
         movc a, @a+dptr
         mov {&h1C}, a
         inc dptr
         clr a
         movc a, @a+dptr
         mov {&h1D}, a
         ret
      sin16_shx:
         mov r4, {&h08}
         mov r5, {&h09}
         mov r6, {&h0A}
         mov a, r3
         jz sin16_sxdn
         mov r7, a
      sin16_sxlp:
         mov a, r6
         rlc a
         mov a, r6
         rrc a
         mov r6, a
         mov a, r5
         rrc a
         mov r5, a
         mov a, r4
         rrc a
         mov r4, a
         djnz r7, sin16_sxlp
      sin16_sxdn:
         ret
      sin16_shy:
         mov r0, {&h10}
         mov r1, {&h11}
         mov r2, {&h12}
         mov a, r3
         jz sin16_sydn
         mov r7, a
      sin16_sylp:
         mov a, r2
         rlc a
         mov a, r2
         rrc a
         mov r2, a
         mov a, r1
         rrc a
         mov r1, a
         mov a, r0
         rrc a
         mov r0, a
         djnz r7, sin16_sylp
      sin16_sydn:
         ret
      sin16_core:
         mov a, {&h1A}
         jnb acc.7, sin16_cpos
      Sin16_cneg:
         clr c
         mov a, {&h08}
         addc a, r0
         mov {&h08}, a
         mov a, {&h09}
         addc a, r1
         mov {&h09}, a
         mov a, {&h0A}
         addc a, r2
         mov {&h0A}, a
         clr c
         mov a, {&h10}
         subb a, r4
         mov {&h10}, a
         mov a, {&h11}
         subb a, r5
         mov {&h11}, a
         mov a, {&h12}
         subb a, r6
         mov {&h12}, a
         clr c
         mov a, {&h18}
         addc a, {&h1B}
         mov {&h18}, a
         mov a, {&h19}
         addc a, {&h1C}
         mov {&h19}, a
         mov a, {&h1A}
         addc a, {&h1D}
         mov {&h1A}, a
         ret
      Sin16_cpos:
         clr c
         mov a, {&h08}
         subb a, r0
         mov {&h08}, a
         mov a, {&h09}
         subb a, r1
         mov {&h09}, a
         mov a, {&h0A}
         subb a, r2
         mov {&h0A}, a
         clr c
         mov a, {&h10}
         addc a, r4
         mov {&h10}, a
         mov a, {&h11}
         addc a, r5
         mov {&h11}, a
         mov a, {&h12}
         addc a, r6
         mov {&h12}, a
         clr c
         mov a, {&h18}
         subb a, {&h1B}
         mov {&h18}, a
         mov a, {&h19}
         subb a, {&h1C}
         mov {&h19}, a
         mov a, {&h1A}
         subb a, {&h1D}
         mov {&h1A}, a
         ret
      Sin16_fin:
         mov a, {&h11}
         mov {Res_sin_i}, a
         mov a, {&h12}
         mov {Res_sin_i+1}, a
         jnb f0, sin16_fssp
         clr c
         mov a, #0
         subb a, {Res_sin_i}
         mov {Res_sin_i}, a
         mov a, #0
         subb a, {Res_sin_i+1}
         mov {Res_sin_i+1}, a
      Sin16_fssp:
         mov a, {&h09}
         mov {Res_cos_i}, a
         mov a, {&h0A}
         mov {Res_cos_i+1}, a
         jnb f1, sin16_exit
         clr c
         mov a, #0
         subb a, {Res_cos_i}
         mov {Res_cos_i}, a
         mov a, #0
         subb a, {Res_cos_i+1}
         mov {Res_cos_i+1}, a
      sin16_exit:
         ret
      sin16_tab:
         db 0,0,32
         db 5,228,18
         db 56,251,9
         db 18,17,5
         db 13,139,2
         db 216,69,1
         db 246,162,0
         db 124,81,0
         db 190,40,0
         db 95,20,0
         db 48,10,0
         db 24,5,0
         db 140,2,0
         db 70,1,0
         db 163,0,0
         db 81,0,0
         db 41,0,0
         db 20,0,0
         db 10,0,0
         db 5,0,0
         db 3,0,0
         db 1,0,0
   $end Asm

Return
Графики

Если нужна другая точность, вход в градах, гонах, двоичное представление и.д. - ищите желающего оплатить работу. Десятина пойдёт в копилку форума.

Для сравнения:

Ошибки вычисления встроенной функции bascom-avr 2.0.8.7

Таблица https://disk.yandex.ru/d/n3e6qYfwtOaSJQ

код
Код:
$regfile = "m16adef.dat"
$crystal = 16000000
$hwstack = 40
$swstack = 16
$framesize = 32
$baud = 19200
Config Base = 0
Dim X As Single : X = -7.85398
Dim X_b(4) As Byte At X Overlay
Dim Res_sin_s As Single : Dim Res_sin_b(4) As Byte At Res_sin_s Overlay
Dim Res_cos_s As Single : Dim Res_cos_b(4)as Byte At Res_cos_s Overlay
Dim N As Word
Open "comb.1:19200,8,n,1" For Output As #1
Config Portd.1 = Output
For N = 1 To 65535

   Res_sin_s = Sin(x) : Res_cos_s = Cos(x)

   Print X_b(0) ; " " ; X_b(1) ; " " ; X_b(2) ; " " ; X_b(3) ;
   Print " Res_sin_b=" ; Res_sin_b(0) ; " " ; Res_sin_b(1) ; " " ; Res_sin_b(2) ; " " ; Res_sin_b(3) ;
   Print " Res_cos_b=" ; Res_cos_b(0) ; " " ; Res_cos_b(1) ; " " ; Res_cos_b(2) ; " " ; Res_cos_b(3) ;
   Print " " ; X

   X = X + 0.00024

Next N

Stop

Отредактировано Кот Обормот (2026-03-17 17:48:07)

+2

104

особенность print
Код:
$regfile = "8H1K08.DAT"
$crystal = 35000000
$ramsize = 1024
$map
$large
Dim Shaitanama(4) As Byte
Dim X As Single
Dim N As Byte
X = 0.0350603

For N = 1 To 7
   X = X + 0.0000005
Next N

!mov {Shaitanama}, {x}
!mov {Shaitanama+1}, {x+1}
!mov {Shaitanama+2}, {x+2}
!mov {Shaitanama+3}, {x+3}
Print X ; " " ; Shaitanama(1) ; " " ; Shaitanama(2) ; " " ; Shaitanama(3) ; " " ; Shaitanama(4)

X = 0.0350637
!mov {Shaitanama}, {x}
!mov {Shaitanama+1}, {x+1}
!mov {Shaitanama+2}, {x+2}
!mov {Shaitanama+3}, {x+3}
Print X ; " " ; Shaitanama(1) ; " " ; Shaitanama(2) ; " " ; Shaitanama(3) ; " " ; Shaitanama(4)

X = X * 100
Print "x100 " ; X

Stop

Код выводит следующее (значение single и байтовое представление в памяти):
0.0350637 14 159 15 61
0.0350637 244 158 15 61
x100 3.5063698
Замечено в диапазоне чисел ~0,03÷0,5
Посколько отправлял в com через print,

то в данном диапазоне получал такое при построении графика

Три дня искал причину резонанса квантования функции в коде. Я в лёгком недоумении. :dontcare:

Отредактировано Кот Обормот (2026-03-10 16:28:10)

0

105

Shaitanama

0

106

Немножко преобразуем строку с числом в экспоненциальную форму
Код:
$regfile = "8H1K08.DAT"
$crystal = 35000000
$ramsize = 1024
$map
$large
Dim X_s As Single
Dim X_str As Xram String * 20
Dim X_e_str As Xram String * 8
Dim X_spc As String * 10
Dim X_len As Byte
Start Timer1
Do

   Gosub Sub_x_rand
   '============================================================================
   X_str = Str(x_s)                                           'ÈÑÕÎÄÍÀß ÑÒÐÎÊÀ X_str
   Gosub Exp_str                                              'ÐÅÇÓËÜÒÀÒ Â X_e_str
   '============================================================================
   X_len = Len(x_str) : X_len = 15 - X_len
   Print X_s ;
   Print Spc(x_len) ;
   Print "'" ;
   Print X_str ; "'";
   Print Spc(x_len) ;
   Print " -> '" ;
   Print X_e_str ; "'"

Loop

Exp_str:

   $asm
         MOV   R0, #0
         MOV   R7, #0
         MOV   R4, #255
         MOV   R6, #0
         MOV   R2, #48
         MOV   R3, #48
         MOV   R5, #0
         MOV   R1, #0
         MOV   DPTR, #{X_str}
         MOVX  A, @DPTR
         CJNE  A, #45, exp_str_st
         INC   R7
      exp_str_st:
         MOV   A, R7
         ADD   A, DPL
         MOV   DPL, A
         MOV   A, DPH
         ADDC  A, #0
         MOV   DPH, A
      exp_str_sl:
         MOVX  A, @DPTR
         JZ    exp_str_sd
         CJNE  A, #46, exp_str_cd
         MOV   R4, R0
         SJMP  exp_str_sn
      Exp_str_cd:
         CLR   C
         SUBB  A, #48
         JC    exp_str_sn
         MOVX  A, @DPTR
         SUBB  A, #58
         JNC   exp_str_sn
         MOVX  A, @DPTR
         MOV   B, A
         CJNE  R6, #0, exp_str_chk_d2
         CJNE  A, #48, exp_str_fd1
         SJMP  exp_str_sn
      exp_str_fd1:
         MOV   R2, B
         MOV   R5, R0
         MOV   R6, #1
         SJMP  exp_str_sn
      exp_str_chk_d2:
         CJNE  R6, #1, exp_str_chk_d3
         MOV   R3, B
         MOV   R6, #2
         SJMP  exp_str_sn
      exp_str_chk_d3:
         CJNE  R6, #2, exp_str_sn
         CLR   C
         MOV   A, B
         SUBB  A, #53
         JC    exp_str_skip_rnd
         MOV   R1, #1
      exp_str_skip_rnd:
         MOV   R6, #3
         SJMP  exp_str_sn
      exp_str_sn:
         INC   DPTR
         INC   R0
         SJMP  exp_str_sl
      Exp_str_sd:
         CJNE  R6, #0, exp_str_calc_exp
         MOV   R2, #48
         MOV   R3, #48
         MOV   R4, #0
         SJMP  exp_str_wo
      Exp_str_calc_exp:
         CJNE  R1, #1, exp_str_exp_logic
         MOV   A, R3
         CJNE  A, #57, exp_str_rnd_inc
         MOV   R3, #48
         MOV   A, R2
         CJNE  A, #57, exp_str_rnd_carry
         MOV   R2, #49
         MOV   A, R4
         INC   A
         MOV   R4, A
         SJMP  exp_str_exp_logic
      exp_str_rnd_inc:
         INC   A
         MOV   R3, A
         SJMP  exp_str_exp_logic
      exp_str_rnd_carry:
         INC   A
         MOV   R2, A
         SJMP  exp_str_exp_logic
      Exp_str_exp_logic:
         MOV   A, R4
         CJNE  A, #255, exp_str_ce
         MOV   R4, R0
      exp_str_ce:
         MOV   A, R4
         CLR   C
         SUBB  A, R5
         MOV   R4, A
         JNB   Acc.7, exp_str_epa
         SJMP  exp_str_wo
      exp_str_epa:
         DEC   A
         MOV   R4, A
      exp_str_wo:
         MOV   DPTR, #{X_str}
         MOVX  A, @DPTR
         MOV   DPTR, #{X_e_str}
         CJNE  A, #45, exp_str_wd1
         MOV   A, #45
         MOVX  @DPTR, A
         INC   DPTR
      exp_str_wd1:
         MOV   A, R2
         MOVX  @DPTR, A
         INC   DPTR
         MOV   A, #46
         MOVX  @DPTR, A
         INC   DPTR
         MOV   A, R3
         MOVX  @DPTR, A
         INC   DPTR
         MOV   A, #69
         MOVX  @DPTR, A
         INC   DPTR
         MOV   A, R4
         JNB   Acc.7, exp_str_esp
         MOV   A, #45
         MOVX  @DPTR, A
         INC   DPTR
         MOV   A, R4
         CPL   A
         INC   A
         SJMP  exp_str_wev
      exp_str_esp:
         MOV   A, #43
         MOVX  @DPTR, A
         INC   DPTR
         MOV   A, R4
      exp_str_wev:
         MOV   B, #10
         DIV   AB
         ADD   A, #48
         MOVX  @DPTR, A
         INC   DPTR
         MOV   A, B
         ADD   A, #48
         MOVX  @DPTR, A
         INC   DPTR
         CLR   A
         MOVX  @DPTR, A
   $end Asm

Return

Sub_x_rand:

   $asm
      mov a, th1
      Swap A
      mov {x_s+1}, a
      mov a, tl1
      mov r7, a
      anl a, #7
      add a, #60
      mov c, F0
      mov acc.7, c
      cpl F0
      mov {x_s+3}, a
      mov a, r7
      Swap A
      mov {x_s+2}, a
      mov a, r7
      rl a
      mov {x_s}, a
   $end Asm

Return

Вывод:
240.2931824    '240.2931824'     -> '2.4E+02'
-504.5907898   '-504.5907898'    -> '-5.0E+02'
0.0768045      '0.0768045'       -> '7.7E-02'
-0.7472519     '-0.7472519'      -> '-7.5E-01'
0.0763160      '0.0763160'       -> '7.6E-02'
-1.4788731     '-1.4788731'      -> '-1.5E+00'
27.7870388     '27.7870388'      -> '2.8E+01'
-1.4788731     '-1.4788731'      -> '-1.5E+00'
27.7870388     '27.7870388'      -> '2.8E+01'

0

107

Слишком "грубое" округление получается порой... ;)

+1

108

Для компактного представления порядка числа достаточно. Особенно если нужно накапливать выборки.
Любой может переточить под нужное число знаков. Особенно если диапазон заранее известен.

0

109

Более точный синус. Точнее только с переходом на double без нативной поддержки со стороны bascom прямой работой с байтовым массивом на ассемблере .

Выходные значения целочисленные long.

Отредактировано Кот Обормот (2026-03-27 11:15:33)

0

110

Раз уж синус и косинус вычислены, то тангенс уже бонусом. Но код разбухает до немыслимых 837 байт. Зато все вычисления выполняются исключительно в регистровой памяти.
Оператор print выдаёт входной угол, его байтовое представление в памяти, синус, косинус и тангенс (поделить на 32768)
Код:
$regfile = "8H1K08.DAT"
$crystal = 35000000
$ramsize = 1024
$map
$large
Dim X As Single : X = -7.85398
Dim X_b(4) As Byte
Dim Res_sin_i As Integer
Dim Res_cos_i As Integer
Dim Res_tan_l As Long
Dim I As Word

For I = 1 To 65535
   !mov {x_b},{x}
   !mov {x_b+1},{x+1}
   !mov {x_b+2},{x+2}
   !mov {x_b+3},{x+3}
   Gosub Trig
   Print X ; " : bytes(" ; X_b(1) ; "  " ; X_b(2) ; "  " ; X_b(3) ; "  " ; X_b(4) ; ") | sin " ; Res_sin_i ; " | cos " ; Res_cos_i ; " | tan " ; Res_tan_l
   X = X + 0.00024
Next I

Stop

Trig:
   '837
$asm
         clr f0
         clr f1
         mov a, {X+3}
         mov r7, a
         mov a, {X+2}
         mov r6, a
         mov a, {X+1}
         mov r5, a
         mov a, {X}
         mov r4, a
         mov a, r7
         jnb acc.7, trig_spin
         setb f0
         anl a, #127
         mov r7, a
         sjmp trig_sexp
      trig_spin:
         clr f0
      trig_sexp:
         mov a, r6
         rlc a
         mov a, r7
         rlc a
         jnz trig_snz
         mov {&h18}, #0
         mov {&h19}, #0
         mov {&h1A}, #0
         mov {&h1E}, #0
         ljmp trig_sinit
      trig_snz:
         clr c
         subb a, #126
         mov r0, a
         mov a, r6
         anl a, #127
         orl a, #128
         mov r6, a
         mov r7, #0
         mov a, r0
         jz trig_ssav
         jnb acc.7, trig_sshl
         cpl a
         inc a
         mov r0, a
      trig_sshr:
         clr c
         mov a, r7
         rrc a
         mov r7, a
         mov a, r6
         rrc a
         mov r6, a
         mov a, r5
         rrc a
         mov r5, a
         mov a, r4
         rrc a
         mov r4, a
         djnz r0, trig_sshr
         sjmp trig_ssav
      trig_sshl:
         clr c
         mov a, r4
         rlc a
         mov r4, a
         mov a, r5
         rlc a
         mov r5, a
         mov a, r6
         rlc a
         mov r6, a
         mov a, r7
         rlc a
         mov r7, a
         djnz r0, trig_sshl
      trig_ssav:
         mov {&h18}, r4
         mov {&h19}, r5
         mov {&h1A}, r6
         mov {&h1E}, r7
         lcall trig_sscl
         clr f1
         mov a, {&h1A}
         jb acc.7, trig_srdpi
         sjmp trig_schpi
      trig_srdpi:
         clr c
         mov a, {&h18}
         subb a, #0
         mov {&h18}, a
         mov a, {&h19}
         subb a, #0
         mov {&h19}, a
         mov a, {&h1A}
         subb a, #128
         mov {&h1A}, a
         cpl f0
         cpl f1
      trig_schpi:
         mov a, {&h1A}
         jb acc.6, trig_srhpi
         sjmp trig_sinit
      trig_srhpi:
         clr c
         mov a, #0
         subb a, {&h18}
         mov {&h18}, a
         mov a, #0
         subb a, {&h19}
         mov {&h19}, a
         mov a, #128
         subb a, {&h1A}
         mov {&h1A}, a
         cpl f1
      trig_sinit:
         mov {&h08}, #64
         mov {&h09}, #186
         mov {&h0A}, #77
         mov {&h10}, #0
         mov {&h11}, #0
         mov {&h12}, #0
         mov r3, #0
      trig_sloop:
         lcall trig_sldat
         lcall trig_sshx
         lcall trig_sshy
         lcall trig_score
         inc r3
         mov a, r3
         cjne a, #22, trig_sloop
         lcall trig_tcalc
         ljmp trig_sfin
      trig_sscl:
         mov a, {&h19}
         mov b, #96
         mul ab
         mov r6, a
         mov r7, b
         mov a, {&h18}
         mov b, #190
         mul ab
         add a, r6
         mov a, r7
         addc a, b
         mov r4, a
         mov r6, r4
         mov r7, #0
         mov a, {&h1A}
         mov b, #96
         mul ab
         add a, r6
         mov r6, a
         mov a, b
         addc a, r7
         mov r7, a
         mov a, {&h19}
         mov b, #190
         mul ab
         add a, r6
         mov r6, a
         mov a, b
         addc a, r7
         mov r7, a
         mov a, {&h18}
         mov b, #40
         mul ab
         add a, r6
         mov r6, a
         mov a, b
         addc a, r7
         mov r4, a
         mov r6, r4
         mov r7, #0
         mov a, {&h1E}
         mov b, #96
         mul ab
         add a, r6
         mov r6, a
         mov a, b
         addc a, r7
         mov r7, a
         mov a, {&h1A}
         mov b, #190
         mul ab
         add a, r6
         mov r6, a
         mov a, b
         addc a, r7
         mov r7, a
         mov a, {&h19}
         mov b, #40
         mul ab
         add a, r6
         mov {&h18}, a
         mov a, b
         addc a, r7
         mov r4, a
         mov r6, r4
         mov r7, #0
         mov a, {&h1E}
         mov b, #190
         mul ab
         add a, r6
         mov r6, a
         mov a, b
         addc a, r7
         mov r7, a
         mov a, {&h1A}
         mov b, #40
         mul ab
         add a, r6
         mov {&h19}, a
         mov a, b
         addc a, r7
         mov r4, a
         mov r6, r4
         mov a, {&h1E}
         mov b, #40
         mul ab
         add a, r6
         mov {&h1A}, a
         ret
      trig_sldat:
         mov dptr, #trig_stab
         mov a, r3
         mov b, #3
         mul ab
         add a, dpl
         mov dpl, a
         mov a, dph
         addc a, #0
         mov dph, a
         clr a
         movc a, @a+dptr
         mov {&h1B}, a
         inc dptr
         clr a
         movc a, @a+dptr
         mov {&h1C}, a
         inc dptr
         clr a
         movc a, @a+dptr
         mov {&h1D}, a
         ret
      trig_sshx:
         mov r4, {&h08}
         mov r5, {&h09}
         mov r6, {&h0A}
         mov a, r3
         jz trig_ssxdn
         mov r7, a
      trig_ssxlp:
         mov a, r6
         rlc a
         mov a, r6
         rrc a
         mov r6, a
         mov a, r5
         rrc a
         mov r5, a
         mov a, r4
         rrc a
         mov r4, a
         djnz r7, trig_ssxlp
      trig_ssxdn:
         ret
      trig_sshy:
         mov r0, {&h10}
         mov r1, {&h11}
         mov r2, {&h12}
         mov a, r3
         jz trig_ssydn
         mov r7, a
      trig_ssylp:
         mov a, r2
         rlc a
         mov a, r2
         rrc a
         mov r2, a
         mov a, r1
         rrc a
         mov r1, a
         mov a, r0
         rrc a
         mov r0, a
         djnz r7, trig_ssylp
      trig_ssydn:
         ret
      trig_score:
         mov a, {&h1A}
         jnb acc.7, trig_scpos
      trig_scneg:
         clr c
         mov a, {&h08}
         addc a, r0
         mov {&h08}, a
         mov a, {&h09}
         addc a, r1
         mov {&h09}, a
         mov a, {&h0A}
         addc a, r2
         mov {&h0A}, a
         clr c
         mov a, {&h10}
         subb a, r4
         mov {&h10}, a
         mov a, {&h11}
         subb a, r5
         mov {&h11}, a
         mov a, {&h12}
         subb a, r6
         mov {&h12}, a
         clr c
         mov a, {&h18}
         addc a, {&h1B}
         mov {&h18}, a
         mov a, {&h19}
         addc a, {&h1C}
         mov {&h19}, a
         mov a, {&h1A}
         addc a, {&h1D}
         mov {&h1A}, a
         ret
      trig_scpos:
         clr c
         mov a, {&h08}
         subb a, r0
         mov {&h08}, a
         mov a, {&h09}
         subb a, r1
         mov {&h09}, a
         mov a, {&h0A}
         subb a, r2
         mov {&h0A}, a
         clr c
         mov a, {&h10}
         addc a, r4
         mov {&h10}, a
         mov a, {&h11}
         addc a, r5
         mov {&h11}, a
         mov a, {&h12}
         addc a, r6
         mov {&h12}, a
         clr c
         mov a, {&h18}
         subb a, {&h1B}
         mov {&h18}, a
         mov a, {&h19}
         subb a, {&h1C}
         mov {&h19}, a
         mov a, {&h1A}
         subb a, {&h1D}
         mov {&h1A}, a
         ret
      trig_sfin:
         mov a, {&h11}
         mov {Res_sin_i}, a
         mov a, {&h12}
         mov {Res_sin_i+1}, a
         jnb f0, trig_sfssp
         clr c
         mov a, #0
         subb a, {Res_sin_i}
         mov {Res_sin_i}, a
         mov a, #0
         subb a, {Res_sin_i+1}
         mov {Res_sin_i+1}, a
      trig_sfssp:
         mov a, {&h09}
         mov {Res_cos_i}, a
         mov a, {&h0A}
         mov {Res_cos_i+1}, a
         jnb f1, trig_sexit
         clr c
         mov a, #0
         subb a, {Res_cos_i}
         mov {Res_cos_i}, a
         mov a, #0
         subb a, {Res_cos_i+1}
         mov {Res_cos_i+1}, a
      trig_sexit:
         ret
      trig_stab:
         db 0,0,32
         db 5,228,18
         db 56,251,9
         db 18,17,5
         db 13,139,2
         db 216,69,1
         db 246,162,0
         db 124,81,0
         db 190,40,0
         db 95,20,0
         db 48,10,0
         db 24,5,0
         db 140,2,0
         db 70,1,0
         db 163,0,0
         db 81,0,0
         db 41,0,0
         db 20,0,0
         db 10,0,0
         db 5,0,0
         db 3,0,0
         db 1,0,0
   trig_tcalc:
         mov a, {&h08}
         orl a, {&h09}
         orl a, {&h0A}
         jz trig_tovf
         mov {&h13}, #0 : mov {&h14}, #0
         mov {&h15}, {&h12} : mov {&h16}, {&h11} : mov {&h17}, {&h10}
         mov {Res_tan_l}, #0 : mov {Res_tan_l+1}, #0
         mov {Res_tan_l+2}, #0 : mov {Res_tan_l+3}, #0
         mov r0, #31
   trig_tloop:
         mov a, {Res_tan_l+3}
         jb acc.6, trig_tovf
         acall trig_tstep
         mov a, {Res_tan_l}   : rlc a : mov {Res_tan_l}, a
         mov a, {Res_tan_l+1} : rlc a : mov {Res_tan_l+1}, a
         mov a, {Res_tan_l+2} : rlc a : mov {Res_tan_l+2}, a
         mov a, {Res_tan_l+3} : rlc a : mov {Res_tan_l+3}, a
         djnz r0, trig_tloop
         sjmp trig_tasgn
   trig_tovf:
         mov {Res_tan_l}, #255 : mov {Res_tan_l+1}, #255
         mov {Res_tan_l+2}, #255 : mov {Res_tan_l+3}, #127
   trig_tasgn:
         mov c, F0
         jnb F1, trig_tchkng
         cpl c
   trig_tchkng:
         jnc trig_tfexit
         clr a : clr c
         mov a, {Res_tan_l}   : cpl a : add a, #1 : mov {Res_tan_l}, a
         mov a, {Res_tan_l+1} : cpl a : addc a, #0 : mov {Res_tan_l+1}, a
         mov a, {Res_tan_l+2} : cpl a : addc a, #0 : mov {Res_tan_l+2}, a
         mov a, {Res_tan_l+3} : cpl a : addc a, #0 : mov {Res_tan_l+3}, a
         ret
   trig_tstep:
         clr c
         mov a, {&h17} : rlc a : mov {&h17}, a
         mov a, {&h16} : rlc a : mov {&h16}, a
         mov a, {&h15} : rlc a : mov {&h15}, a
         mov a, {&h14} : rlc a : mov {&h14}, a
         mov a, {&h13} : rlc a : mov {&h13}, a
         clr c
         mov a, {&h15} : subb a, {&h08} : mov r1, a
         mov a, {&h14} : subb a, {&h09} : mov r2, a[url=https://upforme.ru/uploads/0000/25/b8/2167/498985.png][img]https://upforme.ru/uploads/0000/25/b8/2167/t498985.png[/img][/url]

         mov a, {&h13} : subb a, {&h0A}
         jnc trig_tstepok
         clr c : ret
   trig_tstepok:
         mov {&h15}, r1 : mov {&h14}, r2 : mov {&h13}, a
         setb c : ret
   Trig_tfexit:
         ret

$end Asm

Return
Ошибки для малых углов
Ошибки в диапазоне -π/2÷+π/2
Если результат стремится к бесконечности, то он ограничивается максимальным значением для типа long. Если косинус получается ноль, то происходит то же самое.

Версия без тангенса

Для сравнения точность в bascom-avr 2.0.8.7

В общем, данный недотангенс бесполезен. Проще поделить sin/cos самим bascom-8051. Потому как если реализовывать без потери точности, то выйдет то же самое что делается штатно. Но пусть лежит как пример говнокода.

Отредактировано Кот Обормот (2026-03-25 11:10:55)

+1

111

По следам публикаций

Теперь вход single, выход тоже single.

Ошибка на малых углах минимизирована насколько это возможно. В расчёте используются только регистры (все до 1F). Дальнейшее повышение точности только при "свопе" из xram (тратить пользовательскую память харам).

tan(x) получаеся штатным делением bascom single/single.

Отредактировано Кот Обормот (2026-03-27 21:19:59)

0

112

Продолжаем наблюдать за синусом...

Искусственная 6-байтовая беззнаковая переменная. Может показаться избыточным, но так вытягивется точность синуса на малых углах (и косинуса в соответствующих диапазонах).
Точность single для штатного применения в bascom-8051.
Крупнее для sin
Ещё крупнее для sin
Чёткое квантование точности single
Относительная ошибка на малых углах
TAN(x). Штатно делим single на single и вроде бы то же самое...
Но на малых углах...

Дальнейшее повышение точности имеет смысл только при штатной поддержке типа переменных double. А так, сколько есть xram, столько и можно посчитать бит точности. У меня где-то валяется извлечение квадратного корня из мегабитного числа.

Отредактировано Кот Обормот (2026-04-01 20:29:07)

0

113

думаю, Вас понимает только Вы )))

+1

114

Я в этом совсем не разбираюсь. Просто отправляю запросы в космос и получаю ответы какие кнопки нажимать.

0