Define CONFIG1L = 0x00 Define CONFIG1H = 0x02 Define CONFIG2L = 0x1e Define CONFIG2H = 0x00 Define CONFIG3L = 0x00 Define CONFIG3H = 0x83 Define CONFIG4L = 0x80 Define CONFIG4H = 0x00 Define CONFIG5L = 0x0f Define CONFIG5H = 0xc0 Define CONFIG6L = 0x0f Define CONFIG6H = 0xe0 Define CONFIG7L = 0x0f Define CONFIG7H = 0x40 '''Define SIMULATION_WAITMS_VALUE = 1 AllDigital '18F4520 July -2016 RTC & RXD Intr 'ONLY 1 File for SD Card on this version Define LCD_LINES = 4 Define LCD_CHARS = 20 Define LCD_BITS = 4 Define LCD_DREG = PORTD Define LCD_DBIT = 4 'portb.4 spr Define LCD_EREG = PORTB Define LCD_EBIT = 3 Define LCD_RSREG = PORTB Define LCD_RSBIT = 2 Define LCD_RWREG = PORTB Define LCD_RWBIT = 1 'portb.0 int n/u Define LCD_READ_BUSY_FLAG = 1 'portc.0 'portc.1 Define SPI_CS_REG = PORTC 'SD CARD Define SPI_CS_BIT = 2 Define SPI_SCK_REG = PORTC Define SPI_SCK_BIT = 3 Define SPI_SDI_REG = PORTC Define SPI_SDI_BIT = 4 Define SPI_SDO_REG = PORTC Define SPI_SDO_BIT = 5 'portc.6 txd 'portc.7 rxd Define CLOCK_FREQUENCY = 20 Define I2CREAD_DELAYUS = 400 Define I2CCLOCK_STRETCH = 10 Define STRING_MAX_LENGTH = 48 'define the SDA and SCL channels for RTC Symbol scl = PORTE.0 Symbol sda = PORTE.1 Symbol dht = PORTE.2 '''''''''''' Symbol optkey = PORTD.0 Symbol inckey = PORTD.1 Symbol deckey = PORTD.2 Symbol entkey = PORTD.3 Dim x As Byte Dim rxbyt As Byte Dim rxchr As String Dim sdstr As String Dim varstr As String Dim daystr As String Dim stat As Byte Dim low_int As Bit Dim page As Byte Dim txd_on As Byte Dim rec_run As Bit Dim once As Byte Dim rec_rate As Byte Dim rec_int As Byte Dim tx_int As Byte Dim del As Word Dim err_flg As Bit 'DS3231 rtc buffers Dim secs As Byte Dim mins As Byte Dim hrs As Byte Dim day As Byte Dim date As Byte Dim mnth As Byte Dim year As Byte Dim templ As Byte Dim temph As Byte Dim tempw As Word Dim binval As Word Dim tmpb As Byte Dim tens As Byte Dim units As Byte Dim alt1 As Byte Dim dta(32) As Byte 'used on SD read Dim val(5) As Byte Dim val2asc2 As Byte Disable High Disable Low T1CON = %00111101 '1:8 T2CON = 0 T3CON = 0 OSCCON = %01111100 '20mhz INTCON = %00000000 INTCON2 = %00000000 INTCON3 = %00000000 PIR1 = 0 PIR2 = 0 PIE1 = 0 PIE2 = 0 PIE1.RCIE = 1 'rxd Intr IPR1 = 0 IPR2 = 0 RCON.IPEN = 1 'this MUST be included TRISA = 0x0f 'porta.0 adc 'porta.1,2,3 input 'porta.4,5 out TRISB = 0x01 'portb.5,6,7 pgm 'portb.4 spr 'portb.3,2,1 lcd 'portb.0 int n/u TRISC = %00000000 TRISD = %00001111 LATD = %00001111 TRISE.2 = 0 PORTB = 0 LATB = 0 ADCON0 = 0x01 'porta digital ADCON1 = 0x0e ADCON2 = %10100100 'setup the I2C for the DS3231 I2CPrepare sda, scl WaitMs 50 Lcdinit Lcdout "HC12 RX Ready" Hseropen 9600 Hserout "HC12 RX Ready", CrLf Read 10, rec_rate If rec_rate > 250 Then rec_rate = 5 'secs Write 10, rec_rate Endif Read 11, txd_on If txd_on > 2 Then txd_on = 1 Write 11, txd_on Endif rec_run = 0 page = 0 PORTA.4 = 0 PORTA.5 = 0 Gosub init_card Enable High Enable Low '''''''''''''''''''''''''''''''''''''''''''''' idle_loop: 'idling loop, low intr enabled If low_int = 1 Then '111 Lcdcmdout LcdLine1Home varstr = MidStr(sdstr, 39, 8) + " " Lcdout varstr Lcdcmdout LcdLine1Pos(10) Select Case alt1 Case 0 varstr = MidStr(sdstr, 14, 5) Lcdout "A", varstr, "V" alt1 = 1 Case 1 varstr = MidStr(sdstr, 20, 5) Lcdout "B", varstr, "v" alt1 = 2 Case 2 varstr = MidStr(sdstr, 9, 4) Lcdout "RH", varstr, "%" alt1 = 0 EndSelect Lcdcmdout LcdLine2Home varstr = MidStr(sdstr, 33, 5) Lcdout varstr, "Ci" Lcdcmdout LcdLine2Pos(10) varstr = MidStr(sdstr, 3, 5) Lcdout varstr, "Co" Read 10, rec_rate Lcdcmdout LcdLine3Home If rec_run = 1 Then '222 Lcdout "Rec=ON ", #rec_rate, " Sec" Else Lcdout "Rec=OFF ", #rec_rate, " Sec" Endif '222 rec_int = rec_int + 5 If rec_run = 1 Then '333 If rec_int >= rec_rate Then 'Disable Low rec_int = 0 Gosub app_data 'Enable Low Endif Endif '333 If txd_on = 1 Then Disable Low Hserout sdstr Enable Low Endif varstr = MidStr(sdstr, 26, 6) If LeftStr(varstr, 1) = "1" Then '444 PORTA.4 = 1 Else PORTA.4 = 0 Endif '444 low_int = 0 Endif '111 keys: If optkey = 1 Then 'menu page = page + 1 While optkey = 1 Wend If page > 8 Then page = 0 Endif Lcdcmdout LcdLine4Home Select Case page 'keys Case 0 Lcdcmdout LcdLine4Home Lcdout "Sel Inc Dec Ent" Goto idle_loop Case 1 Lcdout "SET Rec On/Off?" If entkey = 1 Then Disable Low Gosub set_record Enable Low WaitMs 200 Endif Case 2 Lcdout "SET Rec Rate? " If entkey = 1 Then Disable Low Gosub set_rate Enable Low Endif Case 3 Lcdout "Read SD File? " If entkey = 1 Then Disable Low Gosub read_card Enable Low page = 0 Endif Lcdcmdout LcdLine4Home Case 4 Lcdout "Del SD File? " If entkey = 1 Then Disable Low Gosub delete_file Write 11, 0x01 page = 0 Lcdcmdout LcdLine4Clear Enable Low Endif Case 5 Lcdout "SET TXD On/Off?" If entkey = 1 Then Disable Low Gosub set_txd Enable Low Endif Case 6 Lcdout "SET Time? " If entkey = 1 Then Disable Low Gosub set_time Enable Low INTCON.INT0IF = 1 Endif Case 7 Lcdout "SET Date? " If entkey = 1 Then Disable Low Gosub set_date Enable Low INTCON.INT0IF = 1 Endif Case Else Lcdcmdout LcdLine4Clear page = 0 EndSelect sdstr = "" Goto idle_loop End On High Interrupt 'not used Save System INTCON.INT0IF = 0 Resume 'interrupt on RXD expected ~5 secs rate On Low Interrupt Save System PIR1.RCIF = 0 sdstr = "" If RCSTA.OERR = 1 Then 'if over run error then flush RXD buffer RCSTA.CREN = 0 RCSTA.CREN = 1 rxbyt = RCREG rxbyt = RCREG PIR1.RCIF = 0 Endif Hserin rxbyt rxchr = Chr(rxbyt) If rxchr = "A" Then 'string ID sdstr = sdstr + rxchr sync1: 'get rest of string Hserin rxbyt rxchr = Chr(rxbyt) sdstr = sdstr + rxchr If rxchr = Lf Then Goto eomsg Goto sync1 Endif eomsg: sdstr = LeftStr(sdstr, 31) + "," read_rtc: I2CStart I2CSend 0xd0 'DS3231 slave addr wr WaitUs 10 I2CSend 0x00 'first word addr wr I2CStop WaitUs 10 I2CStart I2CRead sda, scl, 0xd1, 0, secs I2CRead sda, scl, 0xd1, 1, mins I2CRead sda, scl, 0xd1, 2, hrs I2CRead sda, scl, 0xd1, 3, day I2CRead sda, scl, 0xd1, 4, date I2CRead sda, scl, 0xd1, 5, mnth I2CRead sda, scl, 0xd1, 6, year I2CRead sda, scl, 0xd1, 0x11, temph 'house temp I2CRead sda, scl, 0xd1, 0x12, templ I2CStop tempw.HB = temph tempw.LB = templ tempw = ShiftRight(tempw, 6) tempw = (tempw * 200) / 8 binval = tempw Gosub bin2asc sdstr = sdstr + "+" + Chr(val(3)) + Chr(val(2)) + "." + Chr(val(1)) + "," Gosub read_time low_int = 1 Resume 'this proc for setting Record on/off, also SAVE to eeprom set_record: Gosub yesno While entkey = 1 Wend show_rec: Lcdcmdout LcdLine3Home If rec_run = 1 Then Lcdout "Rec=ON ", #rec_rate, " Sec" Else Lcdout "Rec=OFF ", #rec_rate, " Sec" Endif If inckey = 1 Then rec_run = 1 WaitMs 100 Endif If deckey = 1 Then rec_run = 0 WaitMs 100 Endif While deckey = 1 Or inckey = 1 Wend If optkey = 1 Then Gosub no_save Goto esc_rec Endif If entkey = 0 Then Goto show_rec While entkey = 1 Wend If rec_run = 1 Then once = 0 Gosub init_card WaitMs 100 Gosub read_date Gosub show_date Gosub create_file 'this should write date as 1st line of a new file Else sdstr = "EOF " + CrLf + CrLf Gosub app_data Endif esc_rec: page = 0 Return 'this Proc used to SET current Recording Rate 'Saved to Eeprom set_rate: Lcdcmdout LcdLine4Clear While entkey = 1 Wend Gosub incdec show_rate: Lcdcmdout LcdLine3Home If rec_run = 1 Then Lcdout "Rec=ON ", #rec_rate, " Sec" Else Lcdout "Rec=OFF ", #rec_rate, " Sec" Endif If inckey = 1 Then rec_rate = rec_rate + 5 If rec_rate > 250 Then rec_rate = 5 Endif Endif If deckey = 1 Then rec_rate = rec_rate - 5 If rec_rate < 5 Then rec_rate = 250 Endif Endif If optkey = 1 Then Gosub no_save Goto esc_rate Endif While deckey = 1 Or inckey = 1 Wend If entkey = 0 Then Goto show_rate While entkey = 1 Wend Write 10, rec_rate esc_rate: page = 0 Return yesno: Lcdcmdout LcdLine4Home Lcdout "Ent Inc Dec Sel" Return incdec: Lcdcmdout LcdLine4Home Lcdout "Esc Inc Dec Ent" Return 'this proc for setting TXD on/off set_txd: Gosub yesno While entkey = 1 Wend show_txd: Lcdcmdout LcdLine3Home Gosub yesno Lcdcmdout LcdLine3Home If txd_on = 1 Then Lcdout "Txd=ON " Else Lcdout "Txd=OFF " Endif If inckey = 1 Then txd_on = 1 WaitMs 100 Endif If deckey = 1 Then txd_on = 0 WaitMs 100 Endif If optkey = 1 Then Gosub no_save Goto esc_txd Endif While deckey = 1 Or inckey = 1 Wend If entkey = 0 Then Goto show_txd While entkey = 1 Wend Write 11, txd_on esc_txd: sdstr = "SOF " + sdstr Hserout sdstr, CrLf page = 0 Return 'at 1sec show time read_time: 'timstr = "" '''Lcdcmdout LcdLine1Home val2asc2 = hrs Gosub bcd2asc 'Lcdout val(1), val(0), ":" sdstr = sdstr + Chr(val(1)) + Chr(val(0)) + ":" val2asc2 = mins Gosub bcd2asc 'Lcdout val(1), val(0), ":" sdstr = sdstr + Chr(val(1)) + Chr(val(0)) + ":" val2asc2 = secs Gosub bcd2asc 'Lcdout val(1), val(0), " " sdstr = sdstr + Chr(val(1)) + Chr(val(0)) + CrLf Return show_date: sdstr = "" Lcdcmdout LcdLine1Home val2asc2 = date Gosub bcd2asc Lcdout val(1), val(0), "-" daystr = Chr(val(1)) + Chr(val(0)) + "-" val2asc2 = mnth Gosub bcd2asc Lcdout val(1), val(0), "-" daystr = daystr + Chr(val(1)) + Chr(val(0)) + "-" val2asc2 = year Gosub bcd2asc Lcdout val(1), val(0) daystr = daystr + Chr(val(1)) + Chr(val(0)) + CrLf sdstr = sdstr + daystr Return 'user has selected set time set_time: 'show the current DS3231 time '''''Gosub read_time Lcdcmdout LcdCurBlink WaitMs 100 While entkey = 1 'enter Wend set_hrs: tmpb = hrs hrsset: If optkey = 1 Then Gosub no_save Goto esc_time Endif If inckey = 1 Then Call unpack(tmpb) tmpb = tmpb + 1 If tmpb > 23 Then tmpb = 0 Endif Call set_datim(1) WaitMs 200 Goto hrsset Endif If deckey = 1 Then Call unpack(tmpb) tmpb = tmpb - 1 If tmpb > 23 Then tmpb = 23 Endif Call set_datim(1) WaitMs 200 Goto hrsset Endif Call show_asc(1) If entkey = 0 Then 'not accept key Goto hrsset Endif hrs = tmpb While entkey = 1 'pressed so wait Wend WaitMs 100 set_min: tmpb = mins minset: If inckey = 1 Then minup1: Call unpack(tmpb) tmpb = tmpb + 1 If tmpb > 59 Then tmpb = 0 Endif Call set_datim(4) WaitMs 200 Goto minset Endif If deckey = 1 Then mindn1: Call unpack(tmpb) tmpb = tmpb - 1 If tmpb > 59 Then tmpb = 59 Endif Call set_datim(4) WaitMs 200 Goto minset Endif Call show_asc(4) If entkey = 0 Then Goto minset Endif mins = tmpb While entkey = 1 Wend WaitMs 100 set_sec: tmpb = 00 'always zero the seconds secset: Call show_asc(7) If optkey = 1 Then Gosub no_save Goto esc_time Endif If entkey = 0 Then Goto set_sec Endif secs = tmpb WaitMs 100 While entkey = 1 Wend 'the user has accepted the time Gosub write2ds3231 esc_time: Return read_date: I2CStart I2CSend 0xd0 'DS3231 slave addr wr WaitUs 10 I2CSend 0x00 'first word addr wr I2CStop WaitUs 10 I2CStart I2CRead sda, scl, 0xd1, 3, day I2CRead sda, scl, 0xd1, 4, date I2CRead sda, scl, 0xd1, 5, mnth I2CRead sda, scl, 0xd1, 6, year I2CStop Return 'user has selected set date, switch on lcd underline set_date: 'show the current DS3231 date Gosub show_date Lcdcmdout LcdCurBlink WaitMs 100 While entkey = 1 Wend set_days: tmpb = date dayset: If inckey = 1 Then dayup1: Call unpack(tmpb) tmpb = tmpb + 1 If tmpb > 31 Then tmpb = 1 Endif Call set_datim(1) Goto dayset Endif If deckey = 1 Then daydn1: Call unpack(tmpb) tmpb = tmpb - 1 If tmpb = 0 Then tmpb = 31 Endif Call set_datim(1) Goto dayset Endif Call show_asc(1) If optkey = 1 Then Gosub no_save Goto esc_date Endif If entkey = 0 Then Goto dayset Endif date = tmpb While entkey = 1 Wend WaitMs 100 tmpb = mnth mnthset: If inckey = 1 Then mnthup1: Call unpack(tmpb) tmpb = tmpb + 1 If tmpb > 12 Then tmpb = 1 Endif Call set_datim(4) Goto mnthset Endif If deckey = 1 Then mnthdn1: Call unpack(tmpb) tmpb = tmpb - 1 If tmpb = 0 Then tmpb = 12 Endif Call set_datim(4) Goto mnthset Endif Call show_asc(4) If entkey = 0 Then Goto mnthset Endif mnth = tmpb While entkey = 1 Wend WaitMs 100 set_year: tmpb = year yearset: If inckey = 1 Then yearup1: Call unpack(tmpb) tmpb = tmpb + 1 If tmpb > 99 Then tmpb = 0 Endif Call set_datim(7) Goto yearset Endif If deckey = 1 Then yeardn1: Call unpack(tmpb) tmpb = tmpb - 1 If tmpb > 99 Then tmpb = 99 Endif Call set_datim(7) Goto yearset Endif Call show_asc(7) If entkey = 0 Then Goto yearset Endif 'else save date year = tmpb WaitMs 100 While entkey = 1 Wend Gosub write2ds3231 esc_date: Return 'user has accepted the Date settings, write to DS3231 write2ds3231: I2CSend 0xd0 'DS3231 slave addr wr WaitUs 10 I2CSend 0x00 'first word addr wr I2CStop WaitUs 10 I2CWrite sda, scl, 0xd0, 0, secs I2CWrite sda, scl, 0xd0, 1, mins I2CWrite sda, scl, 0xd0, 2, hrs I2CWrite sda, scl, 0xd0, 3, day I2CWrite sda, scl, 0xd0, 4, date I2CWrite sda, scl, 0xd0, 5, mnth I2CWrite sda, scl, 0xd0, 6, year I2CWrite sda, scl, 0xd0, 7, 0 I2CWrite sda, scl, 0xd0, 8, 0 I2CWrite sda, scl, 0xd0, 9, 0 I2CWrite sda, scl, 0xd0, 10, 0 I2CWrite sda, scl, 0xd0, 11, 0 I2CWrite sda, scl, 0xd0, 12, 0 I2CWrite sda, scl, 0xd0, 13, 0 I2CWrite sda, scl, 0xd0, 14, %01000000 I2CStop page = 0 Lcdcmdout LcdCurOff Lcdcmdout LcdLine4Clear Return init_card: SDCardInit SDCardFAT32Init Lcdcmdout LcdLine4Clear del = 0 wt1: If sd_fat32_status.sd_fat32_error = 0 Then err_flg = 0 Lcdout "FAT32 Init OK " Hserout "FAT32 Init OK", CrLf Goto eof_init Else WaitMs 10 del = del + 1 If del > 200 Then Goto wt1 err_flg = 1 Lcdout "FAT32 Init Fail" Hserout "FAT32 Init Fail! ", CrLf Endif eof_init: WaitMs 500 Lcdcmdout LcdLine4Clear page = 0 Return create_file: If err_flg = 1 Then Return Hserout "Creating hc12file.txt", CrLf SDCardFAT32FileCreate "hc12file.txt" del = 0 wt2: If sd_fat32_status.sd_fat32_wr_opened = 1 Then SDCardFAT32FileWrite "hc12file.txt", " ", daystr Hserout "File Opened: ", daystr, CrLf Goto eof_open Else WaitMs 10 del = del + 1 If del < 200 Then Goto wt2 Hserout "File Open Error", CrLf Endif eof_open: SDCardFAT32FileClose Return get_stat: stat = sd_fat32_status '.sd_fat32 For x = 0 To 7 If stat.x = 1 Then Hserout "1," Else Hserout "0," Endif Next x Hserout CrLf Return app_data: 'set append current file If err_flg = 1 Then SDCardFAT32FileClose Goto sk2 Endif Lcdcmdout LcdLine3Pos(7) Lcdout "#" del = 0 stat = sd_fat32_status wt3: If sd_fat32_status.sd_fat32_notfound = 1 Then WaitMs 10 del = del + 1 If del < 500 Then Goto wt3 Lcdcmdout LcdLine3Pos(7) Lcdout "!" Goto sk2 'not found Endif stat = sd_fat32_status PORTA.5 = 1 SDCardFAT32FileAppend "hc12file.txt" SDCardFAT32FileWrite sdstr PORTA.5 = 0 Lcdcmdout LcdLine3Pos(7) Lcdout " " sk2: SDCardFAT32FileClose Return read_card: rec_run = 0 Lcdcmdout LcdLine3Home SDCardFAT32FileOpen "hc12file.txt" Hserout "hc12file.txt", CrLf If sd_fat32_status.sd_fat32_notfound = 1 Then Hserout "File not found!", CrLf Lcdout "File not found!" Goto eof_err1 Endif If sd_fat32_status.sd_fat32_opened = 1 Then Hserout "Reading file ", CrLf Hserout "File Size= ", #sd_fat32_filelen, " Bytes", CrLf, CrLf Lcdout "Reading file " Lcdcmdout LcdLine4Home Lcdout "Size= ", #sd_fat32_filelen, " Bytes" read_file: SDCardFAT32FileRead For x = 0 To 31 dta(x) = sd_fat32_buff(x) If sd_fat32_bytes_read = 0 Then Goto eof_read Hserout dta(x) dta(x) = 0 Next x WaitMs 10 Goto read_file Endif eof_read: Lcdcmdout LcdLine4Clear Lcdout "EOF" WaitMs 500 Lcdcmdout LcdLine4Clear eof_err1: WaitMs 500 SDCardFAT32FileClose Return delete_file: rec_run = 0 Hserout "Delete File", CrLf Lcdcmdout LcdLine4Clear Lcdout "Delete File" Gosub init_card If err_flg = 1 Then Goto del1 Endif nxt1: Lcdcmdout LcdLine4Clear Lcdout "Delete All" Hserout "Deleting All", CrLf SDCardFAT32FileDelete "hc12file.txt" del = 0 wt5: If sd_fat32_status.sd_fat32_notfound = 1 Then WaitMs 10 del = del + 1 If del < 200 Then Goto wt5 Lcdcmdout LcdLine4Clear Lcdout "All Deleted" Hserout "All Deleted", CrLf Goto del1 Endif If sd_fat32_status.sd_fat32_deleted = 1 Then Lcdcmdout LcdLine4Clear Lcdout "Deleting" Hserout "Deleting", CrLf once = 0 WaitMs 500 Goto nxt1 Endif del1: SDCardFAT32FileClose WaitMs 1000 Return 'the user settings are not changed no_save: WaitMs 100 While optkey = 0 Wend Lcdcmdout LcdCurOff Lcdcmdout LcdClear Lcdout "Cancelled !" Lcdcmdout LcdLine2Home Lcdout "NO Change " WaitMs 1000 Lcdcmdout LcdClear page = 0 Return 'these subr are for user date/time setting functions Proc set_datim(arg1 As Byte) Call pack(tmpb) Lcdcmdout LcdLine1Pos(arg1) Lcdout val(1), val(0) WaitMs 500 End Proc Proc show_asc(arg1 As Byte) Lcdcmdout LcdLine1Pos(arg1) Call unpack(tmpb) Call pack(tmpb) Lcdout val(1), val(0) End Proc 'convt the packed bcd to bin for counting Proc unpack(arg1 As Byte) units = arg1 And 0x0f tens = arg1 And 0xf0 tens = ShiftRight(tens, 4) tens = tens * 10 tmpb = tens + units End Proc 'convt the bin count number to packed bcd for rtc write Proc pack(arg1 As Byte) tens = arg1 / 10 units = arg1 Mod 10 val(1) = tens Or 0x30 val(0) = units Or 0x30 tens = ShiftLeft(tens, 4) tmpb = tens Or units End Proc 'convert packed bcd Byte to ascii for lcd 'enter with BCD value in val2asc2,exit with 2 ascii values bcd2asc: tmpb = val2asc2 val(1) = tmpb And 0xf0 val(1) = ShiftRight(val(1), 4) val(0) = tmpb And 0x0f val(1) = val(1) Or 0x30 val(0) = val(0) Or 0x30 Return bin2asc: val(4) = binval / 10000 val(4) = val(4) Or 0x30 tempw = binval Mod 10000 val(3) = tempw / 1000 val(3) = val(3) Or 0x30 tempw = binval Mod 1000 val(2) = tempw / 100 val(2) = val(2) Or 0x30 tempw = tempw Mod 100 val(1) = tempw / 10 val(1) = val(1) Or 0x30 'val(0) = tempw Mod 10 'val(0) = val(0) Or 0x30 Return