'avrproject.ru 'exersizze 2012 $regfile = "m64def.dat" $crystal = 16000000 ' 16 MHz $baud = 38400 $lib "ds1307clock.lib" 'подключение библиотеки ds1307 'Конфигурация дисплея '================================================================================================================= Config Lcd = 20 * 4 Config Lcdpin = Pin , Rs = Portf.0 , E = Portf.1 , Db4 = Portf.2 , Db5 = Portf.3 , Db6 = Portf.4 , Db7 = Portf.5 Cursor Off Cls 'настройка внешних прерываний для подключения кнопок '================================================================================================================= Config Int0 = Falling 'прерывание по нисходящему фронту On Int0 B0 'button 0 Config Int1 = Falling On Int1 B1 'button 1 Config Int2 = Falling On Int2 B2 'button 2 Config Int3 = Falling On Int3 B3 'button 3 Enable Interrupts Enable Int0 Enable Int1 Enable Int2 Enable Int3 'конфигурация I2C интерфейса 'scl и sda пины '============================================================================================== Config Sda = Portc.1 ' I2C Data Config Scl = Portc.0 ' I2C Clock 'конфигурация подключения светодиода '============================================================================================ Config Portd.7 = Output Led Alias Portd.7 'заводим константы на биты чтения и записи ds1307 Const Ds1307w = &HD0 ' бит записи Const Ds1307r = &HD1 ' бит чтения 'переменные для работы с DS1307 '=========================================================== 'в десятичном формате 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 Seco_bcd As Byte Dim Mine_bcd As Byte Dim Hour_bcd As Byte Dim Day_bcd As Byte Dim Dat_bcd As Byte Dim Month_bcd As Byte Dim Year_bcd As Byte 'в тестовом формате Dim Minestr As String * 2 Dim Hourstr As String * 2 Dim Daystr As String * 2 Dim Datstr As String * 2 Dim Monthstr As String * 2 Dim Yearstr As String * 2 Dim Z As Byte 'переменные для работы датчика BMP085 '=========================================================== Dim Ac1 As Integer Dim Ac1a As Long Dim Ac2 As Integer Dim Ac3 As Integer Dim Ac4 As Word Dim Ac5 As Word Dim Ac5a As Single Dim Ac6 As Word Dim B1 As Integer Dim B2 As Integer Dim B3 As Long Dim B3a As Long Dim B4 As Long Dim B5 As Long Dim B6 As Integer Dim B6a As Long Dim B7 As Long Dim Mb As Integer Dim Mc As Integer Dim Mc2 As Long Dim Md As Integer Dim Adres As Byte Dim Wert As Byte Dim Ut As Long Dim X1 As Long Dim X1t As Single Dim X2 As Long Dim X3 As Long Dim T As Single Dim T2 As Long Dim Temperatur As String * 6 Dim Luftdruck As String * 8 Dim Druck As Single Dim P As Long Dim P2 As Long Dim 2potenz15 As Long Dim 2potenz11 As Integer Dim 2potenz13 As Integer Dim 2potenz8 As Integer Dim 2potenz4 As Integer Dim 2potenz2 As Integer Dim 2potenz16 As Long Dim 2potenz12 As Integer Dim Potenz5255 As Single Dim Altitude As Single Dim Altitudes As String * 8 Dim Msb As Long Dim Lsb As Long Dim Up As Long Dim Druckvar As Byte Declare Sub Berechne_temp Declare Sub Berechne_druck Declare Sub Schreibe_bmp085(byval Adres As Byte , Byval Wert As Byte) Declare Sub Lese_bmp085(byval Adres As Byte , Wert As Byte) Declare Sub Lese_roh_daten Declare Sub Messen Declare Sub Lese_kalib_data Const Addr_schreiben = &B11101110 'адрес микросхемы + запись Const Addr_lesen = &B11101111 'адрес микросхемы + чтение Call Lese_kalib_data Deflcdchar 0 , 31 , 32 , 32 , 32 , 32 , 32 , 32 , 32 'верхняя линия 'подключение датчика DHT11 '=============================================================== Dht_put Alias Portb.7 Dht_get Alias Pinb.7 Dht_io_set Alias Ddrb.7 'переменные для работы датчика DHT11 Dim T_dht As Byte 'перееменная для хранения температуры Dim H_dht As Byte 'переменная для хранения влажности Dim Crc_dht As Byte 'переменная для хранения байта четности Dim Mybyte_dht As Byte Dim Sensor_data As String * 40 'сюда будут записываться данные отсылаемые датчиком Dim Tmp_str8 As String * 8 Dim Count_dht As Byte 'переменная для подсчета принятых бит Do Gosub Ds1307 'переход на подпрограмму считывания времени и даты Gosub Dht11 Call Messen 'опрос датчика BMP085 Gosub Bmp085 'окончательное преобразование данных с BMP085 Led = 1 Gosub Disp Led = 0 If Z > 0 Then Cls Locate 1 , 1 Lcd "Setup RTC DS1307" Wait 1 Do 'вавод экрана настроек If Z = 1 Then Cls Locate 1 , 1 Lcd "Set date:" Locate 2 , 4 Lcd Datstr ; "." ; Monthstr ; "." ; Yearstr ; " " ; Hourstr ; ":" ; Minestr Locate 3 , 4 Lcd Chr(0) ; Chr(0) Elseif Z = 2 Then Cls Locate 1 , 1 Lcd "Set month:" Locate 2 , 4 Lcd Datstr ; "." ; Monthstr ; "." ; Yearstr ; " " ; Hourstr ; ":" ; Minestr Locate 3 , 7 Lcd Chr(0) ; Chr(0) Elseif Z = 3 Then Cls Locate 1 , 1 Lcd "Set year:" Locate 2 , 4 Lcd Datstr ; "." ; Monthstr ; "." ; Yearstr ; " " ; Hourstr ; ":" ; Minestr Locate 3 , 10 Lcd Chr(0) ; Chr(0) Elseif Z = 4 Then Cls Locate 1 , 1 Lcd "Set hour:" Locate 2 , 4 Lcd Datstr ; "." ; Monthstr ; "." ; Yearstr ; " " ; Hourstr ; ":" ; Minestr Locate 3 , 13 Lcd Chr(0) ; Chr(0) Elseif Z = 5 Then Cls Locate 1 , 1 Lcd "Set min:" Locate 2 , 4 Lcd Datstr ; "." ; Monthstr ; "." ; Yearstr ; " " ; Hourstr ; ":" ; Minestr Locate 3 , 16 Lcd Chr(0) ; Chr(0) End If Waitms 200 Loop Until Z = 0 End If Wait 3 Loop End 'опрос микросхемы DS1307 '================================================================ Ds1307: I2cstart I2cwbyte Ds1307w I2cwbyte &H00 I2cstart I2cwbyte Ds1307r 'прием и запись данных I2crbyte Seco_bcd , Ack I2crbyte Mine_bcd , Ack I2crbyte Hour_bcd , Ack I2crbyte Day_bcd , Ack I2crbyte Dat_bcd , Ack I2crbyte Month_bcd , Ack I2crbyte Year_bcd , Nack I2cstop Gosub Convert Return 'Преобразование и форматирование переменных времени и даты '================================================================ Convert: 'преобразование в десятичную систему Seco = Makedec(seco_bcd) Mine = Makedec(mine_bcd) Hour = Makedec(hour_bcd) Day = Makedec(day_bcd) Dat = Makedec(dat_bcd) Month = Makedec(month_bcd) Year = Makedec(year_bcd) 'форматирование Minestr = Str(mine) Minestr = Format(minestr , "00") Hourstr = Str(hour) Hourstr = Format(hourstr , "00") Daystr = Str(day) Daystr = Format(daystr , "00") Datstr = Str(dat) Datstr = Format(datstr , "00") Monthstr = Str(month) Monthstr = Format(monthstr , "00") Yearstr = Str(year) Yearstr = Format(yearstr , "00") Return 'опрос датчика DHT11 '================================================================ Dht11: Set Dht_io_set Set Dht_put Count_dht = 0 Sensor_data = "" Set Dht_io_set 'делаем PD.6 выходом Reset Dht_put 'прижимаем шину к земле Waitms 25 'ждем не менее 18мс Set Dht_put 'отпускаем шину Waitus 40 Reset Dht_io_set 'делаем PD.6 входом Waitus 40 'ждем 40 мкс If Dht_get = 1 Then 'если на нем по прежнему 1 H_dht = 1 'значит датчик не ответил Return 'выходим из подпрограммы End If Waitus 80 If Dht_get = 0 Then 'если на линии по прежнему 0 H_dht = 2 'значит датчик сошел с ума Return 'выходим из подпрограммы End If While Dht_get = 1 : Wend 'ждем пока на шине появится 1 Do 'начинаем принимать 40 бит данных While Dht_get = 0 : Wend 'ждем появления на шине 0 Waitus 30 'после появления 0 ждем 30мкс If Dht_get = 1 Then 'если на шине 1 Sensor_data = Sensor_data + "1" 'записываем в переменную эту единицу While Dht_get = 1 : Wend 'и ждем пока датчик отправит следующий бит Else 'иначе, если там был 0 Sensor_data = Sensor_data + "0" 'записываем этот 0 в переменную End If Incr Count_dht 'увеличиваем счетчик на 1 Loop Until Count_dht = 40 'повторяем пока счетчик не досчитает до 40 Set Dht_io_set Set Dht_put Tmp_str8 = Left(sensor_data , 8) 'берем левые 8 символов переменной H_dht = Binval(tmp_str8) 'это целая часть влажности Tmp_str8 = Mid(sensor_data , 17 , 8) 'вытаскиваем 8 символов из середины T_dht = Binval(tmp_str8) 'это целая часть температуры Tmp_str8 = Right(sensor_data , 8) 'правые 8 символов Crc_dht = Binval(tmp_str8) 'проверочные данные 'проверка контрольной суммы Mybyte_dht = T_dht + H_dht 'складываем значение температуры и влажности If Mybyte_dht <> Crc_dht Then 'если контрольная сумма не сошлась H_dht = 3 'значит полученные данные не верны End If Return 'вывод информации на дисплей '============================================================================= Disp: Cls Locate 1 , 1 Lcd Datstr ; "/" ; Monthstr ; "/" ; Yearstr ; " " ; Hourstr ; ":" ; Minestr Locate 2 , 1 Lcd "DHT: " ; T_dht ; Chr(223) ; "C" ; " " ; H_dht ; "%" Locate 3 , 1 Lcd "BMP: " ; Temperatur ; Chr(223) ; "C" ; " " ; Luftdruck ; "mm" Return 'обработчик кнопки Button0 '============================================================================================ B0: Decr Z If Z = 0 Then Z = 1 End If Waitms 30 'ожидание утихания дребезга Eifr = 0 'сброс флага прерывания Return 'обработчик кнопки Button1 '============================================================================================ B1: Select Case Z 'увеличиваем значение одной из переменных Case 1 : Decr Dat Case 2 : Decr Month Case 3 : Decr Year Case 4 : Decr Hour Case 5 : Decr Mine End Select If Dat > 31 Or Dat = 0 Then Dat = 1 If Month = 0 Or Month > 12 Then Month = 1 If Year > 99 Then Year = 0 If Hour > 23 Then Hour = 0 If Mine > 59 Then Mine = 0 'форматирование Minestr = Str(mine) Minestr = Format(minestr , "00") Hourstr = Str(hour) Hourstr = Format(hourstr , "00") Daystr = Str(day) Daystr = Format(daystr , "00") Datstr = Str(dat) Datstr = Format(datstr , "00") Monthstr = Str(month) Monthstr = Format(monthstr , "00") Yearstr = Str(year) Yearstr = Format(yearstr , "00") Waitms 30 Eifr = 2 Return 'обработчик кнопки Button2 '============================================================================================ B2: Select Case Z 'увеличиваем значение одной из переменных Case 1 : Incr Dat Case 2 : Incr Month Case 3 : Incr Year Case 4 : Incr Hour Case 5 : Incr Mine End Select If Dat > 31 Or Dat = 0 Then Dat = 1 If Month = 0 Or Month > 12 Then Month = 1 If Year > 99 Then Year = 0 If Hour > 23 Then Hour = 0 If Mine > 59 Then Mine = 0 'форматирование Minestr = Str(mine) Minestr = Format(minestr , "00") Hourstr = Str(hour) Hourstr = Format(hourstr , "00") Daystr = Str(day) Daystr = Format(daystr , "00") Datstr = Str(dat) Datstr = Format(datstr , "00") Monthstr = Str(month) Monthstr = Format(monthstr , "00") Yearstr = Str(year) Yearstr = Format(yearstr , "00") Waitms 30 Eifr = 4 Return 'обработчик кнопки Button3 '============================================================================================ B3: Incr Z If Z = 6 Then Seco = 0 Seco = Makedec(seco) Gosub Setup_rtc Z = 0 End If Waitms 30 Eifr = 8 Return 'отправление данных в часы '============================================================================================= Setup_rtc: Led = 1 Seco_bcd = Makebcd(seco) I2cstart I2cwbyte Ds1307w I2cwbyte 0 I2cwbyte Seco_bcd I2cstop Mine_bcd = Makebcd(mine) I2cstart I2cwbyte Ds1307w I2cwbyte 1 I2cwbyte Mine_bcd I2cstop Hour_bcd = Makebcd(hour) I2cstart I2cwbyte Ds1307w I2cwbyte 2 I2cwbyte Hour_bcd I2cstop Day_bcd = Makebcd(day) I2cstart I2cwbyte Ds1307w I2cwbyte 3 I2cwbyte Day_bcd I2cstop Dat_bcd = Makebcd(dat) I2cstart I2cwbyte Ds1307w I2cwbyte 4 I2cwbyte Dat_bcd I2cstop Month_bcd = Makebcd(month) I2cstart I2cwbyte Ds1307w I2cwbyte 5 I2cwbyte Month_bcd I2cstop Year_bcd = Makebcd(year) I2cstart I2cwbyte Ds1307w I2cwbyte 6 I2cwbyte Year_bcd I2cstop Wait 1 Led = 0 Return 'опрос BMP085 '==================================================================================== ' ==попытки что-то понять из этого может привести к расстройству нервной системы :) '==================================================================================== Sub Messen 'Измерение температуры Call Schreibe_bmp085(&Hf4 , &H2E) Adres = &HF6 Call Lese_roh_daten Shift Msb , Left , 8 Ut = Msb + Lsb Call Berechne_temp 'Измерение давления Call Schreibe_bmp085(&Hf4 , &H74 ) Adres = &HF6 Call Lese_roh_daten Shift Msb , Left , 16 Shift Lsb , Left , 8 Up = Msb + Lsb Shift Up , Right , 6 Call Berechne_druck End Sub Sub Berechne_temp Ut = Ut - Ac6 2potenz15 = 2 ^ 15 Ac5a = Ac5 / 2potenz15 X1t = Ut * Ac5a 2potenz11 = 2 ^ 11 Mc2 = Mc * 2potenz11 X3 = X1t + Md X2 = Mc2 / X3 B5 = X1t + X2 2potenz4 = 2 ^ 4 T2 = B5 + 8 T = T2 / 2potenz4 End Sub Sub Berechne_druck B6 = B5 - 4000 2potenz12 = 2 ^ 12 B6a = B6 * B6 B6a = B6a / 2potenz12 X1 = B2 * B6a X1 = X1 / 2potenz11 X2 = Ac2 * B6 X2 = X2 / 2potenz11 X3 = X1 + X2 Ac1a = Ac1 * 4 Ac1a = Ac1a + X3 Shift Ac1a , Left , 2 Ac1a = Ac1a + 2 B3 = Ac1a / 4 2potenz13 = 2 ^ 13 B6a = B6 / 2potenz13 X1 = Ac3 * B6a B6a = B6 * B6 B6a = B6a / 2potenz12 X2 = B1 * B6a 2potenz16 = 2 ^ 16 X2 = X2 / 2potenz16 X3 = X1 + X2 X3 = X3 + 2 2potenz2 = 2 ^ 2 X3 = X3 / 2potenz2 B4 = X3 + 32768 B4 = B4 * Ac4 B4 = B4 / 2potenz15 If B4 <= 0 Then B4 = B4 * -1 B7 = Up - B3 B3a = 50000 Shift B3a , Right , 2 ' B7 = B7 * B3a If B7 <= 0 Then B7 = B7 * -1 If B7 < &H80000000 Then P = B7 * 2 P = P / B4 Else P = B7 / B4 P = P * 2 End If 2potenz8 = 2 ^ 8 P2 = P / 2potenz8 X1 = P2 * P2 X1 = X1 * 3038 X1 = X1 / 2potenz16 X2 = -7357 * P X2 = X2 / 2potenz16 P2 = P P = X2 + 3791 P = P + X1 P = P / 2potenz4 P = P + P2 End Sub Sub Lese_kalib_data Adres = &HAA Call Lese_bmp085(adres , Wert) Msb = Wert Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Lsb = Wert Shift Msb , Left , 8 Ac1 = Msb + Lsb Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Msb = Wert Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Lsb = Wert Shift Msb , Left , 8 Ac2 = Msb + Lsb Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Msb = Wert Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Lsb = Wert Shift Msb , Left , 8 Ac3 = Msb + Lsb Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Msb = Wert Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Lsb = Wert Shift Msb , Left , 8 Ac4 = Msb + Lsb Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Msb = Wert Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Lsb = Wert Shift Msb , Left , 8 Ac5 = Msb + Lsb Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Msb = Wert Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Lsb = Wert Shift Msb , Left , 8 Ac6 = Msb + Lsb Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Msb = Wert Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Lsb = Wert Shift Msb , Left , 8 B1 = Msb + Lsb Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Msb = Wert Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Lsb = Wert Shift Msb , Left , 8 B2 = Msb + Lsb Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Msb = Wert Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Lsb = Wert Shift Msb , Left , 8 Mb = Msb + Lsb Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Msb = Wert Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Lsb = Wert Shift Msb , Left , 8 Mc = Msb + Lsb Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Msb = Wert Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Lsb = Wert Shift Msb , Left , 8 Md = Msb + Lsb Adres = Adres + 1 End Sub Sub Lese_roh_daten Call Lese_bmp085(adres , Wert) Msb = Wert Adres = Adres + 1 Call Lese_bmp085(adres , Wert) Lsb = Wert End Sub Sub Schreibe_bmp085(byval Adres As Byte , Byval Wert As Byte) I2cstart I2cwbyte Addr_schreiben I2cwbyte Adres I2cwbyte Wert I2cstop Waitms 10 End Sub Sub Lese_bmp085(byval Adres As Byte , Wert As Byte) I2cstart I2cwbyte Addr_schreiben I2cwbyte Adres I2cstart I2cwbyte Addr_lesen I2crbyte Wert , Nack I2cstop Waitms 10 End Sub 'продолжение преобразований данных с датчика BMP085 'психам из Bosh привет... '=================================================== Bmp085: T = T / 10 Temperatur = Fusing(t , "###.#") Potenz5255 = 1 / 5.255 Altitude = P / 101325 Altitude = Altitude ^ Potenz5255 Altitude = 1 - Altitude Altitude = Altitude * 44330 Druck = P Druck = Druck * 0.0075 Luftdruck = Fusing(druck , "####.##") Return