РАЗРАБОТКА И КОДИРОВАНИЕ АЛГОРИТМОВ ДЛЯ PIC-МИКРО

0

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

 

Кафедра промышленной электроники и

 информационно-измерительной техники

 

 

 

 

 

МЕТОДИЧЕСКИЕ   УКАЗАНИЯ

 

 

РАЗРАБОТКА И КОДИРОВАНИЕ АЛГОРИТМОВ

ДЛЯ PIC-МИКРО

 

                                    

 

Содержание

 

1 Разработка простых программ  …………………………………………...

4

2 Разработка программ сложной структуры ………………………………

8

3 Формирование интервалов времени  …………………………………….

15

4 Дискретный ввод-вывод  …………………………………………………

20

5 Аналоговый ввод …….…………………………………………...............

24

6 Вывод символьной информации …………………………………………

29

7 Обработка прерываний …………………………………………………..

34

8 Программная реализация микропрограммного автомата ………………

40

Список использованных источников ………………………………………

45

Приложение А – Система команд PIC16F87X

46

 

 

 

1 Разработка простых программ

 

1.1 Описание задания

 

Необходимо разработать и кодировать на языке Ассемблера микроконтроллера (МК) PIC-micro алгоритм программы генератора чисел. Числовая последовательность формируется на линиях порта PORTD  в соответствии с вариантом задания по таблице 1.1.

 

Таблица 1.1

Вариант

Задание

1

Суммирующий двоичный счетчик по модулю 16

2

Вычитающий двоичный счетчик по модулю 16

3

Суммирующий восьмиразрядный счетчик в унитарном коде

4

Вычитающий восьмиразрядный счетчик в унитарном коде

5

Суммирующий восьмиразрядный счетчик в коде Джонсона

6

Вычитающий восьмиразрядный счетчик в коде Джонсона

 

1.2 Рекомендации по выполнению

 

Алгоритм – точный набор инструкций, описывающих последовательность действий некоторого исполнителя для достижения результата, решения некоторой задачи за конечное время. Если исполнителем является процессорное ядро МК, то в конечном итоге набор инструкций необходимо представить в виде последовательности машинных команд – загрузочного кода программы. Кодированное представление алгоритма получают путем последовательного преобразования исходного описания, отличающегося меньшей степенью детализации и представленного в форме, удобной для восприятия человеком.  

Исходное представление алгоритм программы обычно формируют по результатам анализа ее функциональной спецификации. По заданию основные функции программы:

- модификация содержимого ячейки Cnt (в соответствии с вариантом задания);

- вывод содержимого ячейки Cnt в порт PORTD.

На рисунке 1.1 приведен пример - схема программы, реализующей алгоритм формирования на линиях порта PORTD числовой последовательности по закону суммирующего десятичного счетчика. При старте программа выполняет инициализацию порта вывода, инициализацию ячейки счетчика Cnt. После чего в теле цикла программы выполняется модификация (инкремент) содержимого ячейки Cnt и вывод ее содержимого в порт PORTD. Если содержимое счетчика превышает допустимое значение, определяемое модулем счета, счетчик обнуляется.

Теперь перейдем к кодированию алгоритма на языке Ассемблера - формированию исходного текста программы. Сводная таблица команд МК PIC16F87X приведена в приложении А, подробное описание приведено в документации изготовителя [1]. Рекомендуемые структуры исходного текста программ на языке Ассемблера для МК PIC-micro приводятся в шаблонах системы MPLAB, которые находятся в директории C:\Program Files\ Microchip\MPASM Suite\Template\. Варианты шаблонов для получения абсолютного кода программы находятся в папке ..\Code. Для МК типа PIC16F877 шаблон находится в файле 16F877TEMP.asm.

 

Рисунок 1.1

 

Данный шаблон с комментариями на русском языке приведен ниже:

        

list     p=16f877,st = OFF        ; директива листинга

                   #include <p16f877.inc>           ; определение микроконтроллера

        

         __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_ON & _CPD_OFF              ; директива установки разрядов слова конфигурации

 

;***** Определение переменных

w_temp       EQU            0x70           ; переменные для сохранения контекста

status_temp EQU            0x71            ;

; директивы определения остальных переменных

;*****************************************************************

                   ORG           0x000                    ; вектор старта

                   clrf              PCLATH              ; очистка программного счетчика

                   goto             main                      ; переход на начало программы

 

                   ORG           0x004                    ; вектор прерывания

                   movwf         w_temp                 ; сохранение контекста

                   movf           STATUS,w          ;

                   movwf        status_temp           ;

; операторы подпрограммы обработки прерывания

                   movf           status_temp,w       ; восстановление контекста

                   movwf        STATUS               ;

                   swapf          w_temp,f

                   swapf          w_temp,w             ;

                   retfie                                         ; возврат из подпрограммы

 

main 

; операторы программы

                   END                                         ; директива окончания программы

 

В общем случае текст программы на Ассемблере состоит из следующих разделов:

- директив листинга, определения модели МК;

- директив определения переменных;

- директивы указания вектора старта;

- оператора переход на начало программы;

- директивы указания вектора прерывания;

- операторов подпрограммы обработки прерывания;

- операторов программы;

- директивы окончания программы.

В данном случае механизм прерываний не используется, поэтому из шаблона можно удалить раздел подпрограммы обработки прерывания и команду перехода на операторы основной программы (goto main).

Для настройки линий PORTD на вывод в регистр TRISD необходимо загрузить управляющее слово b'00000000' или очистить регистр TRISD [1]. Регистр TRISD находится в банке 1, поэтому перед использованием оператора очистки регистра TRISD необходимо переключить соответствующие разряды (IRP, RP1,RP0) регистра STATUS. После очистки регистра TRISD необходимо вернуть исходное состояние измененных разрядов (RP0) регистра STATUS.   

Особенностью системы команд МК PIC-micro является отсутствие команд сравнения и условных переходов. Поэтому эти действия необходимо выполнить, используя реализованные операции системы команд.

Сравнение слов информации обычно реализуют путем вычитания без сохранения разности. Результат сравнения можно оценить по значениям признаков выполнения операции (флагов):  C – признака переноса и Z – признака нулевого результата. Вычитание константы можно заменить сложением с константой противоположного знака. В результате сложения:

movlw        -.10                      ; число -10

           addwf         cnt,w                    ; прибавить к содержимому счетчика

флаг С установится, если условие cnt < 10 не выполняется. Ветвление алгоритма можно реализовать с помощью команд:

btfss           STATUS,C          ; если С=1

goto            inc                        ; пропустить, иначе выполнить

           goto             loop                      ;.

Если С=0 (cnt<10), будет выполнен переход на метку inc, иначе переход на метку loop.

Сформированный исходный текст приведен ниже

 

list     p=16f877,st = OFF        ; директива листинга

                   #include <p16f877.inc>           ; определение микроконтроллера

        

         __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_ON & _CPD_OFF              ; директива установки разрядов слова конфигурации

 

;***** Определение переменных

Cnt              EQU            0x20                     ; счетчик

;*****************************************************************

                   ORG           0x000                    ; вектор старта

                   clrf              PCLATH              ; очистка программного счетчика

                  

bsf               STATUS,RP0       ; банк 1 (адреса 80h - FFh)

           bcf              STATUS,IRP

           bcf              STATUS,RP1

           clrf              TRISD^80           ; все линии PORTD на вывод

           bcf              STATUS,RP0      ; банк 0 (адреса 00h - 7Fh)

Loop          clrf              Cnt                      ; обнулить счетчик

Inc              movf           Cnt,w                    ;

           movwf        PORTD      

           incf             Cnt,f                    ; инкремент счетчика

           movlw        -.10                      ; число -10

           addwf         Cnt,w                   ; прибавить к содержимому счетчика

           btfss           STATUS,C          ; для сравнения

           goto            Inc                       ;

           goto             Loop                    

           END                                         ; директива окончания программы.

 

2 Разработка программ сложной структуры

 

2.1 Описание задания

 

Необходимо разработать и кодировать на языке Ассемблера МК PIC-micro алгоритм программы вычисления арифметического выражения в соответствии с вариантом задания по таблице 2.1.

 

Таблица 2.1

