Версия программы на языке С
Выбор языка программирования происходит при задании в Project ^ Select Language Toolsuite (Проект Выбор языковых средств) - рис. 1.41.
Конечно, компилятор Hi-Tech должен быть установлен согласно инструкции.
Создадим файл заголовка и основной файл. Добавим в файлы заголовка нужный нам контроллер. Остальная часть работы мало, чем отличается от работы на ассемблере. В этой версии программы я не сохраняю состояние реле в EEPROM.
Файл заголовка
#define MODULNAMESIM "R" #define CMDSIM я$я
#define bitset {var, bitno) ((var) 1= 1 « (bitno))
Рис. 1.41. Установка языка программирования С |
#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 <picl6f62xa. h> #include <stdio. h> #include "reley_c. h"
Unsigned char input; регистра.
// Считываем содержимое приемного // Первый символ адреса модуля. // Второй символ адреса модуля. // Символ реле. |
Unsigned char M0D_SIM1; unsigned char M0D_SIM2; unsigned char REL_SIM;
Unsigned char COMMAND; // Символ команды.
Int MOD_ADDR; 11 Заданный адрес модуля, как число.
Int siml_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;
Siml_num = getch(); // Чтение первого символа номера.
M0D_SIM1 = siml_num; // Сохраним первый символ. sim2_num = getch(); // Чтение второго символа номера.
MOD_SIM2 = sim2_num; // Сохраним второй символ. siml__num = siml_num - 0x30; //От первого символа к числу, s im2_num = sim2_num - 0x30; //От второго символа к числу. sim_end_num = siml_num*"x0A + sim2_num; //Объединим в одно число.
Return sim_end_num;
}
// Получение и выполнение команды.
Int cmd() {
Input = getch ();
REL_NUM = input; // Номер реле в символьном виде.
REL_SIM = REL_NUM;
REL_NUM = REL_NUM - 0x30; // Номер реле в числовом виде.
Switch (COMMAND = getchO) // Прочитаем команду. {
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; // Сбросив бит, переписываем в порт
// Отправляем символ R. // Первый символ номера модуля. // Второй символ номера модуля. // Символ статуса. // Символ номера реле. |
Putch("R"); putch (MOD_SIMl); putch(MODJSIM2); putch(и #и); putch(REL_SIM); |
// Выполнение команды передачи состояния заданного реле.
Int rel_stat(int num) {
If ((RELSTAT»REL_NUM)&0х01) putch("N"); 11 Установлен ли бит?
If (I ((RELSTAT»REL_NUM)&0x01)) putch("F"); // Сброшен ли бит?
Putch(ОхОА); // Только для вывода в файл!!!!!!
}
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 (); 11 Инициализация модуля.
// Прочитаем и преобразуем номер модуля.
MOD_ADDR = PORTB; 11 Номер модуля в старших битах. 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" Проверим, не будет ли мешать посторонняя команда nL03$3N" Проверим, не отвечает ли модуль на обращение к другим модулям
"R11$2N" Проверим, не отвечает ли модуль на чужие адреса "R03$2N" Включим второе реле третьего релейного модуля "R01$2S" Проверим, не отвечает ли модуль на чужие адреса "R03$2S" Запросим состояние второго реле третьего релейного модуля
"R15$1N" Проверим, не отвечает ли модуль на чужие адреса "R03$1N" Включим первое реле третьего релейного модуля "R03$lSn Запросим состояние первого реле третьего релейного модуля
NR03#lFn Проверим, не отвечает ли модуль на передачу состояния
"R03$1F" Выключим первое реле третьего релейного модуля "R03$1S" Запросим состояние первого реле третьего релейного модуля
NR03$2S" Запросим состояние второго реле третьего релейного модуля
Получаем выходной файл output. txt:
R03#2N R03#1N R03#1F R03#2N
Теперь, пока вы опробуете работу в среде MPLAB, я, пожалуй, прерву работу над книгой. Поеду и куплю все необходимое для сборки конвертора RS232-RS485, программатора и создания прототипа. Затем соберу прототип на макетной плате, а когда закончу и проверю, поделюсь впечатлениями.