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

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

  • ===================================== Справочник по программированию «Bascom-8051» == 23. Вычисления и преобразования чисел

  • Справочник по программировани 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
    КатегорияПромышленность. Энергетика
    страница18 из 25
    1   ...   14   15   16   17   18   19   20   21   ...   25
    ===================================== Справочник по программированию «Bascom-8051» ==
    Временные диаграммы, формируемые операторами последовательного ввода
    Оператор
    Временная диаграмма
    Скорость
    Shiftin, mode 0
    ___ ____ ____ ____ ____ ____
    ___X____X____X____X____X____ In_Data msb __ _ _ _ _ __ lsb
    |__| |__| |__| |__| |__| Clk
    Пиковая
    100 Кбод, средняя
    80 Кбод
    Shiftin, mode 1
    ___ ____ ____ ____ ____ ____
    ___X____X____X____X____X____ In_Data msb __ __ __ __ __ lsb
    __| |_| |_| |_| |_| |__ Clk
    Пиковая
    100 Кбод, средняя
    80 Кбод
    Shiftin, mode 2
    ___ ____ ____ ____ ____ ____
    ___X____X____X____X____X____ In_Data lsb __ _ _ _ _ __ msb
    |__| |__| |__| |__| |__| Clk
    Пиковая
    100 Кбод, средняя
    80 Кбод
    Shiftin, mode 3
    ___ ____ ____ ____ ____ ____
    ___X____X____X____X____X____ In_Data lsb __ __ __ __ __ msb
    __| |_| |_| |_| |_| |__ Clk
    Пиковая
    100 Кбод, средняя
    80 Кбод
    Shiftin, mode 4
    ___ _____ _____ _____ _____ __
    ___X_____X_____X_____X_____X__ Out_Data msb _ _ _ _ lsb
    _____| |___| |___| |___| |____ Clk External
    До 100 Кбод, средняя
    80 Кбод
    Shiftin, mode 5
    ___ _____ _____ _____ _____ __
    ___X_____X_____X_____X_____X__ Out_Data msb_____ ___ ___ ___ ____ lsb
    |_| |_| |_| |_| Clk External
    До 100 Кбод, средняя
    80 Кбод
    Shiftin, mode 6
    ___ _____ _____ _____ _____ __
    ___X_____X_____X_____X_____X__ Out_Data lsb _ _ _ _ msb
    _____| |___| |___| |___| |____ Clk External
    До 100 Кбод, средняя
    80 Кбод
    Shiftin, mode 7
    ___ _____ _____ _____ _____ __
    ___X_____X_____X_____X_____X__ Out_Data lsb_____ ___ ___ ___ ____ msb
    |_| |_| |_| |_| Clk External
    До 100 Кбод, средняя
    80 Кбод
    Bascom предлагает также операторы Spiin и Spiout, обеспечивающих подключение устройств с последовательным SPI-интерфейсом. Эти операторы реализуют интерфейс программно и в несколько упрощенном виде (не обеспечивается одновременный вывод и ввод соттветственно). По сути, это те же операторы
    Shiftin и Shiftout, работающие в режиме 1, но только с добавлением сигнала “выбора кристалла”. Тем не менее, операторами Spiin и Spiout можно успешно пользоваться во многих случаях, т.к. большинство периферийных микросхем используют именно такой режим. Ниже в таблице представлены упрощенные (и укороченные) временные диаграммы на линиях интерфейса при работе операторов Spiin и Spiout.
    =============================================================================
    22-2

    ===================================== Справочник по программированию «Bascom-8051» ==
    Оператор
    Временная диаграмма
    Скорость при
    12 МГц
    Spiout
    _ _
    |__________________________| CS
    ___ _____ _____ _____ _____ __
    ___X_____X_____X_____X_____X__ Out_Data msb _ _ _ _ lsb
    _____| |___| |___| |___| |____ Clk
    Пиковая
    100 Кбод, средняя
    80 Кбод
    Spiin
    _ __
    |_________________________| CS
    ___ ____ ____ ____ ____ ____
    ___X____X____X____X____X____ In_Data msb __ __ __ __ __ lsb
    __| |_| |_| |_| |_| |__ Clk
    Пиковая
    100 Кбод, средняя
    80 Кбод
    Далее приведены примеры ассемблерного кода, выдаваемого компилятором, при использовании операторов последовательного ввода вывода. Обращаем внимание, что операторы Spiin и Spiout оформлены в виде подпрограмм. Операторы Shftin и Shiftout просто вставляются в исполняемый код, что при многократном их использовании дает соответствующее увеличениие размера получаемого кода. Если размер кода является критичным, а операторы Shftin и Shiftout применяются неоднократно, то рекомендуется встраивать их в специально созданные подпрограммы.
    ;оператор SPIOUT
    ;при входе указывают: R0-данные, R7-число байт
    ;F0=0 - из внутренней памяти, F0=1 - из внешней
    Spiout:
    CLR P1.2 ;сигнал выбор кристалла
    Spio1:
    ACALL Rdda ;считать байт
    MOV R2,#08H ;число бит
    Spio2:
    RLC A ;выдвинуть старший бит
    MOV P1.1,C ;в порт вывода
    SETB P1.3 ;сформировать импульс
    NOP
    CLR P1.3
    DJNZ R2,Spio2 ;повторить восемь раз
    ACALL Incinx ;инкремент указателя
    DJNZ R7,Spio1;повторять, пока все байты не выдвинуты
    SETB P1.2 ;снять сигнал выбора кристалла
    RET
    ;считывание данных
    Rdda:
    JB F0,Rda1
    MOV A,@R0
    RET
    Rda1:
    MOVX A,@DPTR
    RET
    ;запись данных
    Wrda:
    JB F0,Wrd1
    MOV @R0,A
    RET
    Wrd1:
    MOVX @DPTR,A
    RET
    ;инкремент указателя
    Incinx:
    JB F0,Iinx1
    =============================================================================
    22-3

    ===================================== Справочник по программированию «Bascom-8051» ==
    INC R0
    RET
    Iinx1:
    INC DPTR
    RET
    ;-----------------------------
    ;оператор SHIFTOUT в режиме 1
    Shiftout1:
    CLR P1.3 ;исходное состояние линии Clk
    MOV R0,#Dat ;адрес данных
    MOV R2,#01H ;число байт
    Sho1_1:
    MOV A,@R0
    MOV R3,#08H
    Sho1_2:
    RLC A
    MOV P1.0,C
    SETB P1.3
    NOP
    NOP
    CLR P1.3
    NOP
    NOP
    DJNZ R3,Sho1_1
    DEC R0
    DJNZ R2,Sho1_2
    ;-----------------------------
    ;оператор SHIFTIN в режиме 0
    Shiftin0:
    SETB P1.1
    MOV R0,#34H
    MOV R2,#02H
    INC R0
    Shi0_1:
    MOV R3,#08H
    Shi0_2:
    CLR P1.1
    NOP
    NOP
    MOV C,P1.2
    RLC A
    SETB P1.1
    NOP
    NOP
    DJNZ R3,Shi0_2
    MOV @R0,A
    DEC R0
    DJNZ R2,Shi0_1:
    ;-----------------------------
    ;оператор SHIFTIN в режиме 1
    Shiftin1:
    CLR P1.1
    MOV R0,#34H
    MOV R2,#02H
    INC R0
    Shi1_1:
    MOV R3,#08H
    Shi1_2:
    SETB P1.1
    NOP
    NOP
    MOV C,P1.2
    RLC A
    =============================================================================
    22-4

    ===================================== Справочник по программированию «Bascom-8051» ==
    CLR P1.1
    NOP
    NOP
    DJNZ R3,Shi1_2
    MOV @R0,A
    DEC R0
    DJNZ R2,Shi1_1
    ;-----------------------------
    Мы видим, что описанные операторы Bascom не обеспечивают предельно возможную (для процессора
    8051) скорость приема и передачи, хотя сегодня, уже трудно представить реальные периферийные устройства, все еще требующие такую низкую скорость. Это сделано намеренно и, как увидим дальше, совершенно правильно, чтобы иметь возможность программно принимать выдвигаемые данные (смотри режим 4 оператора Shiftin), а также передавать данные через оптроны, которые обычно дают задержку от 1 до 10 мкс. Таким образом, принятая скорость передачи является компромиссной и удовлетворяющей наибольшее число пользователей. Для ускорения процесса приема или передачи можно использовать собственные программы, например, такие как, примененные для записи и считывания данных, в программе тестирования АЦП типа AD7711A (смотри выше). Еще быстрее работает программа считывания или записи данных, использующая в качестве линии передачи (и приема) данных порт P0.0, а порты P3.6 и P3.7 соответственно как линии синхронизации при записи и считывании данных. Ниже представлен пример программы записи данных, в которой импульс синхронизации формируется аппаратно применением команды MOVX.
    Mov A , Data ;загрузим аккумулятор
    Rl A ;начиная со старшего разряда
    Movx @DPTR , A ;передадим один бит из аккумулятора
    Rl A ;повторим восемь раз
    Movx @DPTR , A
    Rl A
    Movx @DPTR , A
    Rl A
    Movx @DPTR , A
    Rl A
    Movx @DPTR , A
    Rl A
    Movx @DPTR , A
    Rl A
    Movx @DPTR , A
    Rl A
    Movx @DPTR , A
    Еще быстрее (Fкв / 12) можно записывать или считывать данные, используя аппаратный универсальный последовательный интерфейс микроконтроллера, включенный в режиме 3, но при этом занимаются линии P3.0 и P3.1, что часто недопустимо. Если применять модель процессора AT89S8252, имеющего полноценный многорежимный аппаратный SPI-интерфейс, то можно будет работать с максимальной скоростью Fкв / 4.
    Bascom не поддерживает своими специальными операторами все эти режимы, поэтому чтобы воспользоваться ими, нужно применять обычные операторы загрузки и чтения регистров процессора.
    =============================================================================
    22-5

    ===================================== Справочник по программированию «Bascom-8051» ==
    23. Вычисления и преобразования чисел
    Bascom позволяет производить арифметические вычисления (сложение, вычитание, умножение и деле- ние) над целыми числами (одно-, двух и четырехбайтными) и числами в формате с плавающей точкой. В следую- щей таблице показано расположение байтов переменных в памяти.
    Расположение в памяти
    Тип переменной
    Первый байт
    (Adr*)
    Второй байт
    (Adr+1)
    Третий байт
    (Adr+2)
    Четвертый байт
    (Adr+3)
    Однобайтовая пе- ременная (Byte)
    Байт - - -
    Двухбайтовая
    (Word, Integer)
    Младший байт
    Старший байт -
    -
    Четырехбайтовая
    (Long)
    1-й байт
    (младший)
    2-й байт 3-байт 4-й байт
    (старший)
    1-й байт
    (младший)
    2-й байт 3-байт
    (старший)
    Знак
    В формате с пла- вающей точкой
    (Single)_
    Нормализованная мантасса, принимающая значения от 1 до 2, старший бит мантиссы отбрасывается (только подразумевает- ся наличие всегда равного 1).
    Примеры кода 00 00 80 3F = 1 чисел в порядке, 00 00 00 40 = 2 расположения в 00 00 80 40 = 4 памяти 00 00 00 41 = 8 00 00 80 41 = 16 00 00 00 42 = 32 00 00 80 42 = 64 00 00 00 43 = 128 00 00 20 C1 = -10 00 00 20 C0 = -2.5
    Байт порядка.
    Вычисляется как
    127+p, где p- порядок из вы- ражния:
    2^p + Мантисса
    0 - плюс
    1 - ми- нус
    * Adr – адрес переменной определенный при компиляции
    Bascom с целыми двухбайтными числами может выполнять знаковые (с переменными типа Integer и
    Long) и беззнаковые (с переменными типа Byte и Word) арифметические операции. Арифметические операции с четырехбайтными числами всегда производятся с учетом знака. При целочисленных вычислениях длина результа- та, не может превышать длины исходных числовых переменных. Даже при умножении 8-разрядных чисел резуль- тат будет тоже 8-разрядным. Аналогично для 16-разрядных и 32-разрядных чисел. Смешанные произведения дают результат, равный по длине, более длинной переменной. Главная неприятность этой особенности компилятора заключается в том, что при переполнении (возможном при сложении и особенно умножении) теряются старшие разряды. Эта ошибка не показывается компилятором потому, что считается ошибкой программиста. Чтобы этого не происходило, сложение и умножение при наличии вероятности переполнения нужно выполнять с использова- нием переменных двойной длины, а это значительно увеличивает время операции, или применять быструю ас- семблерную программу с собственной программой сложения и умножения. Ниже приведена одна такая програм- ма.
    Компилятор может производить много вариантов преобразования чисел в явном (с помощью специаль- ных операторов) или в неявном виде (при выполнении других операции). Преобразование в неявном виде проис- ходит при перезаписи данных или при вычислении значения операндов разного типа. Причем, если преобразова- ние производится при считывании исходных значений (до выполнения назначенной операции), вероятность ошибки невелика, т.к. компилятор выбирает подпрограмму обработки, в зависимости от типа исходных перемен- ных. Если запись результата назначена в регистр, отличающийся по типу, от переменных, применяемых при вы- числениях, то ошибка неизбежна, т.к. компилятор использует имя переменной-приемника уже механически. При наличии ошибки несоответствия длины результата и размера переменной, куда помещается результат, последняя может быть заполнена не полностью или, еще хуже, перекрыта по длине. Эти ошибки также не выявляются и не показываются компилятором. Ошибки подобного рода исключены, при выполнении специальных операций пре- образования, когда компилятор проверяет размерность переменной - приемника данных;
    Ниже приведена программа, в которой имеются примеры вычисления и преобразования чисел, выполняе- мые компилятором Bascom.
    '----------------------------------------------------
    =============================================================================
    23-1

    ===================================== Справочник по программированию «Bascom-8051» ==
    ' Преобразование числовых переменных и вычисления '----------------------------------------------------
    $large
    Dim Cnt As Const 5 'число 5
    Dim Bt As Bit 'определим по паре переменных всех типов
    Dim Byt As Byte , Byt1 As Byte
    Dim Wrd As Word , Wrd1 As Word
    Dim Intg As Integer , Intg1 As Integer
    Dim Lng As Long , Lng1 As Long
    Dim Sng As Single , Sng1 As Single
    '----------------------------------------------------
    Set Bt 'установить бит '----------------------------------------------------
    'преобразование переменных
    Byt = Bt 'значение бита помещается в младший разряд
    Byt = Cnt 'записать число (константу)
    Wrd = Byt 'в младший байт данные, в старший байт 00
    Intg = Wrd 'переместить данные без изменений
    Intg = Not Intg 'инвертировать
    Wrd = Intg 'обратно без изменений
    Sng = Wrd : Print Sng 'преобразовать в плавающую Sng = 65550.0
    Sng = Intg : Print Sng 'преобразовать в плавающую Sng = -6.0
    '----------------------------------------------------
    'целочисленные вычисления
    Intg = Intg * 5 : Print Intg 'результат Intg = -30
    Intg = Intg / 5 : Print Intg 'рузультат Intg = -6
    Intg1 = 1000
    Intg = Intg1 / Intg : Print Intg'результат Intg = -166
    Intg = Intg * -1 'смена знака. Это медленный вариант
    Intg = Not Intg : Intg = Intg + 1 'аналогично, но работает намного быстрее
    Intg = Not Intg : Incr Intg 'тоже работает быстро
    Lng = Intg 'чтобы получить 32-разр. результат умножения,
    Lng = Lng * Intg 'хотя бы один из операндов должен быть 32-разр.
    Lng = 1000000 : Lng = Not Lng 'инверсия для смены знака
    Incr Lng '-1000001 + 1 = -1000000
    Print Lng 'результат Lng = -1000000
    Lng = Lng / 1000 'деление на константу
    Print Lng 'результат Lng = -1000
    Wrd = Lng / 1000 'так неправильно, хотя компилятор ошибку не покажет
    Lng = Lng / 1000 : Wrd = Lng 'а это правильно
    Intg1 = -10
    Lng = Lng / Intg1 'деление на переменную другой размерности
    Print Lng 'результат Lng = 100
    '----------------------------------------------------
    'вычисление с плав. точкой
    Sng = Sng * Lng 'умножение целого числа на плавающее
    Print Sng 'результата Sng = -600.0
    Sng1 = 0.15 : Sng = Sng * Sng1 'умножение плавающих чисел
    Print Sng 'результата Sng = -90.0
    Sng = Sng / -10 'деление на константу
    Print Sng 'результата Sng = 9.0
    $asm
    Xrl {Sng+3} , #&h80 'мгновенная смена знака числа с плав. точкой
    Anl {Sng+3} , #&h7f 'или установка положительной полярности
    Prl {Sng+3} , #&h80 'или установка отрицательной полярности
    $end asm
    '----------------------------------------------------
    'демонстрация неправильного умножения
    Byt = 10 : Byt1 = 15 : Wrd = &H1234 'назначим числа
    Wrd = Byt * Byt1 'произведение сразу запишем в двухбайтное число
    Printhex Wrd 'результат Wrd = 1296h - только в младших разрядах
    Byt = Byt * Byt1 'проделываем это же иначе, а затем
    Wrd = Byt 'переписываем с очисткой старших разрядов
    =============================================================================
    23-2

    ===================================== Справочник по программированию «Bascom-8051» ==
    Byt1 = Wrd 'обратно берутся только младшие разряды и
    Print Byt ; " " ; Byt1 ; " " ; Wrd 'теперь результат везде одинаков = 150
    '----------------------------------------------------
    ' определим время исполнения арифметических операций
    Byt = 50 : Byt1 = 10 'назначим числа
    Byt = Byt + Byt1 'сложение - 11 тактов
    Byt = 50 : Byt1 = 10 ' числа
    Byt = Byt - Byt1 'вычитание - 12 тактов
    Byt = 20 : Byt1 = 10 ' числа
    Byt = Byt * Byt1 'умножние - 10 тактов
    Byt = 50 : Byt1 = 10 ' числа
    Byt = Byt / Byt1 'деление - 10 тактов '----------------------------------------------------
    Wrd = 500 : Wrd1 = 100 ' числа
    Wrd = Wrd + Wrd1 'сложение - 20 тактов
    Wrd = 500 : Wrd1 = 100 ' числа
    Wrd = Wrd - Wrd1 'вычитание - 21 такт
    Wrd = 200 : Wrd1 = 100 ' числа
    Wrd = Wrd * Wrd1 'умножние - 63 такта
    Wrd = 500 : Wrd1 = 100 ' числа
    Wrd = Wrd / Wrd1 'деление - 560 тактов '----------------------------------------------------
    Intg = 500 : Intg1 = -100 ' числа
    Intg = Intg + Intg1 'сложение - 20 тактов
    Intg = 500 : Intg1 = -100 ' числа
    Intg = Intg - Intg1 'вычитание - 21 тактов
    Intg = 200 : Intg1 = -100 ' числа
    Intg = Intg * Intg1 'умножние - 95 тактов
    Intg = 500 : Intg1 = -100 ' числа
    Intg = Intg / Intg1 'деление - 620 тактов '----------------------------------------------------
    Lng = -5000 : Lng1 = 1000 ' числа
    Lng = Lng + Lng1 'сложение - 74 такта
    Lng = -5000 : Lng1 = 1000 ' числа
    Lng = Lng - Lng1 'вычитание - 74 такта
    Lng = -2000 : Lng1 = 1000 ' числа
    Lng = Lng * Lng1 'умножние - 2500 тактов
    Lng = -5000 : Lng1 = 1000 ' числа
    Lng = Lng / Lng1 'деление - 3200 тактов '----------------------------------------------------
    Sng = 50 : Sng1 = 10 ' числа
    Sng = Sng + Sng1 'сложение - 240 тактов
    Sng = 50 : Sng1 = 10 ' числа
    Sng = Sng - Sng1 'вычитание - 290 тактов
    Sng = 20 : Sng1 = 10 ' числа
    Sng = Sng * Sng1 'умножение - 2000 тактов
    Sng = 50 : Sng1 = 10 ' числа
    Sng = Sng / Sng1 'деление - 2300 тактов '----------------------------------------------------
    'определим время исполнения преобразований
    Byt = 100 : Sng = Byt 'байт в плавающую - 490 тактов 'обратно преобразования не производится
    Wrd = 10000 : Sng = Wrd 'слово в плавающую -370 тактов
    Wrd = Sng 'обратно -340 тактов
    Intg = -1000 : Sng = Intg 'знаковое слово в плав. - 470 тактов
    Intg = Sng 'обратно - 420 тактов
    Lng = 1000000 : Sng = Lng 'двойное слово в плав. - 280 тактов
    Lng = Sng 'обратно - 250 тактов '----------------------------------------------------
    End
    В демонстрационной программе имеются ответы почти на все вопросы применения операций преобразова- ния и использования в вычислениях числовых переменных. Нужно заметить, что измеренные значения произво- дительности операций вычисления и преобразования приблизительны, т.к. зависят от значения преобразуемого
    =============================================================================
    23-3

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


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