Вариант

Задание

1

18*26 - 34*78 - 156

2

56*24 + 37*98 +1000

3

81*62 - 43*87

4

65*42 + 73*89 - 100

5

174*78 - 85*103 

6

38*55 - 237*5 -132

 

2.2 Рекомендации по выполнению

 

Часто при реализации алгоритма приходится выполнять одни и те же последовательности операторов (например, при выполнении типовых арифметических вычислений). С целью сокращения объема кода программы рационально последовательно выполнять один и тот же участок кода, вместо того, чтобы дублировать в программе этот участок кода несколько раз.

Участок программы, к которому можно многократно обращаться из различных мест программы называется подпрограммой. Вызов подпрограммы выполняется по команде call , возврат из подпрограммы - по команде return. Описанную ситуацию иллюстрирует рисунок 2.1.

 

Рисунок 2.1

Программы, содержащие подпрограммы, имеют сложную структуру. Ассемблер MPASM / 2 / может транслировать такие программы в двух режимах:

- для генерации абсолютного кода (HEX файл), который может быть загружен непосредственно в память программ микроконтроллера;

- для генерации объектных кодов, которые необходимо связывать с другими объектными модулями при помощи редактора связей MPLINK.

По умолчанию MPASM работает в режиме генерации абсолютного кода (рисунок 2.2). В этом случае текст всей программы, включая подпрограммы, должен храниться в одном файле.

 

Рисунок 2.2

 

При трансляции исходного файла в этом режиме, все значения базовых адресов используемых ячеек должны быть явно указаны в директивах:

- ORG для памяти программ;

- EQU или CBLOCK для памяти данных.

Рассмотрим формирование исходного текста программы сложной структуры на примере задачи вычисления суммы произведений чисел 53*45 + 13*11. В системе команд МК семейств PIC16 нет команды умножения, поэтому приходится реализовать эту операцию программно. На рисунке 2.3 приведена схема подпрограммы умножения восьмиразрядных чисел методом поразрядной обработки разрядов множителя. Сначала обнуляются ячейки, в которых формируется шестнадцатиразрядное произведение (H_byte, L_byte), а также в счетчик циклов Count загружается необходимое число шагов. В теле циклического алгоритма, пока Count > 0, анализируется текущее значение младшего разряда множителя Mulplr. Если он равен 1, то к старшему байту произведения H_byte прибавляется множимое Mulcnd. Затем выполняется сдвиг вправо текущего шестнадцатиразрядного произведения (H_byte, L_byte), сдвиг вправо множителя Mulplr и декремент счетчика циклов Count.

  Исходный текст варианта программы для прямой трансляции в абсолютный код приведен ниже:

 

Рисунок 2.3

 

           

LIST    p=16F877, st=OFF

           #include "P16F877.INC"

           CBLOCK 0x20     ; Структура данных

            Mulcnd                 ; множимое

            Mulplr                  ; множитель

            H_byte                  ; старший байт произведения

            L_byte                  ; младший байт произведения

            Count                    ; счетчик циклов

            H_sum                  ; старший байт суммы

            L_sum                  ; младший байт суммы

           ENDC

 

                   ORG           0x000         ;вектор старта

          goto             Start

;************* Подпрограмма умножения ************

Mpy            clrf              H_byte

                   clrf              L_byte

                   movlw         8

          movwf         Count

                   movf           Mulcnd,w

                   bcf               STATUS,C       

Loop           rrf                Mulplr,f

                   btfsc            STATUS,C

                   addwf          H_byte,f

                   rrf                H_byte,f

                   rrf                L_byte,f

                   decfsz          Count,f

                   goto             Loop

                   retlw            0

;*************************************************

Start            clrw

Main           clrf              H_sum                 ;очистить сумму

                   clrf              L_sum

                   movlw         0x35

                   movwf         Mulplr                 ;35h умножить на 2Dh

                   movlw         0x2D

                   movwf         Mulcnd

                   call              Mpy                     ;вызов подпрограммы

                   movf           H_byte,w

                   movwf        H_sum

                   movf           L_byte,w

                   movwf        L_sum

                   movlw         0x0D

                   movwf         Mulplr                 ;0Dh умножить на 0Bh

                   movlw         0x0B

                   movwf         Mulcnd

                   call              Mpy                     ;вызов подпрограммы

                   movf           L_byte,w

                   addwf         L_sum,f               ;сложить мл.байты

btfsc           STATUS,C

                   incf             H_sum

                   movf           H_byte,w

                   addwf         H_sum,f               ;сложить ст.байты

                   goto             Main

                   END

 

MPASM также может генерировать объектные модули, которые могут быть связаны друг с другом с использованием линкера MPLINK для окончательного формирования исполняемого (абсолютного) кода (рисунок 2.4). Данный подход позволяет многократно использовать отлаженные модули программы. Объектные файлы могут быть сгруппированы в библиотечные файлы с помощью программы MPLIB. Библиотеки могут указываться в качестве параметра во время редактирования связей (линковки) и, таким образом, в исполняемый код будут включены только необходимые процедуры.

Написание исходного текста программы, который будет транслироваться в объектный файл, несколько отличается от создания программы с непосредственной трансляцией в HEX файл. Подпрограммы, разработанные для трансляции непосредственно в HEX файл, потребуют незначительных изменений для получения корректного перемещаемого объектного модуля.

 

Рисунок 2.4

 

При трансляции исходных файлов в этом режиме базовые адреса используемых ячеек задаются в параметрах директив / 2 /:

- CODE для памяти программ;

- UDATA (или UDATA_OVR, UDATA_SHR, IDATA) для памяти данных.

Фирма Microchip разработала стандартные файлы сценария (например, 16f877.inc), в которых приведена информация о распределении адресных пространств программ и данных для конкретной модели микроконтроллера.

Операторам программы должна предшествовать директива CODE, определяющая секцию перемещаемого кода.

 

PROG1      CODE                  ;сегмент PROG1 (0x0000 - 0x07FF)

nop

goto            Start

…………………………..      

PROG1      CODE                  ;сегмент PROG1

Start            clrw

 

Физический адрес кода в памяти программ может быть установлен, указав необязательный параметр директивы

CODE         <ROM address>.

Указание физического адреса может быть необходимо, например, в случаях определение вектора прерывания.

Распределение ячеек оперативной памяти должно быть выполнено в секции данных. Существует пять типов секций данных, в данном задании используются UDATA – неинициализированные данные. Это наиболее общий тип размещения данных. Ячейки, зарезервированные в этой секции, не инициализируются, а обращение к данным выполняется только с использованием меток или косвенной адресацией. Адрес инициализации данных в памяти можно установить, указав необязательный параметр <RAM address>.

Метки, которые определены в одном модуле и используются в других объектных модулях, должны быть отмечены директивой GLOBAL после их объявления. Модули, использующие эти метки, должны объявить их директивой EXTERN. Исходный текст варианта программы для трансляции в относительный код приведен ниже.

Подключаемый модуль (подпрограмма умножения):

                  

LIST    p=16F877, st = OFF

                   #include "P16F877.INC"

                   UDATA               ; Структура данных     

Mulcnd       RES     1               ; множимое

Mulplr        RES     1               ; множитель

H_byte        RES     1               ; старший байт произведения

L_byte        RES     1               ; младший байт произведения

Count          RES     1               ; счетчик циклов

 

                   GLOBAL  mulcnd, mulplr, H_byte, L_byte

 

PROG1      CODE                  ; сегмент кода PROG1 (0x0000 - 0x07FF)          

Mpy           GLOBAL    mpy

clrf              H_byte

clrf              L_byte

movlw         8

                   movwf         Count

                   movf           Mulcnd, W

                   bcf               STATUS,C  ; Очистка флага C.

Loop           rrf                Mulplr,f

                   btfsc            STATUS,C

                   addwf          H_byte,f

                   rrf                H_byte,f

                   rrf                L_byte,f

                   decfsz          Count,f

                   goto             Loop

                   retlw            0

                   END

Основной модуль

 

LIST    p=16F877, st = OFF

                   #include "P16F877.INC"

__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_ON & _CPD_OFF

                  

UDATA                                  ; Структура данных     

