Главная страница
Навигация по странице:

  • ===================================== Справочник по программированию «Bascom-8051» ==

  • ===================================== Справочник по программированию «Bascom-8051» == 24. Преобразование строковых переменных

  • Справочник по программировани BASCOM-8051 (М.Л. Кулиш, 2001). Справочник по программированию bascom8051 Краснодар 2001


    Скачать 6.61 Mb.
    НазваниеСправочник по программированию bascom8051 Краснодар 2001
    АнкорСправочник по программировани BASCOM-8051 (М.Л. Кулиш, 2001).pdf
    Дата26.04.2017
    Размер6.61 Mb.
    Формат файлаpdf
    Имя файлаСправочник по программировани BASCOM-8051 (М.Л. Кулиш, 2001).pdf
    ТипСправочник
    #5699
    КатегорияПромышленность. Энергетика
    страница19 из 25
    1   ...   15   16   17   18   19   20   21   22   ...   25
    ===================================== Справочник по программированию «Bascom-8051» == числа, особенно в операциях с плавающей точкой, и еще в большей степени при операции деления. Разница в ре- зультате при использовании знаков деления “/” и “\” не замечена.
    Ниже дается пример быстрой ассемблерной программы беззнакового умножения 16-разрядных чисел, дающей 32-разрядный результат.
    ;----------------------------------------------
    ;УМНОЖЕНИЕ ДВУХБАЙТНОГО ЧИСЛА НА ДВУХБАЙТНОЕ ЧИСЛО.
    ;ВРЕМЯ ИСПОЛНЕНИЯ 52 ТАКТА.
    ;ИСХОДНЫЕ ЧИСЛА: В R3-СТ.,R2-МЛ. И R1-СТ.,R0-МЛ. РЕЗУЛЬТАТ В R7-СТ.,R6,R5,R4
    ;----------
    MUL2B: ;УМНОЖЕНИЕ МЛАДШИХ ЦИФР ПЕРВОГО И ВТОРОГО ЧИСЛА
    MOV A,R2
    MOV B,R0
    MUL AB
    MOV R4,A
    MOV R5,B
    ;УМНОЖЕНИЕ МЛАДШЕЙ ЦИФРЫ ПЕРВОГО ЧИСЛА НА СТАРШУЮ ВТОРОГО ЧИСЛА
    MOV A,R2
    MOV B,R1
    MUL AB
    ;СЛОЖИТЬ С ПРЕДЫДУЩИМ РЕЗУЛЬТАТОМ
    ADD A,R5
    MOV R5,A
    CLR A
    ADDC A,B
    MOV R6,A
    ;УМНОЖЕНИЕ МЛАДШЕЙ ЦИФРЫ ВТОРОГО ЧИСЛА НА СТАРШУЮ ПЕРВОГО ЧИСЛА
    MOV A,R3
    MOV B,R0
    MUL AB
    ;СЛОЖИТЬ С ПРЕДЫДУЩИМ РЕЗУЛЬТАТОМ
    ADD A,R5
    MOV R5,A
    MOV A,R6
    ADDC A,B
    MOV R6,A
    CLR A
    RLC A
    MOV R7,A
    ;УМНОЖЕНИЕ СТАРШИХ ЦИФР ПЕРВОГО И ВТОРОГО ЧИСЛА
    MOV A,R3
    MOV B,R1
    MUL AB
    ;СЛОЖИТЬ С ПРЕДЫДУЩИМ РЕЗУЛЬТАТОМ
    ADD A,R6
    MOV R6,A
    MOV A,R7
    ADDC A,B
    MOV R7,A
    ;----------------------------------------------------
    Bascom позволяет производить очень сложные вычисления, благодаря краткой форме записи производи- мых действий. Компилятор при этом создает очень компактный код, содержащий только установку исходных зна- чений и вызов библиотечных подпрограмм. При реализации сложных формул необходимо раскладывать ее на ряд последовательно выполняемых операций, каждая из которых должна содержать только одно действие. Чтобы уменьшить число переменных, используемых при вычислениях, необходимо анализировать порядок их использо- вания, занимая для хранения промежуточных результатов регистры с уже ненужными данными. Ниже, в качестве примера, приведена простая подпрограмма для вычисления квадратного корня. У данной программы есть одна неприятность – неопределенность результата при нулевом значении аргумента. Чтобы избавится от этого недос- татка, к исходному числу добавляется любое незначительное число.
    '----------------------------------------------------
    ' тестирование программы вычисления квадратного корня
    Dim X As Single , Y As Single , Z As Single 'временные значения
    =============================================================================
    23-4

    ===================================== Справочник по программированию «Bascom-8051» ==
    Do
    Input "x=" , X
    X = X + 0.00001 'чтобы никогда не было нулевого значения, которое 'вызывает переполнение при вычислении квадратного корня
    Gosub Sqr 'теперь вычислим квадратный корень (время вычисления 50 мс)
    Print Y 'посмотрим результат
    Loop
    '-----------------------------
    'подпрограмма вычисления квадратного корня по формуле Ньютона 'вычисление производится методом последовательных приближений:
    ' Yi+1 = (X / Yi + Yi) * .5
    'начальное (исходное) значение вычисляется по формуле:
    ' Y0 = X / 200 + 2
    Sqr:
    'вычислим начальное значение, с которого начнем иттерацию
    Y = X * 0.005 : Y = Y + 2
    Do
    'вычислим очередное значение корня Y = (X / Y + Y) * .5
    Z = Y : Y = X / Y : Y = Y + Z : Y = Y * 0.5
    'проверим IF ABS(Y1 - Y) > Y / 1000 GOTO srq_1
    'в Bascom функция ABS не работает с числами в формате с плавающей точкой
    Z = Z - Y : Z = Z / Y 'вычисляем отношение между посл. и предпосл. значение
    $asm
    Anl {z + 3} , #&H7f ; делаем абсолютное значение стиранием знака
    $end Asm
    Loop Until Z < 0.001 'если необходимая точность достигнута (0.1 %)
    Return 'выходим '----------------------------------------------------
    Далее приведены еще несколько подпрограмм для вычисления функций методом разложения в степенной ряд. В этих программах для сокращения размера кода применена упаковка повторяющихся операций в подпро- граммы, что значительно сокращает размер кода (2 – 3 раза).
    '--------------------------------------------------------------------------
    'вычисление десятичного логарифма. Log(x) функция в Ua от аргумента Ua
    '--------------------------------------------------------------------------
    Log:
    'выделим порядок (двоичный исходного числа), а остаток сделаем 'числом в диапазоне от 1 до 2
    $asm
    Mov R0 , #{ua + 2}
    Mov A , @R0
    Mov C , Acc.7
    Clr Acc.7
    Mov @R0, A
    Inc R0
    Mov A , @r0
    Rlc A
    Mov {tmpb} , A
    Mov @R0 , #&H40
    $end Asm
    'Числа для справки:
    'ln(2)= 0,69314718, 1/ln(2)=1.442695, ln(10)=2.3025851, 1/ln(10)=0.4342945
    Gosub Ln 'вычислим натуральный логарифм остатка
    Ua = Ua * 1.442695 'преобразуем в двоичный логарифм остатка
    Ub = Tmpb : Ub = Ub - 128 : Ua = Ua + Ub 'объединим порядок и логарифм остатка 'и получим двоичный логарифм числа
    Ua = Ua * 0.30103001 'преобразуем в десятичный логарифм
    Return
    '--------------------------------------------------------------------------
    'вычисление натурального логарифма. Ln(x) функция в Ua от аргумента Ua
    'очень хорошая точность только от x = 1 до x = 3 (около 0.003 %)
    =============================================================================
    23-5

    ===================================== Справочник по программированию «Bascom-8051» ==
    'при x = 5 погрешность около 0.02 %, а при x = 10 - 0.7 %
    '
    ' 3 5 7 9 11 13 n
    ' p p p p p p p x-1
    ' ln(x)=2*[p + - + - + - + - + -- + -- ...+-] где p = -----
    ' 3 5 7 9 11 13 n x+1
    '
    '--------------------------------------------------------------------------
    Ln:
    Ub = Ua - 1 : Ua = Ua + 1
    Ua = Ub / Ua
    Ub = Ua * Ua : Uc = Ub * Ua : Ud = Uc * 0.3333333 : Gosub Add_aad
    Gosub Mul_cbc : Ud = Uc * 0.2 : Gosub Add_aad
    Gosub Mul_cbc : Ud = Uc * 0.14285714 : Gosub Add_aad
    Gosub Mul_cbc : Ud = Uc * 0.1111111111 : Gosub Add_aad
    Gosub Mul_cbc : Ud = Uc * 0.09090909 : Gosub Add_aad
    Gosub Mul_cbc : Ud = Uc * 0.07692308 : Gosub Add_aad 'точность 0.003 %
    ' Gosub Mul_cbc : Ud = Uc * 0.06666667 : Gosub Add_aad
    ' Gosub Mul_cbc : Ud = Uc * 0.05882353 : Gosub Add_aad
    ' Gosub Mul_cbc : Ud = Uc * 0.05263158 : Gosub Add_aad
    Ua = Ua + Ua : Return
    '---------------------
    'для сокращения размера кода повторяющиеся программы выделим
    Mul_cbc:
    Uc = Ub * Uc : Return
    '---------------------
    Add_aad:
    Ua = Ua + Ud : Return
    '---------------------
    '--------------------------------------------------------------------------
    'синусная функция в Ua от аргумента Ua в радианах 'хорошая точность только до 90 град (около 0.0002 %)
    'при 180 град погрешность достигает 4 %!!!
    Sin:
    Ub = Ua : Ua = Ua * Ua
    Uc = Ua
    Ua = Ua * 0.013888889 ' 1/72
    Gosub Sub_aa1
    Gosub Mul_aac
    Ua = Ua * 0.0238095243 '1/42
    Gosub Add_aa1
    Gosub Mul_aac
    Ua = Ua * .05 '1/20
    Gosub Sub_aa1
    Gosub Mul_aac
    Ua = Ua * 0.16666667 '1/6
    Gosub Add_aa1
    Gosub Mul_aab
    Return
    '---------------------
    Add_aa1:
    Ua = Ua + 1
    Return
    '---------------------
    Sub_aa1:
    Ua = Ua - 1
    Return
    '---------------------
    Mul_aac:
    Ua = Ua * Uc
    Return
    '---------------------
    =============================================================================
    23-6

    ===================================== Справочник по программированию «Bascom-8051» ==
    Mul_aab:
    Ua = Ua * Ub
    Return
    '--------------------------------------------------------------------------
    'косинусная функция в Ua от аргумента Ua в радианах 'хорошая точность только до 90 град (около 0.003 % от максимального значения)
    'при 180 град погрешность достигает 3 %!!!
    Cos:
    Ua = Ua * Ua 'angle squared
    Ub = Ua 'save
    Ua = Ua * 0.017857144 '1/56
    Gosub Sub_aa1
    Gosub Mul_aab
    Ua = Ua * 0.033333333 '1/30
    Gosub Add_aa1
    Gosub Mul_aab
    Ua = Ua * 0.083333333 '1/12
    Gosub Sub_aa1
    Gosub Mul_aab
    Ua = Ua * 0.5 '1/2
    Gosub Add_aa1
    Return
    '--------------------------------------------------------------------------
    'показательная функция e^x в Ua от аргумента Ua в радианах 'хорошая точность только до x = 3 (около 0.002 %)
    'точность при x = 4 (около 0.07 %), а при x = 10 - 4 %
    Exp:
    Ub = Ua + 1 '1+x/1!
    Gosub Mul_cac : Ud = Uc * 0.5 : Gosub Add_bbd '+x^2/2!
    Gosub Mul_cac : Ud = Uc * 0.16666667 : Gosub Add_bbd '+x^3/3!
    Gosub Mul_cac : Ud = Uc * 0.041666667 : Gosub Add_bbd '+x^4/4!
    Gosub Mul_cac : Ud = Uc * 0.008333333 : Gosub Add_bbd '+x^5/5!
    Gosub Mul_cac : Ud = Uc * 0.0013888889 : Gosub Add_bbd '+x^6/6!
    Gosub Mul_cac : Ud = Uc * 0.0001984127 : Gosub Add_bbd '+x^7/7!
    Gosub Mul_cac : Ud = Uc * 0.000024801587 : Gosub Add_bbd '+x^8/8!
    Gosub Mul_cac : Ud = Uc * 0.000002755732 : Gosub Add_bbd '+x^9/9!
    Gosub Mul_cac : Ud = Uc * 0.0000002755732 : Gosub Add_bbd '+x^10/10!
    Return
    '---------------------
    Add_bbd:
    Ub = Ub + Ud : Return
    '---------------------
    Mul_cac:
    Uc = Uc * Ua : Return
    '---------------------
    Add_cad:
    Ua = Ua + Ud : Return
    '--------------------------------------------------------------------------
    Возможность применения тех или иных вычислительных программ частот обусловлена производительно- стью микроконтроллера. Далее приведена программа цифрового фильтра нижних частот третьего порядка. Для его реализации с указанной частотной характеристикой требуется очень высокая производительность микрокон- троллера – в десять раз выше стандартной (эквивалентно более 120 МГц). Для этого могут быть использованы только улучшенные модели W77E58, DS89C420). При использовании микроконтроллера с ядром AVR эта и все приведенные выше вычислительные программы работают быстрее в среднем в 50 раз (компилированные
    BasAVR).
    '--------------------------------------------------------------------------
    ' фильтр с частотой среза около 5-10 Гц при частоте выборок 500 Гц ' (частоте вызова данной программы). Коэффициент передачи фильтра:
    ' 1 1
    ' К = ----------------------- * ---------
    ' 0.006*p^2 + 0.111*p + 1 0.1*p + 1
    =============================================================================
    23-7

    ===================================== Справочник по программированию «Bascom-8051» ==
    'а это коэффициенты цифрового фильтра
    Const _a = 0.013869625
    Const _b = -0.83217753
    Const _c = 1.8183079
    Const _d = 0.09090909
    Const _e = 0.9090909
    '---------------------
    Dim Ux As Single 'входное значение
    Dim Uy As Single 'выходное значение первого звена
    Dim Uy1 As Single 'предыдущее выходное значение первого звена
    Dim Uy2 As Single 'предпредыдущее выходное значение первого звена
    Dim Uz As Single 'выходное значение второго звена
    Dim Uz1 As Single 'предыдущее выходное значение второго звена '------------------------
    ' программа цифрового фильтра третьего порядка содержащего два звена ' 2-го и 1-го порядка:
    ' Uy = Ux * a + Uy2 * b + Uy1 * c - формула звена второго порядка ' Uz = Uy * d + Uz1 * e - формула фильтра звена первого порядка '-----
    Filtr_3p:
    Uy = Ux * _a : Uz = Uy2 * _b : Uy = Uy + Uz 'программа фильтра второго порядка
    Uz = Uy1 * _c : Uy = Uy + Uz
    Uy2 = Uy1 : Uy1 = Uy
    '-----
    Uz = Uy * _d : Uy = Uz1 * _e : Uz = Uy + Uz 'программа фильтра первого порядка
    Uz1 = Uz : Return
    '------------------------------------------
    Bascom версий 2.хх расширил диапазон возможных действий с битовыми переменными. Теперь стала возможным операция с индексированными битами. Причем в качестве индекса может выступать другая перемен- ная, и конечно только байтовая. Например:
    Dim X As Byte , Y As Byte
    X.3 = Y.2 : P2.1 = Y.4 'передача значений между битами байтовых переменных
    For X = 0 To 7 'индексирование бита
    Set P3.X
    Next
    If P2.X=1 Then 'проверка индексированного бита
    P2.X = 0
    End If
    =============================================================================
    23-8

    ===================================== Справочник по программированию «Bascom-8051» ==
    24. Преобразование строковых переменных
    Строковые переменные могут преобразовываться в другие строковые переменные – длинные разбираться на части и, наоборот, из коротких строк могут складываться длинные. Bascom обеспечивает преобразование цифр, записанных в строковых переменных, в числа и преобразование чисел в строковые переменные. Причем числа могут быть записаны в виде десятичных или шестнадцатеричных цифр (символов). В следующей таблице показано расположение байтов строковой переменной в памяти после ее очистки (нулями). В первом случае в переменную длиной N записано символами число «1234». Во втором случае на его место записано сообщение
    «AF»
    Расположение в памяти строковой переменной, определенной как: Dim S As String * N
    Adr Adr+1 Adr+2 Adr+3 Adr+4 … Adr+N
    Adr+N+1 30H 31H 32H 33H 00H 00H 00H 00H
    41H
    46H
    00H
    33H
    00H
    00H
    00H
    00H
    Преобразование строк может выполняться в явном и неявном виде. Примеры явного преобразования: а) разделение строк с помощью операторов MID(), LEFT(), RIGHT(); б) слияние суммированием строк ( “.. ” + “..”); в) монтаж строк с помощью оператора MID(); г) преобразование строки в число с помощью функций VAL(), HEXVAL(); д) преобразование числа в строку с помощью функций STR(), HEX(), CHR().
    Неявное преобразование строковых переменных происходит при вводе (оператором типа INPUT) и выводе (оператором PRINT) цифровых переменных. Ниже дана демонстрационная программа, показывающая основные способы преобразования строковых переменных. Подобные примеры имеются и в других программах, приведенных выше.
    '-------------------------------
    Dim R_rd As Integer 'код для ЦАП
    Dim R_frq As Single 'частота для синтезатора
    Dim R_lin As String * 6 'введенная строка
    Dim R_tmp As String * 20 'временная строка
    Mc:
    Input "Input six characters" , R_lin
    'в R_lin принятая строка: “+XXXXX”, “-XXXXX”, “HXXXXX” или “R”
    R_tmp = Left(r_lin , 1) 'выделим первый символ для анализа
    If R_tmp = "+" Then 'положительная полярность?
    R_tmp = Mid(r_lin , 2 , 5) 'выделим только числовое значение
    R_rd = Val(r_tmp) 'преобразовать в целое число
    Goto Mc 'строка обработана - в главный цикл
    End If
    If R_tmp = "-" Then 'отрицательная полярность?
    R_rd = Val(r_lin) 'преобразуем строку с полярностью
    Goto Mc 'строка обработана - в главный цикл
    End If
    If R_tmp = "H" Then 'частота в Герцах?
    R_tmp = Mid(r_lin , 2 , 5) 'выделим числовое значение
    R_frq = Val(r_tmp) 'преобразовать в число с плав. точкой
    R_frq = R_frq * 0.001 'преобразовать в килогерцы
    Goto Mc 'строка обработана - в главный цикл
    End If
    If R_tmp = "R" Then 'вернуть значения
    Print "H" ; R_frq ; "D" ; R_rd 'передадим строку состояния 'или иначе
    R_tmp = "H" + Str(r_frq) + "D" + Str(r_rd) 'сформируем строку состояния
    Print R_tmp 'передадим готовую строку
    Goto Mc 'строка обработана - в главный цикл
    End If
    Goto Mc 'в главный цикл '-------------------------------
    В новой версии добавлено два новых оператора LCASE и UCASE, осуществляющих преобразование букв строковых переменных. Первый оператор уменьшает размер букв (делает все буквы строчными), а второй наоборот, делает все буквы большими (прописными). Замечательно, что эти операторы не просто добавляют или
    =============================================================================
    24-1

    ===================================== Справочник по программированию «Bascom-8051» == вычитают из кода символа число 20h, а выбирают символы, являющиеся латинскими буквами. Таким образом цифры и другие служебные символы не преобразуются и остаются неизменными.
    Еще одним важным добавление в версии 1.20 является функция INSTR(), с помощью которой стало возможным производить поиск значения одной строки в составе другой строки. В результате работы этой функции возвращается номер позиции, указывающий на начало искомого фрагмента. Если фрагмент не найден, то возвращается нулевое значение. Практическая ценность этой функции заключается в возможности применения сложных строк в протоколах обмена между процессорами, т.е. стало возможным применять команды переменного состава или производит накопление нескольких команд без обработки. Ниже дается пример применения новых функций.
    '----------------------------------------------
    ' демонстрация декодирования сложных команд '----------------------------------------------
    ' программа запрашивает строку (командой "r", которая ' может содержать одну или несколько команд:
    ' Axx - установить параметр с двухзначным числом ' Bxxxx - установить параметр с четырехзначным числом ' Cxxxxxxxx - установить параметр с восьмизначным числом ' Например: "A12B1234C00123456", "A30", "c00004055" или "a05b0010"
    Dim P_a As Byte , P_b As Word , P_c As Long
    Dim Tmp1 As Byte , Tmps As String * 10
    Dim In_buf As String * 20
    '----------------------------------------------
    P_a = 0 : P_b = 0 : P_c = 0 'очистим переменые параметров
    Do 'цикл установки параметров
    Input "r" , In_buf : 'приняли строку с командами
    In_buf = Ucase(in_buf) 'переведем все символы в верхний регистр 'проверим наличие первой команды
    Tmps = "A" : Tmp1 = Instr(1 , In_buf , Tmps)
    If Tmp1 <> 0 Then 'если она присутствует,
    Tmps = Mid(in_buf , Tmp1 , 2) 'выберем числовое значение
    P_a = Val(tmps) 'и преобразуем в число
    End If
    'проверим наличие второй команды
    Tmps = "B" : Tmp1 = Instr(1 , In_buf , Tmps)
    If Tmp1 <> 0 Then 'если она присутствует, поступим аналогично
    Tmps = Mid(in_buf , Tmp1 , 4) : P_b = Val(tmps)
    End If
    'аналогично проверим наличие третьей команды
    Tmps = "C" : Tmp1 = Instr(1 , In_buf , Tmps)
    If Tmp1 <> 0 Then
    Tmps = Mid(in_buf , Tmp1 , 8) : P_c = Val(tmps)
    End If
    Wait 1 'немного подождем и повторим
    Loop
    =============================================================================
    24-2

    1   ...   15   16   17   18   19   20   21   22   ...   25


    написать администратору сайта