Автомат управления освещением санузла (продолжение).

Автор - Валерий Парусов, Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript .
Опубликовано 02.12.2008.
Привет, хвостатые! Я наконец добрался до обещанного вот тут продолжения на тему автомата управления освещением санузла.
Предупреждаю сразу, что работающий у меня уже в течение года экземпляр немного отличается от приведенного. Здесь программа немного переработана и несколько оптимизирована.
Тестировалось только на PROTEUS-е !!! Частота МК = 1 МГц
При разработке данного устройства я ставил перед собой следующие задачи: - отслеживать геркон туалета, как и раньше;
- так же отслеживать геркон ванны;
- включать вентилятор в туалете, если свет горит и время паузы перед включением истекло;
- выключать вентилятор в туалете, если время его работы истекло;
- измерять температуру воздуха в ванной и если она выше порога включения и выключать, если температура ниже порога выключения;
- настраивать всевозможные времена-задержки с помощью кнопочек и LCD.
Почему, спросите вы, вентилятор в ванне работает от такого странного датчика? А потому что не было у меня датчика влажности, да и стоимость его (870р в одном известном магазине - хватит нам уже бесплатную рекламу делать. Кот.) пугает изрядно. В месте с тем было замечено, если изрядно мыться, то обязательно температура в помещении поднимется - вот тут то мы и включим вентилятор. Если у кого будут какие - ни будь мысли на этот счет, то обязательно поделитесь!
Дисплей я использовал DV-16230 и подключил его немножко не так как сказано в CodeVisionARV с целью разобраться как все же им управлять на уровне ножек-сигналов. Для этого пришлось внимательно прочитать datasheet и написать несколько функций, которые располагаются в файле led.c.
Для понимания всего процесса давайте рассмотрим написанный мною код. Начнем с файла common.h, в котором находятся большинство определений. В первую очередь видим закомментированное определение:
//#define _EEPROM
Если убрать комментарии, то большая часть переменных будет определена как хранимые в EEPROM микропроцессора. Это освободит FLASH - память и позволит настройкам сохраняться при отключении питания.
Но у меня не получилось сделать так, что бы PROTEUS воспринимал бинарный файл EEPROM, который я делал следующим образом:
- CVAVR формирует после компиляции файл main.eep, имеющий формат HEX
- выбираем Project->Configure->After Make ставим галку "Execute User's Program" и жмем кнопку "Program Settings", после чего указываем файл eep.bat.
- данный файл после компиляции вызывает утилиту SwapBinHex.exe, которая формирует из формата HEX формат BIN;
- в PROTEUS в свойствах МК выставляем источник, откуда грузить EEPROM при симуляции
К сожалению, ничего загружено не было. Поэтому для симуляции указанная выше строка была закомментирована.
Дальше идут определения кнопок, функций и всякое разное. Есть там еще структура для хранения времени:
typedef struct _Time_struct{
unsigned char hr;
unsigned char mm;
unsigned char ss;
} _Time;
В принципе она осталась от предыдущего варианта, когда на LCD выводилось время пока горел свет. Собственно для облегчения вывода время и было разбито на 3 части, хотя это и потребовало реализации дополнительных процедур по инкременту и очистке. В новом варианте я не стал переделывать - пусть будет.
Теперь файл led.c, в котором реализованы функции по работе с LCD. Все команды взяты из даташита на DV-16230, а порядок применения подсмотрен в Интернете и выявлен опытным путем.
Инициализация LCD:
void init_LCD(){
   // Установить 4-битный режим на 2-х строчном индикаторе
   PORTD = 0b00101000;
   #asm("nop");
   #asm("nop");
   //Установить OE=0 и ждать
   PORTD = ~OE;
   // подождать
   delay_ms(3);

   // Установить 4-битный режим на 2-х строчном индикаторе
   LCD_CMD(0b00101000);
   // Очистить дисплей
   LCD_CMD(0b00000001);
   // подождать
   delay_ms(3);
   // Установить направление сдвига курсора (вправо)
   LCD_CMD(0b00000110);
   // Задать режим LCD=on, Курсор=off Мерцание курсора=off
   LCD_CMD(0b00001100);
   delay_us(50);
}
Функции LCD_CMD (выдать команду) и LCD_CHAR (отобразить символ) вызывают функцию LCD_func, различия в порядке выдачи сигналов на LCD в обоих случаях них минимальны и заключаютсч в том, что для выдачи команды необходимо на время устанавливать сигнал RS в 1, а для отображения символа - нет. В 4-х битном режиме на LCD сначала надо выдать старшие 4 бита, а потом младшие 4 бита.
void LCD_func(unsigned char CH, unsigned char isCMD){
  unsigned char TEMP;
   //Загрузить символ/команду во временную переменную
   TEMP=CH;
   //Сбросить в о младшие 4 бита
   TEMP = 0xF0;
   // Бит OE=1
   TEMP |= OE;
   //Если выдаем команду, то RS=1
   if (!isCMD) TEMP |= RS;
   //Выдать старшие 4 бита в LCD
   PORTD = TEMP;
   //Короткая задержка перед снятием OE
   #asm("nop");
   #asm("nop");
   //OE=0
   PORTD = ~OE;

   //Загрузить символ/команду во временную переменную
   TEMP=CH;
   //Переместиь младшие 4 бита на место старших
   TEMP=TEMP






Рекомендуемый контент




Copyright © 2010-2017 housea.ru. Контакты: info@housea.ru При использовании материалов веб-сайта Домашнее Радио, гиперссылка на источник обязательна.