H_sum       RES     1                                  ; Старший байт суммы

L_sum         RES     1                                  ; Младший байт суммы

        

                   EXTERN  Mulcnd, Mulplr, H_byte, L_byte

                   EXTERN    Mpy

 

PROG1      CODE                                     ;сегмент PROG1

                   nop

                   start            clrw

Main           clrf              H_sum                 ;очистить сумму

                   clrf              L_sum

                   movlw         0xFF

                   movwf         Mulplr                 ;35h умножить на 2Dh

                   movlw         0x01

                   movwf         Mulcnd

                   call              Mpy                     ;вызов подпрограммы

                   movf           H_byte,w

                   movwf        H_sum

                   movf           L_byte,w

                   movwf        L_sum

                   movlw         0xFF

                   movwf         Mulplr                 ;0Dh умножить на 0Bh

                   movlw         0xFF

                   movwf         Mulcnd

                   call              Mpy                               ;вызов подпрограммы

                   movf           L_byte,w

                   addwf L_     Sum,f                   ;сложить мл.байты

                   btfsc           STATUS,C

                   incf             H_sum,f    

                   movf           H_byte,w

                   addwf         H_sum,f               ;сложить ст.байты

                   goto             Main

                   END

 

 

3 Формирование интервалов времени

 

3.1 Описание задания

 

Необходимо разработать и кодировать на языке Ассемблера алгоритм программы для МК типа PIC16F877, которая  управляет светодиодом, подключенным к линии RD0 порта PORTD. Время включенного и выключенного состояния светодиода формируется в соответствии с вариантом задания (таблица 3.1).

Факультативное задание – автомат, управляющий дорожным светофором (красный, зеленый свет – 20 секунд, желтый свет - 2 секунды).

 

Таблица 3.1

Вариант

Задание

1

Время включенного состояния нарастает от 0.5 до 60 секунд с шагом 0.5 секунды, время выключенного состояния – 1 секунда.

2

Время включенного состояния нарастает от 1 до 60 секунд с шагом 1 секунда, время выключенного состояния – 2 секунды.

3

Время включенного состояния спадает от 100 до 2 секунд с шагом 2 секунды, время выключенного состояния – 2 секунды.

4

Время включенного состояния спадает от 100 до 5 секунд с шагом 5 секунд, время выключенного состояния – 1 секунда.

5

Время включенного состояния нарастает от 1 до 60 секунд с шагом 1 секунда, время выключенного состояния спадает от 60 до 1 секунды с шагом 1 секунда.

6

Время включенного состояния спадает от 50 до 2 секунд с шагом 2 секунды, время выключенного состояния нарастает от 2 до 50 секунд с шагом 2 секунды.

 

3.1 Рекомендации по выполнению

 

Одной из наиболее часто встречающихся функций микропроцессорных устройств (МПУ) является отсчет интервалов времени.

В учебно-отладочном стенде используется кварцевая стабилизация частоты тактового генератора, и она составляет 3.6864 МГц. Длительность машинного цикла МК составляет 4 такта, поэтому тактирование встроенных периферийных модулей происходит с частотой 3.6864 / 4 = 0.9216 МГц. Время выполнения одной команды МК также составляет 4 такта.

Функцию формирования интервалов времени можно реализовать в следующих вариантах:

- программный;

- аппаратный;

- программно-аппаратный.

Программный способ формирования интервала времени основан на выполнении процессорным ядром некоторой фиксированной последовательности команд. При этом общее время их выполнения равно формируемому интервалу времени. Главным недостатком этого способа является загрузка процессорного ядра. Поэтому программный способ используют в случаях, когда формируемый интервал времени не слишком длительный, и процессорное ядро на этом интервале времени свободно от выполнения других функций.

Аппаратный способ формирования интервала времени реализуется на основе специализированных периферийных модулей МК – таймеров. Процессорное ядро в течение формируемого интервала времени свободно для выполнения других функций, если используется механизм прерывания по переполнению таймера. Недостатком этого способа является сложность формирования длительных интервалов времени на таймерах с небольшим числом разрядов. В какой-то степени эту проблему удается решить путем понижения частоты счетных импульсов.

Программно-аппаратный способ позволяет формировать длительные интервалы времени путем многократного программного перезапуска таймера. При этом средняя загрузка процессорного ядра в течение формируемого интервала времени получается небольшой, если исключить программный опрос флага переполнения таймера.

 В составе МК семейства PIC16F87x имеются три таймера [1]:

- 8-разрядный таймер/счетчик TMR0 с 8-разрядным программируемым предделителем;

- 16-разрядный таймер/счетчик TMR1 с 8-разрядным программируемым предделителем и возможностью подключения внешнего резонатора;

- 8-разрядный таймер/счетчик TMR2 с программируемым предделителем и выходным делителем (по 4 разряда).

Оценим возможность использования таймера TMR0. Функциональная схема таймера приведена на рисунке 3.1.

Режим работы таймера определяется состоянием разрядов регистра OPTION_REG (таблица 3.2).

 

Таблица 3.2

 

Если бит T0CS=0, то TMR0 работает от внутреннего тактового генератора, инкремент счетчика происходит в каждом машинном цикле. На входе TMR0 может быть включен предделитель частоты, если бит PSA=0. Коэффициент деления определяется значениями разрядов PS2:PS0. Максимальное значение коэффициента деления частоты 1:256 получается при <PS2:PS0> = 111. Для настройки TMR0 на данный режим в регистр OPTION_REG необходимо загрузить управляющее слово b'10000111'.

 

Рисунок 3.1

 

При переполнении таймера устанавливается флаг T0IF (регистр INTCON). После анализа флага, его необходимо программно сбросить.

При тактовой частоте МК F=3.6864 МГц интервал времени между двумя переполнениями таймера составит:

 

ТTMR = 4×28 ×28/F = 4×256×256/3.6864×106 = 71.11 мс.     

 

Таким образом, при заданном значении тактовой частоты 3.6864 МГц аппаратный вариант на основе таймера TMR0 позволяет формировать интервалы не более  71.11 мс.

Для формирования интервала 0.5 секунды требуемое число переполнений составит

 

500 / 71.11 » 7.

 

         Погрешность формирования интервала 0.5 секунды не превысит

 

         [(500 - 71.11 ∙ 7) / 500] ∙ 100 % = 0.446 %.

 

         Последовательно инициируя от 1 до 255 серий из 7 переполнений таймера TMR0, можно формировать интервал времени в диапазоне от 0.5 до 127.5 секунды с шагом 0.5 секунды.

Для подсчета количества переполнений таймера введем переменную Count. Для подсчета половин секунд используем переменную Count05s.

На рисунке 3.2 приведена схема программы, которая  управляет светодиодом, подключенным к линии RD0 порта PORTD. Время включенного и выключенного состояния светодиода определяется значением целочисленного параметра n, который передается в подпрограмму формирования временного интервала DLY.

 

Рисунок 3.2

 

Ниже приводится исходный текст программы.  Значения интервалов времени (в единицах 0.5 секунды), в течение которых светодиод выключен и включен, задаются значениями констант Delay0 и Delay1 соответственно.

        

list     p=16f877, st = OFF       

         include "p16f877.inc"

;---------------------- Константы ---------------------------

Delay0        EQU           .4                         ;задержка в единицах 0.5 с

Delay1        EQU           .6                         ;задержка в единицах 0.5 с

;---------------------- Переменные --------------------------

                   CBLOCK    H'020'

                   Count                                      ;счетчик переполнения таймера

                   Count05s                                ;счетчик половин секунд

                   ENDC

#define Led  PORTD,0            ;выходной управляющий сигнал

;----------------- Начало кода программы --------------------

                   ORG           0x000                   ;вектор сброса

                   nop                                         ;необходимо для MICD

                   clrf              PORTD               ;инициализация модулей МК

                   bsf               STATUS,RP0       ;банк 1 (адреса 80h - FFh)

                   bcf              STATUS,IRP

                   bcf              STATUS,RP1

                   movlw        b'10000111'         ;режимы TMR0

                   movwf        OPTION_REG^80

          clrf              TRISD^80           ;все линии PORTD на вывод

                   bcf              STATUS,RP0      ;банк 0 (адреса 00h - 7Fh)

