Написання ночаткового тексту програми здійснюється за допомогою редактора Editor Only, наявного в складі інтегрованого середовища MPLAB 3.30. Для того, щоб ввійти в оболонку редактора, необхідно виконати наступні дії:
1. Здійснити запуск основного пакета програм (вибравши в головному меню інтегрованого середовища іконку з написом MPLAB);
2. Вибрати в меню користувача пакетом MPLAB 3.30 пункт Option;
3. Вибрати в меню Option опцію Development Mode... і в ній задати режим «Editor Only», а також тип процесора PIC 16C84 (16F84);
4. Натиснути кнопку з написом RESET (що дозволить запам'ятати нашу зміну);
5. Вибрати в меню користувача пакетом MPLAB пункт File;
6. Вибрати в меню File опцію New Source.
Після цього можна розпочати написання початкового тексту програми. Причому, у початковому тексті програми свідомо зробимо деякі помилки, які необхідно буде виявити і усунути на етапах трансляції і відлагодження програми за допомогою Асемблера MPASM і симулятора MPLAB-SIM.
Початковий текст програми в цьому випадку має наступний вигляд:
LIST P=PIC16C84
; Секція заголовка
TMR0 EQU 01H
STATUS EQU 03H
PORTA EQU 05H
PORTB EQU 06H
INTCON EQU 0BH
TRISA EQU 05H
TRISB EQU 06H
; Опис бітів регістра STATUS
C EQU 00H
DC EQU 01H
Z EQU 02H
PD EQU 03H
TO EQU 04H
RP0 EQU 05H
RP1 EQU 06H
IRP EQU 07H
; Опис бітів регістра INTCON
RBIF EQU 00H
INTF EQU 01H
TOIF EQU 02H
RBIE EQU 03H
INTE EQU 04H
TOIE EQU 05H
EEIE EQU 06H
GIE EQU 07H
; Опис бітів порту В
RB0 EQU 00H
RB1 EQU 01H
RB2 EQU 02H
RB3 EQU 03H
RB4 EQU 04H
RB5 EQU 05H
RB6 EQU 06H
RB7 EQU 07H
; Опис бітів порту А
RA0 EQU 00H
RA1 EQU 01H
RA2 EQU 02H
RA3 EQU 03H
RA4 EQU 04H
; Робоча секція
; Початок частини робочої програми, що виконується
ORG 00H ; Наступна команда буде розташована
;за адресою 00H
GOTO BEGIN
ORG 004H ; Вказуємо адресу комірки
; пам'яті програм 004Н, куди здійснюється перехід при виникненні
; переривання. В нашому випадку це переривання при переповненні
; лічильника таймера tmr0
INCF TMR1, 1 ; Зменшимо лічильник
;TMR1 при виникненні кожного чергового переривання від TMR0. В
;результаті таких дій отримаємо двобайтне число, що зберігається в
;регістрах tmr0 і tmr1. Причому старша частина числа знаходиться в
;регістрі tmr1, а молодша - в регістрі tmr0. Дане число відповідає
;кількості тактів нашого мікроконтролера, що пройшли між імпульсами.
CLRF TMR0 ; Скидаємо значення регістра
; tmr0
BCF INTCON, TOIF ; Скидаємо прапорець TOIF, який
; указує на те, що було переривання
; по переповненню лічильника
; таймера tmr0
RETFIE ; Виходимо з процедури обробки
; переривання від таймера з
; дозволом переривань.
; Тобто, установлюємо біт ; gie в регістрі intcon. Це виконується
; автоматично за командою retfie.
; Далі розміщується текст основної програми
BEGIB ; Мітка BEGIN
CALL INIT ; Викликаємо процедуру для
; ініціалізації портів і переривань
POVTOR BTFSC PORTA, PA1 ; Чекаємо початок імпульсу,
; тобто передній фронт імпульсу
GOTO POVTOR
BCF INTCON, TOIF ; Скидаємо прапорець переривання
; від таймера
BSF INTCON, TOIE ; Дозволяємо переривання по
; факту переповнення
; лічильника таймера
POVTOR_1 BTFSS PORTA, PA1 ; Чекаємо задній фронт першого
; імпульсу, тобто кінець першого
; імпульсу
GOTO POVTOR
POVTOR_2 BTFSC PORTA, PA1 ; Чекаємо передній фронт
; другого імпульсу (тобто його
; початок)
GOTO POVTOR_2
BCF INTCON, TOIE ; Забороняємо переривання по
; факту переповнення лічильника
; таймера
CALL PERED ; Викликаємо процедуру
; передачі інформації
GOTO POVTOR ; Повторюємо вимір
PERED MOVF TMR0, 0 ; Передаємо в порт В
; значення регістра TMR0
MOVWF PORTB
BSF PORTA, PA0 ; Встановлюємо прапорець передачі
NOP ; Організуємо затримку
NOP
NOP
BCF PORTA, PA0 ; Скидаємо прапорець передачі
MOVF TMR1, 0 ; Передаємо в порт В
; значення регістра tmr1
MOVWF PORTB
BSF PORTA, PA0 ; Встановлюємо прапорець
; передачі
NOP ; Організуємо затримку
NOP
NOP
BCF PORTA, PA0 ; Скидаємо прапорець
; передачі
; Вихід з процедури передачі
INIT BSF STATUS, RP0 ; Встановлюємо активною
; другу сторінку пам'яті
MOVLW B'00000010' ; Встановлюємо напрямки
; роботи виводів порту А.
; В даному випадку вивід ra1 буде
; працювати на введення, а інші
; на виведення
MOVWF TRISA
MOVLW B'00000000' ; Встановлюємо напрямки
; роботи виводів порту В.
; Всі виводи порту працюють в
; даному випадку на виведення
; інформації
MOVWF TRISB
BSF 1.5 ; Встановлюємо виходи генера-
; тора і переддільника на таймер
BCF STATUS, RP0 ; Знов робимо активною першу
; сторінку
BCF PORTA, PA0 ; Встановлюємо на виводі
; ra1 нульовий рівень
RETURN ; Кінець процедури ініціалізації
END
; Кінець програми.
Після написання програми зберігаємо її під будь-яким ім'ям. Для цього необхідно вибрати меню FILE і вибрати підменю SAVE AS..., після чого Вас попрохають ввести ім'я файлу з розширенням. За замовчуванням (якщо немає розширення) система автоматично додасть розширення ASM. Збережемо наш файл, наприклад, з ім'ям OUR. ASM.
4.7.3. Перетворення вхідного тексту програми
в об'єктний код
Тепер почнемо створювати об'єктний код (модуль) нашої програми. Для цього ввійдемо в меню PROJECT і вибиремо підменю NEW PROJECT. Після цього у Вас попросять ввести наступну інформацію:
· PROJECT PATH AND NAME – вказати шлях до пошуку
об'єкту і його ім'я.
Пишемо: C:MPLABOUR. PJT
· DEFAULT TOOLBAR – вибрати зовнішній вигляд оболонки.
Залишаємо без змін.
· DEFAULT KEY MAPPING – вказати файл переназначення
функцій клавіш.
Залишаємо без змін.
· DEVELOPMENT MODE – вибрати середовище (режим)
для відлагодження програми.
Вибираємо MPLAB-SIM SIMULATOR і натискаємо кнопку OK.
Після цих дій перед Вами з'явиться вікно EDIT PROJECT, де від Вас вимагається вибрати файл програми, що увійшла в даний проект. В нашому прикладі беремо зі списку NON-PROJECT FILES файл з ім'ям OUR. ASM, вибираємо кнопку <=ADD і натискаємо кнопку ОК.
Тепер вибираємо в меню PROJECT підменю BUILD ALL. Після чого починається компіляція нашої програми.
Після цих дій ми побачимо вікно з ім'ям MPASM v02.00, в якому міститься наступна інформація:
* Зверху перший рядок вказує на наявність помилок. В нашому випадку вони є, тому з'являється наступне повідомлення:
- ERRORS FOUND і червона лінія 100 %;
· Кількість помилок – ERRORS: 12;
· Кількість описок – WARNINGS:
– REPORTED: 1;
– SUPPRESSED: 0;
· Кількість повідомлень:
– REPORTED: 0;
– SUPPRESSED: 0;
· Всього рядків – (LINE ASSEMBLED): 132.
Після цього з'явиться вікно з ім'ям COMPILE STATUS, що містить наступну інформацію:
STATUS: THERE ARE ERRORS
COMMAND LINE:
MPASMWIN/e/l/ainhx8m/q c:mplabour. asm
Це вікно інформує чи були помилки при компіляції. В нашому випадки вони були.
Вибираємо кнопку OK.
Так як були помилки, то система автоматично відкриває вікно з файлом помилок, що генерує MPASM. Тепер, послідовно аналізуючи повідомлення в файлі помилок, будемо виправляти помилки у вхідному тексті програми:
1. Warning [207] C:MPLABOUR. ASM 36: Found label after column 1. (RB7).
В цьому повідомленні про помилку сказано наступне (див. п. 2.5.2.): ПОПЕРЕДЖЕННЯ, [код помилки – 207], шлях до файлу (місце розташування й ім'я програми) – C:MPLABOUR. ASM, номер рядка (в якому виявлена помилка) – 36: коментар до помилки (тобто, в чому полягає помилка) - ЗНАЙДЕНА МІТКА ПІСЛЯ РЯДКА 1. (RB7).
Звертаємось до рядка №36:
RB7 EQU 07H
Дана помилка зв'язана з пробілами на початку рядка, бо асемблер не знає команди RB7.
Наші дії: Прибираємо пробіли на початку рядка.
2. Error [113] C:MPLABOUR. ASM 47: Symbol not previously defined (BEGIN)
В цій помилці говориться: СИМВОЛ НЕВИЗНАЧЕНИЙ (BEGIN)
Дивимось в нашій програмі рядок № 47:
GOTO BEGIN ; Перехід на мітку
Отже, ми визначили мітку BEGIN, але чому ж помилка? Дивлячись програму, ми побачимо, що в рядку № 69 написано:
BEGIB ; МІТКА BEGIN
Тобто, ми написали замість BEGIN-> BEGIB.
Значить потрібно виправити цю описку.
3. Error [113] C:MPLABOUR. ASM 52: Symbol not previously defined (TMR1).
В цій помилці говориться: СИМВОЛ НЕВИЗНАЧЕНИЙ (TMR1).
Перевіряємо опис регістрів в секції заголовка. При цьому з'ясовується, що там взагалі немає опису регістрів пам'яті даних (ОЗУ).
Тому в секцію заголовка додамо опис регістра TMR1, розмістивши його, наприклад, за адресою 0CH в пам'яті даних:
TMR1 EQU 0CH
4. Error [113] C:MPLABOUR. ASM 73: Symbol not previously defined (PA1).
В цій помилці говориться: СИМВОЛ НЕВИЗНАЧЕНИЙ (PA1).
Перевіряємо опис регістрів в секції заголовка і побачимо, що біти порту А визначені під іменами RA0, RA1, RA2, RA3, RA4, а в програмі використовуємо імена РА0, РА1, PA2, PA3, PA4.
Робимо відповідні зміни в програмі.
5. Error [113] C:MPLABOUR. ASM 81: Symbol not previously defined (PA1).
В цій помилці говориться: СИМВОЛ НЕВИЗНАЧЕНИЙ (PA1), тому виконуємо такі ж дії, як і в п. 4.
6. Error [113] C:MPLABOUR. ASM 85: Symbol not previously defined (PA1).
В цій помилці говориться: СИМВОЛ НЕВИЗНАЧЕНИЙ (PA1), тому виконуємо такі ж дії, як і в п. 4.
7. Error [113] C:MPLABOUR. ASM 97: Symbol not previously defined (PA0).
В цій помилці говориться: СИМВОЛ НЕВИЗНАЧЕНИЙ (PA0), тому виконуємо такі ж дії, як і в п. 4.
8. Error [113] C:MPLABOUR. ASM 101: Symbol not previously defined (PA0).
В цій помилці говориться: СИМВОЛ НЕВИЗНАЧЕНИЙ (PA0), тому виконуємо такі ж дії, як і в п. 4.
9. Error [113] C:MPLABOUR. ASM 102: Symbol not previously defined (TMR1).
В цій помилці говориться: СИМВОЛ НЕВИЗНАЧЕНИЙ (TMR1). Ця помилка вже виправлена в п. 3.
10. Error [113] C:MPLABOUR. ASM 105: Symbol not previously defined (PA0).
В цій помилці говориться: СИМВОЛ НЕВИЗНАЧЕНИЙ (PA0), тому виконуємо такі ж дії, як і в п. 4.
11. Error [113] C:MPLABOUR. ASM 109: Symbol not previously defined (PA0).
В цій помилці говориться: СИМВОЛ НЕВИЗНАЧЕНИЙ (PA0), тому виконуємо такі ж дії, як і в п. 4.
12. Error [122] C:MPLABOUR. ASM 112: Illegal opcode (ДРУГА).
В цій помилці говориться: НЕВІДОМА КОМАНДА (ДРУГА).
Дивимось на рядок № 114:
INIT BSF STATUS, RP0 ; Встановлюємо активною
другу сторінку пам'яті
Виявляється, що ми забули поставити знак коментаря (;) на початку 115-го рядка.
Робимо відповідні зміни у початковому тексті програми.
13. Error [113] C:MPLABOUR. ASM 127: Symbol not previously defined (PA0).
В цій помилці говориться: СИМВОЛ НЕВИЗНАЧЕНИЙ (PA0), тому виконуємо такі ж дії, як і в п. 4.
Тепер, коли немовби виправили всі помилки, запускаємо програму, що відкоректована на компіляцію знову.
Тепер все відкомпілювалось без помилок. Після цього, в принципі, можна було б записати відкомпільовану програму в ППЗП мікроконтролера. Однак, більш доцільно спочатку промоделювати і відлагодити роботу програми за допомогою, наприклад, програмного симулятора MPLAB-SIM, наявного в складі інтегрованого середовища MPLAB 3.30.
4.7.4. Відлагодження програми
Для використання симулятора необхідно зробити наступні операції:
– Вибрати в головному меню пункт OPTION;
– Вибрати опцію DEVELOPMENT MODE;
– Вибрати MPLAB-SIM Simulator і тип мікроконтролера PIC16C84;
– Вибрати кнопку RESET, після чого Вас попросять зберегти наш проект і завантажиться симулятор.
Після цього здійснюємо наступні дії:
– Вибираємо в меню PROJECT і завантажуємо наш проект;
– Вибираємо в меню DEBUG-RUN-RESET;
– Вибираємо в меню DEBUG-RUN-STEP для покрокового виконання нашої програми.
Тепер наша програма якось виконується, але для остаточного відлагодження потрібно задати рівні сигналів на виводах мікроконтролера. Для цього скористаємось текстовим редактором (будь-яким) і створимо наступний файл стимулу (файл для емуляції рівнів сигналів на виводах мікроконтролера):
OUR. STI
STEP RA0
25 0
30 1
100 0
105 1
115 0
В цьому файлі STEP – значення лічильника циклів у симуляторі, а RA0 – вивід порту нашого мікроконтролера.
Запускаємо на виконання програму наступним чином:
– Вибираємо в меню DEBUG-RUN-RESET;
– Вибираємо в меню DEBUG-SIMULATOR STIMULUS-PIN STIMULUS-ENABLE;
– Вводимо ім'я нашого файлу OUR.STI;
– Вибираємо в меню DEBUG-RUN-STEP для покрокового виконання нашої програми.
Для спостереження значень регістрів скористаємось функцією WATCH. Для цього вибираємо WINDOW NEW WATCH і вводимо імена регістрів, що нас цікавлять:
TMR0, TMR1, PORTA, PORTB, TRISA, TRISB.
Тепер, виконуючи нашу програму, перевіряємо логіку її роботи і виявляємо наступні помилки:
– в рядку 83 ім'я мітки, куди необхідно переходити, повинно бути POVTOR_1;
– в рядку 112 пропущена інструкція RETURN.
4.7.5. Лістинг відлагодженої програми
Отже, наша програма працює і остаточний вигляд її наступний:
LIST P=PIC16C84
; Секція заголовка
TMR0 EQU 01H
STATUS EQU 03H
PORTA EQU 05H
PORTB EQU 06H
INTCON EQU 0BH
TRISA EQU 05H
TRISB EQU 06H
; Опис бітів регістра STATUS
C EQU 00H
DC EQU 01H
Z EQU 02H
PD EQU 03H
TO EQU 04H
RP0 EQU 05H
RP1 EQU 06H
IRP EQU 07H
; Опис бітів регістра INTCON
RBIF EQU 00H
INTF EQU 01H
TOIF EQU 02H
RBIE EQU 03H
INTE EQU 04H
TOIE EQU 05H
EEIE EQU 06H
GIE EQU 07H
; Опис бітів порту В
RB0 EQU 00H
RB1 EQU 01H
RB2 EQU 02H
RB3 EQU 03H
RB4 EQU 04H
RB5 EQU 05H
RB6 EQU 06H
RB7 EQU 07H
; Опис бітів порту А
RA0 EQU 00H
RA1 EQU 01H
RA2 EQU 02H
RA3 EQU 03H
RA4 EQU 04H
; Опис регістрів пам'яті даних (ОЗУ)
TMR1 EQU 0CH
;
; Робоча секція
; Початок частини робочої програми, що виконується
ORG 00H ; Наступна команда буде
; розташована за адресою 00H
GOTO BEGIN
ORG 004H ; Вказуємо адресу комірки
;пам'яті програм 004Н, куди здійснюється перехід при виникненні ;переривання. В нашому випадку це переривання при переповненні ;лічильника таймера tmr0
INCF TMR1, 1 ; Зменшимо лічильник TMR1
;при виникненні кожного чергового переривання від TMR0. В результаті ;таких дій отримаємо двобайтне число, що зберігається в регістрах tmr0 і ;tmr1. Причому старша частина числа знаходиться в регістрі tmr1, а ;молодша – в регістрі tmr0. Дане число відповідає кількості тактів нашого ;мікроконтролера, що пройшли між імпульсами.
CLRF TMR0 ; Скидаємо значення регістра tmr0
BCF INTCON, TOIF ; Скидаємо прапорець TOIF,
; що вказує на те, що було
; переривання по переповненню
; лічильника таймера tmr0
RETFIE ; Виходимо з процедури обробки
;переривання таймера з дозволом
;переривань. Тобто, установлюємо біт gie
;в регістрі intcon. Це виконується ;автоматично за командою retfie.
; Далі розташовується текст основної програми
BEGIN ; Мітка BEGIN
CALL INIT ; Викликаємо процедуру для
; ініціалізаціі портів і переривань
POVTOR BTFSC PORTA, RA1 ; Чекаємо початок імпульсу,
; тобто передній фронт імпульсу
GOTO POVTOR
BCF INTCON, TOIF ; Скидаємо прапорець переривання від таймера
BSF INTCON, TOIE ; Дозволяємо переривання по
; факту переповнення
; лічильника таймера
POVTOR_1 BTFSS PORTA, RA1 ; Чекаємо задній фронт першого
; імпульсу, тобто кінець першого
; імпульсу
GOTO POVTOR
POVTOR_2 BTFSC PORTA, RA1 ; Чекаємо передній фронт
; другого імпульсу (тобто його
; початок)
GOTO POVTOR_2
BCF INTCON, TOIE ; Забороняємо переривання по
; факту переповнення лічильника
; таймера
CALL PERED ; Викликаємо процедуру
; передавання інформації
GOTO POVTOR ; Повторюємо вимір
PERED MOVF TMR0, 0 ; Передаємо в порт В значення
; регістра TMR0
MOVWF PORTB
BSF PORTA, RA0 ; ;Встановлюємо ;прапор передачі
NOP ; Організуємо затримку
NOP
NOP
BCF PORTA, RA0 ; Скидаємо прапорець передачі
MOVF TMR1, 0 ; Передаємо в порт В значення Рг tmr1
MOVWF PORTB
BSF PORTA, RA0 ; Встановлюємо прапорець передачі
NOP ; Організуємо затримку
NOP
NOP
BCF PORTA, RA0 ; Скидаємо прапорець передачі
; Вихід з процедури передачі
INIT BSF STATUS, RP0 ; Встановлюємо активною другу
; сторінку пам'яті
MOVLW B'00000010' ; Встановлюємо напрямки
; роботи виводів порту А.
; В даному випадку вивід ra1
; буде працювати на введення,
; а інші на виведення
MOVWF TRISA
MOVLW B'00000000 ; Встановлюємо напрямки
; роботи виводів порту В. В
; В даному випадку всі виводи порту
; працюють на виведення інформації;
MOVWF TRISB
BSF 1.5 ; Встановлюємо виходи генератора
BCF STATUS, RP0 ; Знову робимо активною першу
; сторінку
BCF PORTA, RA0 ; Встановлюємо на виводі ra1
; нульовий рівень
RETURN ; Кінець процедури ініціалізації
END
; Кінець всієї нашої програми
4.7.6. Запис програми в ППЗУ мікроконтролера PIC 16F84 (16С84)
Для запису відлагодженої програми в ППЗУ мікроконтролера PIC 16F84 необхідно знову здійснити її компіляцію, вибрати файл з ім'ям OUR. HEX і передати його в програматор.
За наявності під’єднаного до IBM PC програматора PICSTART запис відлагодженої програми в мікроконтролер можна здійснити, не виходячи з оболонки пакета MPLAB 3.30. Для цього необхідно скористатися опцією Picstart Plus в меню основного пакета програм (див. п. 3.6.5).
За відсутності PICSTARTa можна скористатися будь-яким з наступних типів програматорів: COMPIC, PROPIC, PICLAB-16, LEAPER-6 або PROMATE. Для цього необхідно вийти з оболонки інтегрованого пакета і запустити відповідну програму (драйвер), що підтримує наявний у розробника програматор.
Всі зазначені вище програматори мають різноманітні за складністю схеми і функціональні можливості. Але, всі вони розраховані на використання ПЕОМ типу IBM PC і під’єднуються за допомогою послідовних інтерфейсів типу I2C і RS-232C, або через паралельний принтерний порт за допомогою інтерфейсу Centronics.
___________