Понедельник, 21.09.2020, 19:16
Микроконтроллерная техника AVR
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
Меню сайта
Помоги сайту
Поддержи наш сайт
Через WebMoney
U222865683087
R391933670808
Z877043628365
E649133782052

или пополни нашу SMS копилку
SMS.копилка

Ссылки

 Каталог статей
Главная » Статьи » Учимся работать с AVR

Делаем точные часы с календарем на DS1307 + LCD + ATMEGA8, с меню и будильником.
Привет! Итак, начнем!
Сначала немного теории:
DS1307 - часы реального времени с последовательным интерфейсом - низкая потребляемая мощность, полный BCD календарь, часы плюс 56 байтов энергонезависимого статического ОЗУ. Адрес и данные передаются последовательно через 2-проводную двунаправленную шину. Часы / календарь хранят следующую информацию: секунды, минуты, часы, день, дату, месяц и год. Конец месяца автоматически подстраивается для месяцев, в которых менее 31 дня, включая поправку для високосного года. Часы работают в 24-часовом или 12-часовом формате с индикатором AM/PM. DS1307 имеет встроенную схему контроля питания, которая обнаруживает пропадание питания и автоматически переключает схему на питание от батареи.


         DS1307

С использованием этой микросхемы минимально будет грузиться наш микроконтроллер.

Итак приступим, создадим новый проект мастером.


дальше установим все ножки порта D как выход з подтяжкой резисторов pull-up (пометка - P)

Включим саму шину I2C.

Дальше подкорректируем и допишем код со всеми условиями и соберем схему.

КОД:

#include <mega8.h>

// I2C Bus functions
#asm
  .equ __i2c_port=0x12 ;PORTD
  .equ __sda_bit=0
  .equ __scl_bit=1
#endasm
#include <i2c.h>

// DS1307 Real Time Clock functions
#include <ds1307.h>

// Alphanumeric LCD Module functions
#asm
  .equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
#include <delay.h>
// Declare your global variables here
unsigned char hour,min,sek; //часы, минуты, секунды
unsigned char day,month,year; //день, месяц, год
unsigned int inf=0; // переменная меню
bit alm=0; // будильник вкл/выкл
unsigned char a_hour,a_min; // переменные где храняться время срабатывания будильника
void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0xFF;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0xFF;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// 2 Wire Bus initialization
// Generate Acknowledge Pulse: Off
// 2 Wire Bus Slave Address: 0h
// General Call Recognition: Off
// Bit Rate: 400,000 kHz
TWSR=0x00;
TWBR=0x02;
TWAR=0x00;
TWCR=0x04;

// 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 module initialization
lcd_init(16);

rtc_set_date(01,03,9); //установить дату: день,месяц,год
rtc_set_time(23,59,59); //установить время: часы, минуты, секунды

