Основы работы в среде MPLAB


После загрузки программы появляется рабочее окно.



Рис.19


Вид программы обычен для Windows, и, думаю, не требует особых пояснений.

Первое, что мы сделаем, создадим новый проект, в основном меню Project-New. Задаем название проекту relay, в папке, например, Relay, которую я советую открыть в основном разделе диска в папке MPLAB. Неоднократно я сталкивался с проблемой, которая не всегда очевидна. Многие программы, да это и удобно, предлагают хранить проект в папке «Мои документы». Проблема не возникает, если вы пользуетесь англоязычной версией Windows или русскоязычной версией программы. Но многие специализированные англоязычные программы начинают вытворять чудеса, если вы работаете в русскоязычной версии операционной системы. Впервые я столкнулся с этим, когда одна из сред программирования при компиляции программы стала выдавать ошибку в строке -1. Что она имела в виду под строкой с отрицательным номером, я не знаю. Но отыскать ошибку в правильно написанной программе оказалось не так просто. Ошибка крылась в том, что программа, предлагая через операционную систему сохранить проект в папке «Мои документы», эту папку распознать не могла.


После создания нового проекта появляется окно навигатор проекта. Теперь выберем микросхему контроллера в разделе основного меню Configure-Select Device. Выбираем PIC16F628A.

Выглядит это, примерно, так:



Рис.20

Завершив выбор, следует создать файл основной программы. Выбираем File-New. Появляется окно редактора. Сохраним файл под именем relay.asm (File-Save As).



Рис.21

Далее добавим этот файл в проект. Для этого щелкнем правой кнопкой мыши по разделу Source Files в окне навигатора. В открывшемся меню выбираем Add Files, и указываем свой файл.

Для начала перенесем в окно редактора (прямым копированием из текста), небольшой фрагмент программы: инициализация, плюс сама программа, плюс две подпрограммы CALL adrsim и CALL cmnd. Последние в усеченном виде. Адрес будем использовать в данный момент «01». Не забудем поставить END в конце программы.

adrsim: CLRW ; Если адрес 1 запишем символы «0» «1» (30h и 31h)

ADDLW 0x30

MOVWF 0x21

CLRW

ADDLW 0x31

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0x1

BTFSC STATUS, Z

RETURN


cmnd: BCF STATUS, Z

MOVF RCREG, 0

XORLW 0x52 ; Проверим наш ли модуль R (52h)

BTFSS STATUS, Z ; Если нет, вернемся

RETURN

in1: BTFSS PIR1, RCIF ; Ждем прихода первого символа адреса

GOTO in1 ; Если совпадает, продолжим

MOVF RCREG, 0

BCF STATUS, Z

XORWF 0x21, 0 ; Первый символ адреса, запомненный в регистре 21h.

BTFSS STATUS, Z

RETURN

in2: BTFSS PIR1, RCIF ; Ждем прихода второго символа адреса

GOTO in2 ; Если совпадает, продолжим

MOVF RCREG, 0

BCF STATUS, Z

XORWF 0x22, 0 ; Второй символ адреса, запомненный в регистре 22h.

BTFSS STATUS, Z

RETURN

Для отладки откроем окно наблюдения View-Watch, в котором выберем регистры STATUS, WREG, PIR1, EEDATA, RCREG, 20h, 21h, 22h, 30h. Необходимые регистры открываются кнопкой с обозначением стрелки вниз, правее названия регистра, которое, в свою очередь, рядом с кнопочкой ADD SFR. Ее следует нажать после выбора регистра.



Рис.22

Регистры без имени (20h, 21h и т.д.) мы добавляем, просто вводя адрес в колонку Address на новой строке.

Добавим и EEPROM через выбор View - EEPROM. Установим в качестве симулятора программный (Debugger-Select Tool-MPLAB SIM). Создадим два файла input.txt и output.txt (File-New). В файле input.txt, который открывается в окне редактора, запишем слово команды “R01$” в виде строки в кавычках. Сохраним этот файл (File-Save). Теперь сделаем установки отладчика (Debugger-Settings…): частоту процессора зададим 4 мГц, на вкладке Uart1 IO установим опцию Enable Uart1 IO, укажем входной файл input.txt (browse) и выходной output.txt. Подтвердим замену последнего файла, и установим опцию Rewind Input. Изменим значение на вкладке Animation/Realtime на 1 мс. Все это будет выглядеть, как на рисунке 24. Нажмем «Применить» и «ОК». Включим в наши окна View-Output. Создадим новый сценарий, который позволит нам ввести адрес, имитируя переключатель. Для этого выберем в основном меню Debugger-Stimulus Controller-New Scenario. Выберем нужный нам RB4 в окне Pin/SFR. В окне Action выберем Set High. Нажмем кнопочку со стрелкой вправо рядом с этим в колонке Fire. Сохраним сценарий под именем relay и свернем его (не покинем, а свернем!). Теперь откроем окно (Configure-Configuration Bits), где установим биты, записываемые по адресу 2007h. Слово должно получиться 3F1Ah. Закроем это окно.



