Умный дом

Блок обработки команды фотоприемника

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

// Первый символ адреса модуля. // Второй символ адреса модуля.

Пока RA6 в высоком состоянии («1»), ничего не надо делать. Проверим состояние USART. Если обращение идет не к на­шему модулю, делать ничего не надо, вернемся к определе­нию состояния RA6.

Я, как мне кажется, весьма рассудительно подошел к этому блоку программы. Но сомнения остаются. Я не уверен, будет ли она вообще работать, переключаясь с прослушивания от одного источника к другому.

Я, пожалуй, выделю блок и проверю его до написания ос­тальной части программы. Не забудьте установить нужное состояние конфигурации (3FlAh) по адресу 2007Ы Мне понадобится файл заголовка:

#define MODULNAMESIM "С" #define CMDSIM "$"

Void putch (unsigned char); unsigned char getch (void) ; int init_comms () ; int sim_num_adr () ; int cmd();

И файл программы:

#include <picl6f62xa. h> #include <stdio. h> #include "irjrec. h"

Unsigned char input; регистра.

Unsigned char M0D_SIM1; unsigned char M0D_SIM2;

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

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

Int siml_num = 0;

Int sim2_num = 0;

Int sim_end_num = 0;

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

Int PHOTO;

Int PHOTOCOME = 0;

Int FLAG = 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 init_comms () {

}

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

OxCO;

0x7;

OxCO;

0xF6;

0x90;

0x4;

0x16;

PORTA CMCON TRISA TRISB RCSTA TXSTA SPBRG INTCON=0;

PORTB = 0 }

Int cmdO {

// Настройка портов А и В.

// Настройка приемника. // Настройка передатчика.

//

// Настройка режима приема-передачи. Запретить прерывания. // Выключим передатчик драйвера RS485.

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

Input = getchO;

}

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

Int sim_num_adr() {

Sim_end_num = 0;

Siml_num = getchO; // Чтение первого символа номера.

M0D_SIM1 = siml_num; // Сохраним первый символ. sim2_num = getchO; // Чтение второго символа номера.

M0D_SIM2 = sim2_num; // Сохраним второй символ. siml_num = siml_num - 0x30; sim2_num = sim2_num - 0x30; sim_end_nuni = siml_num*0x0A + sim2_num; return sim_end_num;

}

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