while (1)
  {
  // Place your code here
   
   
  rtc_get_time(&hour,&min,&sek); //считать время
  rtc_get_date(&day,&month,&year); //считать дату
  if (PINC.0==0) // если нажата первая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  inf++; // к значению минуты добавляем еденицу 
  }
  if (inf==0)
  {  
  lcd_clear();
  lcd_gotoxy(0,0);
  lcd_putsf("Time is=");
  lcd_putchar(hour/10+0x30);
  lcd_putchar(hour%10+0x30);
  lcd_putchar(':');
  lcd_putchar(min/10+0x30);
  lcd_putchar(min%10+0x30);
  lcd_putchar(':');
  lcd_putchar(sek/10+0x30);
  lcd_putchar(sek%10+0x30);
  lcd_gotoxy(0,1);
  lcd_putsf("Date is=");
  lcd_putchar(day/10+0x30);
  lcd_putchar(day%10+0x30);
  lcd_putchar('-');
  lcd_putchar(month/10+0x30);
  lcd_putchar(month%10+0x30);
  lcd_putchar('-');
  lcd_putchar(year/10+0x30);
  lcd_putchar(year%10+0x30);
  // проверка на будильник
  if ((alm==1)&(a_min==min)&(a_hour==hour))
  PORTD.2=1;
  // отключение будильника
  if (PINC.5==0) 
  {  
  alm=0;
  PORTD.2=0;
  } 
  }
  if (inf==1)
  {
  
  lcd_clear();
  lcd_putsf("Set Time");
  lcd_gotoxy(0,1);
  lcd_putchar(hour/10+0x30);
  lcd_putchar(hour%10+0x30);
  lcd_putchar(':');
  lcd_putchar(min/10+0x30);
  lcd_putchar(min%10+0x30);
  if (PINC.1==0) // если нажата первая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  min++;
  }
  if (PINC.2==0) // если нажата вторая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  min--;
  }
  if (PINC.3==0) // если нажата третья кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  hour++;
  }
  if (PINC.4==0) // если нажата четвертая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  hour--;
  }
   
  if (min==60||min==255) // если мин = 60 или 255
  {
  min=0; // зануляем переменную "минута"
  }
  if (hour==24||hour==255) // так как у нас часы имеют 24 часовый формат
  { // при достыжении 24 часов, онулируем все переменные.
  hour=0;
  }
  rtc_set_time(hour,min,sek); // установка времени
  }
  
  if (inf==2)
  {
  lcd_clear();
  lcd_putsf("Set Data");
  lcd_gotoxy(0,1);
  lcd_putchar(day/10+0x30);
  lcd_putchar(day%10+0x30);
  lcd_putchar('-');
  lcd_putchar(month/10+0x30);
  lcd_putchar(month%10+0x30);
  lcd_putchar('-');
  lcd_putchar(year/10+0x30);
  lcd_putchar(year%10+0x30);
  if (PINC.1==0) // если нажата первая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  day++;
  }
  if (PINC.2==0) // если нажата вторая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  month++;
  }
  if (PINC.3==0) // если нажата третья кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  year++;
  }
  // условие на переолнение 
  if (day==32)
  day=0;
  if (month==13)
  month=0;
  if (year==99)
  year=0;  
  rtc_set_date(day,month,year); //установить дату: день,месяц,год
  }
  if (inf==3)
  {
  lcd_clear();
  lcd_putsf("Set ALARM");
  lcd_gotoxy(0,1);
  lcd_putchar(a_hour/10+0x30);
  lcd_putchar(a_hour%10+0x30);
  lcd_putchar(':');
  lcd_putchar(a_min/10+0x30);
  lcd_putchar(a_min%10+0x30);
  if (PINC.1==0) // если нажата первая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  a_min++;
  }
  if (PINC.2==0) // если нажата вторая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  a_min--;
  }
  if (PINC.3==0) // если нажата третья кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  a_hour++;
  }
  if (PINC.4==0) // если нажата четвертая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  a_hour--;
  }
   
  if (a_min==60||a_min==255) // если мин = 60 или 255
  {
  a_min=0; // зануляем переменную "минута"
  }
  if (a_hour==24||a_hour==255) // так как у нас часы имеют 24 часовый формат
  { // при достыжении 24 часов, онулируем все переменные.
  a_hour=0;
  }
  
  }
  if (inf==4)
  {
  lcd_clear();
  lcd_putsf("ON/OFF Alarm");
  if (PINC.5==0) // on/off alarm
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  alm++;
  }
  lcd_gotoxy(0,1);
  if (alm==0)
  lcd_putsf("Alarm OFF");
  if (alm==1)
  lcd_putsf("Alarm ON");  
  }
  if (inf==5)
  inf=0;
  }  
   
  };

Есть одна особенность, здесь мы используем маленькое меню на 4 пункта.

Особенность роботы.
В нормальном режиме мы видим время и дату. Дальше при нажатии на первую кнопку МК переходит в режим настройки времени, еще раз нажимаем на кнопку и МК переходит в режим настройки даты, еще раз и в режим настройки будильника, после очередного нажатия кнопки мы переходим в режим установки будильника ВКЛ/ВЫКЛ будильник. Стандартно будильник выключен.Следующие кнопки служат для установки времени и даты, смотря в каком режиме находиться МК. Последняя кнопка служит для выключения светодиода после срабатывание будильника. В место светодиода можно использовать Buzzer. 
Будьте внимательны по подключению DS1307, подключайте согласно даташиту.

Все файлы по проекту в разделе «файлы».


Категория: Учимся работать с AVR | Добавил: my-avr (09.02.2009)
Просмотров: 65992 | Комментарии: 39 | Рейтинг: 4.3/7 |
Всего комментариев: 391 2 3 4 »
0
39 gafarovagulnaz   [Материал]
а как можно объединить 2 работы: часы и плавную регулировку яркости?

0
38 UR5WDI   [Материал]
Ребята в моем КодВижене нет библиотеки ds1307, киньте пожалуста на мыло ur5wdi@meta.ua

