Работа с часами реального времени ds1307

  Порой хочется в разрабатываемом устройстве организовать подсчет текущего времени/даты. Если возложить эту обязанность на МК могут возникнуть проблемы с точностью хода часов, потерей данных при пропадании питания или банальная нехватка места в памяти микроконтроллера. Поэтому задачу по счету времени лучше всего оставлять микросхемам, которые заточены под такое дело. Например, популярная микросхема DS1307, которая способна вести подсчет реального времени в секундах, минутах, часах, датах месяца, месяцах, днях недели и годах с учетом высокосности текущего года вплоть до 2100 г. А автономное питание, которое обеспечивается 3-х вольтовой батарейкой, способно прокормить микросхему в течении 10 лет.

Обвязка минимальная: для работы требуется батарейка на 3 В и кварц на 32768 Гц. Для связи со внешним миром микросхема использует интерфейс I2C. Поэтому, следуя стандарту, линии связи должны быть подтянуты через резисторы 4,7К к шине питания.

  В Bascom-AVR имеется стандартная библиотека, облегчающая работу с данной микросхемой донельзя. Для получения данных о текущем дате и времени нужно выполнить следующий код:

I2cstart                                   ‘ даем режим готовности часам

I2cwbyte &HD0                              ‘ адрес микросхемы

I2cwbyte &H00                              ‘ адрес откуда начачинаем читать данные

I2cstart                                   ‘ даема сигнал старт на прочтение данных

I2cwbyte &HD1                              ‘ даем понять что готовы принимать данные

I2crbyte Seco , Ack                        ‘ ловим секунды

I2crbyte Mine , Ack                        ‘ минуты

I2crbyte Hour , Ack                        ‘ часы

I2crbyte Day , Ack                         ‘ день недели

I2crbyte Dat , Ack                         ‘ число месяца

I2crbyte Month , Ack                       ‘ месяц

I2crbyte Year , Nack                       ‘ год

I2cstop                                    ‘ закончили

  Здесь Seco, mine, hour, day, dat, month и year являются переменными типа byte, которые мы предварительно заводим для хранения данных. Команда Ack после приема байта сообщает микросхеме, что требуется отправить следующий байт. Приняв последний интересующий нас байт, останавливаем отправку командой Nack.     Так как данные в микросхеме хранятся в двоично-десятичном формате, с ними нужно проделать операцию преобразования в десятичный формат:

Seco = Makedec(seco)

Mine = Makedec(mine)

Hour = Makedec(hour)

Day = Makedec(day)

Dat = Makedec(dat)

Month = Makedec(month)

Year = Makedec(year)

  Теперь с этими данными можно делать все что угодно: выводить на дисплей, отправлять в терминал или сравнивать  с заданными значениями, получив таким образом будильник или напоминалку событий.   Но для начала работы, дату и время необходимо ввести в память микросхемы.  В данном проекте организована настройка по UART. В основном цикле происходит постоянное опрашивание микросхемы часов и вывод показаний на ЖКИ дисплей. В подпрограмме вывода на дисплей месяцам даны названия в соответствии с календарем: 1-январь, 2-февраль и так далее.   Приход данных по UART вызывает прерывание, в обработчике которого происходит настройка времени и даты. Например, для настройки часов отправляем через терминал hour и получаем возможность ввести текущий час. Для минут отправляем min, а для секунд sec.

 


$regfile = “m32def.dat”

$crystal = 1000000

$baud = 1200

‘* * * настройка пинов для подключния lcd

Config Lcd = 16 * 2

Config Lcdpin = Pin, Rs=Pinc.5, E=Pinc.4, Db4=Pinc.0, Db5=Pinc.1, Db6=Pinc.2, Db7=Pinc.3

Cls

‘* * * подключаем библиотеку ds1307

$lib “ds1307clock.lib”

‘* * * конфигурируем scl и sda пины

Config Sda = Porta.1 ‘ I2C Data

Config Scl = Porta.0 ‘ I2C Clock

‘* * * заводим константы на биты чтения и записи ds1307

Const Ds1307w = &HD0 ‘ бит записи

Const Ds1307r = &HD1 ‘ бит чтения

‘* * * заводим и разрешаем прерывания от UART

On Urxc Getchar

Enable Interrupts

Enable Urxc

‘* * * заводим переменные для своих нужд

Dim C As Byte

Dim Seco As Byte

Dim Mine As Byte

Dim Hour As Byte

Dim Day As Byte

Dim Dat As Byte

Dim Month As Byte

Dim Year As Byte

Dim S As String * 5            ‘ переменная для работы с UART

Cursor Off

Lcd ” ds1307 clock”

Wait 1

Cls

‘* * * * * * основной цикл программы

Do

Gosub Ds1307                  ‘переход на подпрограмму считывания времени и даты

Gosub Displey                 ‘переход на подпрограмму отображения на дисплей

Loop

‘——————————————————————————-

‘* * * узнаем время и дату

Ds1307:

I2cstart

