Схема и программа релейного модуля.



Рис.15


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


На макетной плате я не стал устанавливать реле. Реле тоже достаточно дорогой элемент, который нет нужды покупать без твердого намерения использовать его. Вместо реле я на выходы микроконтроллера включил красные светодиоды АЛ307. Получилось очень полезное решение при наладке и разработке других модулей.

Схема релейного модуля.




Рис.16

Спецификация релейного модуля.

Обозначение

Изделие

Кол-во

Цена (руб.)

Примечания

1

DD1

MAX1483

1

96


2

DD2

PIC16F628A

1

100

Установить на панельку

3

DD3

LM2936-Z5

1

68


4

VT1

КТ503Г

1

5


5

VD1, VD2

АЛ307

2

3


6

VD3

КД522

1

3


7

VD4

АЛ307

1

3


8

P1

12В, 5А/~220В

1

170


10

R1 – R3

1 кОм 0.25 Вт

3

1


11

R4-R7

10 кОм 0.25 Вт

4

1


12

R8

2.2 кОм 0.25 Вт

1

1


13

C1, C2

0.1 мкФ

2

5


14

C3

100 мкФ 16 В

1

20


15

X1

Кл. 6 конт.

1

10


16

S1

Пер. 2 пол. 4 нап.

1

50


17

SOC

DIP18

1

21


Ориентировочная стоимость элементов 558 руб.


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


Команды, на которые модуль должен реагировать:


Включить – Rxx$xN

Выключить – Rxx$xF


Я добавлю команду передачи модулем состояния реле:

Передать статус – Rxx$xS


При передаче статуса используем следующую символику:


Включено – Rxx#xN

Выключено – Rxx#xF


