' ********************************************************************** ' * File: Corso_BASCOMAVR_015.BAS * ' * Versione: 1.1 * ' * Data: 03.08.09 * ' * 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 015 del corso BASCOM AVR. ' Consente di generare dei messaggi in codice Morse e di memorizzarli/ ' prelevarli nella/dalla EEPROM interna.. ' Il programma può eseguire le seguenti operazioni: richiede un messaggio e poi ' lo genera con codice Morse sul buzzer, definisce la velocità di generazione ' dei codici Morse, genera in Morse l'ultimo messaggio usato, salva fino a 5 ' messaggi in EEPROM, preleva un messaggio salvato da EEPROM ed infine genera i ' 3 codici particolari del Morse di attenzione, errore e ripetizione. ' L'interazione con l'utente avviene tramite una console seriale dotata di ' tastiera e 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). ' ' Aggiunte: Readeeprom, Writeeeprom, Chr, Space. ' ' 03/08/09: Corso_BASCOMAVR_015.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 ; J8 in 2-3 !!! ' Risorsa pin Z1 pin Segnale Segnale ' hw GMM TST3 GMM 5115 GMM AM08 uP ' Buzzer BZ1 15 9 PB4 MISO PB4 ' ' Segnale pin COMx pin CN5 pin Z1 pin Segnale Segnale ' PC DB9 GMM TST3 GMM TST3 GMM AM08 GMM AM08 uP ' 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 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 Max_msg_ee = 5 ' Numero massimo di messaggi in EEPROM Const Cod_msg_ee = &H5A ' Codice che indica messaggio salvato in EEPROM '************************ Dichiarazioni variabili ****************************** Dim Choice As Byte ' Operazione scelta Dim Mchr As Byte ' Carattere da generare in Morse Dim Ichr As Byte ' Indice per ricerca carattere da generare Dim Mcod As Byte ' Codice Morse del carattere da generare Dim Ncmp As Byte ' Numero componenti del codice Morse Dim Icmp As Byte ' Indice componenti del codice Morse Dim Mbit As Byte ' Bit attuale nel codice Morse Dim Msgstr As String * 40 ' Stringa con messaggio da generare Dim Mdt As Word ' Durata unità temporale in millisecondi Dim Lstr As Byte ' Lunghezza stringa con messaggio Dim Pstr As Byte ' Puntatore a stringa con messaggio Dim Chrstr As String * 1 ' Carattere del messaggio da generare Dim Datee As Byte ' Dato da scrivere o letto da EEPROM Dim Addee As Word ' Indirizzo locazione EEPROM da scrivere o leggere Dim Hlpb As Byte ' Variabile di aiuto ad uso generico Dim Nmsg As Byte ' Numero messaggio da leggere/scrivere da/su EEPROM Dim Msgsaved As Boolean ' Flag messaggio salvato in EEPROM '************************ Dichiarazioni procedure ****************************** Declare Sub Del_1unit() ' Genera ritardo di una unità temporale Morse Declare Sub Morse_cod() ' Genera un codice Morse Declare Sub Morse_chr() ' Genera una lettera con codice Morse Declare Sub Morse_str() ' Genera un messaggio con codice Morse 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 Read_msg_ee() ' Legge un messaggio dalla EEPROM Declare Sub Write_msg_ee() ' Scrive un messaggio nella EEPROM Declare Sub Show_msg_ee() ' Mostra i messaggi salvati in EEPROM '************************** Programma principale ******************************* Main: Pinrx = 0 ' Inizializza segnali per comunicazione seriale Pintx = 0 ' come ingressi digitali Pinbz1 = 1 ' Inizializza segnale collegato a BZ1 come uscita digitale alta=disattivo Ddrb.4 = 1 Mdt = 200 ' Imposta durata unità temporale iniziale a 200 msec Print ' Separa da precedenti indicazioni, andando su nuova riga Print " Generatore Morse con EEPROM" Do ' Inizio ciclo infinito Print ' Presenta menù con le possibili operazioni Print "M -> Genera messaggio" Print "V -> Imposta velocita` generazione" Print "U -> Genera ultimo messaggio usato" Print "S -> Salva messaggio in EEPROM" Print "L -> Legge messaggio da EEPROM" Print "A -> Genera codice attenzione" Print "E -> Genera codice errore" Print "R -> Genera codice ripetizione" Print "Effettuare la scelta premendo il tasto associato: "; Choice = Waitkey() ' Attende scelta operazione da eseguire Printbin Choice ' Rappresenta scelta effettuata Print If Choice >= "a" Then ' Se scelta minuscola Choice = Choice And &HDF ' La converte in in maiuscolo End If Select Case Choice ' Controlla scelta convertita Case "M": ' Scelta operazione di generazione messaggio Print "Inserire messaggio da generare in Morse (max. 40 caratteri): " Input Msgstr ' Preleva e salva messaggio da generare Call Morse_str() ' Genera messaggio inserito in Morse Case "V": ' Scelta operazione di impostazione velocità Print "Attuale durata unita` temporale Morse: " ; Mdt ' Rappresenta attuale valore e richiede quello nuovo Input "Inserire nuova durata (1..1000 msec): " , Mdt Case "U": ' Scelta operazione di ripetere ultimo messaggio generato Call Morse_str() ' Genera ultimo messaggio inserito in Morse Case "S": ' Scelta operazione di salvare messaggio su EEPROM Call Show_msg_ee() ' Mostra i messaggi salvati in EEPROM Input "Numero messaggio da salvare: " , Nmsg ' Richiede e preleva numero messaggio da salvare Print "Inserire messaggio da salvare in EEPROM (max. 40 caratteri): " Input Msgstr ' Preleva messaggio da salvare in EEPROM Call Write_msg_ee() ' Salva messaggio in EEPROM Case "L": ' Scelta operazione di leggere messaggio da EEPROM Call Show_msg_ee() ' Mostra i messaggi salvati in EEPROM Input "Numero messaggio da leggere: " , Nmsg ' Richiede e preleva numero messaggio da leggere Call Read_msg_ee() ' Legge messaggio da EEPROM Case "A": ' Scelta operazione di generazione codice attenzione Mcod = &H12 ' Setta codice binario di attenzione Ncmp = 5 ' Setta componenti del codice di attenzione Call Morse_cod() ' Genera codice settato in Morse Print "Codice attenzione generato" Case "E": ' Scelta operazione di generazione codice errore Mcod = &H00 ' Setta codice binario di errore Ncmp = 8 ' Setta componenti del codice di errore Call Morse_cod() ' Genera codice settato in Morse Print "Codice errore generato" Case "R": ' Scelta operazione di generazione codice ripetizione Mcod = &H00 ' Setta 1a parte codice binario di ripetizione Ncmp = 2 ' Setta componenti 1a parte del codice di errore Call Morse_cod() ' Genera codice settato in Morse Call Del_1unit() ' Genera ritardo di 3 unità temporali Call Del_1unit() Call Del_1unit() Mcod = &H00 ' Setta 2a parte codice binario di ripetizione Ncmp = 2 ' Setta componenti 2a parte del codice di errore Call Morse_cod() ' Genera codice settato in Morse Print "Codice ripetizione generato" Case Else: ' Scelta non valida Printbin &H07 ' Emette un BEL di avviso sulla console End Select Loop ' Fine ciclo infinito End '************************ Fine programma principale **************************** '****************** Inizio procedure usate dal programma *********************** ' 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 ' Genera un ritardo di una unità temporale Morse. Tale durata genera i codici ' Morse con la velocità settata da utente ' Ingresso: Nulla ' Uscita: Nulla Sub Del_1unit() Waitms Mdt ' Effettua ritardo dei millisecondi salvati nella variabile Mdt End Sub ' Genera carattere in Morse usando il codice ed il numero componenti passati. ' Da ricordare che nel codice un bit a 0 equivale ad un punto (buzzer attivo ' per 1 unità temporale) mentre un bit a 1 equivale ad una linea (buzzer attivo ' per 3 unità temporali). Ogni componente è naturalmente separato dal successivo ' da uno spazio (buzzer disattivo per 1 unità temporale). ' La velocità di generazione dei codici è definita da un apposita variabile ' settabile da utente. ' Ingresso: Mcod = codice Morse da generare ' Ncmp = numero componenti da generare ' Uscita: Nulla Sub Morse_cod() For Icmp = 1 To Ncmp ' Ciclo ripetuto per il numero componenti Mbit = Mcod And &H01 ' Ottiene bit meno significativo del codice Pinbz1 = 0 ' Attiva buzzer BZ1 If Mbit = 0 Then ' Se componente attuale è un punto Call Del_1unit() ' Genera ritardo di 1 unità temporale Else ' Componente attuale è una linea Call Del_1unit() ' Genera ritardo di 3 unità temporali Call Del_1unit() Call Del_1unit() End If Pinbz1 = 1 ' Disattiva buzzer BZ1 Call Del_1unit() ' Genera spazio di 1 unità temporale Shift Mcod , Right , 1 ' Shifta codice di un bit a destra Next Icmp End Sub ' Genera una lettera con codice Morse usando la tabella definita nel programma. ' La velocità di generazione dei codici è definita da un apposita variabile ' settabile da utente. ' Ingresso: Mchr = variabile con carattere da generare ' Uscita: Nulla Sub Morse_chr() If Mchr >= " " And Mchr <= "`" Then ' Se carattere incluso nella tabella codici Morse ' Preleva codice Morse e numero componenti relativi al carattere da generare ' dalla tabella definita alla fine del programma. Mchr = Mchr - &H20 ' Codice ASCII del carattere da generare parte da 0 Restore Morse ' Punta ad inizio tabella Morse For Ichr = 0 To Mchr ' Ciclo che legge la tabella dall'inizio al carattere da generare Read Mcod ' Preleva codice Morse del carattere Ichr dalla tabella Read Ncmp ' Preleva componenti del carattere Ichr dalla tabella Next Ichr Call Morse_cod() ' Genera codice del carattere Morse ' Genera spazio tra un carattere ed il successivo (buzzer disattivo per 3 ' unità temporali) Call Del_1unit() ' Genera ritardo di 3 unità temporali Call Del_1unit() Call Del_1unit() Else Ncmp = 0 ' Settaggio per carattere non generato End If End Sub ' Genera un messaggio con codice Morse usando le procedure definite prima e ' provvedendo a rappresentare i caratteri validi generati. ' La velocità di generazione dei codici è definita da un apposita variabile ' settabile da utente. ' Ingresso: Msgstr = variabile stringa con messaggio da generare ' Uscita: Nulla Sub Morse_str() Print "Caratteri generati: "; Msgstr = Ucase(msgstr) ' Converte messaggio da generare in maiuscolo Lstr = Len(msgstr ) ' Ottiene lunghezza stringa con messaggio For Pstr = 1 To Lstr ' Ciclo ripetuto per i caratteri del messaggio Chrstr = Mid(msgstr , Pstr , 1) ' Preleva carattere attuale del messaggio Mchr = Asc(chrstr) ' Ottiene codice ASCII del carattere attuale If Mchr <> " " Then ' Se carattere non è uno spazio Call Morse_chr() ' Genera carattere attuale in Morse Else ' Genera spazio tra una parola e la successiva (buzzer disattivo per 7 ' unità temporali) Call Del_1unit() ' Genera ritardo di 7 unità temporali Call Del_1unit() Call Del_1unit() Call Del_1unit() Call Del_1unit() Call Del_1unit() Call Del_1unit() Ncmp = 7 ' Setta numero componenti per rappresentare spazio generato End If If Ncmp > 0 Then ' Se carattere attuale valido ed è stato generato Print Chrstr; ' Rappresenta carattere generato su console End If Next Pstr Print ' Separa indicazioni, andando su nuova riga End Sub ' Ogni messaggio occupa 42 bytes di EEPROM, di cui il primo dedicato ad un ' indicatore di messaggio salvato, il secondo dedicato alla lunghezza del ' messaggio ed i restanti 40 dedicati ai 40 caratteri massimi del messaggio. ' ' Legge un messaggio dalla EEPROM, verificando prima se è stato precedentemente ' salvato ' Ingresso: Nmsg = variabile con numero messaggio da leggere ' Uscita: Msgstr = variabile stringa con messaggio letto ' Msgsaved = flag per messaggio salvato che è stato quindi letto Sub Read_msg_ee() Addee = Nmsg * 42 ' Calcola indirizzo inizio messaggio in EEPROM Call Rd_ee() ' Preleva indicatore messaggio salvato If Datee = Cod_msg_ee Then ' Se messaggio già salvato in EEPROM Incr Addee ' Incrementa indirizzo lettura EEPROM Call Rd_ee() ' Preleva lunghezza messaggio da EEPROM Lstr = Datee Msgstr = Space(lstr) ' Prepara stringa lunga quanto il messaggio da leggere For Pstr = 1 To Lstr ' Ciclo ripetuto per i caratteri del messaggio Incr Addee ' Incrementa indirizzo lettura EEPROM Call Rd_ee() ' Preleva codice ASCII carattere attuale da EEPROM Chrstr = Chr(datee) ' Ottiene carattere da codice ASCII Mid(msgstr , Pstr , 1) = Chrstr ' Salva carattere attuale nel messaggio Next Pstr Msgsaved = 1 ' Messaggio salvato in EEPROM e letto Else Msgsaved = 0 ' Messaggio non salvato in EEPROM e non letto End If End Sub ' Scrive un messaggio nella EEPROM, aggiungendo apposita indicazione di ' messaggio salvato ' Ingresso: Nmsg = variabile con numero messaggio da scrivere ' Msgstr = variabile stringa con messaggio da scrivere ' Uscita: Nulla Sub Write_msg_ee() Addee = Nmsg * 42 ' Calcola indirizzo inizio messaggio in EEPROM Datee = Cod_msg_ee ' Salva indicazione messaggio salvato in EEPROM Call Wr_ee() Lstr = Len(msgstr) ' Ottiene lunghezza stringa con messaggio Datee = Lstr ' Salva lunghezza messaggio in EEPROM Incr Addee ' Incrementa indirizzo scrittura EEPROM Call Wr_ee() For Pstr = 1 To Lstr ' Ciclo ripetuto per i caratteri del messaggio Chrstr = Mid(msgstr , Pstr , 1) ' Preleva carattere attuale del messaggio Datee = Asc(chrstr) ' Ottiene codice ASCII del carattere attuale Incr Addee ' Incrementa indirizzo scrittura EEPROM Call Wr_ee() ' Salva codice ASCII carattere attuale in EEPROM Next Pstr End Sub ' Mostra sulla console seriale la lista dei messaggi attualmente scritti= ' salvati in EEPROM ' Ingresso: Nulla ' Uscita: Nulla Sub Show_msg_ee() Print "Messaggi attualmente salvati in EEPROM:" ' Visualizza intestazione lista For Nmsg = 1 To Max_msg_ee Print Nmsg ; " = "; ' Visualizza numero messaggio della lista Call Read_msg_ee() ' Legge messaggio attuale della lista da EEPROM If Msgsaved = 1 Then ' Se messaggio salvato in EEPROM e letto Print Msgstr ' Visualizza messaggio letto nella lista Else ' Messaggio non salvato e non letto Print ' Visualizza messaggio vuoto nella lista End If Next Nmsg End Sub '******************* Fine procedure usate dal programma ************************ '******************** Inizio dati usati dal programma ************************** ' Ogni carattere è codificato con due numeri di cui il primo indica il codice ' a bit dei componenti ed il secondo il numero di componenti. Con componenti ' s'intendono sia i punti che le linee con cui ogni lettera è codificata in ' Morse e: ' - il punto equivale ad un bit a 0; ' - la linea equivale ad un bit a 1; ' - nel codice il bit meno significativo è il primo ad essere generato; ' - i caratteri sono ordinati secondo lo standard ASCII a partire da " "=&H20; ' - i caratteri senza codice Morse hanno codice e numero componenti azzerati. ' ' Ad esempio il carattere 1 è codificato da: punto linea linea linea linea ' a bit diventa: 0 1 1 1 1 ' che per l'ordine invertito di generazione diventa: 1 1 1 1 0 ' ovvero in esadecimale HEX: 1E ' con un numero di componenti: 5 ' che in BASCOM AVR diventa: Data &H1E , 5 ' ' Ad esempio il carattere D è codificato da: linea punto punto ' a bit diventa: 1 0 0 ' che per l'ordine invertito di generazione diventa: 0 0 1 ' ovvero in esadecimale HEX: 01 ' con un numero di componenti: 3 ' che in BASCOM AVR diventa: Data &H01 , 3 ' Morse: Data &H00 , 0 ' Carattere =&H20 Data &H00 , 0 ' Carattere ! Data &H12 , 6 ' Carattere '' Data &H00 , 0 ' Carattere # Data &H48 , 7 ' Carattere $ Data &H00 , 0 ' Carattere % Data &H00 , 0 ' Carattere & Data &H1E , 6 ' Carattere ' Data &H0D , 5 ' Carattere ( Data &H2D , 6 ' Carattere ) Data &H00 , 0 ' Carattere * Data &H0A , 5 ' Carattere + Data &H33 , 6 ' Carattere , Data &H21 , 6 ' Carattere - Data &H2A , 6 ' Carattere . Data &H09 , 5 ' Carattere / Data &H1F , 5 ' Carattere 0=&H30 Data &H1E , 5 ' Carattere 1 Data &H1C , 5 ' Carattere 2 Data &H18 , 5 ' Carattere 3 Data &H10 , 5 ' Carattere 4 Data &H00 , 5 ' Carattere 5 Data &H01 , 5 ' Carattere 6 Data &H03 , 5 ' Carattere 7 Data &H07 , 5 ' Carattere 8 Data &H0F , 5 ' Carattere 9 Data &H07 , 6 ' Carattere : Data &H15 , 6 ' Carattere ; Data &H00 , 0 ' Carattere < Data &H11 , 5 ' Carattere = Data &H00 , 0 ' Carattere > Data &H0C , 6 ' Carattere ? Data &H16 , 6 ' Carattere @=&H40 Data &H02 , 2 ' Carattere A Data &H01 , 4 ' Carattere B Data &H05 , 4 ' Carattere C Data &H01 , 3 ' CArattere D Data &H00 , 1 ' CArattere E Data &H04 , 4 ' CArattere F Data &H03 , 3 ' CArattere G Data &H00 , 4 ' CArattere H Data &H00 , 2 ' CArattere I Data &H0E , 4 ' CArattere J Data &H05 , 3 ' CArattere K Data &H02 , 4 ' CArattere L Data &H03 , 2 ' CArattere M Data &H01 , 2 ' CArattere N Data &H07 , 3 ' CArattere O Data &H06 , 4 ' CArattere P=&H50 Data &H0B , 4 ' CArattere Q Data &H02 , 3 ' CArattere R Data &H00 , 3 ' CArattere S Data &H01 , 1 ' CArattere T Data &H04 , 3 ' CArattere U Data &H08 , 4 ' CArattere V Data &H06 , 3 ' CArattere W Data &H09 , 4 ' CArattere X Data &H0D , 4 ' CArattere Y Data &H03 , 4 ' CArattere Z Data &H00 , 0 ' Carattere [ Data &H00 , 0 ' Carattere \ Data &H00 , 0 ' Carattere ] Data &H00 , 0 ' Carattere ^ Data &H2C , 6 ' Carattere _ Data &H00 , 0 ' Carattere `=&H60 '********************* Fine dati usati dal programma ***************************