Main           bsf               Led                      ;зажечь светодиод

                  movlw         Delay1

                   call              Dly

                   bcf              Led                      ;погасить светодиод

                   movlw         Delay0

                   call              Dly

                   goto            main

;------------------- Подпрограмма задержки ---------------------

Dly             movwf        Count05s             ;загрузить счетчик половин секунд

                   clrf              TMR0                  ;инициализация TMR0

                   bcf              INTCON,T0IF

T05s           movlw        .500000/.256/.256

                   movwf        Count                   ;загрузить счетчик переполнений

T71ms        btfss           INTCON,T0IF

                   goto            T71ms                 ;ожидание переполнения таймера

                   bcf              INTCON,T0IF

                   decfsz         Count,f                ;полсекунды прошло?

                   goto            T71ms

                   decfsz         Count05s,f           ;время закончилоcь?

                   goto            T05s

                   return                                      ;возврат в основную программу

                   END

4 Дискретный ввод-вывод

 

4.1 Описание задания

 

Необходимо разработать и кодировать на языке Ассемблера алгоритм программы дискретного ввода-вывода для МК типа PIC16F877.

Нажатие с последующим отпусканием кнопок RB1 и RB2 должно вызывать разнонаправленную модификацию содержимого ячейки Cnt. Содержимое ячейки Cnt должно отображаться на светоизлучающих диодах, подключенных к линиям порта PORTD. Активному (нажатому) состоянию кнопки соответствует низкий потенциал на выводе порта PORTB. Пассивному (отжатому) состоянию кнопки соответствует высокий потенциал, который обеспечивается встроенными подтягивающими резисторами. Варианты заданий  приведены в таблице 4.1.

 

Таблица 4.1

Вариант

Задание

1

Инкремент и декремент с ограничением в диапазоне 0 .. 255

2

Циклический инкремент и декремент по модулю 10

3

Циклическое вращение единицы

4

Вращение единицы с ограничением

5

Циклический инкремент и декремент в коде Джонсона

6

Инкремент и декремент в коде Джонсона с ограничением

 

 

4.2 Рекомендации по выполнению

 

Функции программы:

- опрос кнопок, подключенных к выводам порта PORTB (RB1 и RB2);

- модификация содержимого ячейки Cnt;

- вывод содержимого ячейки Cnt в порт PORTD.

На рисунке 4.1 приведен пример - схема программы, реализующая алгоритм реверсивного счетчика числа нажатий на кнопки RB1 и RB2 (по модулю 256). Нажатие с последующим отпусканием кнопки RB1 вызывает декремент содержимого ячейки Cnt, нажатие с последующим отпусканием кнопки RB2 вызывает инкремент ее содержимого.

При старте программа выполняет инициализацию портов ввода и вывода, инициализацию ячейки счетчика Cnt. После чего в теле цикла программы анализируются состояния кнопок RB1 и RB2 и, в случае их нажатия, изменяется содержимое ячейки Cnt.

Все механические кнопки имеют одно негативное свойство, известное как «дребезг» контактов, которое обусловлено колебаниями упругих контактов при их замыкании и размыкании. Длительность колебаний составляет всего несколько миллисекунд. В устройствах на базе МК обычно используют программные способы подавления «дребезга» контактов. Простейший из них основан на ограничении минимальных интервалов времени между последовательными операциями анализа состояния входной линии порта. Для надежного считывания состояний кнопки величина этих интервалов не должна быть меньше 15 – 30 мс. Для подавления «дребезга» контактов в цикл основной программы включены операторы вызова подпрограммы задержки D15ms.

 

Рисунок 4.1

 

В таблицах 4.1 и 4.2 приведены регистры специального назначения, связанные с портами PORTB и PORTD. Для настройки линий PORTB на ввод в регистр TRISB необходимо загрузить управляющее слово b'11111111'. Для включения подтягивающих резисторов к линиям PORTB в разряд 7 регистра OPTION_REG необходимо загрузить 0. Для настройки линий PORTD на вывод в регистр TRISD необходимо загрузить управляющее слово b'00000000'.

 

Таблица 4.1

 

Таблица 4.2

 

 

Ниже приводится исходный текст программы реверсивного счетчика по модулю 256.

 

#include      p16f877.inc

                   LIST    p=16F877, st=OFF

__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_ON & _CPD_OFF

;---------------------- Переменные --------------------------

                   CBLOCK   0x20    

                   Cnt                                          ;счетчик

                   Temp1

                   Temp2          

                   ENDC

;---------------------- Константы ---------------------------

Init_PB       EQU            b'11111111'          ;все ввод   

Init_PD       EQU            b'00000000'          ;все вывод   

Init_OPT    EQU            b'00000000'          ;pull-up R  

;------------------ Битовые переменные ----------------------

#define       RB1            PORTB,1              ;кнопка "-"

#define       RB2            PORTB,2              ;кнопка "+"

;------------------ Начало кода программы -------------------

                   ORG           0x000                   ;вектор сброса

                   nop                                         ;необходимо для MICD

          clrf              PORTD               ;инициализация модулей МК

                   clrf              Cnt

                   bsf               STATUS,RP0       ;bank1

                   bcf              STATUS,IRP

                   bcf              STATUS,RP1

                   movlw         Init_PB

                   movwf        TRISB^80h

                   movlw        Init_PD

                   movwf        TRISD^80h

                   movlw         Init_OPT

                   movwf         OPTION_REG^80h

                   bcf              STATUS,RP0       ;bank0

Main           movf           Cnt,W                  ;основной цикл   

          movwf         PORTD                ;вывод на линейный индикатор 

                   btfsc           RB1                      ;опрос кнопки "-"           

                   goto            Bt2                      ;кнопка "-" не нажата          

                   decf             Cnt,1                    ;декремент счетчика

                   goto            Release  

Bt2             btfsc           RB2                      

                   goto            Main                    ;кнопка "+" не нажата                      

                   incf             Cnt,1                    ;инкремент счетчика

Release                                                      ;опрос кнопок (отжатие)

                   call              D15ms                

                   btfss           RB1                      ;опрос кнопки "-"

                   goto            Release                ;кнопка не отжата 

                   btfss           RB2                      ;опрос кнопки "+"       

                   goto            Release                ;кнопка не отжата 

                   call              D15ms                 ;задержка            

                   goto                      Main                     ;кнопка отжата

;------------------- Подпрограмма задержки ---------------------

D15ms                                             ;подпрограмма задержки 15 мс   

                   movlw        .30                      

                   movwf        Temp2                     

_15ms         call              D500us         

                   decfsz         Temp2,1          

                   goto            _15ms                     

                   return

;---------------------------------------------------------------

D500us                                              ;подпрограмма задержки 500 мкс            

                   movlw                  .151

movwf        Temp1

_500us        decfsz          Temp1,1

goto            _500us

return

                   END

 

5 Аналоговый ввод

 

5.1 Описание задания

 

Необходимо разработать и кодировать на языке Ассемблера алгоритм программы аналогового ввода для МК типа PIC16F877. Программа должна выполнять запуск модуля АЦП, получать результаты преобразования, обрабатывать и выводить на индикаторы. Варианты заданий  приведены в таблице 5.1.

 

Таблица 5.1

Вариант

Задание

1

Среднее арифметическое из каналов – AN1 и AN3 в PORTD

2

Разность из каналов – AN0 и AN1 в PORTD, заем в RC5

3

Разность из каналов – AN1 и AN3 в PORTD, заем в RC5

4

Меньшее значение из каналов – AN0 и AN1 в PORTD

5

Большее значение из каналов – AN0 и AN1 в PORTD

6

Меньшее значение из каналов – AN1 и AN3 в PORTD

 

5.2 Рекомендации по выполнению

 

В таблице 5.2 приведены регистры специального назначения, связанные с

модулем АЦП.

 

Таблица 5.2

 

Результат аналого-цифрового преобразования сохраняется в регистрах ADRESH (старший байт) и ADRESL (младший байт);

Разряды регистра управления ADCON0 определяют:

- биты 7-6  ADCS1:ADCS0 - выбор источника тактового сигнала (00 = FOSC/2; 01 = FOSC/8; 10 = FOSC/32; 11 = FRC - внутренний RC генератор модуля АЦП);

