DS1302 Побеждаем время. ds1302.c для WinAVR (GCC)
DS1302 - это микросхема реального времени. Она обеспечивает ход времени, даже когда основное устройство отключено от питания.
Основные характеристики:
- - простота подключения к микроконтроллеру по трехпроводному интерфейсу.
- - питание от 2 до 5.5 В.
- - из внешних элементов часовой кварц 32768 Гц и батарейка резервного питания 3В (я использую RC2032). Батарейки хватает надолго, микросхема потребляет около 300 нА (наноампер)!
- - считает секунды, минуты, часы, день месяца, месяц, год, день недели. Учитываются високосные года. Микросхема сможет работать до 2100года. Дальше не хватит счетчика лет. Это, несомненно, опечалило меня. :)
- - отображение времени в 12 или 24 часовом режимах с отображением AM или PM
Нюансы
Иногда пишут "в микросхеме есть встроенный календарь до 2100 года". Не спешите удивляться, это всего лишь означает, что подсчет времени ведется с учетом високосных лет. И все! На самом деле даже день недели надо устанавливать. Т.е. день недели не определяется по установленной дате. День недели работает как простой счетчик и переключается в полночь. Но с другой стороны, это очень удобно. Ведь в Восточной Европе принято считать первый день недели понедельник, а на западе первый день недели - воскресенье. В данном случае микросхеме абсолютно все равно. Устанавливаем текущий день недели по собственному исчислению, а дальше он будет изменяться каждую полночь.Подключение к МК
Распиновка микросхемы:
Подключение к микроконтроллеру:

