' {$STAMP BS2} ' {$PBASIC 2.5} ' {$PORT COM1} ' I/O Definitions OUTS = %0000000000000100 ' tutte le uscite basse tranne P2 del tasto DeA DIRS = %0000000011111001 ' Direzione dei pin 1= uscita 0=ingresso pbin PIN 2 ' pulsante sulla board i2csda PIN 15 ' i2c SDA SCL PIN 14 ' i2c SCL EN CON 0 ' pin0:ENABLE = lcd pin 6 - attivo basso ' RW CON 1 ' RW = lcd pin 5 - 0 scrive 1 legge, settato HW a 0 RS CON 3 ' pin3:RS = lcd pin 3 - 0 inst 1 text ' OUTB: pin 4-5-6-7 del BS2 sono connessi ai pin 11-12-13-14 del lcd ' LOW RW ' Set LCD To Write Mode (pin 5-RW lcd settato in HW a 0) ' Constanti ' adr RTC 1010.00.A.RW Wr2432a CON %10100000 Wr2432b CON %10100010 Rd2432a CON %10100001 Rd2432b CON %10100011 ACK CON 0 ' acknowledge bit NAK CON 1 ' no ack Bit 'status register RTC PCF8583 'cs_reg CON %00000000 ' osc mode cs_reg CON %00010000 ' 50Hz mode <----------- 'cs_reg CON %00100000 ' counter mode ' Variabili i2cData VAR Byte ' data to/from device i2cWork VAR Byte ' work byte for TX routine i2cAck VAR Bit ' ACK bit from device eeAddr VAR Nib ' massimo 16 celle! porta VAR Bit ' =0 A0=0 =1 A0=1 tempoutc_s VAR Byte 'dati rtc0 tempoutc_m VAR Byte tempoutc_h VAR Byte tempogha_s VAR Byte 'dati rtc1 tempogha_m VAR Byte tempogha_h VAR Byte char VAR Byte ' carattere da scrivere su LCD inst VAR char ' ALIAS istruzione da scrivere su LCD index VAR Word ' puntatore del carattere LCD temp VAR Byte ' Variabile appoggio per LCD X VAR Nib ' puntatore per scrittura lcd riga VAR Bit ' riga 0/1 colonna VAR Nib ' colonna 0/15 POS VAR Byte ' puntatore per lettura tabelle dati carat VAR Byte ' appoggio messaggio errore FLAG1 VAR Bit ' CONTATORE INIZIALIZZATO ' tabelle dei dati EEPROM per scritte su lcd e iniz RTC TESTO1 DATA "UTC = " TESTO2 DATA "GHAy= " TESTO3 DATA "WAIT" ' ORARI DI AVVIO in formato BCD ssss.ssss , mmmm.mmmm , 00hh.hhhh ' orari di avvio=00:00:00 per test del ritardo giornaliero ' ss.mm.hh INIUTC DATA %00000000, %00000000, %00000000 '00:00:00 INISHA DATA %00000000, %00000000, %00000000 '00:00:00 'orari di avvio 01/05/2011 UTC=12:30:00 GHAy=03:06:21 ' ss.mm.hh 'INIUTC DATA %00000000, %00110000, %00010010 ' 00.30.12 'INISHA DATA %01010110, %00000110, %00000011 ' 21.06.03 ' ------------------------------------------ Inizializzazione: GOSUB Init_Lcd ' Inizializza Display lcd Inst = %00001100 ' Turn Off Cursor GOSUB Send_Inst ' ---------------------------------------------------- Main: flag1=0 DO IF flag1=0 THEN GOSUB testa_rtc IF PBIN=0 THEN GOSUB setta_rtc IF FLAG1 =0 THEN GIRA1 GOSUB legge ' legge i due RTC in tempo_x_utc e tempo_x_gha riga=0 ' scrive la prima riga UTC colonna= 8 GOSUB set_pos char= tempoutc_h.HIGHNIB&%11+48 GOSUB Send_Text char= tempoutc_h.LOWNIB+48 GOSUB Send_Text char=":" GOSUB Send_Text char= tempoutc_m.HIGHNIB+48 GOSUB Send_Text char= tempoutc_m.LOWNIB+48 GOSUB Send_Text char=":" GOSUB Send_Text char= tempoutc_s.HIGHNIB+48 GOSUB Send_Text char= tempoutc_s.LOWNIB+48 GOSUB Send_Text riga=1 ' scrive la seconda riga GHA colonna= 8 GOSUB set_pos char= tempogha_h.HIGHNIB&%11+48 GOSUB Send_Text char= tempogha_h.LOWNIB+48 GOSUB Send_Text char=":" GOSUB Send_Text char= tempogha_m.HIGHNIB+48 GOSUB Send_Text char= tempogha_m.LOWNIB+48 GOSUB Send_Text char=":" GOSUB Send_Text char= tempogha_s.HIGHNIB+48 GOSUB Send_Text char= tempogha_s.LOWNIB+48 GOSUB Send_Text GIRA1: LOOP END ' NON SERVE MA NON FA MALE '------------------------------------------------- '------------------------------------------------- testa_rtc: eeaddr=0 GOSUB read_byte IF i2cdata=%00000000 THEN carat="X" GOSUB scrive_errore ELSE flag1=1 GOSUB scrive_sigle ENDIF RETURN '-------------------- setta_rtc: i2cdata= cs_reg ' set status reg porta=0 eeaddr=0 GOSUB write_byte porta=1 eeaddr=0 GOSUB write_byte i2cdata= cs_reg | %10000000 ' stop count bit 7=1 porta=0 eeaddr=0 GOSUB write_byte porta=1 eeaddr=0 GOSUB write_byte porta=0 FOR eeaddr=2 TO 4 'carica contatori rtc0 ss.mm.hh pos=INIUTC + eeaddr - 2 READ pos, i2cdata GOSUB write_byte NEXT porta=1 FOR eeaddr=2 TO 4 'carica contatori rtc1 ss.mm.hh pos=INISHA + eeaddr - 2 READ pos, i2cdata GOSUB write_byte NEXT carat="?" GOSUB scrive_errore aspetta: IF pbin= 0 THEN aspetta ' aspetta avvio con interruttore su pin2 i2cdata= cs_reg & %01111111 ' start count bit 7=0 porta=0 eeaddr=0 GOSUB write_byte porta=1 eeaddr=0 GOSUB write_byte GOSUB scrive_sigle RETURN '------------------------------------------------------------------------------ scrive_sigle: riga=0 colonna= 0 GOSUB set_pos FOR x = 0 TO 5 ' scrive "UTC=" pos = testo1 + x READ pos, char GOSUB Send_Text NEXT riga=1 colonna= 0 GOSUB set_pos FOR x = 0 TO 5 ' scrive "LHAy=" pos = testo2 + x READ pos, char GOSUB Send_Text NEXT RETURN '-------------------- scrive_errore: Inst = %00000001 ' Clears LCD GOSUB Send_Inst riga=0 colonna= 0 GOSUB set_pos FOR x = 0 TO 5 ' scrive "xxxxx=" char=carat GOSUB Send_Text NEXT riga=1 colonna= 0 GOSUB set_pos FOR x = 0 TO 5 ' scrive "xxxxx=" char=carat GOSUB Send_Text NEXT RETURN '------------------- legge: porta=0 eeaddr=2 GOSUB read_byte tempoutc_s= i2cdata eeaddr=3 GOSUB read_byte tempoutc_m= i2cdata eeaddr=4 GOSUB read_byte tempoutc_h= i2cdata porta=1 eeaddr=2 GOSUB read_byte tempogha_s= i2cdata eeaddr=3 GOSUB read_byte tempogha_m= i2cdata eeaddr=4 GOSUB read_byte tempogha_h= i2cdata RETURN ' ------------------------------------------------------------------------------ ' Subroutines lettura e scrittura I2C by Parallax adattate per 2 RTC paralleli ' ------------------------------------------------------------------------------ ' Byte to be written is passed in i2cData ' -- address passed in eeAddr Write_Byte: GOSUB I2C_Start ' send Start IF porta=0 THEN i2cWork = Wr2432a ELSE i2cWork = Wr2432b 'DEBUG CRSRXY, 10, 20, DEC porta, "--", BIN8 i2cWork GOSUB I2C_TX_Byte ' send write command IF (i2cAck = NAK) THEN Write_Byte ' wait until not busy i2cWork=eeAddr GOSUB I2C_TX_Byte i2cWork = i2cData ' send data GOSUB I2C_TX_Byte GOSUB I2C_Stop RETURN '-------------------------------------------------------------- ' Byte read is returned in i2cData ' -- address passed in eeAddr ' LEGGE IL SOLO ULTIMO BYTE, INVIA NAK ' LEGGE UN BYTE, INVIA ACK ' MODIFICARE LA RIGA NECESSARIA Read_Byte: GOSUB I2C_Start ' send Start IF porta=0 THEN i2cWork = Wr2432a ELSE i2cWork = Wr2432b GOSUB I2C_TX_Byte ' send write command 'IF (i2cAck = NAK) THEN Write_Byte ' ORIGINALE: RIMANDO ERRATO IF (i2cAck = NAK) THEN Read_Byte ' CORRETTA: wait until not busy i2cWork= eeAddr GOSUB I2C_TX_Byte GOSUB I2C_Start IF porta=0 THEN i2cWork = Rd2432a ELSE i2cWork = Rd2432b GOSUB I2C_TX_Byte ' send read command 'SCEGLIERE RIGA GIUSTA GOSUB I2C_RX_Byte_Nak ' LEGGE SOLO ULTIMO BYTE 'GOSUB I2C_RX_Byte ' LEGGE DA PRIMO A PENULTIMO BYTE GOSUB I2C_Stop i2cData = i2cWork RETURN ' ------------------------------------------------------------------------------ ' Low Level I2C Subroutines by Parallax ' ------------------------------------------------------------------------------ ' --- Start --- I2C_Start: ' I2C start bit sequence INPUT i2cSDA ' PIN SDA IN ALTA IMPEDENZA E RES PULL UP METTE AD 1 IL BUS INPUT SCL ' PIN SCL IN ALTA IMPEDENZA E RES PULL UP METTE AD 1 IL BUS LOW i2cSDA ' SDA -> low while SCL high Clock_Hold: 'IF (INS.LOWBIT(SCL) = 0) THEN Clock_Hold ' device ready? IN PB 2.0 DO: LOOP WHILE (SCL=0) ' IN PB 2.5 RETURN ' --- Transmit --- I2C_TX_Byte: SHIFTOUT i2cSDA, SCL, MSBFIRST, [i2cWork\8] ' send byte to device SHIFTIN i2cSDA, SCL, MSBPRE, [i2cAck\1] ' get acknowledge bit RETURN ' --- Receive --- I2C_RX_Byte_Nak: ' LEGGE ULTIMO BYTE i2cAck = NAK ' no ACK = high GOTO I2C_RX I2C_RX_Byte: 'LEGGE BYTE DIVERSI DA ULTIMO i2cAck = ACK ' ACK = low I2C_RX: SHIFTIN i2cSDA, SCL, MSBPRE, [i2cWork\8] ' get byte from device SHIFTOUT i2cSDA, SCL, LSBFIRST, [i2cAck\1] ' send ack or nak (NON ULTIMO / ULTIMO) RETURN ' --- Stop --- I2C_Stop: ' I2C stop bit sequence LOW i2cSDA INPUT SCL ' PIN SCL IN HI-Z E RES PULL UP METTE AD 1 IL BUS INPUT i2cSDA ' PIN SDA IN HI.Z IDEM SDA --> high while SCL high RETURN '------------------------------------------- ' Subroutine di gestione lcd by Parallax Init_Lcd: PAUSE 200 OUTS = %00110000 ' Reset The LCD PULSOUT EN,1 ' Send Command Three Times PAUSE 10 PULSOUT EN,1 PAUSE 10 PULSOUT EN,1 PAUSE 10 OUTS = %00100000 ' Set To 4-bit Operation PULSOUT EN,1 Inst = %00101000 ' Function Set (2-Line Mode) GOSUB Send_Inst Inst = %00001110 ' Turn On Cursor GOSUB Send_Inst Inst = %00000110 ' Set Auto-Increment GOSUB Send_Inst Inst = %00000001 ' Clears LCD GOSUB Send_Inst Inst = %00001110 ' Set Cursor To Underline GOSUB Send_Inst RETURN '-------------------------- Send_Inst: LOW RS ' Set Instruction Mode OUTB = Inst.HIGHNIB ' Send High Nibble PULSOUT EN,1 OUTB = Inst.LOWNIB ' Send Low Nibble PULSOUT EN,1 HIGH RS ' Set LCD Back To Text Mode RETURN '-------------------------- Send_Text: OUTB = Char.HIGHNIB ' Send High Nibble PULSOUT EN,1 OUTB = char.LOWNIB ' Send Low Nibble PULSOUT EN,1 PAUSE 100 RETURN '-------------------------- set_pos: ' muove cursore a riga/colonna Inst=128+(64*riga)+colonna GOSUB Send_Inst RETURN ' ------------------------------------------------------------------------------ 'START: ' vecchia routine I2C in PB 2.0 'HIGH SDA 'HIGH SCL 'LOW SDA ' LOW WHILE SCL HIGH 'LOW SCL ' FORSE NON SERVE 'RETURN 'STOP: ' vecchia routine I2C in PB 2.0 'LOW SDA 'HIGH SCL 'HIGH SDA 'HIGH WHILE SCL HIGH 'RETURN ' ------------------------------------------------------------------------------