- биты 5-3 CHS2:CHS0 - выбор аналогового канала AN0.. AN7;

- бит 2 GO/-DONE - бит статуса модуля АЦП (установка бита вызывает начало преобразования, аппаратно сбрасывается по завершении преобразования);

- бит 1 не используется;

- бит 0 ADON - включение модуля АЦП (1 - модуль включен, 0 - модуль выключен и не потребляет ток).

Разряды регистра управления ADCON1 определяют:

- бит 7 ADFM - формат сохранения 10-разрядного результата (пояснения на рисунке 5.1);

- биты 6-4 не используются, читаются как ‘0’;

- биты 3-0 PCFG3:PCFG0 - управляющие биты настройки каналов АЦП и многофункциональных выводов (см. таблицу 5.3).

Когда преобразование завершено, 10-разрядный результат аналого-цифрового преобразования записывается в регистры ADRESH:ADRESL, после чего сбрасывается флаг GO/-DONE (ADCON0<2>) и устанавливается флаг прерывания ADIF в регистре PIR1. Сброс бита GO/-DONE в '0' во время преобразования приведет к его прекращению.

 

Таблица 5.3

PCGF3:

PCGF0

AN7

RE2

AN6

RE1

AN5

RE0

AN4

RA5

AN3

RA3

AN2

RA2

AN1

RA1

AN0

RA0

VREF+

VREF-

0000

A

A

A

A

A

A

A

A

VDD

VSS

0001

A

A

A

A

VREF+

A

A

A

RA3

VSS

0010

D

D

D

A

A

A

A

A

VDD

VSS

0011

D

D

D

A

VREF+

A

A

A

RA3

VSS

0100

D

D

D

D

A

D

A

A

VDD

VSS

0101

D

D

D

D

VREF+

D

A

A

RA3

VSS

011x

D

D

D

D

D

D

D

D

VDD

VSS

1000

A

A

A

A

VREF+

VREF-

A

A

RA3

RA2

1001

D

D

A

A

A

A

A

A

VDD

VSS

1010

D

D

A

A

VREF+

A

A

A

RA3

VSS

1011

D

D

A

A

VREF+

VREF-

A

A

RA3

RA2

1100

D

D

D

A

VREF+

VREF-

A

A

RA3

RA2

1101

D

D

D

D

VREF+

VREF-

A

A

RA3

RA2

1110

D

D

D

D

D

D

D

A

VDD

VSS

1111

D

D

D

D

VREF+

VREF-

D

A

RA3

RA2

 

После включения и конфигурации АЦП выбирается рабочий аналоговый канал. Соответствующие биты TRIS аналоговых каналов должны настраивать линию порта на вход. Рекомендованная последовательность действий для работы с АЦП:

1) настроить и включить модуль АЦП;

2) выдержать паузу, необходимую для зарядки конденсатора CHOLD , не менее 20 мкс [1];

3) начать аналого-цифровое преобразование - установить бит GO/-DONE;

4) ожидать окончания преобразования (пока бит GO/-DONE не будет сброшен или флаг ADIF в регистре PIR1 не будет установлен);

5) считать результат преобразования из регистров ADRESH:ADRESL;

6) для следующего преобразования необходимо выполнить шаги, начиная с пункта 1 или 2.

 

Рисунок 5.1

 

Время получения одного бита результата определяется параметром TAD. Для 10-разрядного результата требуется как минимум 12TAD. Для получения корректного результата преобразования необходимо выбрать источник тактового сигнала АЦП, обеспечивающий время TAD не менее 1.6 мкс. В таблице 5.4 указано максимальное значение тактовой частоты микроконтроллера для каждого режима синхронизирующего сигнала АЦП.

 

Таблица 5.4

Выбор TAD

FOSC ,

максимум

Режим

ADCS1:ADCS0

2TOSC

00

1.25 МГц

8TOSC

01

5 МГц

32TOSC

10

20 МГц

RC генератор

11

не более 1 МГц

 

Чтобы обеспечить требуемые значения паузы, необходимой для зарядки конденсатора CHOLD , а также периода дискретизации аналогового сигнала, в цикле программы между операторами выбора канала и запуска преобразования необходимо выполнять программные задержки.

На рисунке 5.2 приведена схема программы, которая после инициализации модуля АЦП циклически выполняет:

- последовательный запуск модуля АЦП для выполнения преобразования напряжений из каналов AN0 и AN1;

- вычисляет среднее арифметическое значение полученных результатов;

- выводит среднее арифметическое значение в PORTD.

Период дискретизации аналоговых сигналов определяется полным временем выполнения цикла.

 

 

Рисунок 5.2

 

Исходный текст программы

 

         list p=16f877, st = OFF

         include "p16f877.inc"

         __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_ON & _CPD_OFF

 

         CBLOCK 0x20

         Ad0

         Cnt

         ENDC

 

         ORG 0x000

         nop

Init    BANKSEL PORTD

         clrf              PORTD              

         movlw        B'01000001' ;Fosc/8,канал AN0,разрешить A/D

         movwf        ADCON0

         BANKSEL OPTION_REG

         clrf              TRISD^80  ;PORTD все линии на выход

         movlw        B'00000100'         ;Рез-т влево, каналы AN0,AN1,AN3

         movwf        ADCON1^80       ;опорное напряжение VDD и VSS

         BANKSEL PORTD

Main movlw        .38

         call              Dly

         bsf              ADCON0,GO      ;Начало A/D преобразования 

Wait0 btfsc           ADCON0,GO      ;Ожидание завершения

         goto            Wait0         ;        A/D преобразования

         bsf              ADCON0,CHS0 

         movf           ADRESH,W       

         movwf        Ad0

         movlw        .4               

         call              Dly

         bsf              ADCON0,GO      ;Начало A/D преобразования 

Wait1 btfsc           ADCON0,GO      ;Ожидание завершения

         goto            Wait1         ;        A/D преобразования

         bcf              ADCON0,CHS0 

         movf           ADRESH,W       

         addwf          Ad0,F

         rrf               Ad0,W

         movwf        PORTD

         goto            Main          

Dly    movwf        Cnt

Dlp   decfsz         Cnt,F

         goto            Dlp

         return

         END

 

6 Вывод символьной информации

 

6.1 Описание задания

 

Необходимо разработать и кодировать на языке Ассемблера алгоритм программы вывода символьной информации на 7-сегментные индикаторы для МК типа PIC16F877. Варианты заданий  приведены в таблице 6.1.

 

Таблица 6.1

Вариант

Задание

1

Информация из канала AN0 в шестнадцатеричной форме (0 .. 3FF)

2

Информация из канала AN0 в десятичной форме (0 .. 1023)

3

Информация из канала AN0 в шестнадцатеричной форме (0 .. FF)

4

Информация из канала AN0 в десятичной форме (-128 .. 127)

5

Цифровой вольтметр (рабочая шкала 0.000 .. 5.000 В)

6

Цифровой термометр (рабочая шкала 0 .. 125 °С)

 

6.2 Рекомендации по выполнению

 

Для управления индикаторами в отладочном стенде применен специализированный контроллер MC14489BP, схема включения приведена на рисунке 6.1. Эта микросхема обеспечивает вывод информации на 7-сегментные индикаторы (до пяти разрядов) в режиме динамического управления.

 

Рисунок 6.1

Данные от МК к контроллеру MC14489BP передаются через синхронный последовательный интерфейс по трем линиям:

- RE1 (DATA IN) – данные;

- RE0 (Clk) - синхроимпульсы;

- RB3 (-CS) – выборка кристалла.

В отладочном стенде установлены четыре разряда индикатора. Каждый из разрядов индикатора можно запрограммировать на работу в одном из режимов (таблица 6.2):

- стандартного hex-декодирования;

- специального декодирования;

- без декодирования (используются только сегменты a – d).

Таблица 6.2

 

 

Код разряда

 

Символ

Единичные индикаторы

No Decode

Hex

Decode

Special

Decode

 

d

 

c

 

b

 

a

L

L   L

L

0

 

 

 

 

 

L

L   L

H

1

c

 

 

 

on

L

L   H

L

