Тема: Часы-ночник на DS1307
Видео работы:http://www.youtube.com/watch?v=ghEI2i6yKLU
DS1307 это часы реального времени. http://mogalkov.ath.cx/rtc/DS1307.pdf" даташит
Вот схема принципиальная:
Очень внимательно надо отнестись к выбору кварца, от этого зависит точность часов. Не каждый кварц подойдет - в даташите указано что внутренняя емкость кварца нужна 12.5pF. Лучше всего использовать кварц от ненужной материнской платы (он на ней для хода системных часов компьютера). Припаивать кварц лучше как можно ближе к мс(я прямо к ножкам паял).
Также для работы часов необходима батарейка на 3В. Я особо не замарачивался, выпаял с той-же мамки что и кварц.
Перечень элементов:
Bat1 = 3V
C1 = 470µ 25v
C2 = 470µ 25v
C3 = 100n
C4 = 100n
HL1 = ARL-5213RGBC/4C
LCD1 = WH1602A-YGH-CTK
R1 = 1k
R2 = 1k
R3 = 50k//потенциометр выбора настройки и скорости мигания
R4 = 50k//потенциометр установки времени
R5 = 100
R6 = 100
R7 = 100
R8 = 1k
R9 = 1k
R10 = 10k
S1 = тумбле //Переключатель установки
S2 = ртактовая кнопка с фиксацией //переключатель лампы
U1 = 7805
U2 = ATMEGA168
U3 = DS1307
Z1 = 32.768kHz
Z2 = 16 MHz
Печатная плата:
http://mogalkov.ath.cx/rtc/AT168_RTC_004.layПлата в формате lay
Вникать в протокол I2C не стал, скачал готовую библиотеку:
брал тутhttp://code.google.com/p/sjunnesson/downloads/list Также выложил тут: http://mogalkov.ath.cx/rtc/DS1307.rar
скетч:
//необходимые библиотеки, последнюю надо скачивать
#include <LiquidCrystal.h>
#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h> //брал тут “http://code.google.com/p/sjunnesson/downloads/list"
//переменные
int realpot;//Переменная хранения данных потенциометра
int setpot; //Переменная хранения данных потенциометра
int potPinST=2; //потенциометр установки времени
int potPinSE=3;//потенциометр выбора настройки и скорости мигания
int potsec000;//установка времени из потенциометра секунды
int potmin000;//установка времени из потенциометра минуты
int pothor000;//установка времени из потенциометра часы
int potday000;//установка времени из потенциометра дни
int potmon000;//установка времени из потенциометра месяцы
int potyer000;//установка времени из потенциометра годы
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); //пины ЛСД
//хранение времени для чтения с часов и вывода на экран
int hr_00;
int mn_00;
int sc_00;
int DD_00;
int MM_00;
int YY_00;
//хранение времени для установки часов
int hr_01=0;
int mn_01=0;
int sc_01=0;
int DD_01=0;
int MM_01=0;
int YY_01=0;
//делитель времени (:)
char delitel =':';
int ledPinR = 9; //пины светодиода
int ledPinG = 11; //пины светодиода
int ledPinB = 10; //пины светодиода
int swset; //параметр переключателя установки
int swled;//параметр переключателя светодиодной лампы
void btn_read() //Запись состояния переключателей в переменные
{
swset=digitalRead(12); //Переключатель установки
swled=digitalRead(8); //переключатель лампы
}
void Var2LCD()//вывод времени на экран
{
lcd.clear(); //очистка экрана
// координаты ; текст
lcd.setCursor(0,0);lcd.print(hr_00);
lcd.setCursor(2,0);lcd.print(delitel);
lcd.setCursor(3,0);lcd.print(mn_00);
lcd.setCursor(5,0);lcd.print(delitel);
lcd.setCursor(6,0);lcd.print(sc_00);
lcd.setCursor(0,1);lcd.print(DD_00);
lcd.setCursor(2,1);lcd.print('-');
lcd.setCursor(3,1);lcd.print(MM_00);
lcd.setCursor(5,1);lcd.print('-');
lcd.setCursor(6,1);lcd.print(YY_00);
}
void RTC_red2var()//читаем с часов в переменные
{
hr_00=RTC.get(DS1307_HR,true);
mn_00=RTC.get(DS1307_MIN,false);
sc_00=RTC.get(DS1307_SEC,false);
DD_00=RTC.get(DS1307_DATE,false);
MM_00=RTC.get(DS1307_MTH,false);
YY_00=RTC.get(DS1307_YR,false);
}
void RTC_set2var()//Установка часов
{
do {
lcd.clear();//очищаем экран
RTC.stop(); //останавливаем часы
btn_read();//читаем переключатели в переменные
setpot=analogRead(potPinSE); //читаем потенциометр выбора настройки от него зависит что настраиваем
setpot=setpot/128;//Делим показания потенциометра выбора настройки на 128 (1024/128=8) получаем от 0 до 8 вариантов (используются 2-7)
switch (setpot) {
case 2:
//;секунды -Все остальные параметры устанавливаются примерно также
realpot=analogRead(potPinST);//читаем потенциометр установки времени
realpot=realpot/16;//Делим показания потенциометра на 16 (1024/16=64) получаем от 0 до 64 вариантов
if (realpot>=60) {realpot=59;}//ограничиваем до 59 (ни разу не видел у себя на часах 64 секунды, может просто невнимательно смотрел)
potsec000=realpot;//установка времени из потенциометра секунды
lcd.setCursor(0, 0); //координаты отображения
lcd.print("SECONDS");//отображаем текст
lcd.setCursor(1, 1);//координаты отображения
lcd.print(potsec000);//отображаем установки времени из потенциометра секунды
RTC.set(DS1307_SEC,potsec000);//записываем время в часы
break;
case 3:
//;минуты
realpot=analogRead(potPinST);
realpot=realpot/16;
if (realpot>=60) {realpot=59;}
potmin000=realpot;
lcd.setCursor(0, 0);
lcd.print("MINUTES");
lcd.setCursor(1, 1);
lcd.print(potmin000);
RTC.set(DS1307_MIN,potmin000); //set the minutes
break;
case 4:
//;часы
realpot=analogRead(potPinST);
realpot=realpot/40;
if (realpot>23) {realpot=23;}
pothor000=realpot;
lcd.setCursor(0, 0);
lcd.print("HOURS");
lcd.setCursor(1, 1);
lcd.print(pothor000);
RTC.set(DS1307_HR,pothor000); //set the hours
break;
case 5:
//;дни
realpot=analogRead(potPinST);
realpot=realpot/32;
if (realpot>31) {realpot=31;}
if (realpot<=0) {realpot=1;}
potday000=realpot;
lcd.setCursor(0, 0);
lcd.print("DAYS");
lcd.setCursor(1, 1);
lcd.print(potday000);
RTC.set(DS1307_DATE,potday000); //set the date
break;
case 6:
//;месяцы
realpot=analogRead(potPinST);
realpot=realpot/84;
if (realpot>12) {realpot=12;}
if (realpot<=0) {realpot=1;}
potmon000=realpot;
lcd.setCursor(0, 0);
lcd.print("MONTH`S");
lcd.setCursor(1, 1);
lcd.print(potmon000);
RTC.set(DS1307_MTH,potmon000); //set the month
break;
case 7:
//;годы
realpot=analogRead(potPinST);
realpot=realpot/4;
potyer000=realpot;
lcd.setCursor(0, 0);
lcd.print("YEARS");
lcd.setCursor(1, 1);
lcd.print(potyer000);
RTC.set(DS1307_YR,potyer000); //set the year
break;
//если показания потенциометра выбора настройки не подпадают под установки времени
//выводит текст SET TIMES AND DATES
default:
lcd.setCursor(0, 0);
lcd.print("SET TIMES");
lcd.setCursor(1, 1);
lcd.print("AND DATES");
break;
}
delay(5);
} while (swset==LOW);//если переключатель выключен - повторяем по новой
RTC.start();//запускаем часы
}
void color_led()//мигаем трехцветным светодиодом
{
do {
RTC_red2var();//прочитать время в переменные
Var2LCD();//отобразить переменные времени на экран
btn_read();//проверяем переключатели
setpot=analogRead(potPinSE);//используем потенциометр выбора настройки для установки скорости изменения цвета
setpot=setpot/128;
int delayTime = setpot;
// красный нарастает, синий гаснет
for (int i=0; i<256; i++)
{
btn_read();//проверяем переключатели
setpot=analogRead(potPinSE);
setpot=setpot/128;
int delayTime = setpot;
analogWrite(ledPinR, i);
analogWrite(ledPinG, 0);
analogWrite(ledPinB, 256-i);
delay(delayTime);
}
// красный гаснет, зеленый нарастает
RTC_red2var();//прочитать время в переменные
Var2LCD();//отобразить переменные времени на экран
for (int i=0; i<256; i++)
{
btn_read();//проверяем переключатели
setpot=analogRead(potPinSE);
setpot=setpot/128;
int delayTime = setpot;
analogWrite(ledPinR, 256-i);
analogWrite(ledPinG, i);
analogWrite(ledPinB, 0);
delay(delayTime);
}
// зеленый гаснет, синий нарастает
RTC_red2var();//прочитать время в переменные
Var2LCD();//отобразить переменные времени на экран
for (int i=0; i<256; i++)
{
btn_read();//проверяем переключатели
setpot=analogRead(potPinSE);
setpot=setpot/128;
int delayTime = setpot;
analogWrite(ledPinR, 0);
analogWrite(ledPinG, 256-i);
analogWrite(ledPinB, i);
delay(delayTime);
}
} while (swset==LOW);
RTC_red2var(); //прочитать время в переменные
Var2LCD(); //отобразить переменные времени на экран
analogWrite(ledPinR, 0);//выключаем светодиод
analogWrite(ledPinG, 0);//выключаем светодиод
analogWrite(ledPinB, 0);//выключаем светодиод
}
void setup()
{
pinMode(ledPinR, OUTPUT); //пин светодиода у нас выход
pinMode(ledPinG, OUTPUT); //пин светодиода у нас выход
pinMode(ledPinB, OUTPUT); //пин светодиода у нас выход
pinMode(12, INPUT);//Переключатель установки
pinMode(8, INPUT); //переключатель лампы
lcd.begin(16, 2);//экран у меня 16 символов на 2е строки
lcd.home();
}
void loop()
{
btn_read(); //проверяем переключатели
if (swset==LOW){RTC_set2var();} //если переключатель установки 0 запускаем установку даты-времени
else if (swled==LOW){color_led();} //Если переключатель лампы 0 запускаем функцию лампы
else {
RTC_red2var();//прочитать время в переменные
Var2LCD(); //отобразить переменные времени на экран
delay(5);
}
}