'------------------------------------------------------------------------------- 'Название: I2C DS1307 часы на ATmega8 'Версия: 1.2 'Автор: Шумилов К '---------------------------Тип_микроконтроллера-------------------------------- $regfile = "m8def.dat" $crystal = 8000000 '----------------------------Конфигурация_ЖКИ----------------------------------- Config Lcdbus = 4 Config Lcdpin = Pin , Rs = Portb.2 , E = Portb.1 , Db4 = Portb.0 , Db5 = Portd.7 , Db6 = Portd.6 , Db7 = Portd.5 Config Lcd = 16 * 2 Cursor Off Cls '------------------------------Порты-------------------------------------------- '------------I2C--------------------- Config Sda = Portc.4 Config Scl = Portc.5 '-----------Прочее------------------- Config Clock = User Config Date = Dmy , Separator = . Set Portc.0 Set Portc.1 Set Portc.3 Set Portc.2 Cn Alias Pinc.1 'Вниз Cv Alias Pinc.0 'Вверх Vv Alias Pinc.3 'Ввод M Alias Pinc.2 'Меню Config 1wire = Portd.3 'Пин, на который повешан DS18B20 Config Pind.4 = Output 'Пин, на котором висит бипер Spkr Alias Pind.4 '-----------------------Дополнительные_библиотеки------------------------------- $lib "mcsbyte.lbx" $lib "ds1307clock.lib" '--------------------------------Константы-------------------------------------- Const Ds1307w = &HD0 Const Ds1307r = &HD1 '-----------------------------Дополнительные_символы---------------------------- Deflcdchar 0 , 2 , 5 , 5 , 5 , 2 , 32 , 32 , 32 ' знак градус Deflcdchar 1 , 6 , 9 , 9 , 6 , 32 , 32 , 32 , 32 Deflcdchar 2 , 24 , 27 , 4 , 8 , 8 , 8 , 4 , 3 ' replace ? with number (0-7) Deflcdchar 3 , 32 , 32 , 4 , 14 , 31 , 14 , 10 , 14 ' домик Deflcdchar 4 , 32 , 32 , 4 , 14 , 31 , 4 , 4 , 12 ' зонтик '------------------------------Переменные--------------------------------------- Dim J1 As Byte Dim M1 As Byte Dim D1 As Byte Dim H1 As Byte Dim Min1 As Byte Dim Aa As Byte Dim X1 As Byte Dim X2 As Byte Dim X3 As Byte Dim X4 As Byte Dim X5 As Byte Dim Weekday_disp As String * 7 'переменная дня недели, выводимая на дисплей Dim Weekday_read As Byte 'переменная номера дня недели, считываемая из DS1307 Dim Weekday As Byte 'переменная номера дня недели Dim Pos As Byte Dim Digit As Byte Dim Incoming As String * 8 Dim I As Byte Dim Stroka As String * 8 Dim Style As Byte Dim Byte0 As Byte Dim Byte1 As Byte Dim Signtemperatura As String * 1 Dim Temp As Byte Dim Faren0 As Single Dim Faren As Byte Dim T2 As Integer Dim T1 As Single Dim Celsium As String * 5 Dim Dsid1(8) As Byte Dim Dsid2(8) As Byte Dim W As Word Dim Hh As Byte Dim Mm As Byte '------------------------------------Процедуры---------------------------------- Declare Sub Enterdatetime() Declare Sub Getkey() Declare Sub Menu() Declare Sub Digit Declare Sub Style Declare Sub Style1 Declare Sub Style2 Declare Sub Style3 Declare Sub Style4 Declare Sub Minus Declare Sub Plus Declare Sub Gettemp '-----------------------------Оcновной_цикл_программы--------------------------- X3 = 20 X4 = 1 X2 = 10 Style = 1 'Стиль по умолчанию Sound Spkr , 1000 , 500 Do Call Gettemp Call Style If M = 0 Then Gosub Menu End If If Cn = 0 Then Gosub Minus End If If Cv = 0 Then Gosub Plus End If Weekday_read = Dayofweek() 'считываем номер дня недели из DS1307 Weekday_disp = Lookupstr(weekday_read , Weekdays) 'преобразовываем номер дня недели в название дня недели Loop End '------------------------------------------------------------------------------- Sub Minus Sound Spkr , 100 , 800 Cls Style = Style - 1 If Style <= 0 Then Style = 1 Waitms 100 End Sub '------------------------------------------------------------------------------- Sub Plus Sound Spkr , 100 , 800 Cls Style = Style + 1 If Style > 4 Then Style = 4 Waitms 100 End Sub '------------------------------------------------------------------------------- Sub Style Select Case Style Case 1 : Call Style1 End Select End Sub '------------------------------------------------------------------------------- Sub Style1 Locate 2 , 1 Lcd Time$ '------------------------------------------------------------------------------- 'обработка двух датчиков W = 1wirecount() Dsid1(1) = 1wsearchfirst() Do Dsid2(1) = 1wsearchnext() Loop Until Err = 1 If X4 = 1 Then 'переходим на подпрограмму подачи запросов в датчик температуры 1wverify Dsid1(1) : X5 = 0 : Gosub Temperature X4 = 0 Else X4 = X4 + 1 '1 ds18b20 выводим на первой(Х=1) строчке дисплея 1wverify Dsid2(1) : X5 = 1 : Gosub Temperature '2 ds18b20 выводим на второй(Х=2) строчке дисплея End If 'Сдвигаем дату если одна цифра If _day <= 9 Then Locate 1 , 2 Lcd " " ; _day ; " " Else Locate 1 , 2 Lcd _day ; " " End If Locate 1 , 9 Lcd "20" ; _year ; " " Locate 1 , 5 ' обзываем каждый месяц 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 1 , 15 'задаем позицию курсора Lcd Weekday_disp ; " " 'выводим на ЖКИ значение переменной Weekday_disp Return End Sub '------------------------------------------------------------------------------- 'подпрограмма чтения данных из DS1307 '------------------------------------------------------------------------------- Getdatetime: I2cstart ' Generate start code I2cwbyte Ds1307w 'Отправка адреса I2cwbyte 0 'Стартовый адрес в 1307 I2cstart ' Generate start code I2cwbyte Ds1307r 'Отправка адреса I2crbyte _sec , Ack 'Секунды I2crbyte _min , Ack 'Минуты I2crbyte _hour , Ack 'Часы I2crbyte Weekday , Ack 'День недели I2crbyte _day , Ack 'День I2crbyte _month , Ack 'Месяц I2crbyte _year , Nack 'Год I2cstop _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour) _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year) Return Setdate: 'подпрограмма записи даты в DS1307 _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year) I2cstart ' Generate start code I2cwbyte Ds1307w ' send address I2cwbyte 4 ' starting address in 1307 I2cwbyte _day ' Send Data to SECONDS I2cwbyte _month ' MINUTES I2cwbyte _year ' Hours I2cstop Return '------------------------------------------------------------------------------ Settime: 'подпрограмма записи времени в DS1307 _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour) I2cstart ' Generate start code I2cwbyte Ds1307w ' send address I2cwbyte 0 ' starting address in 1307 I2cwbyte _sec ' Send Data to SECONDS I2cwbyte _min ' MINUTES I2cwbyte _hour ' Hours I2cstop Return End '------------------------------------------------------------------------------- Sub Enterdatetime() Cls 'X1 = 08 Aa = 0 X1 = _year Do If X1 > 50 Then X1 = 9 If X1 < 9 Then X1 = 50 Locate 1 , 1 Lcd "[> Setup date <]" Locate 2 , 1 Lcd "Set year: " ; X1 ; " " Getkey J1 = X1 Loop Until Aa = 1 '------------------------------------------- Cls Aa = 0 'X1 = 11 X1 = _month Do If X1 > 12 Then X1 = 01 If X1 < 01 Then X1 = 12 Locate 1 , 1 Lcd "[> Setup date <]" Locate 2 , 1 Lcd "Set month: " ; X1 ; " " Getkey M1 = X1 Loop Until Aa = 1 '------------------------------------------- Cls Aa = 0 'X1 = 1 X1 = _day Do If X1 > 31 Then X1 = 1 If X1 < 1 Then X1 = 31 Locate 1 , 1 Lcd "[> Setup date <]" Locate 2 , 1 Lcd "Set day: " ; X1 ; " " Getkey D1 = X1 Loop Until Aa = 1 _year = J1 _month = M1 _day = D1 Gosub Setdate '------------------------------------------- Cls Aa = 0 'X1 = 12 X1 = _hour Do If X1 > 23 Then X1 = 0 If X1 < 0 Then X1 = 23 Locate 1 , 1 Lcd "[> Setup time <]" Locate 2 , 1 Lcd "Set hours: " ; X1 ; " " Getkey H1 = X1 Loop Until Aa = 1 '------------------------------------------- Cls Aa = 0 'X1 = 30 X1 = _min Do If X1 > 59 Then X1 = 0 If X1 < 1 Then X1 = 59 Locate 1 , 1 Lcd "[> Setup time <]" Locate 2 , 1 Lcd "Set minutes: " ; X1 ; " " Getkey Min1 = X1 Loop Until Aa = 1 _hour = H1 _min = Min1 _sec = 0 Gosub Settime End Sub '------------------------------------------------------------------------------- Sub Getkey() Waitms 300 If Cv = 0 Then Incr X1 If Cn = 0 Then Decr X1 If Vv = 0 Then Aa = 1 Else Aa = 0 End If End Sub '------------------------------------------------------------------------------- Sub Menu() Sound Spkr , 100 , 800 Aa = 0 X1 = 0 Getkey Enterdatetime Cls End Sub End '------------------------------------------------------------------------------- Sub Gettemp Convallt: 1wreset 1wwrite &HCC ' Выдаем команду чтения ПЗУ 1wwrite &H44 ' Запуск измерения Waitms 800 Return ' Ждем окончания преобразования Temperature: 1wwrite &HBE ' Команда чтения ОЗУ датчика Byte0 = 1wread() ' Читаем нулевой байт Byte1 = 1wread() ' Читаем первый байт If Byte1 >= 248 Then ' Проверяем на отрицательную температуру.248 в десятичном - 11111000 в двоичном. Если температура отрицательная - вычитаем из &HFF Byte0 = &HFF - Byte0 Byte1 = &HFF - Byte1 Signtemperatura = "-" Else Signtemperatura = "+" End If T1 = Byte0 / 16 ' Сдвигаем нулевой байт вправо на 4 бита (2*2*2*2=16) T2 = Byte1 * 16 ' Сдвигаем первый байт влево на 4 бита (2*2*2*2=16) T1 = T1 + T2 Hh = Fix(t1) 'отсекаем от температуры все после запятой Temp = T1 * 10 ' Mm = Temp Mod 10 'берем десятичную часть температуры ' *** Коррекция полученных значений If Signtemperatura = "-" Then ' для корректного вывода отрицательных температур T1 = T1 + 1 End If If Signtemperatura = "+" And Hh = 0 And Mm = 0 Then ' убираем знак "+" с нулевой температуры Signtemperatura = " " End If If X3 = 20 Then 'X3 задержка показаний температуры X3 = 0 If X5 = 0 Then If Hh < 10 Then 'сдвигаем значение температуры когда одна цифра Locate 2 , 10 'указываем куда вывести на дисплей Lcd " " ; Chr(3) ; Signtemperatura ; Hh ; "." ; Mm ; Chr(1) 'выводим целую часть потом рисуем точку потом десятую часть температуры Else Locate 2 , 10 'указываем куда вывести на дисплей Lcd Chr(3) ; Signtemperatura ; Hh ; "." ; Mm ; Chr(1) End If Else If Hh < 10 Then Locate 2 , 10 'указываем куда вывести на дисплей Lcd " " ; Chr(4) ; Signtemperatura ; Hh ; "." ; Mm ; Chr(1) 'выводим целую часть потом рисуем точку потом десятую часть температуры Else Locate 2 , 10 'указываем куда вывести на дисплей Lcd Chr(4) ; Signtemperatura ; Hh ; "." ; Mm ; Chr(1) End If End If Else X3 = X3 + 1 End If Return ' Формирмируем результам и выдаем его на индикатор. Команда LCD сама преобразует его в десятичный вид End Sub Weekdays: Data "ЁЅ" 'Понед. Data "Bї" 'Вторник Data "Cp" 'Среда Data "«ї" 'Четверг Data "Ёї" 'Пятница Data "CІ" 'Суббота Data "Bc" 'Воскр. Return