2

H

 

 

on

 

L

L   H

H

3

h

 

 

on

on

L

H   L

L

4

J

 

on

 

 

L

H   L

H

5

L

 

on

 

on

L

H   H

L

6

n

 

on

on

 

L

H   H

H

7

o

 

on

on

on

H

L   L

L

8

P

on

 

 

 

H

L   L

H

9

r

on

 

 

on

H

L   H

L

A

U

on

 

on

 

H

L   H

H

b

u

on

 

on

on

H

H   L

L

C

У

on

on

 

 

H

H   L

H

d

-

on

on

 

on

H

H   H

L

E

=

on

on

on

 

H

H   H

H

F

°

on

on

on

on

 

Режим работы определяется словом конфигурации Диаграммы сигналов для приема, а также  формат конфигурационного слова приведены на рисунке 6.2. Разряды слова конфигурации С7 – С0 определяют:

- режим потребляемой мощности (C0);

- режимы декодирования разрядов (С1 – С7).

При этом разряды С1 – С5 позволяют выбрать либо режим стандартного hex-декодирования, либо иной режим для каждого разряда индикатора. Разряды С6 и С7 позволяют выбрать либо режим специального декодирования, либо режим без декодирования для групп разрядов 1-3 и 4-5 соответственно.

Рисунок 6.2

 

Диаграммы сигналов для приема, а также  формат информационного слова приведены на рисунке 6.3. Информационное слово должно содержать 24 разряда, из них младшие 20 разрядов (D0 – D19) содержат пять тетрад кода отображаемых символов, разряды D20 – D22 управляют сегментами h (точка), разряд D23 – управляет яркостью свечения сегментов.

 

Рисунок 6.3

 

Для работы с индикатором необходимо линии 3 PORTB и 1-0 PORTE настроить на вывод. Для загрузки в регистры ADCON1, TRISB и TRISE можно использовать слова:

Init_AD1    EQU           b'10001110'         ;включены линии PORTE

Init_PB        EQU            b'11110111'          ;бит 3 - вывод   

Init_PE        EQU            b'00000100'          ;линии 1-0 – вывод.

Для программного управления состоянием сигнальных линий удобно определить одноразрядные переменные:

#define        Data_in       PORTE,1             ;сигналы MC14489                             #define          Clk              PORTE,0              ;      

#define        Cs               PORTB,3             ;     

 

Для хранения передаваемого по последовательному каналу байта информации используем ячейку Indval. В соответствии с рисунком 6.2 инициализацию MC14489 будет выполнять подпрограмма Control_MC14489:

Control_MC14489                            ;подпрограмма инициализации MC14489

                   bcf               Cs

                   movlw         b‘00000001’

                   call              Send8

                   bsf               Cs

                   return --.

 

В соответствии с рисунком 6.3 вывод 24-х разрядного слова информации, из ячеек  Fig2, Fig1, Fig0 будет выполнять подпрограмма Dysplay

Dysplay      bcf               Cs               ;подпрограмма отображ. 7сегм. символов

                   movf           Fig2,w            

                   call              Send8             

                   movf           Fig1,w            

                   call              Send8             

                   movf           Fig0,w            

                   call              Send8             

                   bsf               Cs

                   return --.

 

Подпрограмма вывода однобайтного слова Send8:

Send8          bcf              Clk             ;подпрограмма отображения  символа                       

                   movwf        Indval

                   movlw         8

                   movwf        Cntind

Sendloop    bcf              Data_in

                   rlf                Indval,f

                   btfsc            STATUS,C

                   bsf               Data_in

                   nop

                   bsf               Clk

                   nop

                   bcf              Clk

                   decfsz          Cntind,f

                   goto            Sendloop

                   return --.

Для вариантов заданий 2, 4 – 6 потребуется подпрограмма преобразования двоичного кода в двоично-десятичный B2_BCD. Вход - двухбайтное число в ячейках H_byte, L_byte, выход – двоично-кодированное число в ячейках R0, R1, R2.

 

;------------------- Подпрограмма преобразования кода ------------------------

B2_BCD    bcf              STATUS,0

         movlw        .16

         movwf        count

         clrf              R0

         clrf              R1

         clrf              R2

loop16        rlf               L_byte

         rlf               H_byte

         rlf               R2

         rlf               R1

         rlf               R0

         decfsz         count

         goto            adjDEC

         retlw           0

adjDEC      movlw        R2

         movwf        FSR

         call              adjBCD

         movlw        R1

         movwf        FSR

         call              adjBCD

         movlw        R0

         movwf        FSR

         call              adjBCD

         goto            loop16

adjBCD      movlw        3

         addwf 0,w

         movwf        temp

         btfsc           temp,3

         movwf        0

         movlw        30

         addwf 0,w

         movwf        temp

         btfsc           temp,7

         movwf        0

         retlw           0 --.

7 Обработка прерываний

 

7.1 Описание задания

 

Необходимо разработать и кодировать на языке Ассемблера алгоритм программы, в которой используется механизм прерываний. Программа должна выполнять две функции:

- отсчет времени и его отображение в секундах на 7-сегментных индикаторах;

- разнонаправленную модификацию содержимого ячейки Cnt при нажатии с последующим отпусканием кнопок RB1 и RB2 и вывод ее содержимого в порт PORTD (варианты заданий  приведены в таблице 4.1).

 

7.2 Рекомендации по выполнению

 

Рассмотрим решение задачи на примере программы, реализующей алгоритм реверсивного счетчика числа нажатий на кнопки RB1 и RB2 по модулю 256. Возьмем за основу результаты, полученные при выполнении заданий 3, 4 и 6.  Секундные интервалы времени будем формировать путем подсчета количества переполнений таймера TMR0. Тогда МК должен реагировать на следующие события:

- переполнение таймера TMR0;

- нажатие и отпускание кнопок RB1 и RB2.

Использование программного опроса флага T0IF и линий порта RB1 и RB2 может привести к пропуску переполнения таймера и, как следствие, появлению погрешности формирования секундного интервала в моменты времени, когда кнопки могут быть нажаты. Или, что менее вероятно, пропуску кратковременного нажатия на кнопки при ожидании переполнения таймера. Решается эта проблема путем использования механизма прерываний.

При возникновении прерывания МК выполняет текущую команду, запоминает адрес следующей команды (точки возврата) в стеке и передает управление подпрограмме обработки прерывания. После обработки прерывания из стека извлекается адрес точки возврата, и управление передается прерванному процессу. Это позволяет МК своевременно реагировать на различные события, при условии, что обработка прерываний занимает не слишком много времени. При возникновении нескольких прерываний от различных источников, их обработка выполняется последовательно в соответствии с приоритетами.

Для данной задачи примем, что прерывания будут возникать при переполнении таймера TMR0, анализ состояния линий RB1 и RB2 будет выполняться путем программного опроса в главном цикле основной программы.

 Микроконтроллеры PIC16F87X имеют 14 источников прерываний [1]. Логика прерываний приведена на рисунке 7.1. Регистр INTCON содержит флаги отдельных прерываний, биты разрешения этих прерываний и бит глобального разрешения прерываний GIE.

Рисунок 7.1

 

Если бит GIE (INTCON<7>) установлен в ‘1’, разрешены все немаскированные прерывания. Если GIE=0, то все прерывания запрещены. Каждое прерывание в отдельности может быть разрешено/запрещено установкой/сбросом соответствующего бита в регистрах INTCON, PIE1 и PIE2. При сбросе микроконтроллера бит GIE сбрасывается в ‘0’.

В регистре INTCON находятся флаги следующих прерываний: внешнего сигнала INT, изменения уровня сигнала на входах RB7:RB4, переполнения TMR0 (таблица 7.1). В регистрах PIR1, PIR2 содержатся флаги прерываний периферийных модулей микроконтроллера, а в регистрах PIE1, PIE2 соответствующие биты разрешения прерываний. В регистре INTCON находится бит разрешения прерываний от периферийных модулей PEIE.

При переходе на подпрограмму обработки прерываний бит GIE аппаратно сбрасывается в ‘0’, запрещая прерывания, адрес возврата из подпрограммы обработки прерываний помещается в стек, а в счетчик команд PC загружается вектор прерывания 0004h. Источник прерываний можно определить проверкой флагов прерываний. Их необходимо сбросить программно перед разрешением прерываний, чтобы избежать повторного вызова.

