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

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

  • ===================================== Справочник по программированию «Bascom-8051» == 13. Конфигурирование внешних устройств

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

  • Справочник по программировани 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
    КатегорияПромышленность. Энергетика
    страница11 из 25
    1   ...   7   8   9   10   11   12   13   14   ...   25
    ===================================== Справочник по программированию «Bascom-8051» ==
    '---------------------
    '!!! только в эмуляторе подключение поляризованных реле с 80C51GB
    B_dar0 Alias P5.0 : B_dar1 Alias P5.1 : B_dar2 Alias P5.2 : B_dar3 Alias P5.3
    B_cor0 Alias P4.7 : B_cor1 Alias P5.4 : B_cor2 Alias P5.5 : B_cor3 Alias P5.6
    '---------------------
    Начиная с этой строки, компилятор формирует исполняемый код – команды установки внутренних регистров. Первая команда в блоке инициализации компилятора - установка стека, вслед за массивом переменных, определенных выше. Если стек устанавливается “вручную”, это самое подходящее место для того, чтобы записать вставить директиву, запрещающую такой способ вычисления стека.
    $Nosp
    Sp = &h7f 'начало стека 80h
    '---------------------
    Вариант установки конфигурации внутренних устройств микроконтроллера без применения специальных операторов Bascom.
    '$Noinit 'устанавливать конфигурацию будем “вручную“
    'Tcon = &h50 : Tmod = &h22 : T2con = &h34 : Scon = &h70 : Load Timer2 = &hffd9
    '---------------------
    Нормальная установка конфигурации внутренних устройств микроконтроллера.
    'TIMER0 в режиме 16-бит. таймера с внутр. тактир. для часов реального времени
    Config Timer0 = Timer , Gate = Internal , Mode = 1 : Start Timer0
    '---------------------
    Установка режима последовательного канала.
    'TIMER2 в режиме 16-бит. таймера с внутр. тактир. для синхронизации UART
    $baud = 9600 'скорость 9.6 кБ
    $crystal = 12000000 'при кварце 12 МГц
    Config Timer2 = Timer , Gate = Internal , Mode = 2
    Если в тексте программы отсутствуют операторы Print и Input необходимо добавить следующие строки.
    ' вариант с тактированием от таймера 1
    'TIMER1 в режиме 8-бит. таймера с внутр. тактир. для синхронизации UART
    Config Timer1 = Timer , Gate = Internal , Mode = 2
    Scon = &H52 'режим приемопередатчика
    Th1 = 243 'константа скорости
    Pcon = &H80 : Start Timer1 'выключить доп. делитель на 2 и стартовать '---------------------
    ' вариант с тактированием от таймера 2
    'Timer2 в режиме 16 -бит. таймера с внутр. тактир. для синхронизации Uart
    Config Timer2 = Timer , Gate = Internal , Mode = 2
    Scon = &H52 'режим приемопередатчика
    Rcap2h = &HFF : Rcap2l = &HA5 : Start Timer2
    '---------------------
    Объявление используемых прерываний. Указывается связь источника прерывания с именем соответствующей программы обработки, устанавливается приоритет, разрешаются отдельные виды прерываний и производится разрешение всех назначенных прерываний. Если используется прерывание от таймера, то иногда нужно перед этим установить счетчик в состояние, обеспечивающее своевременное наступление прерывания.
    'назначение режимов прерываний
    On Timer0 Timer_0_int Nosave 'вектор прерывания
    On Serial Ser_int Nosave 'вектор прерывания послед. канала
    Enable Timer0 'разрешить прерывание таймера 0
    Enable Serial 'разрешить прерывание послед. канала
    Priority Set Serial 'наивысший приоритет послед. канала
    Enable Interrupts 'вообще разрешить прерывания '---------------------
    Производим действия, например, обеспечивающие работоспособность программы в эмуляторе, выполненном на другом типе процессора.
    '!!! -----------------
    'только в эмуляторе 80C51GB дополнительно инициализируем
    Th0 = &HD8 : Tl0 = &HFD 'чтобы прерыв. наступила не позже 10 мс
    Oscr = &HE1 : Oscr = &H1E 'выключить контроль частоты генератора
    Wdtrst = &H1E : Wdtrst = &HE1 'сбросить будильник
    P4 = &HFF : P5 = &HFF 'уст. эмулирующие порты как в эмулируемые '---------------------
    Производим очистку памяти и всех будующих переменных
    =============================================================================
    12-2

    ===================================== Справочник по программированию «Bascom-8051» ==
    Clr_mem:
    $asm
    Mov R0 , #&hff ;от верхнего значения
    ; Mov R0 , Sp ;или от указателя стека (он уже установлен)
    Clrmem:
    Mov @r0 , #0
    Djnz R0 , Clrmem ;до нуля
    $end Asm
    '---------------------
    Устанавливаем переменные в состояние, обеспечивающее правильное начало работы программы или ее переход в определенный режим. Если проводилась очистка памяти, то устанавливаются только пернеменные, значение которых должно отличаться от нуля.
    'инициализировать переменные
    N_dat = 1 'бит "Новые данные"
    R_cch = Varptr(r_lin) 'указатель буфера
    R_ot = 0 'интегратор термодатчика - нет перегрева '---------------------
    Устанавливаем порты процессора в состояние, безопасное для внешних устройств или обеспечивающее их нормальное функционирование (еще лучше, если это состояние соответствует режиму сброса).
    'подготовить линии управления к работе
    Reset B_data : Reset B_clk : Reset B_fqud : Reset B_ress 'с синтезатором
    Set B_datu : Set B_clku : Set B_ldu 'с опорным ЦАП
    '---------------------
    Настало время провести более глубокую инициализацию и проверку всей системы, управляемой микроконтроллером. Когда в системе используется символьный индикатор, то это лучшее место для его инициализации. Инициализация индикатора занимает около 100 мс и если это время критично для системы прерываний, то можно разрешать прерывания после окончания инициализации индикатора или всего блока инициализации.
    'определим размер индикатора
    Config Lcd = 16 * 2
    'определим подключение линий управления индикатора к портам
    Config Lcdpin, Db4 = P1.4, Db5 = P1.5, Db6 = P1.6, Db7 = P1.7, E = P3.2, Rs = P3.4
    'определим изображение дополнительных символов
    Deflcdchar 0 , 31 , 17 , 17 , 17 , 17 , 17 , 31 , 0
    Deflcdchar 1 , 16 , 16 , 16 , 16 , 16 , 16 , 16 , 31
    Deflcdchar 2 , 241 , 234 , 228 , 224 , 228 , 234 , 241 , 224
    Deflcdchar 3 , 241 , 234 , 228 , 241 , 234 , 228 , 224 , 224
    Deflcdchar 4 , 228 , 234 , 241 , 228 , 234 , 241 , 224 , 224
    Deflcdchar 5 , 228 , 234 , 241 , 234 , 228 , 224 , 224 , 224
    Deflcdchar 6 , 228 , 234 , 241 , 234 , 245 , 241 , 241 , 224
    Deflcdchar 7 , 238 , 234 , 234 , 234 , 255 , 241 , 241 , 224
    Cls 'подготовим индикатор к работе
    Lcd “V7-64 ver.3_7” ‘выдадим стартовое сообщение '---------------------
    При наличии последовательного канала, связанного с другой ЭВМ, сейчас необходимо послать сообщение, устанавливающее логическое соединение.
    Print “1_ON” ‘сообщим о включении '---------------------
    После этого начинаем тестирование подключенных устройств. В первую очередь, проверяем сохранность данных энергонезависимой памяти (вычислив контрольную сумму), хранящей переменные данные между сессиями работы микроконтроллера или блок калибровочных констант. При обнаружении ошибки сообщаем об этом, и при получении подтверждения о принятом сообщении переинициализируем память (записываем начальные значения, которые обеспечат правильную работоспособность системы). Если имеются еще какие-либо устройства, наличие и исправность которых нужно проверить, то производим соответствующие действия.
    Gosub Test_CS_EEPROM 'Проверяем контрольную сумму
    If b_ER = 1 Then 'Есть ошибка?
    Print “Error_CS_Mem!” : Waitkey 'Да – вывести сообщение и ждать нажатия
    Gosub Ini_EEP 'Переинициализировать память
    End If
    '---------------------
    В системе, содержащей ЦАП, АЦП, цифровые синтезаторы, реле и т.п. производим загрузку в ЦАП и синтезаторы кодов начального значения напряжения и частоты, включаем самокалибровку АЦП, переключаем контакты реле в исходное положение.
    =============================================================================
    12-3

    ===================================== Справочник по программированию «Bascom-8051» ==
    Gosub Self_Cal : Gosub Init_DAC : Gosub Reset_Relay 'иниц. аналог. часть схемы '---------------------
    Система готова к работе, все устройства, подключенные к микроконтроллеру, ожидают приема или считывания данных, и далее начинается рабочая программа, которая также может содержать операторы установки конфигурации (изменение) в соответствии с алгоритмом программы. В дальнейшем, также могут устанавливаться и изменяться параметры системы прерывания.
    =============================================================================
    12-4

    ===================================== Справочник по программированию «Bascom-8051» ==
    13. Конфигурирование внешних устройств
    Библиотеки Bascom обеспечивают простой интерфейс с большинством устройств, обычно, подключаемых к микроконтроллеру. Bascom может работать: с последовательным портом (аппаратным и программным), с символьным индикатором (в трех вариантах подключения), устройствами с последовательными интерфейсами
    (SPI, Micro-Wire и т.п.), устройствами на шинах I2C и 1Wire, управлять серводвигателями, прием данных интерфейса RC5 из пультов дистанционного управления с ИК-приемником (инфракрасным), измерение времени заряда RC-цепочки (самого примитивного АЦП, подключенного в линии порта). Чтобы обеспечить работу операторов Bascom с перечисленными устройствами, необходимо сообщить компилятору конфигурацию этих устройств – объявить предназначение и имена портов. Иногда требуется объявить некоторые дополнительные параметры. Рассмотрим наиболее типичные примеры конфигурирования. Проще всего установить конфигурацию одно- и двухпроводных шин – нужно просто указать имена подключенных линии (портов):
    Config 1wire = P1.1 'P1.1 – линия связи
    Config Sda = P1.5 'P1.5 - линия SDA
    Config Scl = P1.4 'P1.4 – линия SCL
    Интерфейс SPI реализуется программно, для чего указываются только подключенные порты:
    CONFIG SPI = SOFT, DIN = P1.0, DOUT = P1.1, CS = P1.2, CLK = P1.3
    Предлагаемый Bascom, интерфейс SPI работает только в одном режиме и поэтому непригоден для всех устройств, имеющих сдвиговый регистр. Более широкие возможности обеспечивают операторы SHIFTIN и
    SHIFTOUT, позволяющие организовать все виды двух-, трех- и четырехпроводных интерфейсов (в том числе и
    SPI во всех режимах). Параметры конфигурации операторов SHIFTIN и SHIFTOUT задаются при их вызове.
    При вызове функции Getrc необходимо объявлять только один порт, принимающий входной сигнал.
    Функция Getrc5 вообще может работать только с портом P3.2, т.к. использует прерывание Int0. Тем не менее, функции Getrc и Getrc5 требуют записи оператора конфигурирования системы. Для работы первой функции, необходимо установить в режим 1 таймера 0, который она использует для вычисления времени задержки. Вторая требует инициализации прерывания внешнего Int0 (смотри описание этих функций).
    Чтобы настроить интерфейс для управления серводвигателями необходимо указать число двигателей
    (число выводов, используемых для формирования ШИМ-сигналов с частотой 50 Гц) и назначить имена используемых портов:
    Config SERVOS = 3, SERVO1 = P1.1 , SERVO2 = P1.2 , SERVO3 = P1.4
    Наиболее сложное подключение к микроконтроллеру имеет символьный индикатор, для которого нужно определить наибольшее число параметров:
    CONFIG LCD = 40 * 4 'тип – число символов и строк
    CONFIG LCDPIN=PIN ,DB4=P1.1,DB5=P1.2,DB6=P1.3,DB7=P1.4,E=P1.5,RS=P1.6 'подключение
    Если индикатор подключен к порту P0, его можно использовать в шинном режиме и тогда нужно определить:
    $LCD = &H8000
    'адрес расположения во внешней памяти
    Config LCDBUS = 4 'и режим – 4-битная шина
    ‘Config LCDBUS = 8 'или 8-битная шина
    Конфигурирование других устройств (таймеров, последовательного порта) вы можете найти в разделах, посвященных их программированию.
    =============================================================================
    13-1

    ===================================== Справочник по программированию «Bascom-8051» ==
    14. Программирование прерываний
    Система прерываний процессора 8051 обеспечивает эффективную обработку внешних событий и процессов с временным разделением. С помощью программ прерываний решается широкий круг задач, в основе которых лежит параллельная отработка нескольких процессов, и связь действий и событий с отметками реального времени. Bascom позволяет полностью использовать возможности системы прерываний как стандартных, так и более старших моделей. При программировании прерываний возможно несколько подходов: а) создание максимально быстро работающих программ обработки прерываний, использующих минимальные ресурсы памяти. Разработка таких программ не отличается от традиционного программирования на
    Ассемблере. Ассемблерные программы прерывания необходимо применять тогда, когда время реакции на прерывание очень критично и требуется полностью контролировать использование ресурсов памяти. Сложность создания ассемблерных программ обработки прерывания (да и всех остальных вставляемых ассемблерных программ) заключается в необходимости “подглядывать” за операторами Bascom (с помощью дисассемблера), чтобы понять и правильно организовать передачу данных Бейсику или считывание данных из переменных
    Бейсика; б) использовать только директивы Bascom и не обращать внимания на скорость обработки и количество занимаемой памяти. Это наилучшее решение при создании простых программ, использующих не более двух прерываний и не требующих очень быстрой реакции на события. Применение операторов Bascom, без сомнения, снижает затраты времени на программирование, а при выполнении определенных правил и вероятность ошибок; в) комбинирование достоинств ассемблера и Бейсика. Это самый практичный и рекомендуемый подход – максимально использовать Бейсик, вставляя ассемблерные команды только в самые «горячие» участки программы туда, где компилятор дает явно неоптимальный код или использует ресурсы памяти недопустимым образом.
    Правила описания программ прерывания не менее актуальны и для Бейсика: а) предельная краткость – будет меньше ошибок; б) совершать как можно меньше действий - перемещать данные между переменными (объектами) и устанавливать флаги для вызова программ обработки этих данных, управлять внешними устройствами, таймерами и портами (считывать или загружать, останавливать или запускать) и, наконец, обслужить устройство вызвавшее прерывание (сбросить флаг вызова, перезагрузить таймер); в) использовать минимальное количество переменных (регистров); г) быть внимательным и не забывать о стеке, в котором уже хранится прерванная задача, и в который будет загружена текущая задача, если случится прерывание более высокого уровня. Переполнение стека или нарушение последовательности загрузки-извлечения данных приводит работу программы к фатальному исходу.
    Компилятор и даже отладчик ошибки такого рода не выявляет; д) в программе прерывания, описанной операторами Bascom, должна быть только одна точка выхода, т.к. компилятор только в одном месте (и только один раз) поставит команду RETI. И эта точка выхода должна обозначаться только оператором RETURN. Если точек выхода несколько, то нужно вместо операторов RETURN вставлять ассемблерную команду RETI. Если говорить точнее, то компилятор заменяет командой RETI только первый оператор RETURN, который он встретит, после метки, обозначающей вектор прерывания; е) допускается использование в программе прерываний блока регистров 3. Чтобы правильно его использовать, нужно сохранить значение регистра PSW и установить биты RS0 и RS1 (Psw = &h18). Если в программе используются операторы умножения чисел в формате с плавающей точкой, то необходимо сохранять и регистр с адресом 18H (R0 третьего банка).
    Ограничения в применяемости операторов Bascom в программах прерываний, с точки зрения компилятора, отсутствуют. Практически, в реальных программах существуют очень жесткие ограничения на характер действий, допустимых в прерываниях и, естественно, распространяющихся на программы, создаваемые в
    Бейсике. Рекомендации по возможности применения операторов Bascom и допустимости совершаемых действий выглядять следующим образом: а) можно без ограничения применять операторы перезаписи данных (без преобразования форматов), устанавливать и изменять значения переменных, осуществлять преобразования и вычисления в регистрах, используемых в текущем прерывании. Допускается делать изменение состояние SFR, таймеров и портов, если этого требует алгоритм программы прерывания и предусмотрено в прерванной программе; б) почти всегда можно применять преобразования форматов целых чисел, одиночных символов и символьных переменных, определенных пользователем. Нежелательно применять операторы вычисления и сравнения чисел с плавающей точкой (они, к тому же, слишком продолжительны). Всегда в этих случаях нужно анализировать возможные последствия. Критерием допустимости является не использование программой прерывания не сохраненных регистров, используемых другой программой. Косвенным признаком возможности коллизии является одновременное использование одного и того же оператора (а значит одной и той же библиотечной подпрограммы) или похожих операций; в) совсем нежелательно использовать операции с символьными переменными. Внутренние переменные
    Bascom, используемые для этого, располагается вне области автоматического сохранения в стеке. Еще в большей степени это относится к семейству операторов вывода данных (PRINT, LCD). Они используют еще больше не
    =============================================================================
    14-1

    ===================================== Справочник по программированию «Bascom-8051» == сохраняемых регистров и периферийные устройства. Критерием возможности применения таких действий является только однозначное разделение во времени (зачем тогда это делать в прерывании?) или использование во всей программе только одной операции, работающей с символьными переменными. Вообще, сложности безошибочного использования в прерываниях и прерываемых программах процедур обработки и вывода символьных строк столь значительны, что решать их лучше радикально – просто не применять в программах обработки прерывания; г) запрещено применять операторы ожидания событий, например, из семейств WAIT и INPUT.
    Происходящие события, напротив, должны вызывать прерывания; д) невозможно правильное одновременное использование в прерываемой программе и программах прерывания операторов RESTORE и READ; е) очень сложно предсказать последствия использования в прерываниях сложных программных конструкций (OPEN .. CLOSE, DO .. LOOP, WHILE .. WEND, SELECT .. CASE). Поэтому лучше их не применять; ж) с очень большой вероятностью будут правильно работать операторы проверки условий (IF .. THEN), операторы циклов (FOR .. NEXT), операторы INCR, DECR применительно к битовым и байтовым переменным.
    Допустимо применение этих операций и с двух- и четырехбайтовыми переменными, хотя при этом падает скорость обработки, получается более громоздкий код и требуется более тщательная проверка правильности работы программы. Не рекомендуются использовать в указанных операторах переменные с плавающей точкой, и тем более, символьные; з) выполнение операторов GET и PUT, использующих последовательный программный интерфейс, не должно вообще прерываться, иначе произойдет нарушение синхронизации; и) во всех сомнительных случаях нужно дисассемблировать подпрограмму прерываний и тщательно проверять в отладчике используемые регистры. По возможности применять уже проверенные и известные программы модули программ прерывания.
    Рассмотрим примеры оформления программ прерываний. Вначале будут представлены фрагменты инициализации прерываний различных типов. Затем будут даны примеры программ обработки прерываний.
    Программирование внешних прерываний INT0 (или INT1) по уровню или спаду:
    On Int0 Int_0_int 'выполнять внешнее прерывание INT0 (INT1 – аналогично)
    Rem On Int0 Int0_int Nosave 'то же самое без сохранения и восстановл. регистров
    Rem Set Tcon.0 'добавить, чтобы выполнять прерывание по спаду (Tcon.0 = 1)
    Enable Int0 'разрешить прерывание INT0 (Ie.0 = 1)
    Enable Interrupts 'разрешить все прерывания (Ie.7 = 1)
    '-------------------------------
    'подпрограмма обработки внешнего прерывания
    Int_0_int:
    Reset P1.7 : Buf = P0 : Set P1.7 : Set New_data
    Return
    '-------------------------------
    Программирование прерывание таймера 0 (или таймера 1):
    Config Timer0 = Timer , Gate = Internal , Mode = 1 'режим 16-разрный
    On Timer0 Timer_0_int 'выполнять прерывание от Таймера0 (Timer1 – аналогично)
    Counter = 0 'чтобы прерывание наступило через 65 мс
    Enable Timer0 'разрешить прерывание INT0 (Ie.1 = 1)
    Enable Interrupts 'разрешить все прерывания (Ie.7 = 1)
    '-------------------------------
    'подпрограмма обработки прерывания таймера
    Timer_0_int:
    Counter0 = &hD8F0 'перезагрузить на интервал 10 мс (при кварце 12 МГц)
    Incr Rtime : Set B_10_mc 'сообщить, что прошло 10 мс
    Return
    '-------------------------------
    Показан более подробный пример программирование прерывания последовательного канала. В его основе прием по прерыванию символьной строки во временный буфер. Процедура прерывания написана на ассемблере, что обеспечивает “прозрачность” использования ресурсов. При объявлении прерывания применена опция Nosave, запрещающая автоматически сохранять регистры.
    Ri Alias Scon.0 'бит RI
    Ti Alias Scon.1 'бит TI
    Dim R_ch As Byte 'принятый символ
    Dim R_cch As Byte 'указатель буфера
    Dim R_lin As String * 6 'введеная строка '--------
    'TIMER2 в режиме 16-бит. таймера с внутр. тактир. для синхронизации UART
    $crystal = 12000000 'при кварце 12 МГц
    =============================================================================
    14-2

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


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