I2cwbyte Ds1307w

I2cwbyte &H00

I2cstart

I2cwbyte Ds1307r

I2crbyte Seco , Ack

I2crbyte Mine , Ack

I2crbyte Hour , Ack

I2crbyte Day , Ack

I2crbyte Dat , Ack

I2crbyte Month , Ack

I2crbyte Year , Nack

I2cstop

Seco = Makedec(seco)

Mine = Makedec(mine)

Hour = Makedec(hour)

Day = Makedec(day)

Dat = Makedec(dat)

Month = Makedec(month)

Year = Makedec(year)

Return

‘——————————————————————————-

‘* * * подпрограмма вывода на дисплей

Displey:

Locate 1 , 5                     ‘ выводим время

Lcd Hour ; “:” ;

If Mine < 10 Then

Lcd “0” ; Mine ; “:” ;

Else

Lcd Mine ; “:” ;

End If

If Seco < 10 Then

Lcd “0” ; Seco

Else

Lcd Seco

End If

Locate 2 , 3                     ‘ выводим дату

Lcd Dat

Locate 2 , 5

Lcd “-“

Locate 2 , 6                     ‘ обзываем каждый месяц

If Month = 1 Then

Lcd “ЗЅі”                        ‘ январь

End If

If Month = 2 Then

Lcd “дeі”                        ‘ февраль

End If

If Month = 3 Then

Lcd “јap”                        ‘ март и так далее

End If

If Month = 4 Then

Lcd “aѕp”

End If

If Month = 5 Then

Lcd “јaЗ”

End If

If Month = 6 Then

Lcd “ёЖЅ”

End If

If Month = 7 Then

Lcd “ёЖ»”

End If

If Month = 8 Then

Lcd “aіґ”

End If

If Month = 9 Then

Lcd “ceЅ”

End If

If Month = 10 Then

Lcd “oєї”

End If

If Month = 11 Then

Lcd “ЅoЗ”

End If

If Month = 12 Then

Lcd “гeє”

End If

Locate 2 , 9

Lcd “-” ; “20” ; Year

Return

‘——————————————————————————-

‘* * * обработчик прерывания UART

Getchar:

Input S                       ‘ то что пришло по UART

If S = “sec” Then             ‘ настроим секунды

Print “input sec…”

Input C

Seco = C

Seco = Makebcd(seco)          ‘ переводим данные в двоично-десятичный формат

I2cstart                      ‘ подаем сигнал старт

I2cwbyte Ds1307w              ‘ отправляем команду записи

I2cwbyte 0                    ‘ отправляем адрес куда пишем – &H00

I2cwbyte Seco                 ‘ записываем значение переменной по этому адресу

I2cstop                       ‘ закончили работать с I2C

cls

End If

If S = “min” Then             ‘ настроим минуты

Print “input min…”

Input C

Mine = C

Mine = Makebcd(mine)

I2cstart

I2cwbyte Ds1307w

I2cwbyte 1                    ‘ адрес хранения минут &H01

I2cwbyte Mine

I2cstop

Cls

End If

If S = “hour” Then            ‘ настроим часы

Print “input hour…”

Input C

Hour = C

Hour = Makebcd(hour)

I2cstart

I2cwbyte Ds1307w

I2cwbyte 2                    ‘ адрес хранения часов

I2cwbyte Hour

I2cstop

Cls

End If

If S = “dat” Then             ‘ настроим дату

Print “input dat…”

Input C

Dat = C

Dat = Makebcd(dat)

I2cstart

I2cwbyte Ds1307w

I2cwbyte 4                    ‘ адрес хранения даты

I2cwbyte Dat

I2cstop

Cls

End If

If S = “month” Then          ‘ настроим месяц

Print “input month…”

Input C

Month = C

Month = Makebcd(month)

I2cstart

I2cwbyte Ds1307w

I2cwbyte 5                   ‘ адрес хранения месяца

I2cwbyte month

I2cstop

Cls

End If

If S = “year” Then           ‘ настроим год

Print “input year…”

Input C

Year = C

Year = Makebcd(year)

I2cstart

I2cwbyte Ds1307w

I2cwbyte 6                   ‘ адрес хранения года

I2cwbyte Year

I2cstop

Cls

End If

Return

End


 Здесь, как можно заметить, не предусмотрена защита от дурака, данные пришедшие через терминал и записываемые в микросхему не проверяются на истинность, тоесть можно легко ввести 30 часов 86 минут и часы это схавают и не подавятся. Я не стал делать проверку с целью упрощения понимания кода.

 Точность часов в основном зависит от точности примененного кварца, у себя я использовал кварц выдернутый с материнской платы, и за те два дня которые проходили часы идут секунду в секунду.

    Программу для вывода русских символов на ЖКИ берем отсюда   Ниже можно скачать прошивку с исходниками и проект в протеусе:

Скачать
Взято с: avrproject.ru


Категория: AVR
Метки:

Написать коментарий

*
= 4 + 6

Добавить изображение

Последние статьи