Нашёл у себя на компьютере экспериментальный проектик на часах DS1307. Сам проект не планировалось собирать, а делался чисто для проверки… поэтому здесь нет никаких наворотов, а просто микроконтроллер+дисплей nokia 3310 + 4 кнопки. Собственно вот схема в Proteus.
На схеме нет кварца — к меге 16мгц, а к часикам часовой кварц желательно с канденсаторами по 22пф. Вообщем чтоб небыло неясностей привожу схему со всеми элементами( схема выше — чисто для симулятора).
Фьюзы — нужно настроить на внешний кварц.
Не забудьте про батарейку для часов.
Исходник написан в CVAVR:
Chip type : ATmega8
Program type : Application
AVR Core Clock frequency: 16,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega8.h>
#include <delay.h>
#include <stdio.h>
#include <stdlib.h> // библиотека преобразоания чисел в символьную строку
#include <ctype.h> // библиотека преобразования символов в число
#include <string.h> //библиотека работы со строками
#include "NokiaLCD.h"
#include "lcd_3310.c"
// I2C Bus functions
#asm
.equ __i2c_port=0x15 ;PORTC
.equ __sda_bit=4
.equ __scl_bit=5
#endasm
#include <i2c.h>
// DS1307 Real Time Clock functions
#include <ds1307.h>
#define btn_m PIND.0
#define btn_minus PIND.2
#define btn_plus PIND.1
#define btn_b PIND.3
unsigned char buff [99]; //буфер дисплея
unsigned char hour,minut,sek; //часы, минуты, секунды
unsigned char m,h,s; //часы, минуты, секунды
unsigned char day,month,year; //день, месяц, год
unsigned char d,mo,y; //день, месяц, год
unsigned char flag,menu;
void read_time()
{
rtc_get_time(&hour,&minut,&sek); //считать время
h=hour;
m=minut;
s=sek;
}
void read_date()
{
rtc_get_date(&day,&month,&year); //считать дату
d=day;
mo=month;
y=year;
}
void btn()
{
if(btn_m==0&&menu==0){menu=1;ClearLcd();}
if(menu==1){if(btn_m!=0){menu=2;ClearLcd();}}
if(btn_m==0&&menu!=0&&menu!=1){delay_ms(100);menu++;flag=0;ClearLcd();}
if(btn_b==0&&menu!=0&&menu!=1){delay_ms(100);menu--;flag=0;ClearLcd();}
if(menu>=8){menu=0;}
if(menu==2)
{
if(flag==0){ read_time(); flag=1;}
if(btn_plus==0){delay_ms(100);hour++;}
if(btn_minus==0){delay_ms(100);hour--;}
}
if(menu==3)
{
if(flag==0){ read_time(); flag=1;}
if(btn_plus==0){delay_ms(100);minut++;}
if(btn_minus==0){delay_ms(100);minut--;}
}
if(menu==4)
{
if(flag==0){ read_time(); flag=1;}
if(btn_plus==0){delay_ms(100);sek++;}
if(btn_minus==0){delay_ms(100);sek--;}
}
if(hour>=24){hour=0;}
if(minut<1){minut=59;hour--;}
if(minut>=60){minut=0;hour++;}
if(sek<1){sek=59;minut--;}
if(sek>=60){sek=0;minut++;}
if(menu>1){ rtc_set_time(hour,minut,sek);} //установить время: часы, минуты, секунды
if(menu==5)
{
if(flag==0){ read_date(); flag=1;}
if(btn_plus==0){delay_ms(100);day++;}
if(btn_minus==0){delay_ms(100);day--;}
}
if(menu==6)
{
if(flag==0){ read_date(); flag=1;}
if(btn_plus==0){delay_ms(100);month++;}
if(btn_minus==0){delay_ms(100);month--;}
}
if(menu==7)
{
if(flag==0){ read_date(); flag=1;}
if(btn_plus==0){delay_ms(100);year++;}
if(btn_minus==0){delay_ms(100);year--;}
}
if(day>=32){day=1;month++;}
if(day<1){day=31;month--;}
if(month>=13){month=1;year++;}
if(month<1){month=12;year--;}
if(year>=255){year=0;}
if(menu>1){ rtc_set_date(day,month,year);} //установить date
}
void lcd()
{
if(menu==0)
{
LcdPutLine("Сегодня:", 2, 1); // вывели текст
sprintf( buff,"%i.%i.%i г ", d,mo,y+2000 );
LcdPutLine(buff, 2, 2);
LcdPutLine("Время:", 2, 3); // вывели текст
sprintf( buff,"%i:%i%i:%i%i ", h,m/10,m%10,s/10,s%10 );
LcdPutLine(buff, 2, 4);
}
if(menu==1)
{
LcdPutLine(" Режим", 2, 3); // вывели текст
LcdPutLine(" Настроек", 2, 4); // вывели текст
delay_ms(500);
}
if(menu==2)
{
LcdPutLine("Сегодня:", 2, 1); // вывели текст
sprintf( buff,"%i.%i.%i г ", d,mo,y+2000 );
LcdPutLine(buff, 2, 2);
LcdPutLine("Время:", 2, 3); // вывели текст
sprintf( buff,"%i<%i%i:%i%i ", h,m/10,m%10,s/10,s%10 );
LcdPutLine(buff, 2, 4);
}
if(menu==3)
{
LcdPutLine("Сегодня:", 2, 1); // вывели текст
sprintf( buff,"%i.%i.%i г ", d,mo,y+2000 );
LcdPutLine(buff, 2, 2);
LcdPutLine("Время:", 2, 3); // вывели текст
sprintf( buff,"%i:%i%i<%i%i ", h,m/10,m%10,s/10,s%10 );
LcdPutLine(buff, 2, 4);
}
if(menu==4)
{
LcdPutLine("Сегодня:", 2, 1); // вывели текст
sprintf( buff,"%i.%i.%i г ", d,mo,y+2000 );
LcdPutLine(buff, 2, 2);
LcdPutLine("Время:", 2, 3); // вывели текст
sprintf( buff,"%i:%i%i:%i%i< ", h,m/10,m%10,s/10,s%10 );
LcdPutLine(buff, 2, 4);
}
if(menu==5)
{
LcdPutLine("Сегодня:", 2, 1); // вывели текст
sprintf( buff,"%i<%i.%i г ", d,mo,y+2000 );
LcdPutLine(buff, 2, 2);
LcdPutLine("Время:", 2, 3); // вывели текст
sprintf( buff,"%i:%i%i:%i%i ", h,m/10,m%10,s/10,s%10 );
LcdPutLine(buff, 2, 4);
}
if(menu==6)
{
LcdPutLine("Сегодня:", 2, 1); // вывели текст
sprintf( buff,"%i.%i<%i г ", d,mo,y+2000 );
LcdPutLine(buff, 2, 2);
LcdPutLine("Время:", 2, 3); // вывели текст
sprintf( buff,"%i:%i%i:%i%i ", h,m/10,m%10,s/10,s%10 );
LcdPutLine(buff, 2, 4);
}
if(menu==7)
{
LcdPutLine("Сегодня:", 2, 1); // вывели текст
sprintf( buff,"%i.%i.%i< ", d,mo,y+2000 );
LcdPutLine(buff, 2, 2);
LcdPutLine("Время:", 2, 3); // вывели текст
sprintf( buff,"%i:%i%i:%i%i ", h,m/10,m%10,s/10,s%10 );
LcdPutLine(buff, 2, 4);
}
}
void main(void)
{
// Port B initialization
PORTB=0x00;
DDRB=0x3F;
// Port C initialization
PORTC=0x70;
DDRC=0x00;
// Port D initialization
PORTD=0x00;
DDRD=0xF0;
PORTD.0=1;
PORTD.1=1;
PORTD.2=1;
PORTD.3=1;
// I2C Bus initialization
i2c_init();
// DS1307 Real Time Clock initialization
// Square wave output on pin SQW/OUT: Off
// SQW/OUT pin state: 0
rtc_init(0,0,0);
LcdInit();
ClearLcd();
LcdContrast (40);
while (1)
{
read_time();
read_date();
lcd();
btn();
}
}
При включени сразуже отображается дата и время. Если нажать кнопку «MENU» то на экране кратковременно появится надпись «Режим настроек» — после этого на дисплее появится стрелка указывающая на изменяемый параметр. Навигация осуществляется той же кнопкой + кнопка «DOWN» для возврата на предыдущий параметр.
Думаю в пояснении схема больше не нуждается, если что то не понятно спрашивайте на форуме или в коментариях.
ВНИМАНИЕ!
Если у вас не работают часы — проверьте питание! — оно должно быть не менее 4,5В! При меньшем напряжении микросхема работает нестабильно, а то и вообще никак!
Скачать проект Часы DS1307 Скачали раз