Таблица 7.1

Адрес

Имя

Бит 7

Бит 6

Бит 5

Бит 4

Бит 3

Бит 2

Бит 1

Бит 0

0Bh,8Bh,

10Bh,18Bh

INTCON

GIE

PEIE

T0IE

INTE

RBIE

T0IF

INTF

RBIF

0Ch

PIR1

PSPIF

ADIF

RCIF

TXIF

SSPIF

CCP1F

TMR2IF

TMR1IF

8Ch

PIE1

PSPIE

ADIE

RCIE

TXIE

SSPIE

CCP1E

TMR2IE

TMR1IE

0Dh

PIR2

-

 

-

EEIF

BCLIF

-

-

CCP2IF

8Dh

PIE2

-

 

-

EEIE

BCLIE

-

-

CCP2IE

При возвращении из подпрограммы обработки прерывания, по команде RETFIE, бит GIE аппаратно устанавливается в ‘1’, разрешая все немаскированные прерывания.

Обработка запроса внешнего прерывания может занимать три или четыре командных цикла процессора, в зависимости от того, в какой момент времени обнаружен запрос.

Прерывание при переполнении таймера TMR0 можно запретить, сбросив бит T0IE в регистре INTCON.

Микроконтроллеры PIC16F87x не имеют специальных команд для сохранения содержимого аккумулятора и специальных регистров во время обработки прерывания с последующим их восстановлением. Автоматически сохраняется только значение программного счетчика для возврата из подпрограммы. Поэтому пользователь должен программно сохранять контекст (содержимое аккумулятора W и регистра STATUS). Пример приведен ниже:

 

Push           movwf        w_tenp                 ;Сохранить содержимое W в W_TEMP

movf           STATUS, w         ; Загрузить содержимое STATUS в W

movwf        Status_Temp        ; сохранить W в STATUS_TEMP

 

                   ……………….                       ; тело подпрограммы

……………….                       ; обработки прерывания

 

Pop            movwf        Status_Temp,w    ; Загрузить сохраненное значение

movwf        STATUS             ; и восстановить его в рег. STATUS

swapf          W_Temp, f           ; восстановить содержимое W

swapf          W_Temp,w

 

Использование команды swapf для загрузки и выгрузки значений обусловлено тем, что эта команда не изменяет состояние флаг-бита нуле­вого результата Z регистра STATUS. Применение команды movf со­кратило бы программный код, но тогда при сохранении значения акку­мулятора может быть изменено состояние бита Z, что в общем случае недопустимо. Корректное программирование требует, чтобы при воз­вращении из подпрограммы прерывания значения регистров W и STATUS были восстановлены абсолютно точно.

В качестве примера рассмотрим программу, которая:

- выполняет счет секунд, результат счета (переменная Time) выводится на семисегментные светодиодные индикаторы.

- реализует алгоритм реверсивного счетчика числа нажатий на кнопки RB1 и RB2 (по модулю 256), результат счета (переменная Cnt) выводится в PORTD.

За основу алгоритма программы можно взять схему на рисунке 4.1. При старте программа должна выполнить инициализацию портов ввода и вывода,  контроллера MC14489, инициализацию ячеек Fig0-Fig2 и Cnt. В это время все прерывания должны быть запрещены. После инициализации прерывания необходимо разрешить. После чего в теле цикла программы анализируются состояния кнопок RB1 и RB2 и, в случае их нажатия, изменяется содержимое ячейки Cnt.

         Схема подпрограммы обработки прерывания приведена на рисунке 7.2.

Режим работы таймера и модуль счетчика переполнений таймера CntT определяется в соответствии с рекомендациями, изложенными в разделе 3.

 

 

Рисунок 7.2

 

 

Ниже приводится текст основы программы, полученной с учетом принятых решений. Операторы отлаженных на других занятиях участков алгоритма представлены комментариями.

 

 

LIST p=16f877, st = OFF

                   INCLUDE "p16f877.inc"

                   __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_ON & _CPD_OFF             

 

CBLOCK   0x20

                   CntT                    ;счетчик переполнений таймера

                   Cnt                       ;счетчик

                   Fig0                      ;разряды 1-0 7сегм. (время)      

                   Fig1                      ;разряды 3-2 7сегм.          

                   Fig2                      ;точки       7сегм.        

                   IndVal                  ;слово в MC14489       

                   CntInd                  ;счетчик разрядов MC14489

          Temp1                 ;

                   Temp2                 ;

                   w_temp                ;переменная для хранения w

                   status_temp          ;переменная для хранения STATUS

          ENDC

 

Init_OPT     EQU   b'10000111'         ;настройка TMR0 

Init_PB        EQU   b'11010111'         ;биты 3,5 - вывод   

Init_PD      EQU   b'00000000'         ;все - вывод 

Init_PE        EQU   b'11111100'         ;биты 1,0 - вывод 

 

;------------------------------- Битовые переменные ------------------------------------

                   #define        RB1            PORTB,1              ;кнопка "-"

                   #define        RB2            PORTB,2              ;кнопка "+"

                   #define        Data_in       PORTE,1             ;сигналы MC14489                         #define        Clk              PORTE,0              ;      

                   #define        Cs               PORTB,3             ;

 

                   ORG           0x000                   ;вектор старта

                   nop

                   goto            Begin

 

;--------------------- Подпрограмма обработки прерывания----------------------------

                   ORG           0x004                   ;вектор прерывания

                   movwf        w_temp                ;сохранение контекста

                   movf           STATUS,w           

                   movwf        status_temp         

                  btfss           INTCON,T0IF     ;прерывание по переполнению TMR0?

                   goto            Ret                       ; нет

                   decfsz         CntT,f                  ;секунда прошла?

                   goto            Cf                        ; нет

                   movlw        .14

                   movwf        CntT                    ;загрузить счетчик переполнений

                   incf             Fig0,f                   ;инкремент секунд

                   call              Dysplay     

Cf               bcf              INTCON,T0IF     ;обнулить флаг прерывания

Ret                                                             ;завершить обработку прерывания

                   movf           status_temp,w      ;восстановление контекста

                   movwf        STATUS            

                   swapf          w_temp,f            

                   swapf          w_temp,w           

                   retfie                                       ; возврат из прерывания

 

;операторы подпрограммы отображ. 7сегм. символов Display     

;операторы подпрограммы инициализации MC14489 Control_MC14489         ;операторы подпрограммы задержки 15 мс  D15ms 

;===========================================================

Begin                                                         ;начало программы

clrf              INTCON              ;запретить все прерывания

 

;операторы инициализации портов, таймера, MC14489

          

                   clrf              Fig0                      ;инициализация ячеек

                   clrf              Fig1              

                   clrf              Fig2

                   clrf              Cnt   

                   movlw        .14

                   movwf        CntT                    ;загрузить счетчик переполнений

bsf              INTCON,GIE      ;разрешить прерывания

bsf              INTCON,T0IE     ;разрешить прерывания от TMR0

Main                                                          ;основной цикл

   

;операторы основного цикла    

           

                   goto                      Main                    

                   end

 

Полный текст программы сохранен в файле LR7.asm.

 

 

8 Программная реализация микропрограммного автомата

 

8.1 Описание задания

 

Необходимо разработать и кодировать на языке Ассемблера алгоритм программной реализации микропрограммного управляющего автомата.

На входные линии PORTE,2 и PORTA,5 МК поступает набор входных сигналов X=<x1,x2>. Текущие значения набора выходных сигналов Y=<y1,y2, y3,y4> формируются на линиях PORTD. Смена внутренних состояний автомата происходит при формировании положительного фронта внешнего сигнала Clk на линии PORTB,0. Микропрограммы заданы в форме граф-схемы алгоритма, варианты заданий  приведены в таблице 8.1.

 

8.2 Рекомендации по выполнению

 

Рассмотрим пример реализации управляющего автомата, выполняющего микропрограмму, заданную граф-схемой алгоритма (ГСА) на рисунке 8.1. На ГСА выполнена отметка состояний для построения автомата Мура, рядом представлен граф автомата Мура.

 