Рис.23

В завершение упорядочим окна (Windows-Tile Horizontally), сохраним все (File-Save All), и добавим в проект файл todo.txt, который предварительно создадим, а в менеджере проекта поместим его в раздел Other Files. В файле todo.txt будем вести план работы.

Теперь откомпилируем проект Project-Build All. Сохраним и вид проекта FileSave Workspace. Мы готовы к отладке программы.

После выхода из программы MPLAB, и подтверждения сохранения вида проекта, новой загрузки программы и открытия проекта (Project-Open) мне приходится обнулять адрес 0h в EEPROM, нажимать Fire в Scenario, и вводить адреса 20h, 21h и т.д. в окне Watch, которые программа пишет Not Found. Я не уверен, что дернул за все веревочки, но…

Если вы правильно перенесли программу, то, нажав на инструментальной панели кнопочку обозначенную ►► вы увидите анимацию, а в регистре RCREG (приемный регистр USART) появятся шестнадцатеричные коды символов из строки файла input.txt. Можно вписать в ячейку по адресу 0h EEPROM значение 1h, и увидеть, как она переписывается в регистр 30h.

Есть еще несколько полезных возможностей. Одна из них проверить работу с некоторого места. Для этого остановим анимацию (кнопочкой ▌▌), установим курсор к нужной строке и нажмем правую клавишу мышки. Выберем в выпадающем меню Set PC at Cursor. Теперь, нажимая значок Step Into{¬}, мы можем отследить все изменения.

В окончательном виде я работаю в среде, которая выглядит так:



Рис.24

Кроме написания программы на ассемблере, среда MPLAB поддерживает написание программ на языке «C». Существуют компиляторы разных производителей. Я использую демонстрационную версию кросс-компилятора Hi-Tech. Посмотрим, не будет ли проще написать предыдущую программу на языке «С»?

Релейный модуль, версия программы на языке «С»

Выбор языка программирования происходит при задании в Project-Select Language Toolsuite:



Рис.25

Создадим файл заголовка и основной файл. Добавим в файлы заголовка нужный нам контроллер. Остальная часть работы мало, чем отличается от работы на ассемблере. В программе я не сохраняю состояние реле в EEPROM. В окончательном виде файл заголовка:

#define MODULNAMESIM 'R'

#define CMDSIM '$'

#define bitset(var,bitno) ((var) |= 1 << (bitno))

#define bitclr(var,bitno) ((var) &= ~(1 << (bitno)))

void putch(unsigned char);

unsigned char getch(void);

int init_comms();

int sim_num_adr();

int cmd();

int rel_on(int num);

int rel_off(int num);

int rel_stat(int num);

Основной файл:

#include <pic16f62xa.h>

#include <stdio.h>

#include "reley_c.h"

unsigned char input; // Считываем содержимое приемного регистра

unsigned char MOD_SIM1; // Первый символ адреса модуля

unsigned char MOD_SIM2; // Второй символ адреса модуля

unsigned char REL_SIM; // Символ реле

unsigned char COMMAND; // Символ команды

int MOD_ADDR; // Заданный адрес модуля, как число

int sim1_num = 0;

int sim2_num = 0;

int sim_end_num = 0;

int MOD_NUM; // Полученный адрес модуля, как число

int REL_NUM; // Номер реле

int RELSTAT = 0; // Статус реле (позиционно): 1 - вкл, 0 - выкл.

/* Получение байта */

unsigned char getch()

{

while(!RCIF) // Устанавливается, когда регистр не пуст

continue;

return RCREG;

}


/* вывод одного байта */

void putch(unsigned char byte)

{

PORTB = 1; // Переключим драйвер RS485 на передачу

TXEN = 1; // Разрешаем передачу

while(!TXIF) // Устанавливается, когда регистр пуст

continue;

TXREG = byte;

}


/* Преобразуем символьный адрес в число*/

int sim_num_adr()

{

sim_end_num = 0;

sim1_num = getch(); // Чтение первого символа номера

MOD_SIM1 = sim1_num; // Сохраним первый символ

sim2_num = getch(); // Чтение второго символа номера

MOD_SIM2 = sim2_num; // Сохраним второй символ

sim1_num = sim1_num - 0x30; // От первого символа к числу

sim2_num = sim2_num - 0x30; // От второго символа к числу

sim_end_num = sim1_num*0x0A + sim2_num; // Объединим в одно число

return sim_end_num;

}