Void main (void) {

Init_comms (); // Инициализация модуля.

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

M0D_ADDR = PORTB; // Номер модуля в старших битах. MOD_ADDR=MOD_ADDR»4; // Сдвинем на четыре бита.

Start: PHOTO = PORTA; // Начинаем работать,

If (PHOTO&0x40) PHOTOCOME = 0; // Нет ИК-сигнала. if (• (PHOTO&0x40)) PHOTOCOME = 1; // Появился ИК-сигнал.

While (PHOTOCOME == 1) // Обработаем ИК команду.

{

FLAG = 1 ;

Break; }

// Нет ИК-сигнала, проверим сеть, input = getch();

While(input == MODULNAMESIM) {

FLAG = 0 ; break;

}

В файл input. txt запишем:

"R03$0Nn "C03$0S -

Перед началом проверки запустим RB4 Set High (Устано­вить в высокое состояние), RB5 Set High и RA6 Set High на Stimulus Controller (я изменил адрес с 01 на 03, а фотоприем­ник на вводе RA6 перевел в пассивное состояние).

Переменная FLAG • покажет, попадаем ли мы в нужное место программы. Впоследствии мы вместо нее будем вызы­вать подпрограммы обработки команды cmd () и ИК-команды ir_cmd(). Кнопками RA6 Set High и RA6 Set Low мы будем имитировать изменение состояния фотоприемника. Вроде бы работает. Хотя, признаюсь, получилось не сразу - я забыл задать слово конфигурации по адресу 2007h.

Перейдем к обработке ИК-команды (обработку команд сети, я думаю, возьмем из предыдущей программы, подпра­вим, попробуем).

После получения заголовка и паузы в 0,55 мс мы можем ожидать прихода всего двух сочетаний импульс-пауза. Ноль - это импульс-пауза одинаковой длительности 0,55 мс. Едини­ца - импульс-пауза, где импульс - 1,1 мс, а пауза - 0,55 мс.

Таким образом, нам нужны два интервала в 1,1 мс и 0,55 мс. Для получения интервалов можно воспользоваться таймерами или отсчитать их в пустом цикле. Я воспользуюсь второй воз­можностью.

Все команды, кроме переходов, выполняются за один ма­шинный цикл (200 не при частоте 20 МГц). Положим, что при частоте 4 МГц машинный цикл равен 1 мкс. Тогда нам нужно досчитать до 1100 для промежутка в 1,1 мс и до 550 для корот­кого промежутка.

Сравнивая эти промежутки времени с приходящими им­пульсами, мы можем определить, единицу или ноль получаем в ИК-команде. Более того, мы можем установить только один счетчик до 550 (для верности возьмем 560) для вычисления байта команды.

На практике при первой проверке я успевал нажать кноп­ку RA6, чтобы имитировать приход ИК-команды. Теперь не успеваю. Слишком все быстро. Попробуем поискать, не мо­жет ли MPLAB помочь с симуляцией, как это было в случае с USART.

И действительно, как любил повторять один из моих зна­комых, «Грамотная программа!». В разделе Debugger SCL Generator (Отладчик SCL генератор) находим New Workbook (Новая рабочая тетрадь). Щелкаем и открываем окошко, в котором можно настроить имитатор работы фо­топриемника.

В очередной раз наступив на грабли (вместо того чтобы почитать описание), я начинаю понимать, что в первой ко­лонке нужно задать текущее время, выделяя события. Для этого следует, щелкнув кнопку со стрелкой правее надписи Time Units (Единицы времени), выбрать мкс (us). Событием в данном случае будет изменение состояния вывода RA6 пор­та А, которое мы зададим, щелкнув большую клавишу Click here to Add Signals (Щелкните здесь, чтобы добавить сигна­лы). Из раскрывающегося меню выберем RA6 и получим еще одну колонку с этим именем. Теперь в колонку Time (dec) впишем десятичные значения текущего времени (мкс), а в колонку RA6 - состояния входа, соединенного с фотоприем­ником. Не следует забывать, что в отсутствие активности фотоприемник на выходе имеет высокий логический уро­вень («1»). Первый ИК-сигнал, с которым я хочу работать, выглядит так: 10000000.

Если вернуться к разговору об ИК-командах и выбранному решению по системным командам, то сигнал, поступающий с фотоприемника на вход RA6, должен выглядеть, как показа­но на рис. 1.49 и 1.50.

Значения, которые следует проставить, представлены в табл. 1.5.

Нет сигнала Заголовок 2750 мкс Единица 1100 мкс Ноль 550 мкс Ноль 550 мкс

550 мкс 550 мкс 550 мкс Проверка и т. д. 8 бит

Рис. 1.49. Схема сканирования бит ИК-команды

Блок обработки команды фотоприемника

С—-, -■ ^ — ~ — «*. - '= • • - - *>- --- - « Г-: - с-....,. -- ' < ' і

Рис. 1.50. Заполнение SCLWorkbook

Таблица 1.5. Задание временных интервалов в сценарии ИК-команды

Time

RA6

Мои пометки (в книге)

10000

0

Через 1000 мкс приходит заголовок RA6 = 0

12750

1

Через 2750 мкс заголовок заканчивается RA6 = 1

13300

0

Через 550 мкс приходит 7-й бит (единица 1100 мкс)

14400

1

Перебивка 550 мкс

14950

0

Ноль 550 мкс 6-й бит

15500

1

Перебибка 550 мкс

16050

0

Ноль 550 мкс 5-й бит

16600

1

Перебивка 550мкс

17150

0

Ноль 550 мкс 4-й бит

17700

1

Перебивка 550 мкс

18250

0

Ноль 550 мкс 3-й бит

18800

1

Перебивка 550 мкс

19350

0

Ноль 550 мкс 2-й бит

19900

1

Перебивка 550мкс

20450

0

Ноль 550 мкс 1-й бит

21000

1

Перебивка 550 мкс

21550

0

Ноль 550 мкс 0-й бит

22100

1

Перебивка 550 мкс

47100

1

Пауза между командами 25 000 мкс

ИК-команда имеет вид 10000000 или 80h.

Теперь нужно сохранить Workbook и, щелкнув кнопку Generate SCL From Workbook (Іенерировать SCL из рабочей тетради), сохранить. scl-файл. Для использования этой имита­ции ИК-команды в Simulus Controller необходимо щелкнуть кнопку Attach (Прикрепить), указав сохраненный прежде. scl-файл. После сохранения Workspace все необходимое будет появляться при загрузке проекта.

Спасибо создателям программы MPLAB, которые позабо­тились о возможности работы с портами ввода-вывода в раз­ных их применениях!

Теперь я собираюсь проделать следующее: при активиза­ции RA6 я перейду к функции обработки ИК-команды:

• пропускаем заголовок;

• пропускаем перебивку в 550 мкс;

• при активизации RA6 приходящим битом запустим «ожи­далку» на 560 мкс (немного длиннее импульса в 550 мкс), после которой проверим состояние ввода RA6; если это ноль, бит «1», если единица, - бит «0» (на схеме сканиро­вания это обозначено словом «Проверка»);

• если единица, еще раз включим «ожидалку», если ноль, не будем этого делать;

• запишем бит в переменную IRCOMMAND, сдвинем вле­во на одну позицию;

• все это проделаем с 8 битами ИК-команды.

Поскольку я человек ленивый, моя «ожидалка» самая про­стая:

For (і = 0; і<560; ++і); // Ждем-с

Было ли это наказанием за лень, или я не справился с на­стройками сценария, но, промучившись несколько Часов, вы­яснил, что во время выполнения цикла for сценарий подхва­тывает циклы команды и успевает выполниться весь, прежде чем осуществляется выход из цикла ожидания. Я пробовал в качестве единиц измерения Time Units и циклы (сус) и мкс (us) - не помогло.

Конечно, хорошо бы выяснить, в чем проблема, но единож­ды наказанный за лень, я решил из двух зол выбрать меньшее,
организовав «ожидалку» на таймере, как это и положено. Пока я, чертыхаясь, пытался оживить программу с циклом for, я заметил, что цикл while не мешает работе сценария.

В конечном счете, эта часть программы (в состоянии про­верки) получилась следующей:

#include <picl6f62xa. h> #include <stdio. h> #include "ir__rec. h"

Unsigned char input; регистра.

Int PH0T0C0ME = 0; int M0D_ADDR; int IRCOMMAND = 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 init_comms () {

PORTA = OxCO; CMCON = 0x7; TRISA = OxCO; TRISB = 0xF6; RCSTA = 0x90; TXSTA = 0x4; SPBRG = 0x16; INTCON=0; // PORTB = 0;

}

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

// Настройка портов А и В.

// Настройка приемника. // Настройка передатчика.

// Настройка режима приема-передачи. Запретить прерывания. // Выключим передатчик драйвера RS485.

PIEl = 0; // Настройка таймера 1, запрет прерывания.

ТІ CON =0; // Выбор внутреннего генератора, бит 1 в ноль. }

Int ir_cmd () {

Int b = 0;

While ((PORTA&0x40)== 0) continue;// Ждем окончания заголовка.

For (b=0; b<8;++b) // Обработаем наши импульсы.

{

While ((PORTA&0x40) != 0) continue; // Дождемся импульса.

Time (); // Включаем таймер 1.

While (ITMR1IF); // Дождемся такта.

ТІ CON = 0x0; // Выключаем таймер.

TMR1IF = 0x0; // Сбросим флаг.

If ((PORTA&0x40) ==0) // Если низкий уровень, то

-Iй.

{

IRCOMMAND = IRCOMMAND +1; // Запишем это. time (); // Включаем таймер 1.

While (1TMR1IF); // Дождемся такта.

T1CON = 0x0; // Выключаем таймер.

TMR1IF = 0x0; // Сбросим флаг.

} else // Высокий уровень, значит "0".

{

IRCOMMAND = IRCOMMAND +0; // Запишем это. }

IRCOMMAND = IRCOMMAND«l; //Сместимся влево на

Бит.

}

// Уехали мы в смещениях на бит далеко, поэтому

IRCOMMAND = IRCOMMAND»l; // сместимся вправо на

Бит.

PHOTOCOME = 0;

}

Int cmd() {

Input = getch(); // switch (COMMAND = getchO) {

// case "N": rel_on(REL_NUM);

11 break;

11 case "F": rel_off (REL_NUM) ;

11 break;

11 case "S": rel_stat (REL_NUM) ;

11 break;

// }

Void time() {

TMR1H = OxFD; переполнения. TMR1L = 0xA7; TlCON = 0x1;

}

// Установка числа циклов до

// FFFF минус 600 (258h). // Включение таймера.

Void main (void) {

Init_comms(); // Инициализация модуля.

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

MOD_ADDR = PORTB; // Номер модуля в старших битах. MOD_ADDR=MOD_ADDR»4; // Сдвинем на четыре бита, start: if (PORTA&0x40) PHOTOCOME =0; //Нет ИК сигнала.

If (I(PORTA&0x40)) PHOTOCOME =1; // Появился ИК - сигнал.

While (PHOTOCOME == 1) {

// Обработаем ИК команду.

Ir_cmd ();

Break; }

// Нет ИК-сигнала, проверим сеть.

Input = getch () ;

While (input == MODULNAMESIM) {

Cmd (); break;

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

}

Все это получилось не сразу, но, вроде бы, заработало. Те­перь осталось проверить программу с другими вариантами

ИК-кода. Например, с командой 00100000, или 20h.

10000

0

Через 1000 мкс приходит заголовок RA6=0

12750

1

Через 2750 мкс заголовок заканчивается RA6=1

13300

0

Через 550мкс приходит 7й бит

13850

1

Перебивка 550 мкс

14400

0

Ноль 550 мкс 6й бит

14950

1

Перебивка 550 мкс

16050

0

Единица 1100 мкс 5й бит

17150

1

Перебивка 550 мкс

17700

0

Ноль 550 мкс 4й бит

18250

1

Перебивка 550 мкс

18800

0

Ноль 550мкс 3 бит

19350

1

Перебивка 550 мкс

19900

0

Ноль 550 мкс 2 бит

20450

1

Перебивка 550 мкс

21000

0

Ноль 550 мкс 1 бит

21550

1

Перебивка 550 мкс

22100

0

Ноль 550 мкс Ой бит

22650

1

Перебивка 550 мкс

47650

1

Пауза между командами 25000 мкс

С командой 10000011, или 83h:

10000

0

Через 1000 мкс приходит заголовок RA6=0

12750

1

Через 2750 мкс заголовок заканчивается RA6=1

13300

0

Через 550 мкс приходит 7-й бит (единица 1100 мкс)

14400

1

Перебивка 550 мкс

14950

0

Ноль 550 мкс 6-й бит

15500

1

Перебивка 550 мкс

16050

0

Ноль 550 мкс 5-й бит

16600

1

Перебивка 550мкс

17150

0

Ноль 550 мкс 4-й бит

17700

1

Перебивка 550 мкс

18250

0

Ноль 550 мкс 3-й бит

18800

1

Перебивка 550 мкс

19350

0

Ноль 550 мкс 2-й бит

19900

1

Перебивка 550мкс

20450

0

Единица 1100 мкс 1-й бит

21550

1

Перебивка 550 мкс

22100

0

Единица 1100 мкс 0-й бит

23200

1

Перебивка 550 мкс

48200

1

Пауза между командами 25000 мкс

И можно двигаться дальше. Предстоит добавить обработ­ку запросов по системной сети, преобразование позиционно­го кода ИК-команды в символьный вид. Функцию обработки запросов по системной сети, подправив, я возьму из версии программы для предыдущего модуля.

Можно слегка изменить и сценарий имитации работы фотоприемника, добавив задание адреса модуля (пусть он пока остается «03») и подключение к порту А фотоприемни­ка RA6 = 1.

Для этого в Workbook SCL Generator кнопкой Click here to Add Signals добавим еще три столбца: RB4, RB5 и PORTA, а в конце (как в табл. 1.5.) - информацию, представленную в табл. 1.6.

Таблица 1.6. Добавление к таблице временных интервалов

Time

RA6

RB4

RB5

PORTA

Мои пометки (в книге)

10000

0

Через 1000 мкс приходит заголовок, RA6=0

И т. д.

47100

1

Пауза между командами 25000 мкс

5

1

1

40

Начальная инициализация адреса фотоприемника

Теперь при запуске программы будет задан адрес модуля, и фотоприемник установит вывод RA6 в «1».

В итоге получилась (не слишком аккуратная) следующая программа:

#include <picl6f62xa. h> #include <stdio. h> #include nir_rec. hn

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

Unsigned char M0D_SIM1; // Первый символ адреса модуля, unsigned char M0D_SIM2; // Второй символ адреса модуля, unsigned char IRSIM1; unsigned char IRSIM2; unsigned char IRSIM3;

Int PHOTOCOME = 0; // Флаг активности фотоприемника.

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

Int IRCOMMAND = 0;

Int siml_num = 0;

Int sim2_num = 0;

Int sim_end_num = 0;

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

Unsigned char getch() {

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

Continue; return RCREG;

}

// Вывод одного байта.

Void putch (unsigned char byte) {

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

Int init_comms () {

PORTA = OxCO; CMCON = 0x7; TRISA = OxCO; TRISB = 0xF6; RCSTA = 0x90; TXSTA = 0x4; SPBRG = 0x16;

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

Continue; TXREG = byte;

}

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

// Настройка портов А и В.

// Настройка приемника. // Настройка передатчика.

// Настройка режима приема-передачи.

INTCON=0; // Запретить прерывания. PORTB = 0; // Выключим передатчик драйвера RS485.

PIE1 = 0; // Настройка таймера 1, запрет прерывания.

T1C0N =0; // Выбор внутреннего генератора, бит 1 в ноль.

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

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

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

Int sim_num_adrO {

Sim_end__num = 0; siml_num = getchO; //

MODJSIM1 = siml_num; // sim2_num = getchO; //

MOD_SIM2 = sim2_num; // siml_num = siml_num - 0x30; sim2_num = sim2_num - 0x30; sim_end_num = siml_num*0x0A return sim_end_num;

}

Int ir_cmd () {

Int b = 0;

Чтение первого символа номера. Сохраним первый символ. Чтение второго символа номера. Сохраним второй символ.

+ sim2_num;

While ((PORTA&0x40)== 0) continue;// Ждем окончания заголовка.

For (b=0; b<8;++b) //Обработаем наши импульсы.

{

While ((PORTA&0x40) != 0) continue; // Дождемся импульса.

Time О; // Включаем таймер 1.

While (ITMR1IF); // Дождемся такта.

T1CON = 0x0; // Выключаем таймер.

TMR1IF = 0x0; // Сбросим флаг.

If ((PORTA&0x40) ==0) // Если низкий уровень, то

П ^ п

{

IRCOMMAND = IRCOMMAND +1; // Запишем это. time О; // Включаем таймер 1.

While (ITMR1IF); // Дождемся такта.

T1CON = 0x0; // Выключаем таймер.

TMR1IF = 0x0; // Сбросим флаг.

} else // Высокий уровень, значит "0".

{

IRCOMMAND = IRCOMMAND +0; // Запишем это. }

IRCOMMAND = IRCOMMAND«l; //Сместимся влево на бит.

}

// Уехали мы в смещениях на бит далеко, поэтому

IRCOMMAND = IRCOMMAND»!; // сместимся вправо на бит.

PHOTOCOME = 0;

}

Int cmd() {

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

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

Input = getch ();

If (input =="$") // Если символ команды. {

While ((input = getch())!= "S"); // Ждем.

Ir_stat(); }

}

}

Void time()

TMR1H = OxFD; переполнения. TMR1L = 0xA7; T1CON = 0x1;

Int ir_stat() {

Int ircom; int ircoml; int ircom2; int ігсотЗ;

Ircom = IRCOMMAND; // Преобразуем команду в символы.

Ircoml = ircom/0x64;

IRSIM1 = ircoml + 0x30;

Ircom2 = (ircom - ircoml*0x64)/OxA;

IRSIM2 = ircom2 + 0x30;

ІгсотЗ = (ircom - ircoml*0x64 - ircom2*0xA);

IRSIM3 = ігсотЗ + 0x30;

Putch ("С");

Putch (MOD_SIMl);

Putch (MOD_SIM2);

// Установка числа циклов до

// FFFF минус 600 (258h). // Включение таймера.

If (IRCOMMAND ==0) // Команда не менялась.

{

Putch("#"); putch("f"); putch(" f");

Putch(ОхОА); // Только для вывода в файл! I! I!!

} else //За время между двумя запросами пришла ИК

Команда. {

Putch(IRSIM1); putch(IRSIM2); putch(IRSIM3);

Putch (ОхОА); // Только для вывода в файл!!!!!!

}

IRCOMMAND =0; //Мы передали ИК команду, она нам больше не нужна.

Void main (void) // Начнем работать. {

Init_comms(); // Инициализация модуля.

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

MOD_ADDR = PORTB; // Номер модуля в старших битах. MOD_ADDR=MOD_ADDR»4; // Сдвинем на четыре бита. // Начинаем работать

Start: if (PORTA&0x40) PHOTOCOME =0; //Нет ИК-сигнала.

If (! (PORTA&0x40)) PHOTOCOME = 1; // Появился ИК - сигнал.

While (PHOTOCOME == 1) {

// Обработаем ИК-команду.

Ir_cmd (); break; )

// Нет ИК-сигнала, проверим сеть, input = getch ();

While (input == MODULNAMESIM) // Если в сети обращение к

Модулю. {

Cmd (); // Обработаем сетевую команду,

Break;

}

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

В крайнем случае, если не забуду, в основной программе системы при отсылке запроса о состоянии модуля ИК-прием­ника, сделаю паузу и при отсутствии ответа повторю запрос.

Есть и еще одно сомнение - не будет ли в реальных усло­виях неправильно считываться ИК-команда? Здесь тоже мож­но что-нибудь придумать. Например, повторять системную команду трижды, а в модуль добавить три считывания, при­нимая в качестве команды ту, которая совпадает дважды. На данном этапе я предпочту отложить решение проблем до момента их появления, хотя, как мне кажется, самое время обо всем позаботиться.

Работа выше приведенной программы происходит при input. txt такого вида:

"R03$0N" "R01$0N" "C03$0Sn

Опция Rewind Input на странице Uartl Ю установлена. В результате имитация сетевых команд постоянно «крутит­ся», принимая три команды, последняя из которых запраши­вает состояние модуля фотоприемника.

Результат работы программы выводится, как и раньше, в файл output. txt:

C03#ff// Команда не менялась

С03131// Пришла команда 131 (десятичная) или 10000011 двоичная

C03#ff// Команда не менялась после последнего запроса C03#ff// Команда не менялась C03#ff// Команда не менялась

По дороге я еще раз наступил на грабли. Внеся исправления в программу, я обнаружил, что она не желает работать. Во вся­ком случае, работать так, как мне хочется. Пытаясь понять, в чем дело, я много раз просматривал программу, пока не обна­ружил, что один из операторов имеет тот же цвет, что и ком­ментарий. Как это получилось? Я использую много одностроч­ных комментариев (тоже следствие лени) и если в конце строчного комментария не нажат ввод при удалении промежут­ков между операторами программы, следующий воспринима­ется программой как продолжение комментария.

{

Cmd (); // Обработаем сетевую команду. ++COONTER; break;

}

Goto start;

Результат эксперимента - за время прохождения двух ИК - команд (83h и 2Oh) счетчик досчитал до 5.

Файл input. txt, который «крутится» без перерывов выгля­дит так:

"R03$ON" "R01S0N"

"C03$0S" Обращение к модулю приемника ИК команд

"R03$0N"

"R01$0N"

"C03$0S" Обращение к модулю приемника ИК команд

Файл output. txt получился следующим:

C03#ff Команда не обновлялась С03131 Команда 131 (83h) C03#ff Команда не обновлялась C03#ff Команда не обновлялась С03032 Команда 32 (20h)

Таким образом:

• ИК-команды не потерялись за непрерывно следующи­ми сетевыми командами;

• ИК-команды прочитались правильно;

• между приходами ИК-команд запрос статуса правильно отображал отсутствие обновления.

Посмотрим, как это все выглядит во времени. Первая ИК-команда приходит через 10 мс и заканчивает­ся через 24 мс, вторая приходит через 60 мс и заканчивается через 73 мс после начала работы. Сетевые команды начина­ют поступать сразу после начала работы. Каждая сетевая ко­манда занимает около 6,3 мс (имеет 60 бит, проходящих со скоростью -9600 бит/ с).

До начала ИК-команды при такой скорости должна прой­ти одна сетевая команда. За время считывания первой

ИК-команды ((10 мс - 6 мс) + 24 мс) = 28 мс пройдет 4 команды. После завершения первой и до конца второй пройдет 73 мс - 24 мс = 49 мс, что соответствует 7-8 командам. Таким образом, за все время пройдет 12-13 команд. То есть, файл input прочи- тается дважды или немного более. Что дает 4-5 обращений к модулю приемника ИК-команд. Файл output фиксирует 5 обра­щений, счетчик фиксирует 5 обращений.

Для большей уверенности посмотрим, как распределяют­ся сетевые обращения:

• за время от начала работы до завершения считывания ИК-команды проходит 5 системных запросов, среди которых один к ИК-приемнику;

• в выходном файле этому соответствует один ответ об отсутствии обновления команд;

• следующая команда во входном файле это запрос к моду­лю;

• в выходном файле на втором месте стоит ответ о при­ходе команды 131 (к этому моменту считывание первой команды завершено);

• до завершения считывания второй команды проходит семь системных команд, среди которых два обращения к модулю приемника;

• в выходном файле два ответа - команда не обновлялась (предыдущая уже передана);

• следующая сетевая команда - запрос о состоянии моду­ля приемника, который следует сразу за завершением считывания ИК-команды, ответ - команда 32 в выход­ном файле.

Если я ничего не напутал, даже при короткой основной программе (центрального управляющего устройства), когда запросы о состоянии модуля приемника идут достаточно час­то, ответ успевает доходить до адресата. Если учесть, что в тестовом варианте две команды проходят с интервалом в 36 мс, что в 10-30 раз быстрее реально отправляемых команд (интервал между двумя нажатиями на одну и ту же клавишу составляет от 0,3 до 1 с), то запас, я думаю, есть.

Конечно, мои подсчеты не страдают излишней продуман­ностью и точностью, но я на время решил успокоиться.

Умный дом

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

Если вам захочется провести эксперименты с радиоканалом вместо проводной связи модулей, то: • лучше было бы воспользоваться готовыми радиомоду­лями, но дорого; • не забывайте, что ваши эксперименты могут мешать вашим …

Немного О программировании на С++

Поскольку при программировании микроконтроллера я ис­пользовал язык С, мне показалось уместным добавить хотя бы несколько слов о языке. Но я не сделаю это лучше, чем С. Липпман. Когда мне понадобилось …

Цоколевка контроллера PIC16F628A

—- RA1/AN1 ]—RAO/ANO ]—- RA7/OSC1 /CLKIN ]—RA6/SDC2/CLKOUT — VDD RB7A10SI/PGD — RB6A1 ОБОДІ CKI/PGC j—RB5 RB4/PGM PDIPSOIC О KJ 1 18 2 17 3 16 4 15 5 14 6 …

Как с нами связаться:

Украина:
г.Александрия
тел. +38 05235 7 41 13 Завод
тел./факс +38 05235  77193 Бухгалтерия
+38 067 561 22 71 — гл. менеджер (продажи всего оборудования)
+38 067 2650755 - продажа всего оборудования
+38 050 457 13 30 — Рашид - продажи всего оборудования
e-mail: msd@inbox.ru
msd@msd.com.ua
Скайп: msd-alexandriya

Схема проезда к производственному офису:
Схема проезда к МСД

Представительство МСД в Киеве: 044 228 67 86
Дистрибьютор в Турции
и странам Закавказья
линий по производству ПСВ,
термоблоков и легких бетонов
ооо "Компания Интер Кор" Тбилиси
+995 32 230 87 83
Теймураз Микадзе
+90 536 322 1424 Турция
info@intercor.co
+995(570) 10 87 83

Оперативная связь

Укажите свой телефон или адрес эл. почты — наш менеджер перезвонит Вам в удобное для Вас время.