ENCICLOPEDIA DELLA RADIOELETTRONICA ED ELETTRICA Programmazione modulare dei sistemi di controllo su MCS48. Enciclopedia dell'elettronica radio e dell'ingegneria elettrica Enciclopedia della radioelettronica e dell'elettrotecnica / microcontrollori È noto che lo stesso microcontrollore può controllare sia apparecchiature tecnologiche complesse che un macinacaffè domestico o un orologio elettronico. L'adattamento a un oggetto specifico viene effettuato modificando il programma del microcontrollore, l'hardware non ne risente quasi. L'articolo proposto è dedicato alle tecniche di programmazione per i microcontrollori della serie MCS48, ampiamente utilizzate nei sistemi di controllo per vari scopi. Le sue disposizioni principali sono valide anche per i dispositivi più moderni. Lo sviluppo e l'ammodernamento dei programmi di controllo è notevolmente facilitato se sono costruiti secondo un principio modulare. In questo caso, dopo aver acquisito una certa esperienza e, soprattutto, la nostra libreria di moduli debuggati, programmare un nuovo sistema di controllo (CS) si riduce a sostituire alcuni moduli di un programma già esistente e debuggato e, possibilmente, integrarlo con frammenti che tenere conto delle specificità di un particolare sistema. Questo principio è incorporato nella struttura di molti linguaggi di alto livello (PASCAL, C++) e il programmatore è letteralmente costretto a seguirlo. Sfortunatamente, gli ASSEMBLATORI (anche per MSS48), pur dando al programmatore maggiore libertà di scelta dei mezzi e dei metodi per risolvere i problemi, di regola, non monitorano affatto l'osservanza della disciplina di programmazione. Ciò spesso porta alla creazione di programmi così confusi che persino i loro autori non riescono a capire cosa è stato fatto dopo un po 'di tempo, per non parlare dell'uso di frammenti sottoposti a debug in altri programmi. L'adesione consapevole a concetti modulari comuni facilita e velocizza enormemente la programmazione dei microcontrollori. Un esempio di un tipico programma modulare per CS è riportato nella tabella. La sua sintassi corrisponde al tabulare ASSEMBLY TASM nella versione per il microprocessore 8048. Come puoi vedere, all'inizio del testo del programma, le direttive EQU danno nomi alle costanti e assegnano valori. L'utilizzo di costanti denominate è sempre preferibile alla specifica di valori numerici direttamente nelle istruzioni eseguibili del processore. Ad esempio, il ritardo di tempo implementato da una delle subroutine discusse di seguito è definito da tre numeri. Sono dati dalle costanti N1, N2 e N3. Se è necessario modificare la velocità dell'otturatore, è sufficiente specificare nuovi valori negli operatori EQU. Altrimenti, si dovrebbe cercare in tutto il programma istruzioni con operandi uguali a questi numeri, decidere se ciascuno di essi si riferisce a un ritardo temporale e indicare nuovi valori nei casi necessari. Ovviamente, tale lavoro richiede molto tempo e spesso non è privo di errori. È particolarmente complicato dal fatto che alcuni comandi potrebbero non utilizzare l'intero numero, ma, ad esempio, il suo byte alto o basso. ASSEMBER già nella fase di traduzione del programma è in grado di calcolare alcune costanti in base ai valori di altre. Questa possibilità è illustrata dal calcolo dei byte alti (N3N) e bassi (N3L) del numero NXNUMX. Successivamente, il programma alloca la memoria per le variabili. Lo fanno con le stesse direttive EQU, ma a differenza delle descrizioni delle costanti, specificano non i valori numerici delle variabili, ma gli indirizzi delle celle di memoria che occupano. Se l'ASSEMBLER lo consente, non va trascurata la possibilità di utilizzare le macro. Ciascuno di essi è, per così dire, una nuova istruzione che esegue un'operazione non prevista direttamente dal sistema di istruzioni del processore. Descrivendo un'istruzione macro, il programmatore le assegna un nome (che, ovviamente, non coincide con il nome di nessuna delle istruzioni "reali") e specifica le azioni richieste sotto forma di Sequenza di istruzioni macchina. Ogni volta che incontra un'istruzione macro in un programma, l'ASSEMBLER la sostituirà con la sequenza specificata. In questo esempio vengono utilizzate due macro. Uno di essi trasferisce il contenuto dell'accumulatore nella cella di memoria dati specificata dal parametro macro e l'altro indietro. Dopo l'accensione (o un segnale di reset), il microcontrollore avvia l'esecuzione del programma dall'indirizzo zero. Questo indirizzo viene solitamente utilizzato per scrivere un comando di salto incondizionato al punto di inizio effettivo del programma (in questo caso, l'etichetta START). Ciò è necessario perché gli interrupt hardware trasferiscono sempre il controllo agli indirizzi fissi 3 e 7 (per altri tipi di microcontrollori, gli indirizzi possono essere diversi, ma si trovano comunque all'inizio della memoria del programma). I comandi di transizione incondizionata alle routine di servizio delle corrispondenti interruzioni poste a questi indirizzi devono essere "bypassati" dal programma principale. Il passaggio successivo è l'impostazione delle modalità operative del controller (ad esempio, la selezione di banchi e registri di memoria), l'inizializzazione di variabili e dispositivi esterni. Un tipico errore dei programmatori alle prime armi è quello di presumere che subito dopo l'avvio del programma le variabili abbiano già dei valori definiti. Questo malinteso è rafforzato dal fatto che alcuni linguaggi di alto livello (come il BASIC) impostano automaticamente tutte le variabili su un valore iniziale pari a zero. Nei programmi in linguaggio assembly (e molti altri linguaggi), il programmatore stesso deve fare attenzione che prima della prima lettura del valore di una variabile, qualcosa sia già stato scritto nella cella di memoria ad essa assegnata. Un buon stile di programmazione richiede che i valori iniziali vengano assegnati alle variabili all'inizio del programma. In questo caso, ciò viene eseguito dalla subroutine 1INIT. La sezione di inizializzazione del dispositivo esterno di solito si presenta come una chiamata alternativa alle subroutine, ciascuna delle quali ne ripristina una (convertitore analogico-digitale, indicatore LED, tastierino, ecc.) e può essere facilmente sostituita durante la finalizzazione e il miglioramento del sistema. Spesso, queste stesse routine controllano l'integrità dei dispositivi. Successivamente, la maggior parte dei programmi di controllo entra in un ciclo principale che si ripete all'infinito, la cui esecuzione è sospesa solo per gestire gli interrupt. Il ciclo è costituito da subroutine per interrogare la tastiera e altri sensori, controllare i flag impostati dalle subroutine di gestione degli interrupt (ad esempio, il flag per la scadenza di un intervallo di tempo specificato o la fine del convertitore analogico-digitale), elaborare le informazioni ricevute in conformità con l'algoritmo di controllo specificato, emettendo azioni di controllo agli attuatori , visualizzando informazioni sullo stato del processo tecnologico su un display a cristalli liquidi o altri indicatori. L'uscita dal loop principale è solitamente prevista solo in situazioni di emergenza, ad esempio se per eliminare le conseguenze di un guasto è necessario ripetere l'inizializzazione di tutte le variabili e dispositivi esterni, nonché durante l'elaborazione degli interrupt. Pertanto, un programma costruito su base modulare è un insieme di subroutine. Se, ad esempio, si utilizza una tastiera diversa nel nuovo sistema di controllo, sarà sufficiente sostituire la subroutine BUTT. Affinché tale sostituzione sia semplice e indolore, è necessario sviluppare e osservare sempre alcune regole. Le subroutine, se possibile, dovrebbero salvare il contenuto di tutti i registri del controller, ricevere i dati iniziali ed emettere i risultati negli stessi registri e celle di memoria, utilizzare la stessa codifica dei caratteri, ecc. È necessario combattere contro il desiderio naturale (soprattutto per i programmatori che hanno superato le prime difficoltà e iniziano a sentirsi dei professionisti) di semplificare il programma allontanandosi da regole ferree e utilizzando tecniche non standard. Apparentemente, a prima vista, la complicazione ingiustificata ripagherà pienamente facilitando il debug e la rielaborazione del programma nel suo insieme. Consideriamo alcune caratteristiche delle subroutine. I NCREM e DESREM eseguono l'operazione richiesta in molti casi, l'operazione di incremento o decremento di un dato valore di un numero binario a 16 bit (i suoi byte alti e bassi sono rispettivamente nei registri R6 e R5). Le costanti che specificano la quantità di incremento sono descritte all'inizio del programma. Poiché qualsiasi microcontrollore funziona molto più velocemente delle apparecchiature tecnologiche, è molto importante poter organizzare il ritardo nel programma. In questo caso viene utilizzato il contatore/timer interno del processore. Ha una capacità limitata e trabocca in millisecondi. Ogni overflow genera una richiesta di interrupt. La routine di servizio di interruzione del timer (TIME) li conta e, quando viene raggiunto il numero specificato, imposta il flag di timeout FLT su uno. Tutte le subroutine il cui lavoro dipende dal tempo, resta da analizzare lo stato di questo flag. Quindi è possibile realizzare velocità dell'otturatore di diversi secondi e persino minuti. Per iniziare a contare un nuovo intervallo, è necessario inserire i valori iniziali nelle celle di lavoro della subroutine TIME e attivare il timer. La subroutine SET2M, ad esempio, imposta il ritardo a 2 minuti. Il calcolo dei valori iniziali ha diverse sottigliezze. È noto che nei microcontrollori della serie MSS48 gli impulsi arrivano all'ingresso del contatore/timer interno con una frequenza 480 volte inferiore alla frequenza dell'oscillatore al quarzo. Ad esempio, con una frequenza del risonatore al quarzo di 7 MHz, il numero scritto sul contatore cambia ogni 480/7000000 = 0,00006857 s = 68,57 µs. Quindi il contatore andrà in overflow (e genererà una richiesta di interrupt) in 68,57 -(256-N1) µs, dove N1 è il numero originariamente scritto nel contatore. Se ogni volta che si avvia un nuovo conteggio da questo numero, gli overflow N0,1 = 2 0,1/[7000000 (1480-N256)] si verificheranno in 1 s (ritardo minimo). Ovviamente, lo stesso ritardo può essere ottenuto con diversi N1 e N2, ma poiché questi numeri non possono essere frazionari, sarà implementato con qualche errore. Il compito è selezionare una tale coppia di valori per i quali l'errore è minimo. Nel caso in esame, l'opzione migliore è N1 = 13, N2 = 6. Un ritardo di 2 min si ottiene ripetendo la procedura descritta N3 = 1200 volte. Spesso è necessario utilizzare procedure diverse per elaborare gli stessi interrupt hardware in diverse modalità di funzionamento del programma. Un modo per farlo è illustrato dalla subroutine INTER. Analizza il codice del tipo di interrupt inserito dal programma principale nella cella INTT e, a seconda del suo valore, chiama una delle routine di servizio di interrupt ISR1 o ISR2. Nota che entrambi terminano con RET, non RETR. È facile aumentare il numero di opzioni di elaborazione e persino fare in modo che per un certo valore del codice vengano richiamate una dopo l'altra diverse subroutine. Non è necessario scrivere tutte le subroutine necessarie nel file di testo del programma principale. I moduli sottoposti a debug e utilizzati ripetutamente in programmi diversi possono essere posizionati in file separati e collegati al programma principale utilizzando le direttive INCLUDE. Ogni file di inclusione può contenere una o più routine. Lo svantaggio di questo metodo è che i nomi di variabili, costanti ed etichette in tutti i moduli utilizzati non devono essere ripetuti. Privo di questo difetto, il metodo di traduzione separata dei moduli con la loro successiva fusione a livello di codice oggetto, purtroppo, non è supportato dal TASM ASSEMBLY. Autore: D. Ryzhov, Vladimir Vedi altri articoli sezione microcontrollori. Leggere e scrivere utile commenti su questo articolo. Ultime notizie di scienza e tecnologia, nuova elettronica: Macchina per diradare i fiori nei giardini
02.05.2024 Microscopio infrarosso avanzato
02.05.2024 Trappola d'aria per insetti
01.05.2024
Altre notizie interessanti: ▪ L'odore del paziente fa sbagliare i medici ▪ Laptop da gioco Lenovo Legion R7000P e R9000P ▪ Il piombo è più forte dell'acciaio News feed di scienza e tecnologia, nuova elettronica
Materiali interessanti della Biblioteca Tecnica Libera: ▪ sezione del sito Casa, terreni domestici, hobby. Selezione di articoli ▪ articolo Culturalogia. Culla ▪ articolo Chi guidò i Troiani nella loro lotta contro gli Achei? Risposta dettagliata ▪ articolo TVZ nella lampada UMZCH. Enciclopedia dell'elettronica radio e dell'ingegneria elettrica
Lascia il tuo commento su questo articolo: Tutte le lingue di questa pagina Homepage | Biblioteca | Articoli | Mappa del sito | Recensioni del sito www.diagram.com.ua |