Министерство науки и образования РФ САМАРСКИЙ ГОСУДАРСТВЕННЫЙ АЭРОКОСМИЧЕСКИЙ УНИВЕРСИТЕТ ИМЕНИ АКАДЕМИКА С.П. КОРОЛЕВА Кафедра «Радиотехнические устройства» Разработка и отладка программ на языке ассемблера для RISC – микроконтроллеров фирмы MICROCHIP в среде интегрированной разработки MPLAB Методические указания для выполнения лабораторной работы по курсу «ЦУ и МП» Самара 2004 2 Составители: И.А. Кудрявцев, С.И. Строгонов УДК 681.325.5-181.48 Разработка и отладка программ на языке ассемблера для RISC – микроконтроллеров фирмы MICROCHIP в среде интегрированной разработки MPLAB: Методические указания для выполнения лабораторной работы / Самарский гос. аэрокосмический ун-т. Сост. И.А. Кудрявцев, С.И. Строгонов. Самара 2004 12стр. Методические указания рекомендуются для студентов, обучающихся по специальности 200700 по курсу "Цифровые устройства и микропроцессоры". Рассмотрены вопросы составления и отладки программ на языке ассемблера RISC – микроконтроллеров фирмы MICROCHIP в среде интегрированной разработки MPLAB. 3 СОДЕРЖАНИЕ ВВЕДЕНИЕ………………………………………………………………………….4 1 СОЗДАНИЕ ПРОЕКТА В СРЕДЕ MPLAB .................................................................... 4 2 СОЗДАНИЕ ИСХОДНЫХ ФАЙЛОВ .............................................................................. 5 3 АССЕМБЛИРОВАНИЕ И ОТЛАДКА ПРОГРАММЫ ................................................... 7 4 РАБОТА С ПОРТАМИ ВВОДА-ВЫВОДА И ЭМУЛЯЦИЯ ВНЕШНИХ СОБЫТИЙ ... 8 4.1 Асинхронная эмуляция внешних событий .......................................................................................................... 8 4.2 Эмуляция внешних событий с помощью файла изменений ............................................................................ 9 4.3 Эмуляция генератора прямоугольных импульсов ............................................................................................ 9 5 РАБОТА С ПРЕРЫВАНИЯМИ .................................................................................... 10 6 ПРИЛОЖЕНИЕ ............................................................................................................. 12 4 ВВЕДЕНИЕ В настоящее время RISC – микроконтроллеры фирмы MICROCHIP получили довольно широкое распространение благодаря совокупности качеств, а именно, высокому быстродействию, универсальности, большой номенклатуре, простоте программирования, доступности средств разработки (фирма свободно распространяет ряд программных средств, позволяющих составлять и отлаживать программы, а также осуществлять программирование микроконтроллеров). Методические указания посвящены основным принципам работы с таким программным средством – интегрированной средой разработки – MPLAB. Кроме этого, дается ряд сведений по особенностям архитектуры и основным приемам использования самих микроконтроллеров. В приложении приводится таблица с системой команд микроконтроллеров фирмы MICROCHIP. Цель работы - освоение приемов работы со средой интегрированной разработки MPLAB и изучение системы команд и основных особенностей микроконтроллеров семейства PIC. 1 Создание проекта в среде MPLAB Для работы в среде MPLAB необходимо создать директорию с проектом, в которой могут быть размещены необходимые файлы с текстом исходной программы, файлы заголовков, служебные файлы и, наконец, будет сформирован файл, содержащий «код прошивки» памяти микроконтроллера. Рекомендуется создать папку с именем, набранным латинскими буквами, для избежания проблем с интерпретацией имени в ряде случаев. Следует отметить, что без создания проекта полноценная работа с MPLAB невозможна. Далее в окне MPLAB необходимо выбрать пункт меню «Projects», а в нем пункт «Project Wizard». В открывшемся диалоговом окне следует указать тип используемого микроконтроллера PIC16F874. В следующем окне необходимо указать набор инструментов «Microchip MPASM Toolsuite». Далее введите название проекта и укажите путь к директории с проектом. Следующим шагом можно подключить уже созданные файлы проекта. При помощи меню «Debugger» / «SelectTool» выбираем тип используемого отладчика «MPLAB SIM». Тактовая частота микроконтроллера устанавливается в меню «Debugger» / «Settings», закладка «Clock». Подключить файлы можно на любом этапе работы, щелкнув правой клавишей мыши по соответствующему заголовку, и затем выбрав меню «Add Files». Файл с исходным текстом программы необходимо поместить в раздел «Source Files», файл заголовок - в раздел «Header Files». Режим работы тактового генератора выбирается в меню «Configure» / «Configuration Bits». Там же можно включить или выключить сторожевой таймер (включен по умолчанию). В нашем случае выбираем Processor – PIC16F874, тактовую частоту – 20 МГц, и режим – HS. После нажатия ОК программа предупреждает, что файл с прошивкой не существует, этот факт необходимо подтвердить – ОК. После этого возвращаемся в основное окно программы. Здесь с помощью меню «File» можно вызвать и редактировать требуемый файл с исходным текстом на языке ассемблера. При отсутствии такого файла его можно создать посредством меню «File» - «New». 5 2 Создание исходных файлов Рекомендуется создать два файла – файл собственно исходного текста программы с расширением «asm» (с тем именем, которое указано при создании проекта) и файл-заголовок с расширением «h» (от «header»). В файле - заголовке содержатся определения констант, используемых в программе и распределение необходимых ячеек памяти. При создании обоих файлов следует придерживаться следующих правил: - С первой позиции набираются метки и комментарии; - Директивы ассемблера и команды набираются в следующей колонке (рекомендуется использовать табуляцию); - Необходимо строго соблюдать регистр, в частности рекомендуется в верхнем регистре набирать имена регистров контроллера и вводимые переменные; - Необходимо соблюдать строгое соответствие между именами переменных в файле - заголовке и файле с исходным текстом. Создайте файл- заголовок, содержащий следующий текст: ; *********************************************************** ; Текстовые константы ; *********************************************************** #define _C STATUS,0 #define _Z STATUS,2 #define _RP0 STATUS,5 #define WORK FLAG,0 ; *********************************************************** ; Порт С ;************************************************************ RXD equ 7 ; прием TXD equ 6 ; передача ; *********************************************************** ; Порт А ; *********************************************************** PINA equ 0 ; Вывод 0 порта А ; *********************************************************** ; Порт В ; *********************************************************** PINB equ 0 ; Вывод 0 порта В ; *********************************************************** ; Константы ; *********************************************************** ULIM equ 0xA0 DLIM equ 0x56 ; *********************************************************** ; Распределение памяти ; *********************************************************** CBLOCK 0x20 W_TEMP: 1 ST_TEMP: 1 ; буферы для реализации прерывания F_TEMP: 1 BUFFER: 1 6 ; ******************************************************* QT: 1 ; FLAG: 1 QB: 1 ; рабочие ячейки ; *********************************************************** QBOT: 0x40 ; очередь передачи ; *********************************************************** ENDC Рассмотрим формат некоторых записей: Директива #define X Y предписывает простую текстовую замену фрагмента Х, встретившегося в тексте программы на фрагмент Y; Директива X equ Y предписывает присвоить выражению Х значение Y; (С помощью этой директивы можно присваивать осмысленные имена разрядам портов ввода-вывода и ячейкам памяти) Конструкция CBLOCK 0х20 LABEL: NUM …. ENDC Определяет список констант (в данном случае адресов памяти). Список начинается с 0х20 (LABEL), при этом каждой следующей константе присваивается значение, больше предыдущего на NUM. Применительно к приведенному примеру, с помощью описываемой конструкции выделено по 1 байту для переменных W_TEMP… QB и блок памяти размером 64 байта выделен для очереди передачи данных (начинающийся с QBOT). Применение такого способа облегчает написание программ и планирование распределения памяти. При необходимости удаления или добавления ячейки достаточно удалить (добавить) соответствующую строку в файл-заголовок. В файле с исходным текстом наберите следующий текст: LIST P=16F874 ; указывает программе тип контроллера TITLE Программа работы с портами ; имя программы include "d:\Progra~1\mplab\p16f874.inc" ; включение в текст имен стандартных регистров микроконтроллера include "name.h" ; включение в текст файла заголовка с нашими определениями ; *********************************************************** org 0x00 goto Entry ; переход к основной программе ; *********************************************************** ; Вектор прерывания ; *********************************************************** include "intvect.inc" 7 ; *********************************************************** ; Инициализация ; *********************************************************** Entry bcf INTCON,GIE ; запрет прерываний bsf _RP0 movlw 0x06 movwf ADCON1 movlw 0xС0 movwf TRISC ; RC6,RC7 – входы, остальные – выходы clrf TRISD ; Настроить порт D как выходной bcf TRISA,PINA ; Определить PINA, как выход ; **************************************************************** ; Конфигурация RS-232 ; **************************************************************** movlw 0x0F movwf SPBRG ; Установка скорости обмена clrf TXSTA ; установка асинхронного режима bcf _RP0 movlw 0x90 movwf RCSTA ; установка режима приема movlw QBOT ; определение очереди данных для передачи movwf QT movwf QB ; **************************************************************** ; Настройка прерываний ; **************************************************************** bsf _RP0 movlw 0x20 movwf PIE1 ; разрешить прерывание от приемника RS-232 bcf _RP0 movlw 0xС0 movwf INTCON ; разрешить прерывания ; **************************************************************** ; Основная программа ; **************************************************************** ; Здесь будет размещена основная программа ; **************************************************************** END Вместо "name.h" необходимо указать имя вашего файла - заголовка. Сохраните оба файла (заголовок и исходник), кроме этого создайте аналогичным образом пустой файл под названием «intvect.inс». Позже в этом файле мы создадим модуль обработки прерываний. 3 Ассемблирование и отладка программы Выберите пункт меню «Project» и, затем «Make project». Если все тексты набраны правильно, в открывшемся окне «Build results» будет указано «Build completed successfully» и перечислены сообщения, возникшие при компиляции. Например, сообщение (Message) с кодом 302 предупреждает, что операнд находится в банке памяти 1. В случае наличия ошибок, они также будут перечислены в списке. После успешного завершения операции ассемблирования в памяти программы имеется исполняемый код и можно приступать к отладке. Увидеть исполняемый код можно с помощью меню «Window» – «Program Memory». 8 Для отладки программы рекомендуется выполнить следующие подготовительные действия: Закрыть окна «Output», «intvect.inc», и файл заголовка; С помощью меню «View» – «Watch» создать список переменных, подлежащих просмотру (w, QT, QB, PORTB), выбрав их из списка доступных переменных; Выровнять окна с помощью меню «Window» – «Tile Vertical». После этих операций в рабочем окне должны остаться два окна – с исходным текстом и контролируемыми переменными. Далее переходим собственно к этапу отладки созданной части программы. Для этого можно воспользоваться различными способами, наиболее простой предполагает выполнение программы по шагам с контролем соответствующих изменений. Для пошагового выполнения можно использовать клавишу «F7», при этом текущая команда выделяется в окне файла - исходника. Выполните набранную программу, наблюдая за изменениями контролируемых переменных. 4 Работа с портами ввода-вывода и эмуляция внешних событий Наберите в файле – исходнике следующий текст основной программы после блока инициализации: ; ************************************************************************ MAIN btfss PORTB,PINB ; проверка «1» на выводе PINB goto $-1 MLOOP btfss PORTB,PINB ; проверка «0» на выводе PINВ goto OUTB bsf PORTA,PINA ; контрольный сигнал bcf PORTA,PINA goto MLOOP ; OUTB movlw ULIM movwf PORTD ; вывод данных в порт D goto MAIN ; *********************************************************** Откомпилируйте заново программу. Программа ожидает события (изменения состояния PINB), затем выводит в порт D данные, после чего возвращается к ожиданию события на PINB. Процесс ожидания появления "0" на PINB после "1" (отпускание кнопки) сопровождается генерацией импульсной последовательности на PINA. Для отладки данного фрагмента программы необходимо эмулировать внешние события на линии PINB порта В. Для этого есть несколько вариантов действий. 4.1 Асинхронная эмуляция внешних событий Для этого выберите меню «Debug» – «Stimulus Controller». В открывшемся окне щелкните правой кнопкой мыши по кнопке «Add Row». В колонке «Type» выберем тип воздействия – «Asynch». В колонке «Action» можно выбрать различные виды воздействий, в нашем случае удобно выбрать переключение 9 («Toggle»). Колонка «Pin» позволяет выбрать порт и разряд порта, на который необходимо оказать воздействие. Выберите «RB0» (Нулевой разряд порта В). Теперь при нажатии (левой кнопкой мыши) на PINB уровень изменяется на противоположный, в соответствии с логикой работы Т-триггера. Добавьте в список контролируемых переменных PORTA, PORTD и удалите QB, QT. Для удаления перейдите в окно «Watch_1», выберите удаляемую переменную и нажмите на клавиатуре «Delete». Для добавления переменной необходимо нажать «Insert». Исследуйте работу набранного фрагмента с помощью созданного инструмента. 4.2 Эмуляция внешних событий с помощью файла изменений Для реализации этого метода в том же разделе меню «Debug» – «Stimulus Controller» выберете закладку «File Stimulus». В разделе Input Files щелкните по клавише «Save». В открывшемся окне введите название файла «1.sti» и сохраните его. Когда название файла появится в окне его необходимо выделить и нажать кнопку «Edit». В первой колонке указывается «Cycle», во второй колонке - количество циклов от начала выполнения программы до момента, когда должно произойти переключение на входе микроконтроллера. В третьей колонке указывается вывод контроллера, на который производится воздействие. В четвертой колонке ставится значение воздействия - «1» или «0». Вы должны внести в созданный файл следующую информацию: Trigger On Cycles Cycles Cycles Cycles Cycles Trig Value 200 200 200 500 1000 Pin RB0 RB0 RB0 RB0 RB0 Value 0 1 0 1 0 В левой колонке указан номер шага программы, в правой - состояние разряда 0 порта В. Для запуска необходимо стартовать программу заново, для чего используйте меню «Debugger» – «Reset». Теперь можно приступить к отладке программы. Для контроля номера текущего шага рекомендуется открыть инструмент «Stopwatch» («Debugger» – «Stopwatch…»). Вручную выполнять программу до 1000-го шага, очевидно, утомительно, поэтому можно воспользоваться установкой точки прерывания. Для этого установите мышью курсор на ту команду, где необходимо остановить выполнение программы, и нажмите левую кнопку мыши. В выпадающем меню выберите пункт «Break point(s)». Текущий оператор будет выделен красным цветом. Для отказа от выбора точки прерывания необходимо повторить указанные действия. После этого можно запустить автономное выполнение программы («Debugger» - «Run»» или с помощью F9). Исследуйте выполнение программы с помощью этого способа. 4.3 Эмуляция генератора прямоугольных импульсов Для выбора этого способа необходимо выбрать меню «Debug» – «Simulator Stimulus» - «Clock». В открывшемся диалоговом окне следует задать требуемый вывод контроллера и параметры импульсной последовательности. Проверьте этот способ. 10 5 Работа с прерываниями Система прерываний микроконтроллера PIC16F874 включает единственный вектор прерывания с адресом 0х04. При входе в подпрограмму обработки прерываний необходимо сохранить содержимое аккумулятора и флагового регистра. Эта задача возлагается на программиста, равно, как и восстановление информации после выхода из подпрограммы обработки прерываний. Кроме этого, необходимо также установить, какой именно источник вызвал прерывание. Все эти операции являются типовыми для подпрограммы обработки прерываний. В следующем примере рассматривается работа с двумя прерываниями – от приемника RS-232 и по изменению состояния порта В. Наберите следующий текст в файле «intvect.inc»: ; **************************************************************** ; Подпрограмма обработки прерывания ; **************************************************************** org 0x04 movwf W_TEMP ; Сохранение рабочих регистров swapf STATUS,W bcf _RP0 movwf ST_TEMP ; **************************************************************** ; Проверка причины прерывания ; **************************************************************** btfsc PIR1,RCIF goto PREC ; прием команды по RS-232 btfsc INTCON,RBIF goto PBPR ; Изменение порта В ; gback swapf ST_TEMP,W ; Восстановление регистров movwf STATUS swapf W_TEMP,1 swapf W_TEMP,W retfie ; **************************************************************** ; Изменение порта В ; **************************************************************** PBPR movlw DLIM movwf PORTD bcf INTCON,RBIF ; очистка флага прерывания goto gback ; **************************************************************** ; Прием команды через RS-232 ; **************************************************************** PREC btfss RCSTA,FERR ; Ошибка ? goto cntx movf RCREG,W ; очистка буфера goto gback ; cntx btfsc RCSTA,OERR ; переполнение буфера ? call OerrP movf RCREG,W ; считывание принятых данных 11 movwf BUFFER ;***************************************************************** Strt sublw 0xAA ; Старт ? btfss _Z goto cEnd bsf WORK ; Установка флага bsf INTCON,RBIE ; Разрешение прерывания от порта В goto gback ; cEnd movf BUFFER,W sublw 0xBB ; Стоп ? btfsc _Z bcf WORK ; Очистка флага goto gback ; OerrP bcf RCSTA,CREN bsf RCSTA,CREN return В файле – исходнике добавьте в блок инициализации команду очистки регистра FLAG (clrf FLAG), а после метки MAIN наберите: ; SUBRR btfsc WORK call SUBRR goto MAIN ; Ожидание старта btfsc WORK goto $-1 bсf INTCON,RBIE return ; Ожидание остановки ; Запрещение прерывания от порта В Кроме этого, измените в файле заголовка номер PINB с 0 на 7. Для удобства отладки откройте файл «intvect.inc» и повторите операцию выравнивания окон. Программа ожидает приема команды "Старт" (байт 0хАА) через интерфейс RS-232, затем переходит в режим ожидания нажатия кнопки (события на PINB). Событие приводит к выводу данных в порт D. Выход из этого режима осуществляется, когда будет принята команда "СТОП" (байт 0хВВ). К сожалению MPLAB не обеспечивает эмуляции порта RS-232 напрямую, следовательно, для отладки придется прибегнуть к обходным маневрам. Запустите программу, установив точку прерывания на метку «MAIN». Затем выполните вручную («Debug» – «Execute» – «Execute An Opcode») команду «bsf PIR1,RCIF». Это приведет к эмуляции прерывания от приемника RS-232. Непосредственно после перехода в подпрограмму обработки прерывания необходимо сбросить аналогичным образом указанный флаг («bсf PIR1,RCIF»). Теперь необходимо вручную записать в регистр данных принятый байт. В частности для эмуляции команды «Старт» необходимо внести в RCREG байт 0хАА. После обработки команды «Старт» можно проверить секцию обработки прерывания от порта В любым из описанных ранее способов. Проведите отладку набранной программы. 12 6 Приложение Описание используемых команд PIC16F874 Обозначения: f – регистр (ячейка памяти); d – Указатель назначения (0 – аккумулятор, 1 – регистр-операнд); b – номер бита; dat – байт непосредственных данных; l – адрес перехода. Мнемоника Описание movf f,d Пересылка f в аккумулятор (d=0) или в себя самого (d=1) (f→d) с установкой флагов movwf f Пересылка аккумулятора в регистр (w→f) swapf f,d Перестановка тетрад (f<7:4> ↔ d<3:0>) clrf f Очистка содержимого f (f=0) goto l Безусловный переход по адресу l call l Переход к подпрограмме по адресу l return Возврат из подпрограммы retfie Возврат из подпрограммы обработки прерывания bcf f,b Сброс бита b в регистре f bsf f,b Установка бита b в регистре f Проверка состояния бита b в регистре f и переход: Если b=1, то следующая команда не выполняется; btfss f,b Если b=1, то выполняется следующая команда. Проверка состояния бита b в регистре f и переход: btfsс f,b Если b=0, то следующая команда не выполняется; Если b=1, то выполняется следующая команда. sublw dat Вычитание dat из аккумулятора (dat-w→w) с установкой флагов