а)                                                                б)

Рисунок 8.1

 

Если в графе автомата преобладают условные переходы, то для программной реализации более рационально использовать табличный метод. Табличный метод реализует представление алгоритма автомата в форме таблицы переходов-выходов. Значения функций переходов и выходов автомата зависят от входных сигналов и внутреннего состояния sk. Каждому сочетанию входного набора X и кода текущего внутреннего состояния Qk можно поставить в соответствие код следующего состояния Qk+1 и текущий выходной набор Y. Общее число таких комбинаций составит 2n × Ns , где n - число входных сигналов, Ns - число состояний автомата.   

 

Таблица 8.1

Вариант 1

 

 

Вариант 2

Вариант 3

Вариант 4

Вариант 5

Вариант 6

 

Программная реализация этого метода сводится к формированию в зависимости от входного слова адреса, по которому в памяти находится соответствующее выходное слово. Под входным словом понимается конкатенация (результат соединения) входного набора и кода текущего состояния автомата (Qk , X). Под выходным словом понимается конкатенация кода следующего состояния автомата Qk+1 и соответствующего ему выходного набора Y.

Символьное представление функций переходов и выходов приведено в таблице 8.2.

 

Таблица 8.2

s

x2 x1

Y

00

01

10

11

s0

s1

s2

s1

s2

-

s1

s5

s5

s3

s3

y1

s2

s5

s5

s3

s3

y2

s3

s4

s4

s4

s4

y2y3

s4

s0

s0

s0

s0

y4

s5

s5

s5

s3

s3

y3

 

            Выполним кодирование внутренних состояний. Число разрядов кода внутренних состояний l определяется числом состояний автомата Ns

 

l = ent(log2Ns),

 

где ent – операция округления до ближайшего большего целого числа. Результат кодирования состояний приведен в таблице 8.3.

   

Таблица 8.3

s

q2

q1

q0

s0

0

0

0

s1

0

0

1

s2

0

1

0

s3

0

1

1

s4

1

0

0

s5

1

0

1

 

         Для экономии памяти целесообразно, чтобы выходные слова хранились в ячейках со смежными адресами. Поэтому для полностью определенного автомата и 2 l > Ns  сформируем входное слово в формате: 000 q2 q1 q0  x2 x1 . Для выходного слова используем формат  y4 y3 y2 y1   q2 q1 q0 0. Требуемое соответствие сформированных входных и выходных слов приведено в таблице 8.4.

Следует отметить, что позиции разрядов кода состояния во входном и выходном словах смещены на один разряд. Это необходимо учитывать при анализе кода текущего состояния автомата.

Таблица 8.4

Входное слово

000 q2 q1 q0  x2 x1

Выходное слово

y4 y3 y2 y1   q2 q1 q0 0

000 000 00

0001 001 0

000 000 01

0010 010 0

000 000 10

0001 001 0

000 000 11

0010 010 0

000 001 00

0100 101 0

000 001 01

0100 101 0

000 001 10

0110 011 0

000 001 11

0110 011 0

000 010 00

0100 101 0

000 010 01

0100 101 0

000 010 10

0110 011 0

000 010 11

0110 011 0

000 011 00

1000 100 0

000 011 01

1000 100 0

000 011 10

1000 100 0

000 011 11

1000 100 0

000 100 00

0000 000 0

000 100 01

0000 000 0

000 100 10

0000 000 0

000 100 11

0000 000 0

000 101 00

0100 101 0

000 101 01

0100 101 0

000 101 10

0110 011 0

000 101 11

0110 011 0

        

Система команд микроконтроллеров PIC оптимизирована для выполнения табличных вычислений. Для идентификаторов, определенных в директиве

 

CBLOCK   0x20    

                   InWord                ;входное слово конечного автомата

                   OutWord              ;выходное слово конечного автомата

                   ………………….

ENDC

 

алгоритм табличного вычисления выходного слова на языке ассемблера имеет вид

…………………..

StateMachine                                             ; конечный автомат

clrf              InWord

btfsc           PORTE,2             ; анализ линии x1

bsf              InWord,0             ;

btfsc           PORTA,5             ; анализ линии x2

bsf              InWord,1

rlf               OutWord,w          ; сдвиг влево

andlw          b'00011100'         ; маска кода состояния

iorwf           InWord,w            ; текущее входное слово

call              Tabl                     ;

movwf        OutWord              ; текущее выходное слово

movwf        PORTD              

…………………..

 

Tabl            addwf         PCL,f                   ;смещение в таблице

retlw            b'00010010'         ;первый элемент таблицы s0->s1

…………………..

retlw            b'01100110'         ;последний элемент таблицы s5->s3

 

При разработке программы следует следить, чтобы при вычислении адреса ячейки таблицы не происходило переполнение. Если это возможно, то следует позаботиться о размещении первого элемента таблицы. Максимально возможный объем таблицы значений – 256 ячеек.

В соответствии с заданием переходы автомата должны выполняться по фронту сигнала Clk. Поэтому приведенный участок кода должен выполняться при изменении потенциала на соответствующей линии порта ввода. Возможен программный опрос этой линии или обработка прерывания. 

 

Список использованных источников

 

1 PIC16F87X [Электронный ресурс]: Техническое описание. – М.: ООО «Микро-Чип», 2001. – 61 с. – Режим доступа : WWW.URL : http: // www.microchip.ru/. – 27.06.2008.

2 MPASM [Электронный ресурс]: Руководство пользователя. – М.: ООО «Микро-Чип», 2001. – 183 с. – Режим доступа: WWW.URL: http: // www.microchip.ru/. – 27.06.2008.

 

 

Приложение А

Система команд МК PIC16F87X

 

Мнемоника

Описание

Циклов

Флаги

ADDWF

f,d

Сложение W и f

1

C,DC,Z

ANDWF

f,d

Побитное 'И' W и f

1

Z

CLRF

f

Очистить f

1

Z

CLRW

-

Очистить W

1

Z

COMF

f,d

Инвертировать f

1

Z

DECF

f,d

Вычесть 1 из f

1

Z

DECFSZ

f,d

Вычесть 1 из f и пропустить если 0

1(2)

 

INCF

f,d

Прибавить 1 к f

1

Z

INCFSZ

f,d

Прибавить 1 к f и пропустить если 0

1(2)

 

IORWF

f,d

Побитное 'ИЛИ' W и f

1

Z

MOVF

f,d

Переслать f

1

Z

MOVWF

f

Переслать W в f

1

 

NOP

-

Нет операции

1

 

RLF

f,d

Циклический сдвиг f влево через перенос

1

C

RRF

f,d

Циклический сдвиг f вправо через перенос

1

C

SUBWF

f,d

Вычесть W из f

1

C,DC,Z

SWAPF

f,d

Поменять местами полубайты в регистре f

1

 

XORWF

f,d

Побитное 'исключающее ИЛИ' W и f

1

Z

BCF

f,b

Очистить бит b в регистре f

1

 

BSF

f,b

Установить бит b в регистре f

1

 

BTFSC

f,b

Проверить бит b в регистре f, пропустить

если 0

1(2)

 

BTFSS

f,b

Проверить бит b в регистре f, пропустить

1 если

1(2)

 

ADDLW

k

Сложить константу с W

1

C,DC,Z

ANDLW

k

Побитное 'И' константы и W

1

Z

CALL

k

Вызов подпрограммы

2

 

CLRWDT

-

Очистить WDT

1

-TO,-PD

GOTO

k

Безусловный переход

2

 

IORLW

k

Побитное 'ИЛИ' константы и W

1

Z

MOVLW

k

Переслать константу в W

1

 

RETFIE

-

Возврат из подпрограммы с разрешением

прерываний

2

 

RETLW

k

Возврат из подпрограммы с загрузкой

константы в W

2

 

RETURN

-

Возврат из подпрограммы

2

 

SLEEP

-

Перейти в режим SLEEP

1

-TO,-PD

SUBLW

k

Вычесть W из константы

1

C,DC,Z

XORLW

k

Побитное 'искл. ИЛИ' константы и W

1

Z

 

Скачать: pz_os_mps.doc

Категория: Методички

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.