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);
Недавні записи
- LCD Display ST7567S (IIC)
- Розпізнавання мови (Speech recognition)
- Selenium
- Комп'ютерний зір (Computer Vision)
- Деякі думки про точність вимірювань в електроприводі
- Датчики Холла 120/60 градусів
- Модуль драйверів напівмосту IGBT транзисторів
- Драйвер IGBT транзисторів на A316J
- AS5600. Варіант встановлення на BLDC мотор
- DC-DC для IGBT драйверів ізольований 2 W +15 -8 вольт
Tags
battery soldering java-script ngnix adc rs-232 flask esp8266 watchdog web exti solar mongodb rtc sms pwm usart books ethernet smd git websocket meteo css python dc-dc displays led ssd1306 eeprom gpio barometer max1674 mpx4115a brushless motor mpu-6050 timer sensors remap servo bldc atmega pmsm 3d-printer flash encoder examples dma raspberry-pi tim ssd1331 piezo mpu-9250 rfid eb-500 foc bme280 gps nvic dht11 bluetooth hih-4000 stm32 st-link docker uart avr html wifi bmp280 bkp nodemcu options usb lcd programmator i2c capture
Архіви