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

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

  • ===================================== Справочник по программированию «Bascom-8051» == 15. Проверка условий и изменение хода выполнения программы

  • ===================================== Справочник по программированию «Bascom-8051» == 16. Программирование вывода на индикатор

  • Справочник по программировани 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
    КатегорияПромышленность. Энергетика
    страница12 из 25
    1   ...   8   9   10   11   12   13   14   15   ...   25
    ===================================== Справочник по программированию «Bascom-8051» ==
    $baud = 9600 'скорость 9.6 кБ
    Config Timer2 = Timer , Gate = Internal , Mode = 2
    Timer2 = &HFFA5 : Start Timer2 'установим скорость
    On Serial Ser_int Nosave 'выполнять прерывание посл. канала
    Enable Serial 'разрешить прерывание посл. канала
    Enable Interrupts 'разрешить прерывания 'обработка прерывания последовательного интерфейса
    Ser_int:
    $asm
    Jbc {Ri} , Intsr ;ищем источник прерывания
    Jbc {Ti} , Intst ;заодно и сбрасываем бит вызвавший прерывание
    Reti
    Intsr:
    Push Psw ;прерывание приемника
    Push Acc
    Mov {R_ch} , Sbuf ;сохранить принятый символ
    Mov A , {R_ch}
    Ints1:
    Cjne A , #&h0d , Ints3
    Setb {N_dat} ;0Dh - принята строка
    Ints2:
    Mov A , {R_cch} ;указатель буфера
    Xch A , R0 ;сохранить R0
    Mov @R0 , #&h00 ;записать в буфер конец строки
    Xch A , R0 ;восстановить R0
    Mov {R_cch} , #{R_lin} ;переинициализировать указатель буфера
    Intse:
    Pop Acc
    Pop Psw
    Reti
    Ints3:
    Cjne A , #&h0a , Ints4
    Sjmp Intse ;0Ah - игнорировать
    Ints4:
    Mov A , {R_cch} ;указатель буфера
    Xch A , R0
    Mov @R0 , {R_ch} ;все остальное записывать в буфер
    Xch A , R0
    Mov A , #{R_lin+6}
    Cjne A , {R_cch} , Ints5
    Sjmp Intse
    Ints5:
    Inc {R_cch} ;если буфер незаполнен – изменим указатель
    Sjmp Intse
    Intst:
    Setb {B_entx} ;прерывание передатчика
    $end Asm
    Return 'этот оператор, компилятор заменит командой Reti
    '-------------------------------
    Программирование таймера 2 для получения такого же результата, как выше в примере программирования таймера 0:
    Config Timer2 = Timer , Gate = Internal , Mode = 0
    On Timer2 Timer_2_int 'выполнять прерывание от таймера 2
    Load Timer2 , 10000 'каждые 10 мс (загружает 65536-10000)
    Enable Interrupts 'разрешить используемые прерывания
    Enable Timer2 'разрешить прерывание таймера 2
    '-------------------------------
    'подпрограмма обработки прерывания таймера 2
    Timer_2_int:
    Reset T2con.7 'сбросить бит, вызвавший прерывание
    Incr Rtime : Set B_10_mc 'сообщить, что прошло 10 мс
    =============================================================================
    14-3

    ===================================== Справочник по программированию «Bascom-8051» ==
    Return
    '-------------------------------
    Программирование нестандартного прерывания, например, от счетчика PCA процессора 87C51FA.
    Компилятор не поддерживает инициализацию нестандартных прерываний, поэтому необходимо загрузить непосредственно регистры конфигурации, которые должны быть описаны в соответствующем файле:
    ' Выбрать файл 8051fa.dat !!!
    On Pca Pca_int 'выполнять прерывание от PCA
    Cmod = &h01 'разрешить прерывание от PCA
    Enable Interrupts 'разрешить используемые прерывания
    Ch = &hD8 : Cl = &hF0 'загрузить на интервал 10 мс (при кварце 12 МГц)
    Ccon.6 = 1 'разрешить счет '-------------------------------
    'подпрограмма обработки прерывания от PCA
    Pca_int:
    Reset Ccon.7 'сбросить бит, вызвавший прерывание
    Ch = &hD8 : Cl = &hF0 'снова загрузить на интервал 10 мс
    Incr Rtime : Set B_10_mc 'сообщить, что прошло 10 мс
    Return
    '-------------------------------
    Для повышения эффективности генерируемого кода некоторые операции в программах прерываний рекомендуется заменять ассемблерными командами (можно и не только в программах прерываний). Ниже в таблице представлены такие примеры.
    Запись в Bascom
    Ассемблерный эквивалент
    If Bn = 1 Then 'если 1
    Reset Bn : Goto Mf 'сбросить и перейти
    End If
    Jbc {Bn} , Mf
    If Rn = 0 Then Goto Mf 'нуль? – перейти
    End If
    Mov A , {Rn}
    Jz Mf
    Rb = High (Rw) 'Rw –двухбайтовая перем. Mov {Rb} , {Rw + 1}
    Отсутствует простой доступ к частям многобайтовых переменных, например, R_Long.
    Не всегда удобен вариант, позволяющий только считывать:
    Tmpw = Loww(R_Long) : Acc = Hi(Tmpw)
    Mov {R_long + 2} , #&hf0 ;запись
    Mov A , {R_long + 1} ;считыванние
    =============================================================================
    14-4

    ===================================== Справочник по программированию «Bascom-8051» ==
    15. Проверка условий и изменение хода выполнения программы
    В описываемой версии Bascom-8051, как и в классическом Бейсике, основу организации работы отдельных частей (модулей) программы обеспечивают операторы проверки условий и изменения хода выполнения программы. Компилятор Bascom-8051 предоставляет возможность проверки значений всех типов переменных. Причем, проверяемая переменная может сравниваться как с константой, так с другой переменной, такого же типа.
    Все числовые переменные могут проверяться на соответствие условиям соотношения с числовым значением и значением другой переменной. Bascom позволяет проверять переменные на соответствие условиям: равенства ( знак соотношения « = »), неравенства (« <> »), меньше (« < »), больше (« > »), меньше или равно (« <=
    ») и больше или равно («>=»). Задаваемое значение константы, записываемое в выражение сравнения, должно соответствовать типу проверяемой переменной таким образом, чтобы не вызывать трудностей компилятору при переводе этого числа в исполняемый код. Сравнение производится с учетом знака переменных и констант.
    Битовые переменные могут сравниваться только с числами 0 и 1 или с другой битовой переменной.
    Bascom также обеспечивает проверку битов одно-, двух- и четырех байтовых переменных, даже не расположенных в битовой области внутренней памяти.
    Строковые переменные могут сравниваться друг с другом или с непосредственно заданной строкой. В примере, приведенном ниже, показаны примеры использования операторов проверки условий с различными типами переменных. Мы видим, что имеется возможность выключать или включать исполнение отдельных участков программы, а также осуществлять переход в другие точки программы с помощью операторов GOTO.
    Применение операторов RETURN (или команды RET) внутри конструкции IF…END IF запрещено, т.к. при этом нарушается баланс стека.
    '---------------------------------
    ' тестирование операций сравнения '---------------------------------
    Dim Bt1 As Bit , Bt2 As Bit , Bd As Byte , Wd As Word , Ld As Long
    Dim Sd1 As Single , Sd2 As Single
    Dim Temp As String * 16 , Tmp1 As String * 16
    M1:
    Input Sd1 : Sd2 = 2.345
    If Sd1 < Sd2 Then 'сравнение чисел в формате с пл. точкой
    Print "ok" : Goto M2
    End If
    Print "no"
    M2:
    Input Temp : Input Tmp1 'ввести строковые переменные
    If Temp = Tmp1 Then
    Print "equ" : Goto M3 'если переменные равны - выход
    Elseif Temp = "stop" Then
    Goto Mend 'а если введено "stop" - закончить
    End If
    Print "no"
    M3: 'проверка числовых переменных
    Input Bd : Input Wd : Input Ld 'ввести значения
    If Bd = &H0A Then 'проверим байтовую переменную
    Print "=" : Goto M4
    Else 'если она не равна 10, проверим остальные
    If Wd >= 1000 Then 'двухбайтовая больше 1000?
    Print ">>" : Goto M4 'да - пойдем дальше
    Elseif Ld <= 1000000 Then 'нет - проверим четырехбайтовую
    Print "<<<<" 'если меньше 1000000 отпечатали
    End If
    End If
    M4: 'сравнение битовых переменных
    Bt1 = 0 : Bt2 = 1
    If Bt1 = Bt1 Then
    Print "ok"
    End If
    Goto M1
    Mend:
    End
    =============================================================================
    15-1

    ===================================== Справочник по программированию «Bascom-8051» ==
    Для того, чтобы программа работала быстрее, надежнее и затрачивала меньше ресурсов, следует применять максимально простую конструкцию операций проверки условий и использовать наиболее компактный тип сравниваемых данных. Не рекомендуется без особой необходимости сравнивать числа в формате с плавающей точкой и строковые переменные длиной более двух-трех символов.
    В последних версиях компилятора стала возможной классическая запись операции проверки условий в одну строку в простом:
    If Wd >= 1000 Then Goto M4
    Или расширенном виде:
    If Wd >= 1000 Then Print ">>" Else Print "<<" 'если меньше 1000000
    При этом нужно иметь в виду, что качестве действия на истинность или не истинность проверяемому условию может быть применен только один оператор. Двоеточие в этой строке понимается как начало следующего оператора, выполняемого безусловно. Также понимается и оператор в следующей строке.
    Еще одна новинка Bascom версии 2.xx – возможность проверки значения индексированных битов.
    Причем индекс может быть задан байтовой переменной:
    Dim X As Byte
    X = 6 'X = 0 – 7
    If P2.X=1 Then 'проверка индексированного бита
    P2.X = 0 'изменение индексированного бита
    End If
    =============================================================================
    15-2

    ===================================== Справочник по программированию «Bascom-8051» ==
    16. Программирование вывода на индикатор
    Компилятор Bascom обеспечивает вывод на символьный индикатор значений числовых переменных и символьных строк во всех возможных вариантах. Синтаксис операторов вывода данных и команд управления курсором достаточно прост и не требует дополнительных, более подробных пояснений, чем это сделано выше.
    Однако нужно заметить, что построение системы отображения данных является более сложной задачей, чем применение последовательности операторов вывода. Проектируемые устройства с символьным индикатором должны отвечать требованиям эргономики, включающей обязательное форматирование и позиционирование выводимых цифровых данных и сообщений. С учетом этого, рассмотрим практические вопросы построения и программирования системы отображения информации. Как обычно, перед началом программирования требуется разработать план системы отображения, включающий в себя следующие составляющие, перечисленные в порядке очередности: а) определить число и разрядность, отображаемых параметров (числовых). Необходимо, хотя бы приблизительно, определить форматы отображения данных, чтобы зарезервировать место для десятичной точки, знака полярности и пробелов-разделителей. При отображении числовых данных нужно решительно избавляться от избыточности - исключать незначащие разряды (за пределами точности или нестабильные); б) определить номенклатуру и число, одновременно отображаемых параметров (переменных); в) определить атрибуты изображения (выбрать сообщения или символы размерности числовых параметров, разделителей полей данных, выбрать или разработать специальные символы); г) придумать все текстовые сообщения таким образом, чтобы они были краткими, приблизительно одной длины и понятны. Настоятельно рекомендуется применять только латинский алфавит потому, что коды кириллических шрифтов и наборов символов (выше 7Fh) отличаются у разных изготовителей индикаторов; д) определить число и расположение полей данных. Для правильного восприятия отображаемой информации расположение и размер полей данных должен быть фиксированным, включая и поле для текстовых сообщений. Так как текстовые сообщения обычно появляются на короткое время (постоянно не отображаются), лучше их размещать на полях малозначительных (второстепенных) параметров и таким образом экономить место.
    Наиболее важные параметры нужно располагать в середине рабочего поля. Менее важные сообщения по краям, на периферии. Ввиду того, что все символы имеют одинаковый размер, для улучшения восприятия, размер полей более важных параметров (сообщений) должен быть больше, чем у менее важных даже путем использования аббревиатур последних. В качестве разделителей полей данных рекомендуется применять пробелы и (или) специальные знаки в виде вертикальных и горизонтальных пунктирных линий; е) произвести выбор типа символьного индикатора. Лучше применять модули индикации стандартных размеров и наиболее употребляемых форматов (в порядке предпочтения): 16 символов х 2 строки, 20 х 2, 20 х 4,
    16 х 1, 24 х 2, 40 х 4. Они более доступны, всегда дешевле, имеют лучшие светотехнические параметры (чаще совершенствуются в процессе производства). Индикаторы уникальных типоразмеров, как правило, только заявлены изготовителем и производятся по специальному заказу. Лучше использовать индикаторы со светодиодной подсветкой (они дает постоянную контрастность изображения при любом освещении) с черными знаками на желтом поле – исполнение для стандартного температурного диапазона. Не рекомендуется без необходимости применять индикаторы, предназначенные для расширенного температурного диапазона (они имеют заметно меньшую контрастность и угол видимости); ж) важно выбрать способ подключения индикатора к микроконтроллеру. При интенсивном использовании индикатора, например, для случаев полного обновления всех данных индикатора несколько раз в секунду (это характерно для измерительных систем), и для модулей с числом знаком более 32 необходимо применение 8-разрядной шины, иначе регенерация изображения станет заметной (появляется эффект снижения контрастности и «паразитного свечения» неиспользуемых знакомест); з) еще раз смоделировать (на бумаге) возможность расположения и читаемость на выбранном индикаторе всех возможных сообщений при всех возможных комбинациях и режимах. Уточнить форматы индикации параметров, текстовые сообщения, атрибуты, аббревиатуры, стараясь максимально использовать общепринятые обозначения и термины.
    Следующий вопрос – программирование изображений. Существуют два подхода к формированию изображения на индикаторе: а) каждый раз при обновлении данных, очищать поле индикации и затем заполнять его данными, зависимыми от текущего состояния выводимых переменных. Принципиально то, что в этом случае не производится анализ и выявление изменившихся данных. Преимущества такого подхода заключаются в том, что формирование и вывод данных в индикатор легко сосредоточить в рамках одной универсальной процедуры и сделать регулярным, со скоростью удобной для восприятия (несколько раз в секунду). При этом процессы формирования данных и отображения данных становятся независимыми и параллельными, что также очень удобно. Недостаток - повышенные требования к быстродействию интерфейса индикаторного модуля и наличие кратковременного состояния неопределенности данных (старое изображение стерто, а новое еще не записано).
    Если это время превышает 5-10 мс (более одного периода частоты сканирования всех сегментов), то становится видимым «мелькание» сегментов с частотой обновления данных;
    =============================================================================
    16-1

    ===================================== Справочник по программированию «Bascom-8051» == б) обновлять только изменяющиеся данные. Достоинства такого подхода - немигающее изображение, отсутствие проблем со способом подключения индикатора. Недостатки - усложнение программного интерфейса
    (он рассыпается на множество процедур по числу отображаемых переменных), вывод становится нерегулярным (с частотой изменения отображаемых переменных), обработка изменения состояния переменной, в свою очередь, тормозится процедурой вывода в индикатор (единицы миллисекунд). Область применения - индикаторы с числом более 40 знаков и системы с нерегулярным обновлением информации, например, при поступлении одиночных событий.
    Ниже представлена большая демонстрационная программа, в которой решаются несколько проблем вывода цифровых данных.
    '--------------------------------------------------------------
    ' Демонстрационная программа вывода данных в символьный индикатор ' показывает, как формируется показания на индикаторе ' измерительного прибора - мультиметра, работающего в пяти режимах ' и имеющего на каждом по пять пределов измерения. Все пределы ' измерения пронумерованы от 0 до 24 (сквозная нумерация).
    ' Программа построена так, что все режимы индикации привязаны ' к переменной Rang, определяющей номер предела. Данные АЦП
    ' и предел изменяются после цикла индикации (каждые 2 секунды)
    '
    ' XXX: ±XXXXXX XX
    ' три знака режима работы _______^ ^ ^ ^
    ' полярности для сигналов пост. тока _| | |
    ' цифровое значение ____________________| |
    ' размерность показаний ______________________|
    '
    '--------------------------------------------------------------
    $large 'большая модель памяти
    Dim B_nd As Bit 'бит "Новые данные"
    Dim B_tim As Bit 'бит "Прошло 10 мс"
    Dim Cnt As Byte 'счетчик мс
    Dim Tmp As Byte 'временные байтовые данные
    Dim Rang As Byte 'это номер предела!!!
    Dim Fld As Single 'данные "АЦП" - измеренное значение
    Dim Rfld As Single 'индицируемые данные
    Dim Temp As String * 10 'временная строка.
    'Внимание!!! При меньшей длине Temp программа «залезает» в стек.
    '--------------------------------------------------------------
    ' подключение индикатора '--------------------------------------------------------------
    Config Lcd = 16 * 2 'размер индикатора
    Config Lcdpin, Db4=P1.4, Db5=P1.5, Db6=P1.6, Db7=P1.7, E=P3.2, Rs=P3.4
    'линия P3.3 не используется – ее надо заземлять '--------------------------------------------------------------
    Config Timer0 = Timer , Gate = Internal , Mode = 1 : Start Timer0
    On Timer0 Timer_0_int Nosave 'вектор прерывания
    Enable Interrupts 'вообще разрешить прерывания
    Enable Timer0 'разрешить прерывания таймера 0
    '!!! --------------------------------------
    Start Timer0 : Cnt = 100 : Rang = 0 : B_nd = 1 : B_tim = 1
    Deflcdchar 1,228,228,234,234,241,241,255,224 'дельта
    Deflcdchar 2,238,241,241,241,234,234,251,224 'омега
    Cls 'привести в действия новые символы
    Cursor Off 'сделать невидимым курсор
    Lcd " Multimeter" 'стартовое приветствие
    Wait 1
    Mc:
    Do 'главный цикл
    If B_nd = 1 Then 'каждые 2 секунды индицировать
    Reset B_nd : Goto Disp
    End If
    If B_tim = 1 Then 'считаем 10 мс прерывания
    Reset B_tim : Decr Cnt
    =============================================================================
    16-2

    ===================================== Справочник по программированию «Bascom-8051» ==
    If Cnt = 0 Then
    Set B_nd : Cnt = 200
    Fld = Lookup(rang , _tab_mes) : Incr Rang
    If Rang = 25 Then
    Rang = 0
    End If
    End If
    End If
    Loop
    '--------------------------------------------------------------
    'вывод данных в индикатор
    Disp:
    Fld = Lookup(rang , _tab_mes) 'считать значение выхода
    Rfld = Lookup(rang , _tab_zc) 'считать масштабирующую константу
    Rfld = Rfld * Fld 'вычислить в размерности индикации
    Cls 'очистить LCD
    Gosub Lcd_attr1 'вывести сообщение о режиме работы
    Tmp = Lookup(rang , _tab_polar)'нужно индицировать полярность?
    If Tmp = 0 Then 'не нужно, если значение из табл. = 0
    $asm
    Anl {rfld + 3} , #&H7f ;сделаем показания безусловно положительными
    $end Asm
    Locate 1 , 7 'сразу поставить в позицию вывода цифр
    Goto Lcd_fp 'и перейдем на форматирование
    End If
    'нужно индицировать число со знаком
    Locate 1 , 6 'курсор в позицию вывода знака
    If Rfld < 0 Then 'какая полярность?
    Goto Lcd_fn 'отрицательная - переход
    End If
    Lcd "+" 'положительная - "+" на индикатор
    Lcd_fp:
    'форматирование положительного числа. Выбираем программу форматирования,
    'соответствующую пределу измерения (все это должно быть записано в одну строчку 'или переносится с помощию символа подчеркивателя
    On Rang Gosub F4 , F2 , F3 , F4 , F5 , F4 , F2 , F3 , _
    F4 , F5 , F4 , F2 , F3 , F4 , F2 , F4 , _
    F2 , F3 , F4 , F2 , F4 , F2 , F3 , F4 , F2
    Goto Lcd_dat
    Lcd_fn:
    'форматирование отрицательного числа. Аналогично форматируем,
    'но длина результата будет на знак больше (добавится знак минуса)
    On Rang Gosub M4 , M2 , M3 , M4 , M5 , M4 , M2 , M3 , _
    M4 , M5 , M4 , M2 , M3 , M4 , M2 , M4 , _
    M2 , M3 , M4 , M2 , M4 , M2 , M3 , M4 , M2
    'отбрасываем знак минуса и выводим его отдельно
    Temp = Mid(temp , 2 , 6 ) : Lcd "-"
    Lcd_dat:
    'еще одна неприятность Bascom: он не выводит незначащие нули слева 'перед десятичной точкой кроме одного. Будем исправлять и этот недостаток.
    'для чего проверим длину форматированной переменной
    Tmp = Len(temp)
    If Tmp = 5 Then 'длина = 5 - отброшен один нуль
    Lcd "0" 'добавим один нуль
    Goto Lcd_od
    End If
    If Tmp = 4 Then 'длина = 4 - отброшено два нуля
    Lcd "00" 'добавим два нуля
    Goto Lcd_od
    End If
    If Tmp = 3 Then 'длина = 3 - отброшено три нуля
    Lcd "000" 'добавим три нуля
    End If
    =============================================================================
    16-3

    1   ...   8   9   10   11   12   13   14   15   ...   25


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