Главная » Статьи » Proton PICBasic |
Термометр с двумя датчиками, памятью и записью лога в PC
В сети много материалов по термометрам и логгерам температуры.
Такие устройства продаются и стоят не очень дорого. Но захотелось сделать устройство "для себя". Чтобы утром перед глазами было время и температура дома и на улице. Основное - индикация на достаточно крупные и яркие семисегментные LED от Kingbright. Динамическая индикация с использованием сдвиговых регистров не требует много ножек от контроллера. Запись идёт во внешнюю EEPROM объёмом 128 кб. Есть 3 режима индикации, три режима записи лога - раз в минуту, раз в час, раз в сутки в установленное время. RTC на DS1302 (была под руками). Простенькая программка на PureBasic для снятия дампа лога и управления устройством. Автоматическое включение-выключение индикаторов при включении света(устройство предполагается установить в прихожей). Контроллер был под руками Pic16f690. Макет в Proteus и платы разведены двухсторонние там же в Ares. Все файлы - в ветке форума http://www.picbasic.ru/forum/5-922-1 Без корпуса выглядит это так: Доступно только для пользователей '*************************************************** '* Notes : Внимание!!! Строка 135 EData !!! '* : EData 1,1,14,11 ' MOD, Log_time, LOG_DAY,YEAR '*************************************************** Device 16F690 ' Использовать микроконтроллер 16F690 Xtal 8 Config CPD_OFF, CP_OFF, MCLRE_OFF, WDT_OFF, INTRC_OSC_NOCLKOUT ' Использовать внутренний генератор на 8 МГц Declare Hserial_Baud 9600 Declare Hserial_Clear = On Declare SDA_Pin PORTB.4 Declare SCL_Pin PORTB.6 'Declare Slow_Bus On Declare Adin_Res = 8 ' 8-bit result required Declare Adin_Tad = FRC ' RC OSC chosen Declare Adin_Stime = 50 ' Allow 50us sample time OSCCON = %01111111 OPTION_REG.7 = 0 ' bit 7 RABPU: PORTA/PORTB Pull-up Enable bit ANSEL = $00 'All_Digital ANSELH = $00000001 'All_Digital WPUA = %00110000 'Pullups A PORTA.4 PORTA.5 WPUB = %00100000 'Pullups B PORTB.5 TRISC = %11000000 '6 и 7 pins порта "c" - входы TRISB.5 = 1 '5 pin порта "B" - вход ADCON1 =%00000000 INTCON.7 = 0 'Global Interrupt Disable '-------------------------------------Объяление переменных---------------------------------- 'DS18s20------------------------- Symbol DQ1 = PORTC.0 ' Подключить DS18S20_1 к выводу PORTC.0 Symbol DQ2 = PORTC.1 ' Подключить DS18S20_2 к выводу PORTC.0 Dim tempID[9] As Byte ' Temp Array storage variable for DS18S20_1 RAM Dim temperature As Byte Dim halfdegre_bit As Bit Dim Sign As Byte ' +/- sign for temp display Dim Sign_char As Byte Dim Less_9 As Bit Dim Error_0 As Bit Dim tempID_1[9] As Byte ' Temp Array storage variable for DS18S20_2 RAM Dim temperature_1 As Byte Dim halfdegre_bit_1 As Bit Dim Sign_1 As Byte ' +/- sign for temp display Dim Sign_char_1 As Byte Dim Less_9_1 As Bit Dim Error_1 As Bit Dim Ds_num As Byte ' Номер датчика Dim TIMEDATA[7] As Byte 'DS1302------------------------- Dim SECONDS As timedata#0 Dim MINUTES As timedata#1 Dim HOURS As timedata#2 Dim DATE As timedata#3 Dim MONTH As timedata#4 Dim YEAR As timedata#5 Dim DAY As timedata#6 Dim HOURS_PRE As Byte Dim MINUTES_PRE As Byte Dim LOG_DAY As Byte Symbol CLK_RTC = PORTC.2 'DS1302 Symbol DTA_RTC = PORTC.3 'DS1302 Symbol RST_RTC = PORTC.4 'DS1302 'DS1302------------------------- Dim fBIT_CNT As Byte 'Var for ASM Dim SAVE_W As Byte 'Var for ASM Dim fTEMP As Byte 'Var for ASM Dim CRC As Byte 'Var for ASM Dim CRC_1 As Byte 'Var for ASM Dim i As Byte 'Counter Dim k As Byte 'Counter Dim l As Word 'Counter Dim m As Byte 'Counter Dim n As Word 'Counter Dim o As Byte 'Counter Dim p As Byte 'Counter Dim C As Byte 'Counter Dim C1 As Byte 'Counter Dim Mem_Read As Word 'Counter Dim _Cycle As Word 'Counter Dim binTEMP1 As Byte ' Для преобразования BCD в BIN и обратно см. подпрограмму Dim decTEMP1 As Byte Dim binTEMP2 As Byte Dim decTEMP2 As Byte Dim binval As Byte Dim decval As Byte ' Для преобразования BCD в BIN и обратно см. подпрограмму ' For Led Display------------------------- Dim char_to_display[8] As Byte Dim ukazatel As Byte Dim Segments As Byte Dim znmesto_tmp As Byte Dim znmesto As Byte Dim Mode As Byte ' Режим отображения 0 - температура, 1 - часы, ошибка, итд. Symbol CLK_LED = PORTA.0 'DS1302 Symbol DTA_LED = PORTA.1 'DS1302 Symbol RST_LED = PORTA.2 'DS1302 '---------------------------------------------------- Кнопки ------------------------- Symbol BUT_1 = PORTA.4 ' Кнопка1 Symbol BUT_2 = PORTA.5 ' Кнопка2 Symbol BUT_3 = PORTA.3 ' Кнопка3 Symbol JMP = PORTC.7 ' JAMPER О общий анод (0) или общий катод (1) Dim _BUTTON As Byte Dim Ser_Input As Byte '--------------------------------------------------- Запись и чтение в 24С128 -------- Dim Address As Word ' 16-bit address required Dim Address_1 As Word Symbol Control = %10100000 ' Target an eeprom Symbol SDA = PORTB.4 ' Alias the SDA (Data) line Symbol SCL = PORTB.6 ' Alias the SSL (Clock) line Dim Wr_to_mem[8] As Byte Dim Rd_from_mem[9] As Byte Dim Rd_from_mem_0 As Byte Dim Light As Byte ' Light Dim Log_time As Byte Dim display_time As Word display_time = 300 Dim MOD As Byte EData 1,2,14,11 ' MOD, Log_time, LOG_DAY,YEAR Less_9 = 0 Less_9_1 = 0 Error_0 = 0 Error_1 = 0 Address = 0 Mode = 1 _BUTTON =0 Ser_Input=0 '-------------------------------Начало программы--------------------------------------------- GoTo Main '-------------------------------Начало программы--------------------------------------------- '********************************************************* 'Подпрограмма Подсчёта контрольной суммы '********************************************************* check_crc: CRC = 0 ' CRC (calculated value) For m = 0 To p ' Counter (p=6 for ROM, p=7 for RAM) fBIT_CNT = 8 ' Byte counter SAVE_W = tempID[m] ' Input Byte 1 Датчика Asm 'Процедура обновления CRC . Параметр в W. 'DO_CRC: Размер CRC - p бит. DoCRC_Loop: Xorwf CRC,0 Movwf fTEMP Rrf fTEMP,0 Movf CRC,0 Btfsc STATUS,0 Xorlw 0x18 Movwf fTEMP Rrf fTEMP,0 Movwf CRC Bcf STATUS,0 Rrf SAVE_W,1 Movf SAVE_W,0 Decfsz fBIT_CNT,1 GoTo DoCRC_Loop EndAsm Next m Return ' Для второго датчика---------------------------------------------- check_crc_1: CRC_1 = 0 ' CRC (calculated value) For m = 0 To p ' Counter (p=6 for ROM, p=7 for RAM) fBIT_CNT = 8 ' Byte counter SAVE_W = tempID_1[m] ' Input Byte 1 Датчика Asm 'Процедура обновления CRC . Параметр в W. 'DO_CRC: Размер CRC - p бит. DoCRC_Loop_1: Xorwf CRC_1,0 Movwf fTEMP Rrf fTEMP,0 Movf CRC_1,0 Btfsc STATUS,0 Xorlw 0x18 Movwf fTEMP Rrf fTEMP,0 Movwf CRC_1 Bcf STATUS,0 Rrf SAVE_W,1 Movf SAVE_W,0 Decfsz fBIT_CNT,1 GoTo DoCRC_Loop_1 EndAsm Next m Return '**************************************************** 'Начало кода '**************************************************** Main: '------------------------------- Чтение из памяти установок --------------------------------- MOD = ERead $00 Log_time = ERead $01 LOG_DAY = ERead $02 '--------------------------- Initiate display on -------------------------------------------- Low PORTC.5 '--------------------------------------- Проверка памяти и установка адреса записи ---------- Mem_check: Rd_from_mem_0 = 0 l=0 Mode = 3 char_to_display[7] = 25 ' C char_to_display[6] = 21 ' char_to_display[5] = 21 ' char_to_display[4] = 21 ' char_to_display[3] = 22 ' H char_to_display[2] = 21 ' char_to_display[1] = 21 ' char_to_display[0] = 21 ' Address = 0 While Rd_from_mem_0 <>$FD And Address < 32767 BStart BusIn Control, Address, [Rd_from_mem_0] BStop Address = Address+1 l = l+1 If l >10 Then l =0 If l = 10 Then GoSub display EndIf Wend Address = Address-1 If Address > 32758 Then GoSub Format EndIf '------------------------------ Mem_count_display ------------------------------------------------------ Mem_count_display: Mode = 3 char_to_display[7] = 27 ' L char_to_display[6] = 0 ' O char_to_display[5] = 37 ' G char_to_display[4] = 21 ' For i = 0 To 3 char_to_display[i] = Dig (Address/9-1), i Next i For n = 0 To 200 GoSub display Next n '------------------------------- Чтение DS 1302 и DS 18S20 --------------------------------- GoSub DS1302_READ GoSub Convert GoSub Temp_Read '-------------------------------------------------------------------------------------------- '-------------------------- Метка начала основной программы --------------------------------- '-------------------------------------------------------------------------------------------- Startconv: Select Case MOD '-------------------------------------------------------------------------------------------- Case 1 ' Температура и время попеременно '-------------------------------------------------------------------------------------------- GoSub _Temperature Temp_disp: Mode = 0 For l = 0 To display_time + 50 If _BUTTON = 1 Or _BUTTON = 2 Then Menu GoSub display Next l GoSub _Time Time_disp: Mode = 1 For o = 0 To display_time - 50 If _BUTTON = 1 Or _BUTTON = 2 Then Menu GoSub display Next o GoTo Startconv '-------------------------------------------------------------------------------------------- Case 2 ' Только температура '-------------------------------------------------------------------------------------------- GoSub _Temperature GoSub DS1302_READ GoSub Convert GoSub Log_Write Mode = 0 For l = 0 To 250 If _BUTTON = 1 Or _BUTTON = 2 Then Menu GoSub display Next l GoTo Startconv '-------------------------------------------------------------------------------------------- Case 3 ' Время и температура одновременно '-------------------------------------------------------------------------------------------- GoSub Temp_Read GoSub Temp_mask1 GoSub DS1302_READ GoSub Convert GoSub Log_Write GoSub Time_mask1 Mode =4 For l = 0 To 250 If _BUTTON = 1 Or _BUTTON = 2 Then Menu GoSub display Next l GoTo Startconv End Select '-------------------------------------------------------------------------------------------- '-------------------------------------------------------------------------------------------- '-------------------------------------------------------------------------------------------- '**************************************************** 'Subroutines '**************************************************** _Temperature: GoSub Temp_Read GoSub Temp_mask1 GoSub Temp_mask2 Return '------------------------- Чтение и индикация температуры ------------------------------------ Temp_Read: '------------------------------- Подготовка DS18S20 к измерениям ----------------------------- GoSub display High DQ1 High DQ2 OWrite DQ1, 1, [$CC, $44] ' Послать датчику1 DS18S20 команду старта измерения температуры GoSub display OWrite DQ2, 1, [$CC, $44] ' Послать датчику2 DS18S20 команду старта измерения температуры Repeat ' Начать служебный цикл For l = 1 To 10 GoSub display Next l ' Ждать полного преобразования ORead DQ1, 4, [C] GoSub display ' Читать данные в цикле без сброса ORead DQ2, 4, [C1] Until C & C1 <> 0 ' Выйти из цикла если DS18S20 закончили преобразование. GoSub display OWrite DQ1, 1, [$CC, $BE] ' Послать датчику1 DS18S20 команду начала чтения из ОЗУ датчика значения температуры GoSub display ORead DQ1, 2,[ Str tempID\9 ] ' Читать значение температуры 1 датчика GoSub display OWrite DQ2, 1, [$CC, $BE] ' Послать датчику2 DS18S20 команду начала чтения из ОЗУ датчика значения температуры GoSub display ORead DQ2, 2,[ Str tempID_1\9 ] ' Читать значение температуры 2 датчика GoSub display '----------------------- Проверка контрольной суммы ------------------------------------------- p=7 GoSub check_crc If CRC <> tempID[8] Then Error_0 = 1 Else Error_0 = 0 EndIf p=7 GoSub check_crc_1 If CRC_1 <> tempID_1[8] Then Error_1 = 1 Else Error_1 = 0 EndIf '----------------------- Расчет температуры 1 датчик ----------------------------------------- If Error_0 = 0 Then temperature = tempID[0] ' Считывем 1-й байт DS halfdegre_bit = temperature.0 ' Бит половинок градуса Less_9 = 0 Sign = tempID [1] If Sign.0 = 1 Then temperature = (~temperature + 1) EndIf temperature = temperature >> 1 Else temperature =88 Sign = $FF EndIf '--------------------------- Второй датчик ------------------- If Error_1 = 0 Then temperature_1 = tempID_1[0] ' Считывем 1-й байт DS halfdegre_bit_1 = temperature_1.0 ' Бит половинок градуса Less_9_1 = 0 Sign_1 = tempID_1 [1] If Sign_1.0 = 1 Then temperature_1 = (~temperature_1 + 1) EndIf temperature_1 = temperature_1 >> 1 Else temperature_1 =88 Sign_1 = $FF EndIf Return Temp_mask1: '--------------------------- Маска первый датчик ------------------- If Error_0 = 1 Then char_to_display[3] = 12 'E char_to_display[2] = 13 'r char_to_display[1] = 13 'r char_to_display[0] = 21 ' GoTo _End_mask1 EndIf char_to_display[0] = 11 If halfdegre_bit = 1 Then char_to_display[1] = 5 If halfdegre_bit = 0 Then char_to_display[1] = 0 char_to_display[2] = Dig temperature, 0 char_to_display[3] = Dig temperature, 1 If Sign.0 = 1 Then char_to_display[3] = 10 ' Минус If temperature > 99 And Sign.0 = 0 Then char_to_display[0] = 18 't char_to_display[1] = 23 'o char_to_display[2] = 22 'H char_to_display[3] = 21 'Погашен EndIf If temperature > 9 And Sign.0 = 1 Then Less_9 = 1 If halfdegre_bit = 1 Then char_to_display[0] = 5 If halfdegre_bit = 0 Then char_to_display[0] = 0 char_to_display[1] = Dig temperature, 0 char_to_display[2] = Dig temperature, 1 char_to_display[3] = 10 ' Минус EndIf If temperature < 10 And Sign.0 = 0 Then char_to_display[3] = 21 ' Погашен EndIf _End_mask1: Return Temp_mask2: '--------------------------- Маска второй датчик ------------------- If Error_1 = 1 Then char_to_display[7] = 12 'E char_to_display[6] = 13 'r char_to_display[5] = 13 'r char_to_display[4] = 21 ' GoTo _End_mask2 EndIf char_to_display[4] = 11 If halfdegre_bit_1 = 1 Then char_to_display[5] = 5 If halfdegre_bit_1 = 0 Then char_to_display[5] = 0 char_to_display[6] = Dig temperature_1, 0 char_to_display[7] = Dig temperature_1, 1 If Sign_1.0 = 1 Then char_to_display[7] = 10 ' Минус If temperature_1 > 99 And Sign_1.0 = 0 Then char_to_display[4] = 18 't char_to_display[5] = 23 'o char_to_display[6] = 22 'H char_to_display[7] = 21 'Погашен EndIf If temperature_1 > 9 And Sign_1.0 = 1 Then Less_9_1 = 1 If halfdegre_bit_1 = 1 Then char_to_display[4] = 5 If halfdegre_bit_1 = 0 Then char_to_display[4] = 0 char_to_display[5] = Dig temperature_1, 0 char_to_display[6] = Dig temperature_1, 1 char_to_display[7] = 10 ' Минус EndIf If temperature_1 < 10 And Sign_1.0 = 0 Then char_to_display[7] = 21 ' Погашен EndIf _End_mask2: Return '----------------------- Чтение и индикация часов ------------------------------------------- _Time: '----------------------- Чтение и индикация часов ------------------------------------------- GoSub DS1302_READ GoSub Convert GoSub Log_Write GoSub Time_mask Return Time_mask: GoSub Time_mask1 char_to_display[3] = Dig DATE, 1 char_to_display[2] = Dig DATE, 0 char_to_display[1] = Dig MONTH, 1 char_to_display[0] = Dig MONTH, 0 Return Time_mask1: char_to_display[7] = Dig HOURS, 1 char_to_display[6] = Dig HOURS, 0 char_to_display[5] = Dig MINUTES, 1 char_to_display[4] = Dig MINUTES, 0 Return '----------------------- Подпрограмма считывания текущего времени ------------------------------------------- DS1302_READ: High RST_RTC SHOut DTA_RTC, CLK_RTC, LsbFirst, [$BF] SHIn DTA_RTC, CLK_RTC, LsbPre, [SECONDS,MINUTES,HOURS,DATE,MONTH,DAY,YEAR] Low RST_RTC Return Convert: ' binval=SECONDS 'здесь производим преобразование полученного ' GoSub BCD_TO_BIN 'двоично-десятичного значения минут ' SECONDS=binval ' в двоичную систему счисления binval=MINUTES 'здесь производим преобразование полученного GoSub BCD_TO_BIN 'двоично-десятичного значения минут MINUTES=binval ' в двоичную систему счисления binval=HOURS 'здесь производим преобразование полученного GoSub BCD_TO_BIN 'двоично-десятичного значения часов HOURS=binval 'в двоичную систему счисления binval=DATE 'здесь производим преобразование полученного GoSub BCD_TO_BIN 'двоично-десятичного значения даты DATE=binval 'в двоичную систему счисления binval=MONTH 'здесь производим преобразование полученного GoSub BCD_TO_BIN 'двоично-десятичного значения месяца MONTH=binval 'в двоичную систему счисления binval=YEAR 'здесь производим преобразование полученного GoSub BCD_TO_BIN 'двоично-десятичного значения года YEAR=binval 'в двоичную систему счисления Return Log_Write: Select Case Log_time Case 1 If MINUTES <> MINUTES_PRE Then GoSub Mem_Write MINUTES_PRE = MINUTES Case 2 If HOURS <> HOURS_PRE Then GoSub Mem_Write HOURS_PRE = HOURS Case 3 If HOURS <> HOURS_PRE And HOURS = LOG_DAY Then GoSub Mem_Write HOURS_PRE = HOURS End Select Return '------------------------------------------------------------------------------------ BCD_TO_BIN: binTEMP1 = binval & $F ' Convert the values from BCD to BIN binTEMP2 = binval & $F0 ' Mast off either side binTEMP2 = binTEMP2 >>4 ' divide by 16 binTEMP2 = binTEMP2 * 10 ' X by 10 binval = binTEMP1 + binTEMP2 ' Now add the original number Return '------------------------------------------------------------------------------------ BIN_TO_BCD: decTEMP2 = decval // 10 'get lsb,same for Bin and BCD decTEMP1 = decval / 10 'get msb decval = decTEMP1 * 16 'covert msb to BCD decval = decval + decTEMP2 'add BCD msb and lsb together Return '----------------------------- MENU ------------------------------------------------------- Menu: Select Case _BUTTON Case 1 GoTo Menu1 Case 2 GoTo Menu2 EndSelect '----------------------------- MENU1 ------------------------------------------------------- '----------------------------- Mode ------ Menu1: _BUTTON = 0 MOD=MOD + 1 If MOD > 3 Then MOD =1 High PORTC.5 EWrite $00, [MOD] DelayMS 500 Low PORTC.5 GoTo Startconv '----------------------------- MENU2 ------------------------------------------------------- Menu2: ' Clock Set GoSub DS1302_READ GoSub Convert YEAR = ERead $03 '----------------------------- Set Month ------------------------------------------------------- Mode = 3 char_to_display[7] = 35 ' M char_to_display[6] = 15 ' n char_to_display[5] = 18 ' t char_to_display[4] = 36 ' h char_to_display[3] = 21 ' char_to_display[2] = 21 ' char_to_display[1] = Dig MONTH, 1 char_to_display[0] = Dig MONTH, 0 GoSub Display_20 _BUTTON = 0 While _BUTTON <> 3 If _BUTTON =1 Then GoSub Display_20 MONTH=MONTH + 1 If MONTH> 12 Then MONTH= 1 EndIf char_to_display[1] = Dig MONTH, 1 char_to_display[0] = Dig MONTH, 0 _BUTTON = 0 GoSub display Wend '----------------------------- Set Date ------------------------------------------------------- char_to_display[7] = 14 ' d char_to_display[6] = 19 ' A char_to_display[5] = 18 ' t char_to_display[4] = 12 ' E char_to_display[3] = 21 ' char_to_display[2] = 21 ' char_to_display[1] = Dig DATE, 1 char_to_display[0] = Dig DATE, 0 GoSub Display_20 _BUTTON = 0 While _BUTTON <> 3 If _BUTTON =1 Then GoSub Display_20 DATE=DATE + 1 If DATE> 31 Then DATE= 1 EndIf char_to_display[1] = Dig DATE, 1 char_to_display[0] = Dig DATE, 0 _BUTTON = 0 GoSub display Wend '----------------------------- Set Hours ------------------------------------------------------- char_to_display[7] = 22 ' H char_to_display[6] = 23 ' o char_to_display[5] = 17 ' u char_to_display[4] = 13 ' r char_to_display[3] = 21 ' char_to_display[2] = 21 ' char_to_display[1] = Dig HOURS, 1 char_to_display[0] = Dig HOURS, 0 GoSub Display_20 _BUTTON = 0 While _BUTTON <> 3 If _BUTTON =1 Then GoSub Display_20 HOURS=HOURS + 1 If HOURS> 23 Then HOURS= 0 EndIf char_to_display[1] = Dig HOURS, 1 char_to_display[0] = Dig HOURS, 0 _BUTTON = 0 GoSub display Wend '----------------------------- Set Minutes ------------------------------------------------------- char_to_display[7] = 35 ' M char_to_display[6] = 28 ' I char_to_display[5] = 30 ' i char_to_display[4] = 15 ' n char_to_display[3] = 21 ' char_to_display[2] = 21 ' char_to_display[1] = Dig MINUTES, 1 char_to_display[0] = Dig MINUTES, 0 GoSub Display_20 _BUTTON = 0 While _BUTTON <> 3 If _BUTTON =1 Then GoSub Display_20 MINUTES=MINUTES + 1 If MINUTES> 59 Then MINUTES= 0 EndIf char_to_display[1] = Dig MINUTES, 1 char_to_display[0] = Dig MINUTES, 0 _BUTTON = 0 GoSub display Wend '----------------------------- Log interval ------ char_to_display[7] = 27 ' L char_to_display[6] = 0 ' 0 char_to_display[5] = 37 ' G char_to_display[4] = 21 ' GoSub Select_Log_disp GoSub Display_20 _BUTTON = 0 While _BUTTON <> 3 If _BUTTON =1 Then GoSub Log_time_Set GoSub Display_20 EndIf GoSub Select_Log_disp _BUTTON = 0 GoSub display Wend If Log_time = 3 Then '----------------------------- LOG_DAY ------ char_to_display[7] = 22 ' H char_to_display[6] = 23 ' o char_to_display[5] = 17 ' u char_to_display[4] = 13 ' r char_to_display[3] = 21 ' char_to_display[2] = 21 ' char_to_display[1] = Dig LOG_DAY, 1 char_to_display[0] = Dig LOG_DAY, 0 GoSub Display_20 _BUTTON = 0 While _BUTTON <> 3 If _BUTTON =1 Then GoSub Display_20 LOG_DAY=LOG_DAY + 1 If LOG_DAY> 23 Then LOG_DAY= 0 EndIf char_to_display[1] = Dig LOG_DAY, 1 char_to_display[0] = Dig LOG_DAY, 0 _BUTTON = 0 GoSub display Wend EndIf EWrite $01, [Log_time] EWrite $02, [LOG_DAY] '----------------------------- Set BCD ------------------------------------------------------- Prepare: 'преобразуем перед тем как записать в DS1302 'в двоично-десятичное значение decval=MONTH 'месяц GoSub BIN_TO_BCD MONTH =decval decval=DATE 'Дата GoSub BIN_TO_BCD DATE =decval decval=HOURS 'часы GoSub BIN_TO_BCD HOURS=decval decval=MINUTES 'минуты GoSub BIN_TO_BCD MINUTES =decval SECONDS = 0 High RST_RTC ' импульс сброса для ds1302 SHOut DTA_RTC, CLK_RTC, LsbFirst, [$8e ,0] 'Разрешаем запись в ds1302 Low RST_RTC High RST_RTC SHOut DTA_RTC,CLK_RTC,LsbFirst,[$be,SECONDS,MINUTES,HOURS,DATE,MONTH,DAY,YEAR] SHOut DTA_RTC, CLK_RTC, LsbFirst, [$8e ,%10000000] 'Запрещаем запись в ds1302 Low RST_RTC For i = 1 To 20 GoSub display Next i GoTo Startconv '-------------------------------------------------------------------------------------- '----------------------------Индикация на 8 LED дисплее-------------------------------- display: For znmesto = 0 To 7 ' Знакоместо справа налево If JMP =1 Then znmesto_tmp = ~Dcd znmesto If JMP =0 Then znmesto_tmp = Dcd znmesto ukazatel = char_to_display[znmesto] ' Номер символа для вывода '----- Знакогенератор ----- ' 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ' 0 1 2 3 4 5 6 7 8 9 - o E r d n F u t A U H o b C c L | p | _ _ _ y M h g Segments = LookUpL ukazatel, [$3F,$06,$5B,$4F,$66,$6D,$7D,$07,$7F,$67,$40,$63,$79,$50,$5E,$54,$71,_ $1C,$78,$77,$3E,$00,$76,$5C,$7C,$39,$58,$38,$30,$73,$10,$08,$48,$49,$6E,$15,$74,$3D] Select Case Mode ' Действия в зависимости от режима Case 0 ' Режим температуры If Error_0 = 0 Then If znmesto = 2 And temperature < 100 And Less_9 = 0 Then Segments = Segments | $80 ' Точка во втором разряде If znmesto = 1 And Less_9 = 1 Then Segments = Segments | $80 EndIf If Error_1 = 0 Then If znmesto = 4 And temperature_1 < 100 And Less_9_1 = 0 Then Segments = Segments | $80 ' Точка во втором разряде старшего дисплея If znmesto = 5 And Less_9_1 = 1 Then Segments = Segments | $80 EndIf Case 1 ' Режим часов If znmesto = 2 Then Segments = Segments | $80 'If znmesto = 6 Then Segments = Segments | $80 If znmesto = 4 Then Segments = Segments | $80 If znmesto = 5 Then Segments = Segments | $80 Case 3 ' Режим настроек Segments = Segments Case 4 ' Режим смешанный 'If znmesto = 6 Then Segments = Segments | $80 If znmesto = 4 Then Segments = Segments | $80 If znmesto = 5 Then Segments = Segments | $80 If Error_0 = 0 Then If znmesto = 2 And temperature < 100 And Less_9 = 0 Then Segments = Segments | $80 ' Точка во втором разряде If znmesto = 1 And Less_9 = 1 Then Segments = Segments | $80 EndIf End Select If JMP = 0 Then Segments = ~Segments '----- Запись в регистр ----- High RST_LED SHOut DTA_LED,CLK_LED,MsbFirst_H,[Segments\8,znmesto_tmp\8 ] Low RST_LED '----------------------------- Опрос кнопок ----- If BUT_1 = 0 Then _BUTTON = 1 If BUT_2 = 0 Then _BUTTON = 2 If BUT_3 = 0 Then _BUTTON = 3 HSerIn 1,Cont,[Ser_Input] If Ser_Input = $44 Or Ser_Input = $64 Then GoSub Mem_dump 'D,d Дамп лога If Ser_Input = $4D Or Ser_Input = $6D Then HSerOut [Dec4 (Address/9-1),0] 'M,m Сколько ячеек занято If Ser_Input = $54 Or Ser_Input = $74 Then 'T,t Выдать текущую температуру High PORTB.7 Sign_char = $2B Sign_char_1 = $2B If Sign.0 = 1 Then Sign_char = $2D If Sign_1.0 = 1 Then Sign_char_1 = $2D HSerOut ["OUT ", Sign_char, Dec2 temperature," IN ",Sign_char_1,Dec2 temperature_1] GoSub Com_End EndIf If Ser_Input = $57 Or Ser_Input = $77 Then GoSub Mem_Write 'W,w Записать температуру в память If Ser_Input = $46 Or Ser_Input = $66 Then GoSub Format: HSerOut ["OK",0] 'F,f "Форматировать" память If Ser_Input = $4C Or Ser_Input = $6C Then GoSub Log_Out 'L,l Прочитать режим лога If Ser_Input = $2B Then GoSub Log_time_Set :GoSub Log_Out '+ - сменить режим лога Cont: Next znmesto Light = ADIn 8 If Light > 10 Then Low PORTC.5 If Light < 5 Then High PORTC.5 Return '---------------------------- Индикация на 8 LED дисплее 20 ms --------------------- Display_20: For i = 1 To 25 GoSub display Next i Return '----------------------- Запись лога во внешнюю память --------------------------------- Mem_Write: If Address > 32757 Then Address =9 BStart For m = 0 To 8 Wr_to_mem[m] = LookUpL m, [$FA,MONTH,DATE,HOURS,MINUTES,Sign,temperature,Sign_1,temperature_1] DelayMS 10 BusOut Control, Address, [Wr_to_mem[m]] ' Send the byte to the eeprom Address = Address+1 Next m DelayMS 10 BusOut Control, Address, [$FD] BStop Return '----------------------- "быстрое форматирование" внешней памяти --------------------------------- Format: Address = 9 BStart BusOut Control, Address, [$FD] ' Запись $FD во внешнюю память BStop Return '----------------------- Вывод в COM порт --------------------------------- Com_out: Sign_char = $2B Sign_char_1 = $2B If Sign.0 = 1 Then Sign_char = $2D If Sign_1.0 = 1 Then Sign_char_1 = $2D HSerOut [ Dec2 DATE,$2E,Dec2 MONTH,$2E,Dec2 YEAR,$20,Dec2 HOURS,$3A,Dec2 MINUTES,$20,"OUT ",Sign_char,Dec2 temperature,$20,"IN ",Sign_char_1,Dec2 temperature_1] Return Com_End: HSerOut [0] Return '----------------------- Выбор вывода на дисплей --------------------------------- Select_Log_disp: Select Case Log_time Case 1 char_to_display[3] = 35 'm char_to_display[2] = 28 'I char_to_display[1] = 30 'i char_to_display[0] = 15 'n Case 2 char_to_display[3] = 21 ' char_to_display[2] = 21 ' char_to_display[1] = 22 'H char_to_display[0] = 13 'r Case 3 char_to_display[3] = 21 ' char_to_display[2] = 14 'd char_to_display[1] = 19 'A char_to_display[0] = 34 'y End Select Return '----------------------------- Memory Dump ------------------------------------------------------- Mem_dump: Address_1 = 0 Rd_from_mem_0 = 0 High PORTC.5 While Rd_from_mem_0 <> $FD Or Address_1>32758 BusIn Control, Address_1, [Rd_from_mem_0] If Rd_from_mem_0 = $FA Then For m = 0 To 7 Address_1 = Address_1+1 BStart BusIn Control, Address_1, [Rd_from_mem_0] BStop Rd_from_mem[m] = Rd_from_mem_0 Next m MONTH = Rd_from_mem[0] DATE = Rd_from_mem[1] HOURS = Rd_from_mem[2] MINUTES = Rd_from_mem[3] Sign = Rd_from_mem[4] temperature = Rd_from_mem[5] Sign_1 = Rd_from_mem[6] temperature_1 = Rd_from_mem[7] HSerOut [Dec4 Address_1/9," "] GoSub Com_out HSerOut [13] EndIf Address_1 = Address_1+1 Wend GoSub Com_End Low PORTC.5 Return '----------------------------- Вывод в COM режима лога ------------------------------------------------------- Log_Out: HSerOut [Dec Log_time,0] Return '----------------------------- Установка режима лога ------------------------------------------------------- Log_time_Set: Log_time = Log_time+1 If Log_time >3 Then Log_time=1 EWrite $01, [Log_time] Return | |
Категория: Proton PICBasic | Добавил: rybkinleo (27.11.2011) | |
Просмотров: 11571 | Комментарии: 4
| Теги: |
Всего комментариев: 4 | |
| |