взяты с документации, которую можно скачать здесь: DS1302.pdf
Для тестов я взял свою отладочную плату и подключил микросхему к ней, припаяв кварц и держатель батарейке RC2032 прямо к ногам микросхемы. Для отображения времени использовал символьный LCD.
Библиотека для GCC WinAVR
Честно говоря, сразу я хотел не заморачиваться и использовать уже готовую библиотеку. Так и сделал, скачал даже две. Одну написал русский программист, а вторую иностранец. Обе не работали должным образом. В первом случае почему-то не выставлялся день больше магического 7 дня месяца, ну конечно, о 12 часовом режиме в России никогда не слышали, а буковки AM PM, для нас славян, чужды и не понятны. Во втором случае... уже догадались? Да! Иностранцы не учли, что где то на планете коварные нации исчисляют время до 24 часов!!! Вдобавок, год записывал (соответственно и считывал) не правильно. Т.е. оно конечно как то работает, но в следующем году вылезут все баги. Плюнул, написал свою простую библиотеку.Перед тем как использовать библиотеку, откроем файл ds1302.h В нем правим только эти параметры:
#define DS1302_E 0
#define DS1302_SCLK 1
#define DS1302_IO 2
#define DS1302_DDR_RTC DDRC
#define DS1302_PORT_RTC PORTC
#define DS1302_PIN_RTC PINC
Т.е. описываем к каким ногам и к какому порту подключена наша ds1302.
Обратите внимание, что в этом же файле описана структура:
typedef struct
{
uint8_t Sec;
uint8_t Min;
uint8_t Hour;
uint8_t Month;
uint8_t Day;
uint8_t Year;
uint8_t WeekDay;
uint8_t AMPM;
uint8_t H12_24;
} tpDateTime;
tpDateTime DateTime;
Через нее и будет выполняться взаимосвязь (запись и чтение) с DS1302.
В библиотеке всего две функции: void DS1302_ReadDateTime(); void DS1302_WriteDateTime();
Для установки времени в микросхеме необходимо 1. В структуру DateTime задать время и режим (12 или 24 часовой) 2. Вызвать функцию DS1302_WriteDateTime();
Для чтения времени из микросхемы: 1. Вызвать функцию DS1302_ReadDateTime(); 2. Читать время и режим из структуры DateTime.
Обратите внимание, что DateTime.AMPM и DateTime.H12_24 задаются следующим образом:
DateTime.AMPM = AM; или DateTime.AMPM = PM;
DateTime.H12_24 = H12; или DateTime.H12_24 = H24;
Пример использования:
#include <avr/io.h>
#include <util/delay.h>
#include "lcd_lib.h"
#include "ds1302.h"
char buffer[16]="";
int main()
{
// Задаем время и параметры (AM/PM следует задавать только при H12)
DateTime.Sec = 57;
DateTime.Min = 59;
DateTime.Hour = 11;
DateTime.Month = 8;
DateTime.Day = 16;
DateTime.Year = 11;
DateTime.WeekDay = 2;
DateTime.AMPM = AM; //AM/PM
DateTime.H12_24 = H12; //H12/H24
// Записываем время в микросхему ds1302
DS1302_WriteDateTime();
// Инициализация дисплея
LCDinit();
LCDcursorOFF();
LCDclr();
while(1)
{
// Читаем время с микросхемы ds1302
DS1302_ReadDateTime();
// Выводим время и дату на дисплей
sprintf(buffer, "%02i:%02i:%02i", DateTime.Hour, DateTime.Min, DateTime.Sec);
LCDGotoXY(0,0);
LCDstring(buffer, 8);
if (DateTime.H12_24 == H12) {
if (DateTime.AMPM == AM){
LCDsendChar(`A`);
}
else {
LCDsendChar(`P`);
}
LCDsendChar(`M`);
}
sprintf(buffer, "%02i-%02i-%02i,%i", DateTime.Day, DateTime.Month, DateTime.Year, DateTime.WeekDay);
LCDGotoXY(0,1);
LCDstring(buffer, 10);
_delay_ms(100);
}
}
Внимание! В примере в следующих строках устанавливается заранее указанное время при старте микроконтроллера.
DateTime.Sec = 57;
DateTime.Min = 59;
DateTime.Hour = 11;
DateTime.Month = 8;
DateTime.Day = 16;
DateTime.Year = 11;
DateTime.WeekDay = 2;
DateTime.AMPM = AM; //AM/PM
DateTime.H12_24 = H12; //H12/H24
// Записываем время в микросхему ds1302
DS1302_WriteDateTime();
Т.е. при каждом включении питания микроконтроллер будет устанавливать одно и то же время. Если в микросхеме уже установлено время (разумеется, при подключенной батарейки), можно закомментировать функцию DS1302_WriteDateTime(); скомпилировать и прошить микроконтроллер новой прошивкой. После чего он будет только читать время из микросхемы.
Библиотека DS1302 обновлена. Исправлен баг при работе в 24 часовом режиме.
...ds1302.c для WinAVR (CGG)... А компилятор не GCC (GNU Compiler Collection)?
:) Спасибо! Смешная опечатка получилась. Исправил.
Это, правда, не так важно, но Столман бы обиделся не на шутку :)
Печалька, у меня не тикают. Данные записываются, читаются а не тикают. (батарейка стоит).
Получилось, оказалось кварц не заводился поменял и всё гуд. Спасибо за статью.
Автор вот подскажите дураку.. При компиляции вашего проекта получаю следуещее... avr-gcc -mmcu=atmega8 -I. -gdwarf-2 -DF_CPU=4000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=test1302.o -std=gnu99 -MMD -MP -MF .dep/test1302.elf.d test1302.o lcd_lib.o --output test1302.elf -Wl,-Map=test1302.map,--cref -lm test1302.o: In function `main`: C:\\ds1302/test1302.c:23: undefined reference to `DS1302_WriteDateTime` C:\\ds1302/test1302.c:33: undefined reference to `DS1302_ReadDateTime` make.exe: *** [test1302.elf] Error 1 что прикажите делать ?
Судя по ошибке файл ds1302.c НЕ включен в проект. <img src="http://www.avislab.com/blog/wp-content/uploads/2011/08/DS1302_WriteDateTime.png" alt="" />
ДД! Попробовал вашу библиотеку - ошибка при считывании дня, а встроенная в CVAVRe работает без ошибки, но там нет дня недели. Жаль. P.S. ДД - это добрый день! :-)
А в чем выражается ошибка? Считывается всегда 0, либо конкретное число?
Число, но не соответсвующее дню (похоже день недели). В CVAVRе прикрутил день недели, там есть функция unsigned char ds1302_read(unsigned char addr);
Tags
bme280 bmp280 gps mpu-6050 options stm32 ssd1331 ssd1306 eb-500 3d-printer soldering tim mpu-9250 dma watchdog piezo exti web raspberry-pi docker ngnix solar bluetooth foc html css brushless flask dc-dc capture gpio avr rs-232 mpx4115a atmega mongodb st-link barometer pwm nvic git java-script programmator dht11 hih-4000 pmsm encoder max1674 smd sensors rtc adc lcd motor timer meteo examples i2c usb flash sms rfid python esp8266 servo books bldc remap eeprom bkp battery ethernet uart usart displays led websocket nodemcu wifi
Архіви