А можно попросить схему подключению к какому нибудь другому LCD? к той же NOKIA7110. Спасибо
Эта прошивка не будет работать с другими дисплеями — для них нужно писать программу отдельно.
написал на форуме, еще в пятницу, до сих пор модерацию не прошел мой пост(((
Возможно Ваш пост не прошёл анти-спам проверку… Что бы писать без модерации нужно быть зарегистрированным пользователем — вы зарегистрированы?
А вы пробывали собрать часы из статьи? или сразу полезли код править?
Собрал в кодевизе 3.19, часы идут(единственно переписал немного под библиотеку LPH9157-2, ну нету у меня 3310:-), работает часы идут, но только стоит нажать на меню, вечно крутит «меню настроек» и на этом все(((
вот код:
#include #include #include #include // библиотека преобразоания чисел в символьную строку #include // библиотека преобразования символов в число #include //библиотека работы со строками #include //#include "NokiaLCD.h" //#include "lcd_3310.c" // I2C Bus functions #asm .equ __i2c_port=0x15 ;PORTC .equ __sda_bit=4 .equ __scl_bit=5 #endasm #include // DS1307 Real Time Clock functions #include #define btn_m PINC.2 #define btn_minus PINC.1 #define btn_plus PINC.0 #define btn_b PIND.3 unsigned char buff [99]; //буфер дисплея unsigned char hour,minut,sek; //часы, минуты, секунды unsigned char m,h,s; //часы, минуты, секунды unsigned char week_day,day,month,year; //день, месяц, год unsigned char d,mo,y; //день, месяц, год unsigned char flag,menu; flash char char_2[] = {"Сегодня"}; flash char char_4[] = {"Меню настройки"}; flash char char_1[] = {"Время"}; void read_time() { rtc_get_time(&hour,&minut,&sek); //считать время h=hour; m=minut; s=sek; } void read_date() { rtc_get_date(&week_day,&day,&month,&year); //считать дату //w=week_day; d=day; mo=month; y=year; } void btn() { if(btn_m==0&&menu==0){menu=1;LCD_FillScreen (0);} if(menu==1){if(btn_m!=0){menu=2;LCD_FillScreen (0);}} if(btn_m==0&&menu!=0&&menu!=1){delay_ms(100);menu++;flag=0;LCD_FillScreen (0);} if(btn_b==0&&menu!=0&&menu!=1){delay_ms(100);menu--;flag=0;LCD_FillScreen (0);} if(menu>=8){menu=0;} if(menu==2) { if(flag==0){ read_time(); flag=1;} if(btn_plus==0){delay_ms(100);hour++;} if(btn_minus==0){delay_ms(100);hour--;} } if(menu==3) { if(flag==0){ read_time(); flag=1;} if(btn_plus==0){delay_ms(100);minut++;} if(btn_minus==0){delay_ms(100);minut--;} } if(menu==4) { if(flag==0){ read_time(); flag=1;} if(btn_plus==0){delay_ms(100);sek++;} if(btn_minus==0){delay_ms(100);sek--;} } if(hour>=24){hour=0;} if(minut=60){minut=0;hour++;} if(sek=60){sek=0;minut++;} if(menu>1){ rtc_set_time(hour,minut,sek);} //установить время: часы, минуты, секунды if(menu==5) { if(flag==0){ read_date(); flag=1;} if(btn_plus==0){delay_ms(100);day++;} if(btn_minus==0){delay_ms(100);day--;} } if(menu==6) { if(flag==0){ read_date(); flag=1;} if(btn_plus==0){delay_ms(100);month++;} if(btn_minus==0){delay_ms(100);month--;} } if(menu==7) { if(flag==0){ read_date(); flag=1;} if(btn_plus==0){delay_ms(100);year++;} if(btn_minus==0){delay_ms(100);year--;} } if(day>=32){day=1;month++;} if(day=13){month=1;year++;} if(month=255){year=0;} if(menu>1){ rtc_set_date(week_day,day,month,year);} //установить date } void lcd() { if(menu==0) { LCD_Putsf (char_2, 68, 6, RED, 0,0,0); // вывели текст sprintf( buff,"%i.%i.%iг ", d,mo,y+2000 ); LCD_Puts (buff, 40, 20, BLUE, 0,2,2); LCD_Putsf (char_1, 76, 40, YELLOW, 0,0,0); sprintf( buff,"%i:%i%i:%i%i ", h,m/10,m%10,s/10,s%10 ); LCD_Puts (buff, 40, 54, GREEN, 0,2,2); delay_ms(20); } if(menu==1) { LCD_Putsf (char_4, 50, 15, NAVY, 0,1,1); //LcdPutLine(" Настроек", 2, 4); // вывели текст delay_ms(100); } if(menu==2) { LCD_Putsf (char_2, 68, 6, RED, 0,0,0); // вывели текст sprintf( buff,"%i.%i.%iг", d,mo,y+2000 ); LCD_Puts (buff, 40, 20, BLUE, 0,2,2); LCD_Putsf (char_1, 76, 40, YELLOW, 0,0,0); // вывели текст sprintf( buff,"%i:%i%i:%i%i", h,m/10,m%10,s/10,s%10 ); LCD_Puts (buff, 40, 54, GREEN, 0,2,2); } if(menu==3) { LCD_Putsf (char_2, 68, 6, RED, 0,0,0); // вывели текст sprintf( buff,"%i.%i.%iг", d,mo,y+2000 ); LCD_Puts (buff, 40, 20, BLUE, 0,2,2); LCD_Putsf (char_1, 76, 40, YELLOW, 0,0,0); // вывели текст sprintf( buff,"%i:%i%i:%i%i", h,m/10,m%10,s/10,s%10 ); LCD_Puts (buff, 40, 54, GREEN, 0,2,2); } if(menu==4) { LCD_Putsf (char_2, 68, 6, RED, 0,0,0); // вывели текст sprintf( buff,"%i.%i.%iг", d,mo,y+2000 ); LCD_Puts (buff, 40, 20, BLUE, 0,2,2); LCD_Putsf (char_1, 76, 40, YELLOW, 0,0,0); // вывели текст sprintf( buff,"%i:%i%i:%i%i", h,m/10,m%10,s/10,s%10 ); LCD_Puts (buff, 40, 54, GREEN, 0,2,2); } if(menu==5) { LCD_Putsf (char_2, 68, 6, RED, 0,0,0); // вывели текст sprintf( buff,"%i.%i.%iг", d,mo,y+2000 ); LCD_Puts (buff, 40, 20, BLUE, 0,2,2); LCD_Putsf (char_1, 76, 40, YELLOW, 0,0,0); // вывели текст sprintf( buff,"%i:%i%i:%i%i", h,m/10,m%10,s/10,s%10 ); LCD_Puts (buff, 40, 54, GREEN, 0,2,2); } if(menu==6) { LCD_Putsf (char_2, 68, 6, RED, 0,0,0); // вывели текст sprintf( buff,"%i.%i.%iг", d,mo,y+2000 ); LCD_Puts (buff, 40, 20, BLUE, 0,2,2); LCD_Putsf (char_1, 76, 40, YELLOW, 0,0,0); // вывели текст sprintf( buff,"%i:%i%i:%i%i", h,m/10,m%10,s/10,s%10 ); LCD_Puts (buff, 40, 54, GREEN, 0,2,2); } if(menu==7) { LCD_Putsf (char_2, 68, 6, RED, 0,0,0); // вывели текст sprintf( buff,"%i.%i.%iг", d,mo,y+2000 ); LCD_Puts (buff, 40, 20, BLUE, 0,2,2); LCD_Putsf (char_1, 76, 40, YELLOW, 0,0,0); // вывели текст sprintf( buff,"%i:%i%i:%i%i", h,m/10,m%10,s/10,s%10 ); LCD_Puts (buff, 40, 54, GREEN, 0,2,2); } } void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=T State6=T State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 //PORTB=0x00; //DDRB=0x3F; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=P State5=P State4=P State3=T State2=T State1=T State0=T //PORTC=0x70; //DDRC=0x00; // Port D initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In // State7=0 State6=0 State5=0 State4=0 State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0xF0; PORTC.0=1; PORTC.1=1; PORTC.2=1; PORTC.3=1; // I2C Bus initialization i2c_init(); // DS1307 Real Time Clock initialization // Square wave output on pin SQW/OUT: Off // SQW/OUT pin state: 0 rtc_init(0,0,0); LCD_init(); SetArea (0,176,0,132); SetRotation(270); LCD_FillScreen (0); //LcdContrast (40); while (1) { read_time(); read_date(); lcd(); btn(); } }в декларации порта С исправил ошибку, но результата нет, если принудительно отправляю в программе на меню2 т.е. установку hour +- кнопки работают, но дальше не переключается, т.е я так понимаю при нажатии не добавляется отнимается menu вопрос почему?
Смотрите Ваш код — очевидно что ошибка в обработке функции кнопок… Подтяжка включена? Проверьте все те изменения которые вносили. И исходник лучше из архива возьмите. В комментариях Ваш код неправильно отображается — пишите или на почту или на форуме.
Артем, вы не могли бы скинуть готовый *.hex? С CVAVR 2.05.0 вылезло еще больше ошибок( Заранее спасибо.
в архиве проекта есть hex файл — в папке exe
попробую скачать эту версию
с проекта под статьёй
скобочки нет, потому что копировал часть кода ))) странно, распаковал проект снова, те же ошибки:
if(menu==7)
{
if(flag==0){ read_date(); flag=1;}
if(btn_plus==0){delay_ms(100);year++;}
if(btn_minus==0){delay_ms(100);year—;}
}
if(day>=32){day=1;month++;}
if(day=13){month=1;year++;}
if(month=255){year=0;}
if(menu>1){ rtc_set_date(day,month,year);} //установить date
}
127 строка
void read_date()
{
rtc_get_date(&day,&month,&year); //считать дату
d=day;
mo=month;
y=year;
}
63 строка
Странный какой то глюк…только что скачал и проверил у себя — всё компилируется… Может изза версии компилятора — у меня стоит версия CVAVR 2.05.0
При компиляции исходников, выдает ошибку :
C:\DS1307\h.c(127): too few arguments in function call
( if(menu>1){ rtc_set_date(day,month,year); )
C:\DS1307\h.c(63): too few arguments in function call
( rtc_get_date(&day,&month,&year); //считать дату )
А вы исходник со статьи брали или с проекта под статьёй? — скачайте весь проект и там уже редактируйте…всё должно работать.
там где строка 127 у вас незакрыта фигурная скобка условия IF — }.
Столкнулся с подобной проблемой при компиляции проекта под Атмега64.
Ошибка говорит о том что не достаточно переменных для функции.
Вот так ошибку не выдает:
( if(menu>1){ rtc_set_date(week_day,day,month,year); )
( rtc_get_date(&week_day,&day,&month,&year); //считать дату )
Артем понимаю что вы уже наигрались 🙂 но вот хочу подкинуть такую задачу у меня не получается:) может вы натолкнёте на идею. Проблема вот в чем камень будет реализоывать не только часы поэтому нужно его как то разгрузить а часики его грузят основательно 🙂 поэтому решил я сделать индикацию 1 раз в секунду с помощью внешнего прерывания по INT0 от выходного такта 1307 SOUT настроенного на 1Hz так вот отдельно все работает и часы и прерывание но когда все это сединяю в протеусе выдает крик души ято в дисплее была попытка чтения после записи полубайта не могу раскусить что делать вызов показа времени идёт прямо из обработчика прерывания может здесь проблема?
Этот выход слаботочный — возможно из-за этого…ну и плюс ко всему протеус не всегда корректно моделирует — поэтому лучше в макете проверить. А вообще по вызову прерывания всё должно работать.
Ещё можно вообще отказаться от внешней микросхемы и использовать асинхронный режим таймера с длительностью 1 секунда (+немного строк кода для реализации часиков) — может это займет меньше ресурсов, но не факт))
Хорошии часы.Спасибо
Не за что, пользуйтесь на здоровье 😉 Может в будущем будет модификация, но маловероятно — так как разрабатывалось чисто для примера и заодно с DS-кой поиграться 🙂
Скачал новые прошивки.Часы заработали.БОЛЬШОЕ спасибо.
правда не понял в чем была проблема.
Я поменял некоторые типы переменных, но дело в том что в в других моих проектах работает и по старому, правда дисплеи там от winstar — возможно из-за этого.
Проверил.Все подключено правильно.Попробовал в протеусе
время не меняется.Точно так же как и у меня на платe.
В протеусе они "тикают" медленно — проверил у себя работают. на всякий случай перезалил файлы — попробуйте скачать новые файлы прошивки.
кварц , батарейку поставил. фьюзы выстовил. экран работает но часы не запускаются
Проверьте цепь кварца DS1307(кстати без канденсаторов она не всегда запускается), также правильность подключения выводов SCL и SDA.
собрал часы реального времени DS1307 на AVR.Но они не работают,почему?
кварц для меги и DS-ки, батарейку для часов поставили? фьюзы правильно настроили? экран работает? если да то что пишет?