Главная » Статьи » Как подключить |
Порой хочется в разрабатываемом устройстве организовать подсчет текущего времени/даты. Если возложить эту обязанность на МК могут возникнуть проблемы с точностью хода часов, потерей данных при пропадании питания или банальная нехватка места в памяти микроконтроллера. Поэтому задачу по счету времени лучше всего оставлять микросхемам, которые заточены под такое дело. Например, популярная микросхема 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 минут и часы это схавают и не подавятся. Я не стал делать проверку с целью упрощения понимания кода.
Точность часов в основном зависит от точности примененного кварца, у себя я использовал кварц выдернутый с материнской платы, и за те два дня которые проходили часы идут секунду в секунду.
Программу для вывода русских символов на ЖКИ берем отсюда
Ниже можно скачать прошивку с исходниками и проект в протеусе:
| |
Просмотров: 68496 | Комментарии: 41
| Теги: |
Всего комментариев: 41 | 1 2 » | ||||||||||||||||||||||||||
| |||||||||||||||||||||||||||
1-30 31-41 | |||||||||||||||||||||||||||
Проекты [46] |
Как подключить [32] |
Инструменты [3] |
Полезная информация [18] |
Объявления [3] |