Здесь Rxx$xN означает: R - релейный модуль, xx – два символа адреса от 00 до 15, $ - символ команды (# - символ статуса), x – номер реле от 0 до 7, N – включить (F - выключить).


Для адресации используются четыре бита RB4-RB7, что позволяет адресоваться к 16 релейным модулям.


Программа модуля на ассемблере:


list p=16f628a

#include p16f628a.inc

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


BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0


CLRF PORTA ;Настройка порта А


MOVLW 0x07

MOVWF CMCON


BCF STATUS, RP1 ; Выбор банка 1

BSF STATUS, RP0

MOVLW 0x80

MOVWF TRISA

MOVLW 0xF6 ;Настройка порта В

MOVWF TRISB


BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

CLRF PORTB

;Настройка приемо-передатчика USART

BSF RCSTA, SPEN ; Настройка приемника

BCF RCSTA, RX9

BSF RCSTA, CREN


BCF STATUS, RP1 ; Выбор банка 1

BSF STATUS, RP0


BCF TXSTA, TX9 ; Настройка передатчика

BCF TXSTA, SYNC

BSF TXSTA, BRGH


MOVLW 0x16

MOVWF SPBRG


BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0


CLRW ; Считывание собственного адреса

ADDWF PORTB, 0 ; Прочитаем порт В

ANDLW 0xF0 ; Нам не нужны младшие биты

MOVWF 0x20 ; Сохраним адрес в 20h

SWAPF 0x20, 1 ; Нам не нужна работа с младшими битами

CALL adrsim ; Преобразуем его в символьный вид


; прочитаем из EEPROM 30h - состояние реле


BSF STATUS, RP0 ; Выбор банка 1

BCF STATUS, RP1

MOVLW 0x00

MOVWF EEADR ; Адрес считываемого регистра

BSF EECON1, RD ; Чтение

MOVF EEDATA,W ; w=EEDATA

BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

MOVWF 0x30

COMF 0x30,1 ; Будем хранить в EEPROM в инверсном виде

CLRW

ADDWF 0x30,0 ; А в регистре 30h в прямом

; перепишем 30h в порт


MOVWF PORTA


; Начало работы, ожидание команды, отработка первой команды


CLRW ; Очистим аккумулятор, ждем команды по USART


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

GOTO start

BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

CALL cmnd ; С приходом первого символа начинаем обработку

GOTO start

NOP


; Обработка команды - проверка адреса, определение команды


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 ; Первый символ адреса

BTFSS STATUS, Z

RETURN

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

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

MOVF RCREG, 0

BCF STATUS, Z

XORWF 0x22, 0 ; Второй символ адреса

BTFSS STATUS, Z

RETURN

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

GOTO in3 ; Если за адресом следует символ команды, продолжим

MOVF RCREG, 0

BCF STATUS, Z

XORLW 0x24 ; Выполнение $(24h)

BTFSC STATUS, Z

CALL swtch ; Вызываем подпрограмму выполнения

RETURN


;Подпрограмма перевода адреса в символы, их храним в 21h, 22h

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

ADDLW 0x30

MOVWF 0x21

CLRW

ADDLW 0x31

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0x1

BTFSC STATUS, Z

RETURN

CLRW ; Если адрес 2 запишем символы 02 (30h и 32h)

ADDLW 0x30

MOVWF 0x21

CLRW

ADDLW 0x32

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0x2

BTFSC STATUS, Z

RETURN

CLRW ; Если адрес 3 запишем символы 03

ADDLW 0x30

MOVWF 0x21

CLRW

ADDLW 0x33

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0x3

BTFSC STATUS, Z

RETURN

CLRW ; Если адрес 4 запишем символы 04

ADDLW 0x30

MOVWF 0x21

CLRW

ADDLW 0x34

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0x4

BTFSS STATUS, Z

RETURN

CLRW ; Если адрес 5 запишем символы 05

ADDLW 0x30

MOVWF 0x21

CLRW

ADDLW 0x35

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0x5

BTFSS STATUS, Z

RETURN


CLRW ; Если адрес 6 запишем символы 06

ADDLW 0x30

MOVWF 0x21

CLRW

ADDLW 0x36

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0x6

BTFSS STATUS, Z

RETURN


CLRW ; Если адрес 7 запишем символы 07

ADDLW 0x30

MOVWF 0x21

CLRW

ADDLW 0x37

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0x7

BTFSS STATUS, Z

RETURN


CLRW ; Если адрес 8 запишем символы 08

ADDLW 0x30

MOVWF 0x21

CLRW

ADDLW 0x38

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0x8

BTFSS STATUS, Z

RETURN


CLRW ; Если адрес 9 запишем символы 09

ADDLW 0x30

MOVWF 0x21

CLRW

ADDLW 0x39

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0x9

BTFSS STATUS, Z

RETURN


CLRW ; Если адрес 10 (A) запишем символы 10

ADDLW 0x31

MOVWF 0x21

CLRW

ADDLW 0x30

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0xA

BTFSS STATUS, Z

RETURN


CLRW ; Если адрес 11 запишем символы 11

ADDLW 0x31

MOVWF 0x21

CLRW

ADDLW 0x31

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0xB

BTFSS STATUS, Z

RETURN


CLRW ; Если адрес 12 запишем символы 12

ADDLW 0x31

MOVWF 0x21

CLRW

ADDLW 0x32

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0xC

BTFSS STATUS, Z

RETURN


CLRW ; Если адрес 13 запишем символы 13

ADDLW 0x31

MOVWF 0x21

CLRW

ADDLW 0x33

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0xD

BTFSS STATUS, Z

RETURN


CLRW ; Если адрес 14 запишем символы 14

ADDLW 0x31

MOVWF 0x21

CLRW

ADDLW 0x34

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0xE

BTFSS STATUS, Z

RETURN


CLRW ; Если адрес 15 запишем символы 15

ADDLW 0x31

MOVWF 0x21

CLRW

ADDLW 0x35

MOVWF 0x22

MOVF 0x20, 0

BCF STATUS, Z

XORLW 0xF

BTFSS STATUS, Z

RETURN


; Подпрограмма включение реле по номеру


cmdset: CLRW ; Запишем в 30h (установить бит)

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x0 ; реле 0

BTFSC STATUS, Z

BSF 0x30, 0

CLRW

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x1 ; реле 1

BTFSC STATUS, Z

BSF 0x30, 1

CLRW

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x2 ; реле 2

BTFSC STATUS, Z

BSF 0x30, 2

CLRW

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x3 ; реле 3

BTFSC STATUS, Z

BSF 0x30, 3

CLRW

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x4 ; реле 4

BTFSC STATUS, Z

BSF 0x30, 4

CLRW

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x5 ; реле 5

BTFSC STATUS, Z

BSF 0x30, 5

CLRW

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x6 ; реле 6

BTFSC STATUS, Z

BSF 0x30, 6

CLRW

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x7 ; реле 7

BTFSC STATUS, Z

BSF 0x30, 7

RETURN

; Подпрограмма выключения реле по номеру

cmdreset: CLRW ; запишем в 30h (сбросить бит)

ADDWF 0x23,0

BCF STATUS, Z

XORLW 0x0 ; реле 0

BTFSC STATUS, Z

BCF 0x30, 0

CLRW

ADDWF 0x23,0

BCF STATUS, Z

XORLW 0x1 ; реле 1

BTFSC STATUS, Z

BCF 0x30, 1

CLRW

ADDWF 0x23,0

BCF STATUS, Z

XORLW 0x2 ; реле 2

BTFSC STATUS, Z

BCF 0x30, 2

CLRW

ADDWF 0x23,0

BCF STATUS, Z

XORLW 0x3 ; реле 3

BTFSC STATUS, Z

BCF 0x30, 3

CLRW

ADDWF 0x23,0

BCF STATUS, Z

XORLW 0x4 ; реле 4

BTFSC STATUS, Z

BCF 0x30, 4

CLRW

ADDWF 0x23,0

BCF STATUS, Z

XORLW 0x5 ; реле 5

BTFSC STATUS, Z

BCF 0x30, 5

CLRW

ADDWF 0x23,0

BCF STATUS, Z

XORLW 0x6 ; реле 6

BTFSC STATUS, Z

BCF 0x30, 6

CLRW

ADDWF 0x23,0

BCF STATUS, Z

XORLW 0x7 ; реле 7

BTFSC STATUS, Z

BCF 0x30, 7

RETURN


Подпрограмма определения команды N (включить), F (выключить) или S (состояние)


swtch: CLRW

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

GOTO in4

MOVF RCREG, 0 ; Прочитаем номер реле

MOVWF 0x23 ; Сохраним номер реле в 23h

MOVLW 0x30 ; Запишем 30h в аккумулятор

SUBWF 0x23, 0 ; Переведем символ в номер

MOVWF 0x23 ; Сохраним номер реле в 23h


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

GOTO in5

MOVF RCREG, 0 ; Прочитаем команду N-включить F-выключить

MOVWF 0x24 ; Сохраним команду в 24h

BCF STATUS, Z

XORLW 0x4E ; Включение N (4Eh)

BTFSC STATUS, Z ; Если не включить, то пропустить

CALL cmdset

MOVF 0x24, 0 ; Перепишем из 24h в аккумулятор

BCF STATUS, Z

XORLW 0x46 ; Выключение F (46h)

BTFSC STATUS, Z ; Если не выключить, то пропустить

CALL cmdreset

MOVF 0x24, 0 ; Перепишем из 24h в аккумулятор

BCF STATUS, Z

XORLW 0x53 ; S (53h) запрос статуса

BTFSC STATUS, Z ; Если не запрос статуса, то пропустить

CALL stat

; Сохраним состояние всех реле в энергонезависимой памяти


CLRW ; Запишем 30h - состояние реле в EEPROM

BSF STATUS, RP0 ; Выбор банка 1

BCF STATUS, RP1

MOVLW 0x00 ; Запишем 0h в аккумулятор

MOVWF EEADR ; Запишем адрес 0h в регистр адреса

BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

CLRW

ADDWF 0x30,0 ; Запишем содержимое 30h в аккумулятор

COMF 0x30,0 ; Инвертируем перед сохранением

BSF STATUS, RP0 ; Выбор банка 1

BCF STATUS, RP1

MOVWF EEDATA

BSF EECON1, WREN ; Разрешить запись

BCF INTCON, GIE ; Запретить прерывания

MOVLW 0x55

MOVWF EECON2 ; Записать 55h

MOVLW 0xAA

MOVWF EECON2 ; Записать ААh

BSF EECON1, WR ; Установить флаг для начала запись

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

BCF EECON1, WREN ; Запретить запись

BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

chkwr: BTFSS PIR1, EEIF ; Проверка завершения записи

GOTO chkwr

CLRW

ADDWF 0x30, 0

MOVWF PORTA ; Перепишем 30h в порт

BCF PIR1, EEIF ; Сбросим флаг

RETURN


; Подпрограмма передачи статуса реле


stat: BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

CLRW ; Проверим реле 0

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x0 ; Реле 0

BTFSC STATUS, Z

CALL rel0

CLRW ; Проверим реле 1

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x1 ; Реле 1

BTFSC STATUS, Z

CALL rel1

CLRW ; Проверим реле 2

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x2 ; реле 2

BTFSC STATUS, Z

CALL rel2

CLRW ; Проверим реле 3

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x3 ; реле 3

BTFSC STATUS, Z

CALL rel3

CLRW ; Проверим реле 4

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x4 ; реле 4

BTFSC STATUS, Z

CALL rel4

CLRW ; Проверим реле 5

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x5 ; реле 5

BTFSC STATUS, Z

CALL rel5

CLRW ; Проверим реле 6

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x6 ; реле 6

BTFSC STATUS, Z

CALL rel6

CLRW ; Проверим реле 7

ADDWF 0x23, 0

BCF STATUS, Z

XORLW 0x7 ; реле 7

BTFSC STATUS, Z

CALL rel7

; теперь это все отправим в передатчик


BSF PORTB, 0 ; Переключим драйвер RS485 на передачу

BCF STATUS, RP1 ; Выбор банка 1

BSF STATUS, RP0

BSF TXSTA, TXEN ; Разрешаем передачу

BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

MOVLW 0x52

MOVWF TXREG ; Отправим символ модуля

BCF STATUS, RP1 ; Выбор банка 1

BSF STATUS, RP0

outdat0: BTFSS TXSTA, TXIF ; Ждем отправки символа

GOTO outdat0

BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

CLRW

ADDWF 0x21,0

MOVWF TXREG ; Отправим первый символ адреса

BCF STATUS, RP1 ; Выбор банка 1

BSF STATUS, RP0

outdat1: BTFSS TXSTA, TXIF ; Ждем отправки символа

GOTO outdat1

BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

CLRW

ADDWF 0x22,0

MOVWF TXREG ; Отправим второй символ адреса

BCF STATUS, RP1 ; Выбор банка 1

BSF STATUS, RP0

outdat2: BTFSS TXSTA, TXIF ; Ждем отправки символа

GOTO outdat2

BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

MOVLW 0x23

MOVWF TXREG ; Отправим символ статуса

BCF STATUS, RP1 ; Выбор банка 1

BSF STATUS, RP0

outdat3: BTFSS TXSTA, TXIF ; Ждем отправки символа

GOTO outdat3

BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

CLRW

ADDWF 0x23,0

ADDLW 0x30

MOVWF TXREG ; Отправим символ номера реле

BCF STATUS, RP1 ; Выбор банка 1

BSF STATUS, RP0

outdat4: BTFSS TXSTA, TXIF ; Ждем отправки символа

GOTO outdat4

BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

CLRW

ADDWF 0x25,0

MOVWF TXREG ; Отправим символ состояния реле

BCF STATUS, RP1 ; Выбор банка 1

BSF STATUS, RP0

outdat5: BTFSS TXSTA, RCIF ; Ждем отправки символа

GOTO outdat5

BCF TXSTA, TXEN ; Запрещаем передачу

BCF STATUS, RP1 ; Выбор банка 0

BCF STATUS, RP0

BCF PORTB, 0 ; Переключим драйвер RS485 на прием

RETURN

Подпрограмма обработки статуса реле


rel0: BTFSC 0x30, 0

CALL sostn

BTFSS 0x30, 0

CALL sostf

RETURN

rel1: BTFSC 0x30, 1

CALL sostn

BTFSS 0x30, 1

CALL sostf

RETURN

rel2: BTFSC 0x30, 2

CALL sostn

BTFSS 0x30, 2

CALL sostf

RETURN

rel3: BTFSC 0x30, 3

CALL sostn

BTFSS 0x30, 3

CALL sostf

RETURN

rel4: BTFSC 0x30, 4

CALL sostn

BTFSS 0x30, 4

CALL sostf

RETURN

rel5: BTFSC 0x30, 5

CALL sostn

BTFSS 0x30, 5

CALL sostf

RETURN

rel6: BTFSC 0x30, 6

CALL sostn

BTFSS 0x30, 6

CALL sostf

RETURN

rel7: BTFSC 0x30, 7

CALL sostn

BTFSS 0x30, 7

CALL sostf

RETURN


; Подпрограммы образования символов состояний

sostn: MOVLW 0x4E ; Состояние - включено

MOVWF 0x25

RETURN

sostf: MOVLW 0x46 ; Состояние - выключено

MOVWF 0x25

RETURN

END


Программа релейного модуля на языке «С»:


Файл заголовка

#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_reciev [6]; // Массив для полученной команды


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

int sim_end_num = 0; // Полный символьный номер модуля

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

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

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

int i;


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

unsigned char getch()

{

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

continue;

return RCREG;

}


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

void putch(unsigned char byte)

{

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

continue;

TXREG = byte;

}


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


int sim_num_adr()

{

sim_end_num = 0;

MOD_SIM1 = command_reciev [1]; // перввый символ номера

MOD_SIM2 = command_reciev [2]; // второй символ номера

MOD_SIM1 = MOD_SIM1 - 0x30; // в виде числа

MOD_SIM2 = MOD_SIM2 - 0x30;

sim_end_num = MOD_SIM1*0x0A + MOD_SIM2;

return sim_end_num;

}


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


int cmd()

{

REL_SIM = command_reciev [4];

REL_NUM = REL_SIM - 0x30;

switch (command_reciev [5])

{

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);

PORTA = RELSTAT;

EEADR =0x0; // Запишем состояние реле в EEPROM

EEDATA = ~RELSTAT;

WREN = 1;

GIE = 0;

EECON2 = 0x55;

EECON2 = 0xAA;

WR =1;

while (WR);

GIE = 1;

WREN = 0;

}


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


int rel_off(int num)

{

bitclr (RELSTAT, REL_NUM);

PORTA = RELSTAT;

EEADR =0x0; // Запишем состояние реле в EEPROM

EEDATA = ~RELSTAT;

WREN = 1;

GIE = 0;

EECON2 = 0x55;

EECON2 = 0xAA;

WR =1;

while (WR);

GIE = 1;

WREN = 0;

}


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


int rel_stat(int num)

{

command_reciev[0] = 'R';

command_reciev[1] = MOD_SIM1+0x30;

command_reciev[2] = MOD_SIM2+0x30;

command_reciev[3] = '#';

command_reciev[4] = REL_SIM;

if ((RELSTAT>>REL_NUM)&0x01) command_reciev[5] = 'N';

if (!((RELSTAT>>REL_NUM)&0x01)) command_reciev[5] = 'F';

CREN =0; // Запрещаем прием

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

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

for (i=0; i<6; ++i) putch(command_reciev[i]);

for (i=0;i<1000;i++); // Задержка для вывода

for (i=0; i<6; ++i) command_reciev [i] = ' ';

RB0 = 0; // Выключаем драйвер RS485 на передачу

TXEN = 0; // Запрещаем передачу

CREN =1; // Разрешаем прием

}

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

{

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

CMCON = 0x7;

TRISA = 0x0;

TRISB = 0xFE;


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

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

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

RB0 = 0; // Выключаем драйвер RS485 на передачу


/* Прочитаем состояние реле из EEPROM*/

EEADR = 0x0;

RD = 1;

RELSTAT = ~EEDATA;

PORTA = RELSTAT;

}




void main(void)

{

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

init_comms();

for (i=0; i<6; ++i) command_reciev [i] = ' ';

command_reciev [0] = 'R';

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

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

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


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

start: CREN =1;

input = getch();

switch (input)

{

case 'R': // Если обращение к релейному модулю

for (i=1; i<6; ++i) // Запишем команду в массив

{

input = getch();

command_reciev [i] = input;

}

MOD_NUM = sim_num_adr(); // Чтение из сети


if (MOD_NUM != MOD_ADDR) break; // Если не наш адрес

else

if (command_reciev [3] = '$') cmd(); // Если команда

default: goto start;

}

goto start;

}


Вот HEX-файл для релейного модуля:


:10000000830100308A0004282030840038300D201D

:100010008301392B04068001840A0406031D0A2883

:020020000034AA

:1004E20083018C1E712A1A0808008301B700831247

:1004F20003130C1E782A370899000800F401F5014D

:100502000310F30CF20C031C8D2A7008F407710817

:100512000318710AF5070310F00DF10D7208730448

:1005220003190034812A8301850107309F00831655

:100532008501FE30860090308312980006308316C3

:100542009800683099008312061083169B011C14D0

:100552001A098312A200850008008301AD01AE01D1

:100562003008A0003108A100D030A007A1070A304E

:10057200F200F3012008F000F1017F222108740744

:10058200AD0075080318750AAE00F1002D08F000E1

:1005920008000130F000831203132908F100F10A68

:1005A200D42A0310F00DF10BD22A7008A2042208FB

:1005B200850083169B018312220983169A001C155B

:1005C2008B1355309D00AA309D009C149C18E72A7D

:1005D2008B171C11831208000130F00083120313E1

:1005E2002908F100F10AF72A0310F00DF10BF52AA0

:1005F2007009A2052208850083169B018312220935

:1006020083169A001C158B1355309D00AA309D004D

:100612009C149C180A2B8B171C118312080083014F

:100622003308A300D030F000FF30F1002308700738

:10063200A90071080318710AAA002E2B2908B50017

:100642002A08B600CA2A2908B5002A08B600ED2AE7

:100652002908B5002A08B6008C2B3408463A03193B

:10066200242B083A03191F2B1D3A031D0800292BBE

:100672009422AB01AC01462B2B082F3E840083133E

:1006820020308000AB0A0319AC0A2C08803AF00033

:1006920080307002063003192B02031C3D2B5230AE

:1006A200AF000608A500A6010430F000260DA60C36

:1006B200A50CF00B572B852BAB01AB0AAC012C0818

:1006C200803AF00080307002063003192B020318C2

:1006D200762B7122A4002B082F3E8400831324085A

:1006E2008000AB0A0319AC0A602BAE227008A70087

:1006F2007108A8002606031D802B25082706031D66

:10070200852B2430B200102318167122A400523A0D

:1007120003195D2B852B52308301AF002008303E38

:10072200B0002108303EB1002330B2002308B300EC

:100732002208F0002908F100F10AA12B0310F00CA5

:10074200F10B9F2B7008F000701CA92B4E30B400E7

:100752002208F0002908F100F10AB12B0310F00C75

:10076200F10BAF2B7008F0007018B92B4630B400B3

:1007720018120614831698168312AB01AC012C08CA

:10078200803AF00080307002063003192B02031801

:10079200D42B2B082F3E8400831300087622AB0A49

:1007A2000319AC0AC02BAB01AC012C08803AF00053

:1007B20083307002E83003192B020318E42BAB0AD2

:1007C2000319AC0AD62BAB01AC012C08803AF0001D

:1007D20080307002063003192B020318FA2B2B0803

:1007E2002F3E8400831320308000AB0A0319AC0A29

:0E07F200E62B061083169812831218160800C4

:00000001FF





Hosted by uCoz