' ********************************************************************** ' * File: Corso_BASCOMAVR_103.BAS * ' * Versione: 1.1 * ' * Data: 13.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 103 del corso BASCOM AVR. ' Gestione termometro e termostato con banda di controllo od isteresi, su 4 ' display a 7 segmenti ed impostabile con 3 tasti. ' Il programma usa i componenti DS 1631 ed SAA 1064 presenti sulla scheda ' didattica K51-AVR rispettivamente come termometro e controllore display ed ' una scheda d'interfaccia provvista di tre pulsanti, un LED ed un buzzer. ' Questa scheda provvede a collegare tutte le risorse al Mini Modulo montato ' sulla GMM TST3, compresa la linea di comunicazione I2C BUS usata dalla K51-AVR. ' Alla partenza il programma prima attiva tutti i segmenti dei display in modo ' da verificarne il funzionamento, poi verifica se il termometro è funzionante ' ed in caso affermativo prosegue con la rappresentazione della temperatura ' attuale sui display. ' Tenendo premuto il tasto 1 per due secondi si entra nella modalità di ' impostazione in cui si possono impostare in sequenza il set point, l'isteresi ' e l'attivazione del termostato, ripremendo sempre il tasto 1; con un ultima ' pressione si esce dall'impostazione e si torna al normale funzionamento. In ' modalità impostazione i tasti 2 e 3 incrementano o decrementano il dato ' attuale, in modo circolare. ' Per ogni pressione di tasto viene anche generato un beep con il buzzer della ' scheda d'interfaccia in modo da generare una segnalazione acustica. ' Il set point, l'isteresi e l'attivazione inserite sono usati dal programma ' per svolgere la funzione di termostato in riscaldamento, sul segnale collegato ' al Buzzer dell'interfaccia. Usando un riscaldatore al posto del Buzzer la ' temperatura si innalzerebbe e manterrebbe il valore di set point impostato. ' Sia la temperatura che il set point e l'isteresi sono rappresentate sui 4 ' display a 7 segmenti con la risoluzione del mezzo grado, nel range da -55.0 ' a +125.0 °C. L'abilitazione del termostato invece è visualizzata sul LED ' della scheda d'interfaccia: quando è acceso il termostato è attivo e viceversa. ' I 3 parametri di configurazione del termostato, sono salvati su EE in doppia ' copia e da questa prelevati e controllati alla partenza, in modo da riprendere ' il funzionamento nelle stesse condizioni anche a seguito di uno spegnimento e ' riaccensione. ' Il programma funziona solo se la GMM AM08 è montata sullo zoccolo Z2 della ' GMM TST3!! ' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NOTA BENE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ' Alcune delle operatività descritte sopra sono commentate nel sorgente in modo ' da ridurre il codice del programma e poterlo quindi compilare con la versione ' demo del BASCOM AVR. ' ' Aggiunte: Nessuna. ' ' 13/09/12: Corso_BASCOMAVR_103.BAS - Ver 1.1 - By G.A. ' Prima versione. ' ' '*************************** 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 - ' Buzzer CN4.8 27 21 PD6 AIN0 PD6 ' LED CN4.6 29 23 PB0 ICP PB0 ' Tasto 1 CN4.1 32 26 PC0 ADC0 PC0 ' Tasto 2 CN4.4 31 25 PC1 ADC1 PC1 ' Tasto 3 CN4.3 30 24 PB1 OC1A PB1 ' ' 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. Buz_interface Alias Portd.6 ' Bit con segnale d'uscita collegato a Buzzer della scheda d'interfaccia Led_interface Alias Portb.0 ' Bit con segnale d'uscita collegato a Led della scheda d'interfaccia Key1_interface Alias Pinc.0 ' Bit con segnale d'ingresso collegato a Tasto 1 della scheda d'interfaccia Key2_interface Alias Pinc.1 ' Bit con segnale d'ingresso collegato a Tasto 2 della scheda d'interfaccia Key3_interface Alias Pinb.1 ' Bit con segnale d'ingresso collegato a Tasto 3 della scheda d'interfaccia 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 Accth = &HA1 ' Access TH register command Const Acctl = &HA2 ' Access TL register command Const Rtemp = &HAA ' Comando lettura ultima temperatura Const Startct = &H51 ' Comando inizio conversioni temperature Const Stopct = &H22 ' Comando fine conversioni temperature Const Beepdt = 75 ' Tempo durata beep segnalazione tasto premuto Const Maindt = 200 ' Ritardo esecuzione ciclo principale in millisecondi Const Settime = 2000 ' Tempo entrata impostazioni in millisecondi Const Setcycle = Settime / Maindt ' Numero cicli entrata impostazioni Const Repdt = 10 ' Tempo esecuzione Debouncing ed autoripetizione in millisecondi Const Reptime = 250 ' Tempo autorepeat tasti in millisecondi Const Repcycle = Reptime / Repdt ' Numero cicli autorepeat tasti '************************ 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 Disdatirq(6) As Byte ' Vettore con dati e pattern per accensione segmenti su display in interrupt Dim I2cbusused As Bit ' Flag linea I2C BUS usata dal programma principale Dim Dispblink As Byte ' Selettore lampeggio display 7 segmenti Dim Blinkcnt As Byte ' Contatore per lampeggio display Dim Keycnt As Byte ' Contatore per gestione tasti Dim Curval As Single ' Valore attuale per impostazioni Dim Minval As Single ' Valore minimo per impostazioni Dim Maxval As Single ' Valore massimo per impostazioni 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 Datee As Byte ' Dato da scrivere o letto da EEPROM Dim Addee As Word ' Indirizzo locazione EEPROM da scrivere o leggere Dim Crcr As Byte ' CRC configurazioni letto da EE Dim Crcc As Byte ' CRC configurazioni calcolato Iniaddcnf Alias Varptr(setpoint) ' Indirizzo inizio variabili di configurazione Dim Setpoint As Single ' Set point per funzione termostato Dim Hyster As Single ' Isteresi per funzione termostato Dim Termact As Byte ' Flag attivazione termostato Endaddcnf Alias Varptr(inihyst) ' Indirizzo fine variabili di configurazione Dim Inihyst As Single ' Temperatura inizio isteresi Dim Heaton As Bit ' Flag con stato riscaldatore Dim Onhyst As Bit ' Flag per controllo in banda isteresi '************************ 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 Ini_distmrirq() ' Inizializza timer per rinfresco display 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_disp7seg_irq() ' Rappresenta temperatura formattata su display a 7 segmenti con rinfresco in interrupt Declare Sub Beep_interface() ' Emette un beep acustico con buzzer su scheda interfaccia Declare Sub Edit_value_temp(byval Minval As Single , Byval Maxval As Single) ' Imposta valore numerico nel range passato Declare Sub Change_temp() ' Gestisce variazione temperatura Declare Sub Rd_ee() ' Legge un byte dalla EEPROM interna del uP Declare Sub Wr_ee() ' Scrive un byte nella EEPROM interna del uP Declare Sub Rdcnfee() ' Legge configurazione da EE Declare Sub Wrcnfee() ' Scrive configurazione su EE Declare Sub Defcnf() ' Setta configurazione di default Declare Sub Getchkcnf() ' Carica e verifica configurazione '************************** Programma principale ******************************* Main: Pinrx = 0 ' Inizializza segnali per comunicazione seriale Pintx = 0 ' come ingressi digitali Buz_interface = 1 ' Inizializza segnale collegato a Buzzer su scheda interfaccia come uscita digitale Config Buz_interface = Output ' alta, in modo da mantenerlo disattivo Led_interface = 1 ' Inizializza segnale collegato a Led su scheda interfaccia come uscita digitale Config Led_interface = Output ' alta, in modo da mantenerlo disattivo Config Key1_interface = Input ' Inizializza segnale collegato a Tasto 1 su scheda interfaccia come ingresso digitale Config Key2_interface = Input ' Inizializza segnale collegato a Tasto 2 su scheda interfaccia come ingresso digitale Config Key3_interface = Input ' Inizializza segnale collegato a Tasto 3 su scheda interfaccia come ingresso digitale I2cbusused = 0 ' Linea I2C BUS non usata Dispblink = 0 ' Display non lampeggianti Blinkcnt = 0 ' Inizializza contatore per lampeggio display Keycnt = 0 ' Inizializza contatore per gestione tasti ' Istruzioni commentate per poter usare versione demo del compilatore BASCOM AVR ' Print ' Print " Termometro/Termostato impostabili da tasti, basato su GMM AM08" ' Print "Montare Mini Modulo su Z2 della GMM TST3, collegare CN3, CN4 ad apposita scheda" ' Print "d'interfaccia e linea I2C BUS dalla scheda interfaccia alla K51-AVR, come da" ' Print "schema." ' Print "Il programma preleva ciclicamente la temperatura dal sensore e la rappresenta" ' Print "sui display in forma numerica, nel range da -55.0 a 125.0. Premere Tasto 1," ' Print "poi 2 (+) e 3 (-) per impostare set point, isteresi ed attivazione del termostato." ' Print "Il LED LD2 sulla K51-AVR segnala l'attivazione dell'uscita di riscaldamento" ' Print "del termostato." ' Print Call Ini_i2c() ' Inizializza linee usate per l'interfaccia I2C BUS software Call Ini_disp7seg() ' Inizializza controllore display a 7 segmenti SAA 1064 Call Ini_distmrirq() ' Istruzioni commentate per poter usare versione demo del compilatore BASCOM AVR ' Disdat(2) = &HFF ' Attiva tutti i segmenti dei quattro display ' Disdat(3) = &HFF ' Disdat(4) = &HFF ' Disdat(5) = &HFF ' 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 ' Wait 1 ' Attesa di 1 secondo per consentire verifica disattivazione segmenti dei display ' Predispone sensore di temperatura+termostato, verificandone il funzionamento Call Initemp_i2c() ' Inizializza sensore I2C BUS DS1631 per acquisizione temperatura Call Getchkcnf ' Verifica e carica parametri di configurazione da EE If Termact = 1 Then ' Se termostato attivo Led_interface = 0 ' Attiva LED scheda interfaccia End If Inihyst = Setpoint - Hyster ' Determina temperatura inizio isteresi Onhyst = 0 ' Controllo non in isteresi Do ' Inizio ciclo infinito Waitms Maindt ' Ritardo tra acquisizioni e controlli If Isds1631 = 1 Then ' Se DS1631 trovato e funzionante Call Gettemp_i2c() ' Acquisisce temperatura del sensore I2C BUS DS1631 Call Shw_temp_disp7seg_irq() ' Rappresenta temperatura formattata su display a 7 segmenti If Termact = 1 Then ' Se termostato attivo ' Effettua controllo temperatura acquisita come termostato in riscaldamento ' e determina stato del riscaldatore nella variabile Heaton If Tdec_i2c < Inihyst Then ' Se temperatura sotto banda isteresi Heaton = 1 ' Riscaldatore attivo Onhyst = 0 ' Controllo non in isteresi End If If Tdec_i2c >= Inihyst And Onhyst = 0 Then ' Se temperatura in banda isteresi e controllo non in isteresi Heaton = 1 ' Riscaldatore attivo End If If Tdec_i2c >= Setpoint Then ' Se temperatura sopra banda isteresi Heaton = 0 ' Riscaldatore disattivo Onhyst = 1 ' Controllo in isteresi End If Else ' Termostato non attivo Heaton = 0 ' Riscaldatore disattivo End If ' Comanda buzzer su scheda d'interfaccia con stato del riscaldatore determinato, ' in logica negata (riscaldatore attivo=buzzer attivo) Buz_interface = Not Heaton ' Setta stato riscaldatore su buzzer If Key1_interface = 0 Then ' Se tasto 1 premuto su scheda interfaccia Incr Keycnt ' Incrementa contatore durata pressione tasto 1 If Keycnt >= Setcycle Then ' Se tasto 1 premuto per almeno 250 msec * 8 = 2 sec Call Beep_interface() ' Emette un beep acustico per segnalare pressione tasto Do Loop Until Key1_interface = 1 ' Attende rilascio tasto 1 Keycnt = 0 ' Azzera contatore per gestione tasti ' Gestione impostazione termostato: set point Curval = Setpoint ' Gestisce impostazione set point del termostato Call Change_temp() Setpoint = Curval ' Gestione impostazione termostato: isteresi Curval = Hyster ' Gestisce impostazione isteresi del termostato Call Change_temp() Hyster = Curval ' Gestione impostazione attivazione termostato ' Istruzioni commentate per poter usare versione demo del compilatore BASCOM AVR ' Curval = Termact ' Valore attuale attivazione termostato ' Do ' Ciclo impostazione attivazione termostato ' Call Edit_value_temp(0 , 0.5) ' Imposta attivazione termostato nel range 0..0.5 ' If Curval = 0 Then ' Salva valore impostato su attivazione termostato attuale ' Termact = 0 ' Termostato non attivo ' Led_interface = 1 ' Disattiva LED scheda interfaccia ' Else ' Termact = 1 ' Termostato attivo ' Led_interface = 0 ' Attiva LED scheda interfaccia ' End If ' Loop Until Key1_interface = 0 ' Ripremendo tasto 1 termina impostazione attivazione termostato ' Call Beep_interface() ' Emette un beep acustico per segnalare pressione tasto ' Do ' Loop Until Key1_interface = 1 ' Attende rilascio tasto 1 ' Salva parametri configurazioni su EE con doppia copia Addee = &H0000 ' Scrive prima copia configurazione su EE Call Wrcnfee Addee = &H0100 ' Scrive seconda copia configurazione su EE Call Wrcnfee Dispblink = 0 ' Display non lampeggianti End If Else Keycnt = 0 ' Azzera contatore durata pressione tasto 1 End If Else ' Sensore DS1631 non trovato o non funzionante Buz_interface = Not Buz_interface ' Complementa Buzzer scheda interfaccia per segnalare l'anomalia End If Loop ' Fine ciclo infinito 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 ' Inizializza generazione interrupt periodico tramite TIMER0 del microcontrollore ' usato per il rinfresco delle rappresentazioni sui display a 7 segmenti. I ' commenti di questa procedura indicano concisamente le operazioni svolte ma ' informazioni dettagliate sono disponibili nel data sheet del microcontrollore ' e nell'aiuto in linea del BASCOM. ' La costante di tempo caricata determina un tempo di 20 msec ed è ottenuta come ' segue: ' Frequenza conteggio TIMER0 = Frequenza clock / 1024 = 7372800 / 1024 = 7200 Hz ' Periodo conteggio TIMER0 = 1 / Frequenza conteggio TIMER0 = 1 / 7200 = 0,000138888 sec ' Numero conteggi interrupt TIMER0 = 0,02 / Periodo conteggio TIMER0 = 0,02/ 0,000138888 = 144 Sub Ini_distmrirq() Config Timer0 = Timer , Prescale = 1024 ' TIMER0 come 8 bit timer, precaler 1024 ed attivazione interna On Ovf0 Timer0_irq ' Definisce procedura risposta interrupt di overflow del TIMER0 Load Timer0 , 144 ' Carica costante di tempo per 20 usec Enable Timer0 ' Abilita interrupt da TIMER0 Enable Interrupts ' Abilitazione generale interrupts Start Timer0 ' Attiva TIMER0 End Sub ' Procedura di risposta all'interrupt periodico associato al TIMER0, ogni 20 msec. ' Effettua il rinfresco periodico delle rappresentazioni sui display a 7 segmenti, ' gestendo autonomamente l'eventuale lampeggio degli stessi. Verifica inoltre se ' la linea I2C BUS usata dal controllore display SAA 1064 e` gia` usata dal ' programma principale. Timer0_irq: Load Timer0 , 144 ' Ricarica costante di tempo per 20 msec Start Timer0 ' Riattiva TIMER0 If I2cbusused = 0 Then ' Se linea I2C BUS non usata dal programma principale ' Gestione eventuale lampeggio dei display ogni 0,5 sec If Dispblink > 0 Then ' Se lampeggio display Incr Blinkcnt ' Incrementa il contatore per lampeggio display If Blinkcnt >= 50 Then ' Se trascorsi 50 interrupt * 20 msec = 1 secondo Blinkcnt = 0 ' Fa ripartire il contatore per lampeggio display End If Else Blinkcnt = 0 ' Mantiene azzerato il contatore per lampeggio display End If ' Rinfresca display a 7 segmenti Disdatirq(1) = Dig1 ' Punta al primo display del controllore SAA 1064 If Blinkcnt >= 25 Then ' Se lampeggio attivo e trascorsi 25 interrupt * 20 msec = 0,5 secondi Select Case Dispblink ' Controlla display da lampeggiare Case 1: ' Lampeggio primi due display Disdatirq(2) = &H00 ' Disattiva tutti i segmenti dei primi due display Disdatirq(3) = &H00 Case 2: ' Lampeggio ultimi due display Disdatirq(4) = &H00 ' Disattiva tutti i segmenti degli ultimi due display Disdatirq(5) = &H00 Case 3: ' Lampeggio tutti i quattro display Disdatirq(2) = &H00 ' Disattiva tutti i segmenti dei quattro display Disdatirq(3) = &H00 Disdatirq(4) = &H00 Disdatirq(5) = &H00 End Select Else Disdatirq(2) = Disdat(2) ' Setta tutti i segmenti dei quattro display con attuale rappresentazione Disdatirq(3) = Disdat(3) Disdatirq(4) = Disdat(4) Disdatirq(5) = Disdat(5) End If I2csend Slawsaa1064 , Disdatirq(1) , 5 ' Invia sequenza con pattern preparati all'SAA 1064 End If Return ' Inizializza sensore I2C BUS per l'acquisizione temperatura a 9 bit di ' risoluzione e conversione continua ' Ingresso: Nulla ' Uscita: Nulla Sub Initemp_i2c() I2cbusused = 1 ' Linea I2C BUS usata 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 I2cbusused = 0 ' Linea I2C BUS non usata 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 I2cbusused = 1 ' Linea I2C BUS usata 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 I2cbusused = 0 ' Linea I2C BUS non usata ' 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 sui display a 7 segmenti, nel formato ' xxx.x o -xx.x ' Ingresso: Tdec_i2c = temperatura attuale ' Uscita: Nulla Sub Shw_temp_disp7seg_irq() ' 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) End Sub ' Emette un beep acustico con buzzer della scheda interfaccia ' Ingresso: Nulla ' Uscita: Nulla Sub Beep_interface() Buz_interface = 0 ' Attiva buzzer su scheda interfaccia Waitms Beepdt ' Durata beep acustico Buz_interface = 1 ' Disattiva buzzer su scheda interfaccia End Sub ' Imposta valore numerico nel range passato con incremento e decremento attuato ' dai tasti della scheda interfaccia ' Ingresso: Curval = Valore iniziale per impostazioni ' Minval = Valore minimo per impostazioni ' Maxval = Valore massimo per impostazioni ' Uscita: Curval = Valore finale impostato Sub Edit_value_temp(byval Minval As Single , Byval Maxval As Single) ' Aggiorna tempi di gestione tasti Waitms Repdt ' Ritardo per debouncing e autoripetizione pressione tasti If Keycnt > 0 Then ' Aggiorna contatore per gestione tasti Decr Keycnt End If ' Gestione eventuale incremento valore attuale If Key2_interface = 0 And Keycnt = 0 Then ' Se premuto tasto 2 (+) e trascorso tempo autorepeat Call Beep_interface() ' Emette un beep acustico per segnalare pressione tasto If Curval < Maxval Then ' Incrementa valore attuale in modo circolare da minimo a massimo Curval = Curval + 0.5 Else Curval = Minval End If Keycnt = Repcycle ' Imposta contatore per gestione tasti End If ' Gestione eventuale decremento valore attuale If Key3_interface = 0 And Keycnt = 0 Then ' Se premuto tasto 3 (-) e trascorso tempo autorepeat Call Beep_interface() ' Emette un beep acustico per segnalare pressione tasto If Curval > Minval Then ' Decrementa valore attuale in modo circolare da massimo a minimo Curval = Curval - 0.5 Else Curval = Maxval End If Keycnt = Repcycle ' Imposta contatore per gestione tasti End If End Sub ' Gestisce variazione temperatura effettuata con i tre tasti della scheda interfaccia, ' effettuando anche la rappresentazione dello stesso valore. ' Ingresso: Curval = Valore iniziale temperatura ' Uscita: Curval = Valore finale temperatura impostato Sub Change_temp() Dispblink = 3 ' Attiva lampeggio di tutti i quattro display che rappresentano temperatura Do ' Ciclo impostazione ore Call Edit_value_temp( -55.0 , 125.0) ' Imposta temperatura nel range -55..+125 Tdec_i2c = Curval ' Salva valore impostato su temperatura da rappresentare Call Shw_temp_disp7seg_irq() ' Rappresenta temperatura impostata formattata su display a 7 segmenti Loop Until Key1_interface = 0 ' Ripremendo tasto 1 termina impostazione ore Call Beep_interface() ' Emette un beep acustico per segnalare pressione tasto Do Loop Until Key1_interface = 1 ' Attende rilascio tasto 1 End Sub ' Legge un byte dalla EEPROM interna del uP. ' Ingresso: Addee = variabile con indirizzo locazione EEPROM da leggere ' Uscita: Datee = variabile con dato letto da EEPROM ' N.B. Il BASCOM AVR dispone di istruzioni dedicate alla gestione della EEPROM ' che svolgono completamente questo compito e la presente procedura è stata ' prevista per trasportabilita` e compatibilita` con altri Mini Moduli. Sub Rd_ee() Readeeprom Datee , Addee ' Legge byte da locazione EEPROM End Sub ' Scrive un byte nella EEPROM interna del uP. ' Ingresso: Addee = variabile con indirizzo locazione EEPROM da scrivere ' Datee = variabile con dato da scrivere su EEPROM ' Uscita: Nulla ' N.B. Il BASCOM AVR dispone di istruzioni dedicate alla gestione della EEPROM ' che svolgono completamente questo compito e la presente procedura è stata ' prevista per trasportabilita` e compatibilita` con altri Mini Moduli. Sub Wr_ee() Writeeeprom Datee , Addee ' Scrive byte su locazione EEPROM End Sub ' Legge configurazione da EE partendo da indirizzo passato e restituisce il CRC ' letto e calcolato e tutti i parametri di configurazione su apposite variabili ' Ingresso: Addee = variabile con indirizzo locazione inizio configurazione ' Iniaddcnf = Indirizzo inizio variabili configurazione ' Endaddcnf = Indirizzo fine variabili configurazione ' Uscita: Crcr = CRC letto da EE ' Crcc = CRC calcolato sui dati letti ' = valori parametri configurazione letti da EE Sub Rdcnfee() Crcc = 0 ' Azzera CRC calcolato Call Rd_ee ' Legge da EE CRC e lo salva Crcr = Datee Incr Addee Hlpw = Iniaddcnf ' Indirizzo inizio configurazioni in XRAM While Hlpw < Endaddcnf ' Ripete per tutti i bytes di configurazione Call Rd_ee ' Legge da EE byte con dato configurazione Crcc = Crcc + Datee ' Aggiorna CRC calcolato Out Hlpw , Datee ' Salva byte con dato configurazione su XRAM Incr Addee ' Aggiorna indirizzo EE Incr Hlpw ' Aggiorna indirizzo XRAM Wend End Sub ' Scrive su EE, partendo da indirizzo passato, tutti i parametri di configurazione ' salvati su apposite variabili ed aggiorna il CRC ' Ingresso: Addee = variabile con indirizzo locazione inizio configurazione ' = valori parametri configurazione da salvare in EE ' Iniaddcnf = Indirizzo inizio variabili configurazione ' Endaddcnf = Indirizzo fine variabili configurazione ' Uscita: Nulla Sub Wrcnfee() Crcc = 0 ' Azzera CRC calcolato Hlpw = Endaddcnf - Iniaddcnf ' Ottiene numero bytes di configurazione in EE Incr Hlpw ' Aggiunge 1 byte per CRC Addee = Addee + Hlpw ' Punta dopo ultimo byte di configurazione Hlpw = Endaddcnf ' Indirizzo fine configurazioni in XRAM While Hlpw > Iniaddcnf ' Ripete per tutti i bytes di configurazione Decr Hlpw ' Aggiorna indirizzo XRAM Decr Addee ' Aggiorna indirizzo EE Datee = Inp(hlpw) ' Preleva byte con dato configurazione da XRAM Call Wr_ee ' Scrive su EE byte con dato configurazione Crcc = Crcc + Datee ' Aggiorna CRC calcolato Wend Decr Addee Datee = Crcc ' Salva CRC calcolato e lo scrive su EE Call Wr_ee End Sub ' Setta parametri di configurazione ai loro valori di default ' Ingresso: Nulla ' Uscita: = valori parametri configurazione di default Sub Defcnf Setpoint = 50.0 ' Set point iniziale a 50 gradi centigradi Hyster = 2.0 ' Isteresi iniziale di 2 gradi centigradi Termact = 0 ' Termostato non attivo End Sub ' Carica configurazione da EE gestendo una doppia copia, ne verifica la validita` ' e restituisce variabili con parametri di configurazione caricati, se validi, o ' di default se non validi ' Ingresso: Nulla ' Uscita: = valori parametri configurazione Sub Getchkcnf Addee = &H0000 ' Legge prima copia configurazione da EE Call Rdcnfee If Crcc <> Crcr Then ' Se prima copia configurazione non valida Addee = &H0100 ' Legge seconda copia configurazione da EE Call Rdcnfee If Crcc <> Crcr Then ' Se seconda copia configurazione non valida Call Defcnf ' Setta configurazione di default Addee = &H0100 ' Scrive seconda copia configurazione su EE Call Wrcnfee End If Addee = &H0000 ' Scrive prima copia configurazione su EE Call Wrcnfee End If End Sub '******************* Fine procedure usate dal programma ************************