' ********************************************************************** ' * File: Corso_BASCOMAVR_094.BAS * ' * Versione: 1.2 * ' * Data: 15.09.12 * ' * Ambiente sviluppo: Bascom-AVR Demo Ver. 1.11.9.1 + * ' * + AVR bootloader grifo(r) Ver. 1.2 * ' * Schede: GMM AM08 + GMM TST3 * ' * Sviluppato da: GRIFO(r) Italian Technology * ' * via Dell'Artigiano 8/6 * ' * 40016 S. Giorgio di Piano (BO) * ' * Tel. +39 051 892052 Fax. +39 051 893661 * ' * http://www.grifo.com http://www.grifo.it * ' * Autore: Gianluca Angelini * ' ********************************************************************** ' Programma di esempio 095 del corso BASCOM AVR. ' Rappresentazione temperatura su display a 7 segmenti tramite I2C BUS. ' Il programma usa il componente SAA 1064 con cui pilota 4 display a 7 segmenti ' più punto decimale, che rappresentano la temperatura attuale prelevata dal ' sensore DS 1631. ' La gestione di entrambi i componenti avviene tramite l'interfaccia I2C BUS ' del Mini Modulo ed i display sono comandati in modalità dinamica. ' Alla partenza il programma prima attiva tutti i segmenti dei display in modo ' da verificarne il funzionamento, poi inizia la rappresentazione della ' temperatura ad ogni secondo, con la risoluzione del mezzo grado, nel range ' da -55 a +125 °C, caratteristica del sensore. ' Il programma si presenta ed usa una console seriale dotata di monitor, con ' un protocollo fisico costante a 19200 Baud, 8 Bit x chr, 1 Stop bit, Nessuna ' parità. ' Questa console può coincidere con un sistema in grado di gestire una ' comunicazione seriale in RS 232. Al fine di semplificarne l'uso si può ' usare un PC dotato di una linea COMx, che esegue un programma di emulazione ' terminale come HYPERTERMINAL o l'omonima modalità offerta dal BASCOM AVR ' (vedere Configurazioni IDE). ' Il programma funziona solo se la GMM AM08 è montata sullo zoccolo Z2 della ' GMM TST3!! ' ' Aggiunte: Nessuna. ' ' 28/10/11: Corso_BASCOMAVR_95.BAS - Ver 1.1 - By G.A. ' Prima versione. ' 15/09/12: Corso_BASCOMAVR_95.BAS - Ver 1.2 - By G.A. ' Corretta rappresentazione temperatura per l'intero range del sensore. ' ' '*************************** Configurazioni IDE ******************************** ' NOTE: per usare correttamente questo programma demo, eseguire i seguenti ' punti: ' 1) Controllare la presenza del file M8DEF.DAT nella directory di ' installazione del BASCOM-AVR e se non disponibile copiarlo e dopo ' rilanciare l'IDE. ' 2) Nella finestra "Options | Compiler | Chip" impostare: ' Chip: m8def.dat ' XRAM: None ' HW Stack: 64 ' Soft Stack: 32 ' Framesize: 64 ' XRAM waitstate: disattivo ' External Access Enable: disattivo ' 3) Nella finestra "Options | Compiler | I2C, SPI, 1WIRE" settare: ' I2C ' SCL port = PORTC.5 ' SDA port = PORTC.4 ' 1Wire ' 1wire = indifferente ' SPI ' Clock = indifferente ' MOSI = indifferente ' MISO = indifferente ' SS = indifferente ' Use Hardware SPI = disattivo ' 4) Nella finestra "Options | Communication" settare: ' COM port = la linea del PC collegata alla GMM AM08, tramite la GMM TST3 ' Baudrate = 19200 ' Parity = None ' Databits = 8 ' Stopbit = 1 ' Handshake = None ' Emulation = TTY ' Font = Terminal, Normale, 12 punti, colore bianco ' Backcolor = Navy ' 5) Al termine della compilazione, della programmazione del codice nella ' GMM AM08, aprire la finestra di emulazione terminale del BASCOM AVR con ' l'opzione: Tools | Terminal emulator (Ctrl+T) ed a questo punto resettare ' o riaccendere il Mini Modulo. '********************** Direttive del compilatore ****************************** $regfile "M8DEF.DAT" ' File di definizione microcontrollore usato $romstart = &H0 ' Indirizzo inizio codice in FLASH $crystal = 7372800 ' Frequenza quarzo del microcontrollore $hwstack = 64 ' Spazio per stack hardware $swstack = 32 ' Spazio per stack software $framesize = 64 ' Spazio per frame $map ' Genera informazioni di debug $baud = 19200 ' Velocità comunicazione seriale: 19200 Baud ' Altri parametri sono fissi a: 8 bit x chr ' 1 Stop bit ' No parity '******************************* Definizioni *********************************** ' Le risorse usate dal programma sono collegate come illustrato nella seguenti ' tabelle: ' !!! N.B. Sulla GMM TST3 i jumper devono essere posizionati come segue: ' J1 in 2-3 ; J2 in 1-2 ; J3 in 1-2 ; J5 in 2-3 ; J7 in 2-3 ; J8 in 2-3 ' J9 in 2-3 !!! ' ' Segnali Risorsa pin Z2 pin Segnale Segnale uP ' esterni GMM TST3 GMM TST3 GMM AM08 GMM AM08 usato ' SCL DS1631 SCL SAA1064 CN3.15 12 6 PC5 ADC5 SCL PC5 ' SDA DS1631 SDA SAA1064 CN3.16 13 7 PC4 ADC4 SDA PC4 ' Vdd DS1631 Vcc SAA1064 CN3.18 34 28 +5 Vdc - ' GND DS1631 Vss SAA1064 CN3.17 20 14 GND - ' ' Segnale pin COMx pin CN5 pin Z2 pin Segnale Segnale uP ' PC DB9 GMM TST3 GMM TST3 GMM AM08 GMM AM08 usato ' TX 3 3 9 3 RxD RS232 PD0 ' RX 2 2 10 4 TxD RS232 PD1 ' GND 5 5 20 14 GND - ' Da questa tabella si ricava che il cavo di collegamento tra la COM del PC ed ' il CN5 della GMM TST3 è un normale cavo dritto o prolunga. Volendolo ' richiedere alla grifo(r) si deve specificare il codice CCR 9+9E. Pinrx Alias Ddrd.0 ' Bit con direzione segnale collegato a RxD GMM AM08 Pintx Alias Ddrd.1 ' Bit con direzione segnale collegato a TxD GMM AM08 '************************ Dichiarazioni costanti ******************************* Const Cret = &H0D ' Codice ASCII Carriage Return Const Slawsaa1064 = &H70 ' Slave address SAA1064 in scrittura Const Slarsaa1064 = &H71 ' Slave address SA1064 in lettura Const Ctb = 0 ' Indirizzo Control byte SA1064 Const Dig1 = 1 ' Indirizzo Digit 1 SA1064 Const Dig2 = 2 ' Indirizzo Digit 2 SA1064 Const Dig3 = 3 ' Indirizzo Digit 3 SA1064 Const Dig4 = 4 ' Indirizzo Digit 4 SA1064 Const Slawds1631 = &H98 ' Slave address DS1631 in scrittura Const Slards1631 = &H99 ' Slave address DS1631 in lettura Const Acccfg = &HAC ' Access Config register command Const Rtemp = &HAA ' Comando lettura ultima temperatura Const Startct = &H51 ' Comando inizio conversioni temperature Const Stopct = &H22 ' Comando fine conversioni temperature '************************ Dichiarazioni variabili ****************************** Dim Hlpb As Byte ' Variabile byte di aiuto ad uso generico Dim Hlpw As Word ' Variabile word di aiuto ad uso generico Dim Digit As Word ' Cifra da rappresentare Dim Patdis(10) As Byte ' Vettore con pattern cifre numeriche da rappresentare su display Dim Minus As Byte ' Pattern rappresentazione segno negativo su display Dim Disdat(6) As Byte ' Vettore con dati e pattern per accensione segmenti su display Dim Isds1631 As Boolean ' Flag sensore DS1631 presente Dim Cfgreg As Byte ' Variabile con stato registro configurazione Dim Temph As Byte ' Variabile per byte H della temperatura acquisita da sensore Dim Templ As Byte ' Variabile per byte L della temperatura acquisita da sensore Dim Tint_i2c As Integer ' Temperatura intera (in 0,5 °C), acquisita da sensore DS1631 Dim Tdec_i2c As Single ' Temperatura decimale (in °C), acquisita da sensore DS1631 Dim Gstr As String * 6 ' Stringa per visualizzazione temperatura formattata '************************ Dichiarazioni procedure ****************************** Declare Sub Ini_i2c() ' Inizializza linee usate per l'interfaccia I2C BUS software Declare Sub Ini_disp7seg() ' Inizializza controllore display a 7 segmenti SAA 1064 Declare Sub Shw_disp7seg() ' Visualizza stato dei segmenti su display comandati da SAA 1064 Declare Sub Initemp_i2c() ' Inizializza sensore I2C BUS DS1631 per acquisizione temperatura Declare Sub Gettemp_i2c() ' Acquisisce temperatura attuale del sensore I2C BUS DS1631 Declare Sub Shw_temp() ' Rappresenta temperatura formattata sulla console Declare Sub Shw_temp_disp7seg() ' Rappresenta temperatura formattata su display a 7 segmenti '************************** Programma principale ******************************* Main: Pinrx = 0 ' Inizializza segnali per comunicazione seriale Pintx = 0 ' come ingressi digitali Call Ini_i2c() ' Inizializza linee usate per l'interfaccia I2C BUS software Print Print " Rappresentazione temperatura su display 7 segmenti, con GMM AM08 + GMM TST3" Print "Montare Mini Modulo su Z2 della GMM TST3, collegare linea I2C BUS ai componenti" Print "SAA 1064 e DS 1631, come da schema." Print "Il programma preleva ciclicamente la temperatura dal sensore e la rappresenta" Print "sui display in forma numerica, con la risoluzione di 0,5 gradi centigradi." Print Call Ini_disp7seg() ' Inizializza controllore display a 7 segmenti SAA 1064 Disdat(2) = &HFF ' Attiva tutti i segmenti dei quattro display Disdat(3) = &HFF Disdat(4) = &HFF Disdat(5) = &HFF Call Shw_disp7seg() ' Visualizza stato impostato su display Wait 1 ' Attesa di 1 secondo per consentire verifica attivazione segmenti dei display Disdat(2) = &H00 ' Disattiva tutti i segmenti dei quattro display Disdat(3) = &H00 Disdat(4) = &H00 Disdat(5) = &H00 Call Shw_disp7seg() ' Visualizza stato impostato su display Wait 1 ' Attesa di 1 secondo per consentire verifica disattivazione segmenti dei display Call Initemp_i2c() ' Inizializza sensore I2C BUS DS1631 per acquisizione temperatura If Isds1631 = 1 Then ' Se DS1631 trovato Print "Sensore DS1631 trovato." Print "Temperatura (C)" Do Call Gettemp_i2c() ' Acquisisce temperatura del sensore I2C BUS DS1631 Call Shw_temp_disp7seg() ' Rappresenta temperatura formattata su display a 7 segmenti Call Shw_temp() ' Rappresenta temperatura attuale su console Printbin Cret ' Mantiene rappresentazione su stessa riga Wait 1 ' Ritardo di 1 secondo Loop ' Fine ciclo infinito Else Print "Sensore DS1631 non trovato!" Print "Controllare collegamenti e rieseguire il programma." End If End '************************ Fine programma principale **************************** '****************** Inizio procedure usate dal programma *********************** ' Inizializza segnali e variabili usati per l'interfaccia I2C BUS gestita via ' software ' Ingresso: Nulla ' Uscita: Nulla Sub Ini_i2c() ' Questa procedura è stata realizzata per compatibilità con i programmi demo ' delle EEPROM con altri protocolli gestite a basso livello. Per il protocollo ' I2C BUS si usano invece le istruzioni ad alto livello del BASCOM. ' Per le connessioni linee dell'interfaccia I2C BUS software vedere help in ' linea e precedente tabella. Config Scl = Portc.5 ' Segnale del micro usato come segnale SCL dell'I2C BUS Config Sda = Portc.4 ' Segnale del micro usato come segnale SDA dell'I2C BUS I2cinit ' Inizializza segnali I2C BUS End Sub ' Procedura che inizializza controllore display a 7 segmenti SAA 1064, in I2C BUS ' Ingresso: Nulla ' Uscita: Patdis() = Vettore con pattern cifre numeriche da rappresentare su display Sub Ini_disp7seg() Do I2creceive Slarsaa1064 , Hlpb , 0 , 1 ' Legge registro di stato SAA 1064 Loop Until Hlpb = 0 ' Attende accensione SAA 1064 ' Prepara sequenza di inizializzazione dell'SAA1064 Disdat(1) = Ctb ' Punta al registro di controllo Disdat(2) = &B00100111 ' bit0 =1 dynamic mode ' bit1 =1 digit 1+3 not blanked ' bit2 =1 digit 2+4 not blanked ' bit3 =0 no test segment ' bit4 =0 no 3mA segment current ' bit5 =1 6mA segment current ' bit6 =0 no 12mA segment current ' bit7 =0 indifferente Disdat(3) = 0 ' Setta DY1 off Disdat(4) = 0 ' Setta DY2 off Disdat(5) = 0 ' Setta DY3 off Disdat(6) = 0 ' Setta DY4 off I2csend Slawsaa1064 , Disdat(1) , 6 ' Invia sequenza preparata all'SAA 1064 ' Inizializza vettore con pattern per convertire una cifra da 0 a 9 nella codifica a 7 segmenti Patdis(1) = &H3F ' 0 D0 Patdis(2) = &H06 ' 1 +----+ Patdis(3) = &H5B ' 2 | | Patdis(4) = &H4F ' 3 D5 | | D1 Patdis(5) = &H66 ' 4 | D6 | Patdis(6) = &H6D ' 5 +----+ Patdis(7) = &H7D ' 6 | | Patdis(8) = &H07 ' 7 D4 | | D2 Patdis(9) = &H7F ' 8 | D3 | Patdis(10) = &H6F ' 9 +----+ . D7 Minus = &H40 ' Pattern rappresentazione segno negativo End Sub ' Visualizza stato dei segmenti su display comandati da SAA 1064 ' Ingresso: Disdat() = Pattern per visualizzazione valore su display ' Uscita: Nulla Sub Shw_disp7seg() Disdat(1) = Dig1 ' Punta al primo display del controllore SAA 1064 I2csend Slawsaa1064 , Disdat(1) , 5 ' Invia sequenza con pattern preparati all'SAA 1064 End Sub ' Inizializza sensore I2C BUS per l'acquisizione temperatura a 9 bit di ' risoluzione e conversione continua ' Ingresso: Nulla ' Uscita: Nulla Sub Initemp_i2c() I2cstart ' Invia sequenza di Start I2C BUS I2cwbyte Slawds1631 ' Invia Slave address del DS1631 in scrittura I2cwbyte Acccfg ' Invia comando per accesso al registro configurazione I2cwbyte &B00000010 ' Setta registro configurazione per: 9 bit di risoluzione ' Polarita Tout attiva alta ' Conversione continua I2cstop ' Invia sequenza di Stop I2C BUS Waitms 50 ' Ritardo per fine scrittura EEPROM interna del DS1631 I2cstart ' Invia sequenza di Start I2C BUS I2cwbyte Slawds1631 ' Invia Slave address del DS1631 in scrittura I2cwbyte Acccfg ' Invia comando per accesso al registro configurazione I2cstart ' Invia sequenza di Repeated Start I2C BUS I2cwbyte Slards1631 ' Invia Slave address del DS1631 in lettura I2crbyte Cfgreg , Nack ' Legge dato ed indica fine lettura I2cstop ' Invia sequenza di Stop I2C BUS Cfgreg = Cfgreg And &B00011111 ' Mantiene i bits 4..0 con stato certo dopo configurazione effettuata If Cfgreg = &B00000010 Then ' Se stato dopo configurazione valido Isds1631 = 1 ' Sensore DS1631 presente I2cstart ' Invia sequenza di Start I2C BUS I2cwbyte Slawds1631 ' Invia Slave address del DS1631 in scrittura I2cwbyte Startct ' Invia comando Start Conversion temperature I2cstop ' Invia sequenza di Stop I2C BUS Else Isds1631 = 0 ' Sensore DS1631 non presente End If End Sub ' Gestione acquisizione temperatura attuale del sensore I2C BUS DS1631. ' La procedura prima invia il comando di lettura ultima conversione e poi legge ' e trasforma i due byte con la temperatura acquisita, usando i 9 bits di ' risoluzione preselezionati ' Ingresso: Nulla ' Uscita: Tdec_i2c = Temperatura decimale (in °C) acquisita da sensore Sub Gettemp_i2c() ' Preleva due byte con temperatura acquisita dal sensore I2cstart ' Invia sequenza di Start I2C BUS I2cwbyte Slawds1631 ' Invia Slave address del DS1631 in scrittura I2cwbyte Rtemp ' Invia comando lettura ultima temperatura I2cstart ' Invia sequenza di Repeated Start I2C BUS I2cwbyte Slards1631 ' Invia Slave address del DS1631 in lettura I2crbyte Temph , Ack ' Legge byte H della temperatura e non indica fine lettura I2crbyte Templ , Nack ' Legge byte L della temperatura ed indica fine lettura I2cstop ' Invia sequenza di Stop I2C BUS ' Ottiene temperatura intera (in 0,5 °C) dai due byte prelevati, a 9 bit Tint_i2c = Temph ' Salva byte H nella variabile per temperatura intera Shift Tint_i2c , Left , 1 ' Sposta byte H un bit a sinistra Tint_i2c.0 = Templ.7 ' Copia solo il bit 7 del byte L su bit 0 della temperatura ' Completa codifica temperatura negativa in complemento a 2, a 9 bit If Temph.7 = 1 Then ' Se temperatura negativa Tint_i2c = Tint_i2c Or &HFE00 ' Setta ad 1 i bit non letti da sensore per complemento a 2 End If ' Trasforma temperatura intera (in 0,5 °C) in decimale (in °C) Tdec_i2c = Tint_i2c ' Salva temperatura intera ottenuta su variabile single Tdec_i2c = Tdec_i2c / 2.0 ' Ottiene temperatura decimale in °C End Sub ' Rappresenta temperatura formattata sulla console nel formato xxx.x o -xx.x ' Ingresso: Tdec_i2c = temperatura attuale ' Uscita: Nulla Sub Shw_temp() Gstr = Fusing(tdec_i2c , "000.#") ' Formatta temperatura con tre cifre intere ed una decimale Print " " ; Gstr ; ' Rappresenta temperatura valida acquisita e formattata End Sub ' Rappresenta temperatura formattata sui display a 7 segmenti, nel formato ' xxx.x o -xx.x ' Ingresso: Tdec_i2c = temperatura attuale ' Uscita: Nulla Sub Shw_temp_disp7seg() ' Converte temperatura attuale If Tdec_i2c < 0 Then ' Se temperatura negativa Disdat(2) = Minus ' Salva pattern segno meno per primo display (DY1=DY5) Hlpw = Tdec_i2c * -10 ' Ottiene temperatura intera e positiva Else ' Temperatura positiva Hlpw = Tdec_i2c * 10 ' Ottiene temperatura intera Digit = Hlpw \ 1000 ' Ottiene cifra delle centinaia 0..9 Incr Digit ' Trasforma centinaia da 1..10 Disdat(2) = Patdis(digit) ' Salva pattern cifra delle centinaia per primo display (DY1=DY5) End If Hlpw = Hlpw Mod 1000 ' Ottiene cifra delle decine 0..9 Digit = Hlpw \ 100 Incr Digit ' Trasforma decine da 1..10 Disdat(3) = Patdis(digit) ' Salva pattern cifra delle decine per secondo display (DY2=DY6) Hlpw = Hlpw Mod 100 ' Ottiene cifra delle unità 0..9 Digit = Hlpw \ 10 Incr Digit ' Trasforma unità da 1..10 Disdat(4) = Patdis(digit) ' Salva pattern cifra delle unità per terzo display (DY3=DY7) Disdat(4) = Disdat(4) Or &H80 ' Attiva punto decimale su terzo display (DY3=DY7) Digit = Hlpw Mod 10 ' Ottiene cifra dei decimi 0..9 Incr Digit ' Trasforma decimi da 1..10 Disdat(5) = Patdis(digit) ' Salva pattern cifra dei decimi per quarto display (DY4=DY8) Call Shw_disp7seg() ' Visualizza stato impostato su display End Sub '******************* Fine procedure usate dal programma ************************