/* Получение и выполнение команды */

int cmd()

{

input = getch();

REL_NUM = input; // Номер реле в символьном виде

REL_SIM = REL_NUM;

REL_NUM = REL_NUM - 0x30; // Номер реле в числовом виде


switch (COMMAND = getch()) // Прочитаем команду

{

case 'N': rel_on(REL_NUM); // Если команда включить

break;

case 'F': rel_off(REL_NUM); // Если команда выключить

break;

case 'S': rel_stat(REL_NUM); // Если команда передать состояние

break;

}

}


/* Выполнение команды включения заданного реле */

int rel_on(int num)

{

bitset (RELSTAT, REL_NUM); // В переменной RELSTAT побитовое состояние реле

PORTA = RELSTAT; // Установив бит, переписываем в порт А

}


/* Выполнение команды выключения заданного реле */

int rel_off(int num)

{

bitclr (RELSTAT, REL_NUM);

PORTA = RELSTAT; // Сбросив бит, переписываем в порт А

}


/* Выполнение команды передачи состояния заданного реле */

int rel_stat(int num)

{

putch('R'); // Отправляем символ R

putch(MOD_SIM1); // Первый символ номера модуля

putch(MOD_SIM2); // Второй символ номера модуля

putch('#'); // Символ статуса

putch(REL_SIM); // Символ номера реле

if ((RELSTAT>>REL_NUM)&0x01) putch('N'); // Проверяем, установлен ли бит?

if (!((RELSTAT>>REL_NUM)&0x01)) putch('F'); // Проверяем, сброшен ли бит?

putch(0x0A); // Только для вывода в файл!!!!!!

}


int init_comms() // Инициализация модуля

{

PORTA = 0x0; // Настройка портов А и В

CMCON = 0x7;

TRISA = 0x80;

TRISB = 0xF6;


RCSTA = 0x90; // Настройка приемника

TXSTA = 0x4; // Настройка передатчика

SPBRG = 0x16; // Настройка режима приема-передачи


INTCON=0; // Запретить прерывания

PORTB = 0; // Выключим передатчик драйвера RS485

}


void main(void)

{

/* Инициализация модуля */

init_comms();

/* Прочитаем и преобразуем номер модуля */

MOD_ADDR = PORTB; // Номер модуля в старших битах

MOD_ADDR=MOD_ADDR>>4; // Сдвинем на четыре бита

/* Начинаем работать */

start: input = getch();

while(input != MODULNAMESIM) input = getch(); // Ждем, если не наш модуль

MOD_NUM = sim_num_adr(); // Чтение из сети (файла)

if (MOD_NUM == MOD_ADDR) // Если наш адрес модуля

{

input = getch();

if (input == CMDSIM) cmd(); // Если символ команды

}

goto start;

}


Это не шедевр программы на языке «С», но, вроде бы, работает. В качестве входного файла команд я использовал input.txt (примечания, которые я сделал, только для книжного варианта, в файле их делать не следует) такого вида:


"noperat" Проверим, не будет ли мешать посторонняя команда

"L03$3N" Проверим, не отвечает ли модуль на обращение к другим модулям

"R11$2N" Проверим, не отвечает ли модуль на чужие адреса

"R03$2N" Включим второе реле третьего релейного модуля

"R01$2S" Проверим, не отвечает ли модуль на чужие адреса

"R03$2S" Запросим состояние второго реле третьего релейного модуля

"R15$1N" Проверим, не отвечает ли модуль на чужие адреса

"R03$1N" Включим первое реле третьего релейного модуля

"R03$1S" Запросим состояние первого реле третьего релейного модуля

"R03#1F" Проверим, не отвечает ли модуль на передачу состояния

"R03$1F" Выключим первое реле третьего релейного модуля

"R03$1S" Запросим состояние первого реле третьего релейного модуля

"R03$2S" Запросим состояние второго реле третьего релейного модуля


Получаем выходной файл output.txt:


R03#2N

R03#1N

R03#1F

R03#2N


Теперь, пока вы опробуете работу в среде MPLAB, я, пожалуй, прерву работу над книгой. Поеду в магазин «Чип и Дип», что на Земляном валу, возле Курского вокзала, куплю все необходимое для сборки конвертора RS232-RS485, программатора и создания прототипа. Затем соберу прототип на макетной плате, а когда закончу и проверю, поделюсь впечатлениями.





Hosted by uCoz