Заранее благодарен !

0
37 werter8   [Материал]
Собрал. Не работает. На жк дисплее ничего нет.
Дисплей использовал wh1602b. Пробовал два той же марки - результат один.
В чем может быть проблема? Какие фьюзы выставлять?

0
36 Антошин   [Материал]
Тема хорошая,жаль только что архив поврежден,сам скомпилировать не могу Codevision
требует коммерческую версию.Просьба - выложите хотя бы прошивочку.

0
35 borodavkin93   [Материал]
Запускаю в протеусе этот проект и загрузка CPU 100% и при этом часы тормозят жестко, почему так? angry

0
34 Алексей   [Материал]
Здравствуйте. Всё нашел, вопрос снимается.
" 32 HiSER (26.06.2011 11:00)
Есть здесь все, времени нет...
И рекламу давать других сайтов это не хорошо..."
А как быть, если все молчат. Кому тут вопросы задавать, я задал а что толку.

0
33 Алексей   [Материал]
Здравствуйте. Вот решил попробовать часы реального времени, но при компиляции программы, выскакивает ошибка. Начал разбираться, оказалось что в CodeVision не было #include <ds1307.h>, а точнее библиотеки и хидера. Как у Вас всё работало? Если есть библиотека, и хидер - скиньте пожалуйста ссылку.

0
31 Oleg   [Материал]
Вобщем всё сделал, вся загвоздка была в том, что не было батарейки(или не была vBat заземлена) сейчас часики тикают(проверил это путём передачи из МК через RS-232 переменной, которая получает данные с таймера с помощью функции rtc_get_time(&hour,&min,&sek)).
Спасибо огромное Medved’у, что помог в этой ситуации...
его страничка http://avrdevices.ru
там много чего интересного можно вычитать и совет ещё дадут)
Жаль, что здесь нет тех. поддержки.

0
32 HiSER   [Материал]
Есть здесь все, времени нет...
И рекламу давать других сайтов это не хорошо...

0
30 Oleg   [Материал]
Добрый день! Уже совсем всё перепробывал! уже и новый кварц ставил, и таймер менял, и резисторы какие-только не пробовал....
вообщем подключил всё как на схеме( подключил к scl и sda резисторы на 4.7 кОм). Создал проект с помощью визарда. скомпилил.
Импульсы на ножках scl и sda идут, при нажатии на кнопку ( при нажатии на кнопку запускается процеудра rtc_get_time(&hour,&min,&sek);)
Всё вроде бы хорошо, НО... На кварце(а он 32.768 кГц) нет синусоиды, на одной ножке (X2) примерно +0.5 В, на другой (X1) 0В. импульсы от SQW/OUT не идут....То есть таймер похоже не запускается....Я уже второй такой таймер подключаю... и ничего.... вообщем уже завозился с ним, помогите, кто сможет! Заранее спасибо!)

0
29 Anton   [Материал]
Когда разбирался с программой выяснились следующие моменты:
1. DS1307 не работает при частоте 2Wire больше 100кГц(См datasheet). В авторском варианте 400кГц. Я так понимаю автор моделировал в Proteus, а он не обращает внимания на частоту.
2. Если есть малейшая помеха по питанию обмен данными с DS1307 происходит не корректно.

1-10 11-20 21-30 31-34
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Copyright My-AVR © 2020
Наша кнопка
У нас появилась кнопка, код кнопки:

Лаборатория самоделок на микроконтроллерах AVR

Форма входа
Наш опрос
Какой МК вы используете?
Всего ответов: 3213
Статистика/Друзья
CY-PR.com



Онлайн всего: 1
Гостей: 1
Пользователей: 0

РадиоКОТ - популярно об электронике. Авторские схемы, новые разработки. Обучение по электронике, микроконтроллерам, ПЛИС. Форум Сайт по радиоэлектронике. У нас все просто и интересно… ARV Reserch: Электроника — просто, полезно, увлекательно. Электронные устройства и программные средства для радиолюбителей и профессионалов, только авторские разработки, плагиата нет! Разработки на заказ. AVR projects Создание электронных роботов своими руками Схемы и программы на AVR http://ur5yfv.ucoz.ua/BANNER.gif Блог начинающего эмбеддера. Дай волю паяльнику! Самоделки на all-make.ru Принципиальные схемы Модулі автозапуску бензогенератора та системи АВР, електромонтажні роботи
Хостинг от uCoz