' ********************************************************************** ' * File: Corso_BASCOMAVR_078.BAS * ' * Versione: 1.1 * ' * Data: 20.09.10 * ' * 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 078 del corso BASCOM AVR. ' Gestione orologio sveglia tramite Timer1 del Mini Modulo. ' Il programma aggiorna un orario composto da scnondi, minuti ed ore, usando ' un interrupt periodico generato dal TIMER1 del microcontrollore, e lo ' rappresenta continuamente sulla console. ' Sempre da console si può reimpostare l'orario attuale ed attivare una sveglia ' ad un tempo definibile; quando l'orologio raggiunge il tempo di sveglia, ' attiva un'uscita bufferata a relè (Relay1 usata negli esempi precedenti) ed ' emette un suono intermittente sul buzzer della GMM TST3. A questo punto, ' sempre da console, è possibile disattivare la sveglia che non scatterà più ' fino ad una nuova attivazione. ' L'orologio software gestito dal programma, è inevitabilmente caratterizzato ' da una scarsa precisione, dovuta al clock del microcontrollore che non è un ' multiplo intero del secondo. Tali errori si risolvono ad esempio usando un ' componente dedicato alla funzione di orologio in tempo reale (RTC), come ' illustrato nei programmi seguenti. ' Il programma si presenta ed usa una console seriale dotata di monitor e ' tastiera, 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!! ' Nel programma i nomi che identificano i segnali usati sono riferiti allo ' schema elettrico ed al manuale tecnico della GMM TST3!! ' ' Aggiunte: Nessuna. ' ' 20/09/10: Corso_BASCOMAVR_078.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 | 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 ' 4) 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 2-3 ; J3 in 1-2 ; J5 in 2-3 ; J7 in 2-3 ; J8 in 2-3 ' J9 in 2-3 !!! ' ' Segnale Risorsa pin Z2 pin Segnale Segnale uP ' esterno GMM TST3 GMM TST3 GMM AM08 GMM AM08 usato ' - Buzzer BZ1 15 9 PB4 MISO PB4 ' Relay1 CN4.6 29 23 PB0 ICP PB0 ' GND CN4.17 20 14 GND - ' +5 Vdc CN4.18 34 28 +5 Vdc - ' ' 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. Pinbz1 Alias Portb.4 ' Bit con segnale d'uscita collegato a buzzer BZ1 Pinrl1 Alias Portb.0 ' Bit con segnale d'uscita collegato a relè 1 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 '************************ Dichiarazioni variabili ****************************** Dim Alron As Bit ' Flag per sveglia attiva Dim Isalr As Bit ' Flag per sveglia scattata Dim Choice As Byte ' Scelta utente Dim Cntirq As Byte ' Contatore interrupt periodici Dim Scn As Byte ' Secondi orologio Dim Mnu As Byte ' Minuti orologio Dim Hou As Byte ' Ore orologio Dim Alrsec As Byte ' Secondi sveglia Dim Alrmnu As Byte ' Minuti sveglia Dim Alrhou As Byte ' Ore sveglia Dim Oldsec As Byte ' Secondi precedenti '************************ Dichiarazioni procedure ****************************** Declare Sub Ini_tmrirq() ' Inizializza TIMER usato per interrupt periodico Declare Sub Shw_time ' Trasmette ora formatta sulla console Declare Sub Chk_alarm() ' Controlla e gestisce sveglia '************************** Programma principale ******************************* Main: Pinrx = 0 ' Inizializza segnali per comunicazione seriale Pintx = 0 ' come ingressi digitali Pinbz1 = 1 ' Inizializza segnale collegato a buzzer BZ1 come uscita digitale Config Pinbz1 = Output ' alta, in modo da mantenerlo disattivo Pinrl1 = 1 ' Inizializza segnale collegato a relè 1 come uscita digitale Config Pinrl1 = Output ' alta, in modo da mantenerlo disattivo Print ' Separa da precedenti indicazioni, andando su nuova riga Print Print " Orologio software con TIMER" Print Print "Premere I per impostare orologio, A per attivare sveglia, D per disattivarla." Print "Al raggiungimento del tempo di sveglia impostato, il buzzer della GMM TST3" Print "diventa intermittente e si attiva l'uscita a rele` collegata a CN4.6." Print Scn = 0 ' Inizializza orario attuale ad inizio giornata (00:00:00) Mnu = 0 Hou = 0 Alron = 0 ' Sveglia disattiva Isalr = 0 ' Sveglia non scattata Call Ini_tmrirq() ' Inizializza TIMER usato per interrupt periodico Do ' Inizio ciclo infinito Call Shw_time() ' Rappresenta orario attuale Printbin Cret ' Mantiene rappresentazione su stessa riga Waitms 100 ' Ritardo tra acquisizioni e controlli Choice = Inkey() ' Verifica se tasto premuto su console If Choice > 0 Then ' Se tasto premuto su console If Choice >= "a" Then ' Se tasto minuscolo Choice = Choice And &HDF ' Lo converte in in maiuscolo End If Select Case Choice ' Controlla scelta convertita Case "I": ' Scelta impostazione orologio Print Input "Ore attuali: " , Hou ' Richiede orario attuale Input "Minuti attuali: " , Mnu Input "Secondi attuali: " , Scn Print Case "A": ' Scelta attivazione sveglia Print Input "Ore sveglia: " , Alrhou ' Richiede orario per sveglia Input "Minuti sveglia: " , Alrmnu Input "Secondi sveglia: " , Alrsec Alron = 1 ' Sveglia attiva Isalr = 0 ' Sveglia non scattata Oldsec = 60 ' Assicura intermittenza buzzer allo scatto della sveglia Print "Sveglia attivata" Print Case "D": ' Scelta disattivazione sveglia Alron = 0 ' Sveglia disattiva Print Print "Sveglia disattivata" Print Case Else: ' Scelta non valida Printbin &H07 ' Emette un BEL di avviso sulla console End Select End If Loop ' Fine ciclo infinito Stop Timer1 ' Ferma TIMER1 End '************************ Fine programma principale **************************** '****************** Inizio procedure usate dal programma *********************** ' Inizializza generazione interrupt periodico tramite TIMER1 del microcontrollore ' usato come base temporale per l'orologio software. 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 50 msec ed è ottenuta come ' segue: ' Frequenza conteggio TIMER1 = Frequenza clock / 1024 = 7372800 / 1024 = 7200 Hz ' Periodo conteggio TIMER0 = 1 / Frequenza conteggio TIMER0 = 1 / 7200 = 0,000138888 sec ' Numero conteggi interrupt TIMER1 = 0,05 / Periodo conteggio TIMER1 = 0,05/ 0,000138888 = 360 ' Ingresso: Nulla ' Uscita: Cntirq = Contatore interrupt periodici azzerato Sub Ini_tmrirq() Cntirq = 0 ' Azzera contatore interrupt periodici Config Timer1 = Timer , Prescale = 1024 ' TIMER1 come 16 bit timer, precalsr 1024 ed attivazione interna On Ovf1 Timer1_irq ' Definisce procedura risposta interrupt di overflow del TIMER1 Load Timer1 , 360 ' Carica costante di tempo per 50 msec Enable Timer1 ' Abilita interrupt da TIMER1 Enable Interrupts ' Abilitazione generale interrupts Start Timer1 ' Attiva TIMER1 End Sub ' Procedura di risposta all'interrupt periodico associato al TIMER1. ' Gestisce l'aggiornamento dell'orologio software ogni 50 msec. Per ottenere ' tempi lunghi, il Timer1 è programmato in modo 1 senza autoreload: per questo ' la procedura ricarica la costante di tempo e riattiva il TIMER1. ' Ingresso: Cntirq = Contatore interrupt periodici ' Scn,Mnu,Hou = orario attuale ' Uscita: Cntirq = Contatore interrupt periodici aggiornato ' Scn,Mnu,Hou = orario attuale aggiornato Timer1_irq: Load Timer1 , 360 ' Ricarica costante di tempo per 50 msec Start Timer1 ' Riattiva TIMER1 ' Aggiorna orologio software Incr Cntirq ' Incrementa contatore interrupt periodici If Cntirq = 20 Then ' Se trascorso 1 secondo (20 interrupt da 50 msec) Cntirq = 0 ' Azzera contatore interrupt periodici Incr Scn ' Incrementa secondi If Scn = 60 Then ' Se trascorso un minuto (60 secondi) Scn = 0 ' Azzera secondi Incr Mnu ' Incrementa minuti If Mnu = 60 Then ' Se trascorso un'ora (60 minuti) Mnu = 0 ' Azzera minuti Incr Hou ' Incrementa ore If Hou = 24 Then ' Se trascorso un giorno (24 ore) Hou = 0 ' Azzera ore End If End If End If End If Call Chk_alarm() ' Controlla e gestisce sveglia Return ' Rappresenta ora formatta sulla console nel formato oo:mm:ss ' Ingresso: Scn,Mnu,Hou = orario attuale ' Uscita: Nulla Sub Shw_time If Hou < 10 Then ' Rappresenta ore a due cifre Print "0"; End If Print Hou ; ":" ; ' Con separatore If Mnu < 10 Then ' Rappresenta minuti a due cifre Print "0"; End If Print Mnu ; ":" ; ' Con separatore If Scn < 10 Then ' Rappresenta secondi a due cifre Print "0"; End If Print Scn ; End Sub ' Controlla e gestisce sveglia ' Ingresso: Scn,Mnu,Hou = orario attuale ' Alrsec,Alrmnu,Alrhou = orario per sveglia ' Alron,Isalr = Flag per gestione sveglia ' Uscita: Isalr = Flag sveglia scattata aggiornato Sub Chk_alarm() If Alron = 1 Then ' Se sveglia attiva If Scn = Alrsec And Mnu = Alrmnu And Hou = Alrhou Then ' Se orario attuale ha raggiunto quello per sveglia Isalr = 1 ' Sveglia scattata End If If Isalr = 1 Then ' Se sveglia attiva e scattata Pinrl1 = 0 ' Attiva rele` 1 If Scn <> Oldsec Then ' Se trascorso un secondo Pinbz1 = Not Pinbz1 ' Cambia stato al buzzer per intermittenza Oldsec = Scn End If Else ' Sveglia attiva ma non scattata Pinrl1 = 1 ' Disattiva rele` 1 Pinbz1 = 1 ' Disattiva buzzer End If Else ' Sveglia disattiva Pinrl1 = 1 ' Disattiva rele` 1 Pinbz1 = 1 ' Disattiva buzzer End If End Sub '******************* Fine procedure usate dal programma ************************