Автомат управления освещением санузла (продолжение).
Автор - Валерий Парусов, Этот 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
Рекомендуемый контент
Радиолюбителю