ITIS M. PLANCK ( LANCENIGO DI VILLORBA TV) CORSO SERALE ( Classe 5 /STE ) Area di progetto anno scolastico 2006/2007 Allievo: Crema Claudio Tutor : Prof. Italo Zaniol Controllo di un asse
Indice: Descrizione del progetto Schema a blocchi Descrizione dello schema a blocchi Interfaccia Demoboard Analisi del circuito elettrico la tecnica del PWM Circuito di condizionamento sensori Driver interfaccia motore Analisi del programma Programma principale
Descrizione del progetto In questo progetto si è realizzato un controllo di posizione di un asse. Le applicazioni riguardano l automazione industriale in macchine come calandre, piegatrici, taglierine, troncatrici, saldatrici ecc.. Prendiamo ad esempio una macchina che effettua il taglio di lamiere. Si rende necessario posizionare la lamiera alla giusta distanza dalle lame di taglio. Queste macchine presentano una barra di riferimento dove verrà appoggiata la lamiera. Il posizionamento di tale barra può essere effettuato mediante un motore controllato da una logica elettronica. Dei fine corsa delimitano le zone di movimento della barra di posizionamento. L operatore mediante un tastierino e un display può interagire con il sistema elettronico che movimenta e controlla la posizione di tale barra. Il sistema realizzato è di tipo didattico e le varie parti sono state costruite a livello hobbistico con materiali poveri ( legno ) e spesso di recupero. La trasformazione del moto rotatorio del motore in lineare per la movimentazione della barra posizionatrice, è stata realizzata con una vite senza fine ed un dato. La rotazione della barra comporta uno spostamento longitudinale del dado a cui, ipoteticamente, è collegata la barra posizionatrice. Anche il trasduttore utilizzato per misurare lo spostamento è stato costruito a mano forando una lamina di bachelite a forma circolare. Nonostante ciò, la precisione che si ha nel posizionamento è di tutto riguardo e corrisponde ad un decimo di millimetro.
Schema a blocchi: Descrizione dello schema a blocchi: Lo schema a blocchi evidenzia come il cuore del sistema di controllo sia costituito da un microprocessore. Per maggior precisione si tratta di un microcontrollore che, rispetto ad un microprocessore, prevede al suo interno una serie di periferiche standard ( memorie, interfacce di I/O, controllo PWM, seriale ecc. ) che consentono un risparmio di costi ed una maggior affidabilità. Il microcontrollore gestisce le periferiche ad esso collegate che brevemente riassumiamo: Tastierino esadecimale e display LCD: mediante queste due periferiche l operatore addetto alla macchina può interagire col sistema operativo implementato nel microcontrollore. Tramite tastierino è possibile dare questo tipo di ordini: 1. spostamento veloce della barra 2. spostamento lento della barra 3. posizionamento della barra alla quota zero 4. posizionamento della barra ad un determinata misura Il display LCD consente di verificare se gli ordini sono forniti correttamente e di avere il valore della posizione della barra. Interfaccia di potenza. Mediante tre segnali, il microcontrollore controlla la rotazione del motore. I tre segnali sono: 1. Break con funzioni di marcia/arresto del motore 2. direction con funzioni di controllare il verso di rotazione del motore 3. PWM con funzioni di controllare la velocità di rotazione del motore Interfaccia sensori ed encoder: mediante questa interfaccia il microcontrollore è in grado di sapere se la barra oltrepassa i limiti di spostamento consentiti mediante dei sensori all infrarosso che vengono comunemente utilizzati nelle stampanti per controllare la massima escursione del carrello. Tale interfaccia fornisce anche gli impulsi provenienti dall encoder usati per sapere la posizione della barra.
Segnalazioni: le segnalazioni sono di tipo ottiche a diodi led ed aiutano l operatore a sapere lo stato della macchina. Questi diodi segnalano se: 1. lo spostamento della barra avviene in avanti o all indietro 2. se il motore è fermo o in rotazione Dettaglio sensore fine corsa Dettaglio sensore encoder Dettaglio tastierino alfanumerico Dettaglio programmatore pic
Interfaccia demoboard: Analisi dello schema elettrico Trattandosi di un prototipo, la realizzazione hardware non è stata fatta su un unico circuito stampato. E stata utilizzata una demoboard che prevede,oltre al microcontrollore, il display, la tastiera, led di segnalazione e dei connettori che consentono di collegare delle schede di espansione che utilizzano svariate periferiche. Tale demoboard è molto comoda in applicazioni di tipo didattiche in quanto evita di dover ogni volta progettare l hardware di base che è sempre lo stesso. Ci si concentra quindi sulla sola applicazione concreta. Nel caso in oggetto la scheda di espansione presenta due strip di tipo maschio che consentono l interfacciamento tra demoboard e: 1. il driver per il motore in corrente continua 2. il circuito di condizionamento dei sensori ottici dei fine corsa e dell encoder. Lo schema elettrico della demoboard e la disposizione dei componenti vengono proposti per comodità.
SCHEMA ELETTRICO DEMOBOARD DISPOSIZIONE DEI COMPONENTI DELLA DEMOBOARD
L interfacciamento tra demoboard e circuito di condizionamento verso i sensori ottici rispecchia lo schema di figura. CIRCUITO DI CONDIZIONAMENTO SENSORI OTTICI Come si può vedere il sensore è costituito da una forcella che implementa un diodo all infrarosso e un foto transistore. Quando all interno della forcella non è presente un ostacolo il transistore è in saturazione, la tensione all ingresso della porta Not trigger di Schmitt è basso e Vout alta. In caso di ostacolo il transistore è interdetto e Vout è opposta al caso precedente cioè bassa. La porta Not con caratteristica di trasferimento Trigger di Schmitt serve a squadrare il segnale di uscita dalla forcella. Dettaglio scheda interfaccia sensori
Lo schema elettrico del driver per il motore è il seguente. DRIVER PER MOTORE IN CORRENTE CONTINUA Lo schema elettrico presenta due multiplexer 74151 utilizzati per realizzare un circuito combinatorio che pilota, insieme a dei transistori, i 4 Bjt di potenza del ponte. I due multiplexer vengono pilotati dal PIC sulle linee di indirizzamento. A seconda dei valori degli ingressi PWM, DIRECTION, BREAK, le uscite Y e W ( W è negata rispetto a Y ) assumono valori che dipendono dai livelli logici presenti sugli ingressi Di. Tale interfaccia è stata utilizzata con successo in altri progetti. Quando Break è basso conduce una coppia di transistori che dipende dallo stato degli ingressi Direction e PWM. Quando il motore è in rotazione esso continua a girare anche se PWM viene portato basso grazie ai diodi di ricircolo della corrente. I Bjt di potenza sono dei darlington BDX53 e BDX54 con correnti di 8 A; inoltre essi hanno già al loro interno i diodi di ricircolo. Dettaglio scheda interfaccia potenza motore
LA TECNICA PWM La tecnica PWM consente di dosare la potenza fornita ad un carico alimentato sia in corrente continua che in corrente alternata utilizzando sistemi di controllo digitali. CONTROLLO DI POTENZA IN CORRENTE CONTINUA Nello schema di figura un generatore di onde quadre alimenta, tramite interfaccia di potenza, un generico carico. L onda quadra ha periodo T e la durata dell impulso è t. Nell ipotesi che Vcc sia l ampiezza dell impulso, la tensione media fornita al carico vale Vm = Vcc*t/T. Il termine t/t si chiama duty cycle e viene di norma fornito in %. Variando il duty cycle, vale a dire mantenendo T costante e facendo variare t, la tensione media sul carico puo variare da 0 a Vcc e così pure la potenza da 0 ad un certo valor massimo. Dunque variando t, si modula la potenza fornita al carico. Alcune applicazioni potrebbero riguardare il controllo di grandezze fisiche come la temperatura, la velocità o la posizione di un motore in corrente continua. Nel caso in oggetto si tratta di variare la velocità del motore. Poiché la velocità di rotazione del motore è direttamente proporzionale alla tensione continua applicata ai suoi morsetti, variando il duty cycle si varia indirettamente la velocità del rotore. Infatti l onda quadra può essere scomposta, come insegna l analisi di Fourier, in una componente continua più una serie di infinite armoniche con frequenza multipla della fondamentale. Dato che il motore in corrente continua è un sistema di tipo passa basso con frequenza di taglio di alcuni Hz, segue che esso è sensibile alla sola componente continua che, come visto in precedenza, è proporzionale al duty cycle. INTERFACCIA PWM NEL PIC 16F877 Questo microcontrollore dispone di due uscite PWM,RC2/CCP1 e RC1/CCP2, che possono essere controllate via software agendo su opportuni registri dedicati. Di seguito si analizza come controllare l uscita RC2/CCP1 che è quella utilizzata nel progetto; analoghi discorsi valgono per l altra uscita PWM. Per maggiori dettagli, è necessario consultare il manuale. I registri dedicati al controllo dell uscita CCP1 in modalità PWM sono T2CON, TMR2, PR2, CCPR1L, CCPR1H e CCP1CON. Il funzionamento è il seguente: 1. Quando il contatore a 8 bits TMR2, comandato dal clock del processore, raggiunge il valore contenuto nel registro PR2, l uscita PWM si porta alta automaticamente, TMR2 viene azzerato, il contenuto del registro CCPR1L e i 2 bit 5 e 4 del registro CCP1CON vengono trasferiti in CCPR1H. Quest ultimo registro non è accessibile da software ma è solo un latch. 2. L uscita rimane alta finchè TMR2 raggiunge il valore contenuto nel registro CCPR1H. Da quanto esposto, per variare il duty cycle è necessario variare il contenuto di CCPR1L mentre il registro PR2 è utilizzato per stabilire il periodo T. Nel progetto realizzato la frequenza del quarzo è di 20MHz; avendo impostato il divisore di frequenza ( prescaler ) a 1, si ha che T = [(PR2) + 1 ] * 4 * Tosc * ( valore del prescaler di TMR2 ) = (256)*4*0.05* 1 = 51.2 microsecondi a cui corrisponde una frequenza pari a 19.53KHz. Il valore di t varia da 0 ( CCPR1L=0 ) a δ = ( CCPR1L:CCP1CON<5,4>) * Tosc * ( valore del prescaler di TMR2 ) = 1020*0.05*1=51microsecondi avendo impostato i due bit 5 e 4 di CCP1CON a 0. Il duty cycle varia quindi da 0 a 51/51.2 cioè fino al 99.6% con passi di circa il 3.9%. Se si desidera aumentare la frequenza dell onda quadra, diminuisce la risoluzione. Ad esempio se PR2=128 si ottiene una frequenza di 38.8KHz ma, come conseguenza, il contenuto massimo di CCPR1L deve essere 128 e la risoluzione diventa del 7.75%.
Analisi del programma: Sono di seguito analizzate alcune parti significative del programma. Programma principale Il programma principale, come al solito, configura inizialmente il PIC cioè stabilisce quali siano le linee utilizzate come ingressi, quali come uscite, abilita la funzione PWM, configura il registro prescaler ecc. La parte di controllo vera e propria è di seguito riportata. Come si può vedere vengono interrogati con la tecnica del polling sei pulsanti. Se uno di questi viene trovato azionato, viene chiamata in causa una routine che risponde alle richieste dell operatore. Le funzioni sono: Posizionamento alla quota zero richiesta posizionamento ad una quota fornita dall operatore Spostamento veloce del carrello verso sinistra Spostamento veloce del carrello verso destra Spostamento lento del carrello verso sinistra Spostamento lento del carrello verso destra LOOP MOVLW B'00000111' ;CONTROLLA SE PREMUTO A - SE SI POSIZIONA QUOTA ZERO MOVWF PORTB BTFSC PORTB,4 ;PREMUTO A? GOTO AV_1 LOOP1 BTFSS PORTB,4 ;ATTENDI RILASCIO PULSANTE GOTO LOOP1 CALL QUOTA_0 ;POSIZIONA QUOTA ZERO AV_1 MOVLW B'00001011' ;CONTROLLA SE PREMUTO B - SE SI CHIEDI QUOTA MOVWF PORTB BTFSC PORTB,4 ;PREMUTO B? GOTO AV2 LOOP2 BTFSS PORTB,4 ;ATTENDI RILASCIO PULSANTE GOTO LOOP2 CALL QUOTA ;CHIEDI QUOTA E POSIZIONA AV2 MOVLW B'00001110' ;SPOSTAMENTO MANUALE VELOCE A DX? MOVWF PORTB BTFSS PORTB,5 ;PREMUTO #? SPOSTAMENTO A DX CALL MANV_DX BTFSS PORTB,7 ;PREMUTO *? SPOSTAMENTO A SX CALL MANV_SX MOVLW B'00001101' ;SPOSTAMENTO MANUALE LENTO MOVWF PORTB BTFSS PORTB,5 ;PREMUTO 9? ROTAZIONE DX CALL MANL_DX BTFSS PORTB,7 ;PREMUTO 7? SPOSTAMENTO A SX CALL MANL_SX GOTO LOOP ;RIPETI CICLO INDEFINITAMENTE Routine che posiziona l asse alla quota zero Le modalità di posizionamento avvengono in questo modo: Il carrello viene spostato verso destra di 12 mm in modo veloce o Infatti la parte bassa del registro che conta gli impulsi viene azzerata e poi si controlla quando il conteggio degli impulsi provenienti dall encoder è giunto a 240. Poiché l encoder ha trenta fori, esso fornisce 240 impulsi quando la vite che muove
il carrello ha compiuto almeno 8 giri. Dato che il passo della vite è di 1.5 mm lo spostamento orizzontale è appunto di 12mm. Qualora il carrello raggiunga il fine corsa FC2 prima di aver percorso i 12mm si ha l inversione di marcia Compiuti gli 8 giri oppure raggiunto il fine corsa, si ha l inversione di marcia e lo spostamento veloce del carrello verso sinistra fino a raggiungere il fine corsa FC1 che sancisce la posizione zero. Raggiunto FC1 il carrello viene spostato ancora verso destra di circa 4.5 mm e poi di nuovo a destra in modo lento in modo da non oltrepassare per l inerzia dell asse la posizione zero. Questa modalità di posizionamento è tipica in quanto determina con precisione la posizione voluta. Si potrebbe obbiettare che se il sensore rilevasse il carrello nella posizione zero non sarebbe necessaria tutta la procedura descritta. Nella realtà niente di preciso si può dire se il carrello sia esattamente nella posizione voluta in quanto esso potrebbe essere arrivato in questa posizione mediante uno spostamento veloce che sicuramente determina il superamento della quota a causa della inevitabile inerzia di tutte le parti meccaniche che sono azionate dal motore nonché l inerzia del rotore del motore stesso. Questa routine utilizza tutta una serie di sottoprogrammi che vengono utilizzati anche in altre parti del programma. Riassumiamo brevemente le routine richiamate: 1. DISP_MOTOR_ON: visualizza sul display che il motore è in rotazione 2. ROT_PIU: il motore viene fatto girare in modo da spostare il carrello verso destra 3. ROT_MENO: il motore viene fatto girare in modo da spostare il carrello verso sinistra 4. STOP_MOTOR: il motore viene arrestato 5. DISP_MOTOR_OFF1: visualizza sul display che il motore è fermo ;********** ROUTINE QUOTA ZERO QUOTA_0 MOVLW 0XFF ; IMPONI MASSIMO DUTY CYCLE MOVWF CCPR1L CLRF FLAG ;SEGNALA MISURAZIONI ON CALL DISP_MOTOR_ON CLRF TMR1L ;AZZERA CONTEGGIO IMPULSI ENCODER CALL ROT_PIU ;ROTAZIONE MOTORE ORARIA LPQ_ENC BTFSS PORTC,FC2 ;CONTROLLA SE ARRIVATO A FINE CORSA GOTO ALT0 MOVLW D'240' ;CONTROLLA SE IL MOTORE HA FATTO 8 GIRI SUBWF TMR1L,0 BTFSS STATUS,2 GOTO LPQ_ENC ALT0 CALL ROT_MENO ;INVERTI MARCIA LP_FC1 BTFSC PORTC,FC1 ;ARRIVATO QUOTA 0? GOTO LP_FC1 CALL ROT_PIU ;INVERTI ROTAZIONE MOTORE CLRF TMR1L ;AZZERA CONTEGGIO IMPULSI LPQ_ENC1 MOVLW D'100' ;CONTROLLA SE IL MOTORE HA FATTO 100 PASSI SUBWF TMR1L,0 BTFSS STATUS,2 GOTO LPQ_ENC1 CALL ROT_MENO ;INVERTI MARCIA MOVLW 0XA0 ; AVVICINAMENTO LENTO MOVWF CCPR1L LP_FC11 BTFSC PORTC,FC1 ;ARRIVATO QUOTA 0? GOTO LP_FC11 CALL STOP_MOTOR CALL DISP_MOTOR_OFF1 ;MOTOR OFF E QUOTA 000.00 CLRF TMR1L ;AZZERA CONTEGGIO ENCODER CLRF TMR1H
Routine che posiziona l asse alla quota desiderata Anche questa routine utilizza numerosi sottoprogrammi: 3. CHIEDI_QUOTA:questa routine fornisce lo spostamento desiderato in codice BCD dei decimi di mm, mm, decine di mm. e centinaia di mm.. 4. ELABORA: trasforma lo spostamento in codice BCD in numero di giri che deve compiere l asse del motore ( le modalità di elaborazione vengono analizzate più avanti ). 5. MISURA: visualizza, durante lo spostamento e in tempo reale, la posizione del carrello 6. ERRORE: qualora venga richiesta una misura che ecceda il massimo spostamento possibile ( quindi oltre FC2 ) viene visualizzato un messaggio di errore e la richiesta di una nuova quota. 7. Le altre routine richiamate sono state analizzate in precedenza La logica di controllo del motore è la seguente: Richiede quota in codice BCD Viene controllato se il carrello è in posizione zero. Se non lo è viene richiamata la routine che provvede a spostare il carrello in posizione zero Vengono azzerati i registri che conteggiano gli impulsi provenienti dall encoder Viene azzerato un segnalatore ( FLAG ) che segnala ad altre parti del programma che è attiva la funzione di visualizzazione della quota sul display Viene richiesto di trasformare lo spostamento in numero di giri del motore. o Viene controllato se la quota ecceda lo spostamento massimo o Viene controllato se la rotazione dell asse è minore di tre giri ( 4.5 mm di spostamento lineare) In caso affermativo si ha uno spostamento lento verso la quota desiderata in modo da evitare posizionamenti errati dovuti alla solita inerzia meccanica delle parti in movimento In caso negativo il motore viene fatto girare alla massima velocità finchè non ci siano le condizioni per lo spostamento lento. Raggiunta la quota il motore viene fermato QUOTA CALL CHIEDI_QUOTA BTFSC PORTC,FC1 ;CONTROLLA SE IN QUOTA 0? CALL QUOTA_0 ;SE NO POSIZIONA CLRF TMR1L ;AZZERA CONTEGGIO ENCODER CLRF TMR1H CLRF FLAG ;SEGNALA MISURAZIONI ON CALL ELABORA MOVLW 0X08 ;CONTROLLA SE RICHIESTA MISURA ECCEDENTE LUNGHEZZA MACCHINA SUBWF IMPH,0 GOTO QUOTA1 LPP MOVF IMPH ;CONTROLLA QUANDO RALLENTARE BTFSC STATUS,2 GOTO ZAN2 ;SE PARTE ALTA CONTEGGIO IMPULSI è=0 CONTROLLA SOLO PARTE BASSA MOVF IMPH,0 ;ALTRIMENTI ESEGUI CONTROLLO SU ENTRAMBE LE PARTI MOVWF IMPHM ;MEMORIZZA PARTE ALTA CONTEGGIO FINALE MOVF TMR1L,0 ;CALCOLA LA DIFFERENZA TRA CONTEGGIO FINALE E QUELLO ATTUALE SUBWF IMPL,0 MOVWF DIFF BTFSS STATUS,0 DECF IMPHM MOVF TMR1H,0 SUBWF IMPHM MOVLW D'90' ;è minore di 90? (3 giri ) SUBWF DIFF GOTO ZAN1 MOVF IMPHM BTFSS STATUS,2 GOTO ZAN1 GOTO PIANO ZAN1 MOVLW 0XFF ; MASSIMA VELOCITà MOVWF CCPR1L CALL ROT_PIU ;PORTA MOTORE IN ROTAZIONE CALL DISP_MOTOR_ON
CALL MISURA GOTO LPP PIANO MOVLW 0X96 ; RALLENTA MOVWF CCPR1L LOOP222 CALL ROT_PIU ;PORTA MOTORE IN ROTAZIONE CALL DISP_MOTOR_ON CALL MISURA MOVF TMR1H,0 SUBWF IMPH,0 BTFSS STATUS,2 GOTO LOOP222 MOVF TMR1L,0 ;CONTROLLA SE RAGGIUNTA QUOTA SUBWF IMPL,0 GOTO LOOP222 CALL STOP_MOTOR CALL MISURA ZAN2 MOVF TMR1L,0 ;CALCOLA LA DIFFERENZA TRA CONTEGGIO FINALE E QUELLO ATTUALE SUBWF IMPL,0 MOVWF DIF MOVLW D'90' SUBWF DIF BTFSS STATUS,0 GOTO PIANO GOTO ZAN1 QUOTA1 CALL ERRORE GOTO QUOTA Routine che trasforma lo spostamento da codice BCD in numero di giri del motore Come riportato nel commento al sottoprogramma ad ogni impulso contato dall encoder il carrello si sposta di 5 centesimi di millimetro. Vale allora la seguente relazione tra misura in mm e il numero di impulsi contati dall encoder: MISURA = (IMPULSI x5)/100 ( ad esempio se si contano 10 impulsi lo spostamento è di 10X5/100= 0.5mm. Dalla relazione si ricava IMPULSI = 100*(MISURA/5) che, per facilitare l elaborazione, può essere scritta come 100*[(2/10)*MISURA]. Questa relazione evidenzia che se si fissa una risoluzione pari ad un decimo di millimetro, per trasformare lo spostamento da decimi in numero di giri basta moltiplicare i decimi per 2 e si ottengono i giri cercati. Infatti IMPULSI = (100*2/10)*MISURA = 2*(MISURA/10) ( dove MISURA/10 è lo spostamento in decimi di millimetro. La routine si fa quindi carico di trasformare, per prima cosa, lo spostamento fornito in codice BCD in decimi di millimetro secondo la seguente relazione. DECIMI = DEC IMI BCD + MM BCD *10 + DECINE BCD *100 + CENTINAIA BCD *1000 Le moltiplicazioni per 10, 100 e 1000 non utilizzano routine di moltiplicazione ma si basano sul fatto che la moltiplicazione di un numero intero per una costante si può ottenere come una sommatoria di prodotti tra il numero stesso e potenze del 2. Ad esempio N*100 = N*(64+32+4) = N*64 +N*32 + N*4 = N*2 6 +N*2 5 + N*2 2 La moltiplicazione di un numero per una potenza del 2, consiste in un numero di shift a sinistra del numero pari alla potenza del 2. Ad esempio moltiplicare N per 64, bisogna effettuare 6 shift a sinistra del numero stesso. Naturalmente il risultato dovrà essere contenuto in due registri a 8 bit ( parte alta del risultato e parte bassa del risultato ). La moltiplicazione finale per 2 viene risolta con i medesimi criteri. Di seguito si riporta solo una parte di questa routine. ;********** ROUTINE ELABORA:CALCOLA QUANTI IMPULSI DEVE CONTARE L'ENCODER PER LA MISURA. ;********** LA VITE AVANZA DI 1.5 MM PER GIRO CIOè 1.5/30=0.05 MM PER IMPULSO (5 CENTESIMI ) ;********** DI CONSEGUENZA SI HA: MISURA=IMPULSI*5 IN CENTESIMI DI MM SEGUE QUINDI: ;********** N_IMPULSI=MISURA/5=2*MISURA/10 = 2*MISURA1 DOVE MISURA1 è IN DECIMI ;********** QUINDI LA RISOLUZIONE è DI 1 DECIMO DI MILLIMETRO E N_IMPULSI=2*MISURA1 ELABORA BCF STATUS,0 ;MOLTIPLICA MM PER 10 - MM*(2+8) RLF MM ;MOLTIPLICA MM PER 2 E SALVA
MOVF MM,0 MOVWF MEM2 RLF MEM2 ;MOLTIPLICA PER 4 RLF MEM2,0 ;MOLTIPLICA PER 8 ADDWF MM ;TROVA DECIMI*10 BCF STATUS,0 ;MOLTIPLICA MM10 PER 100 - MM10*(64+32+4) ( MM10 sono le decine di millimetro) RLF MM10 ;MOLTIPLICA MM10 PER 4 E SALVA. Programma principale: ;**************************************************************** ;***************** controllo di un asse ************************* ;**************************************************************** #include <p16f877.inc> config ( _CP_OFF & _DEBUG_OFF & _WDT_OFF & _XT_OSC & _CPD_OFF & _BODEN_OFF & _WRT_ENABLE_OFF & _LVP_OFF ) MS EQU 0X20 ;NOMI SIMBOLI LOCAZIONI RAM DS EQU 0X21 SAVE_W EQU 0X22 SAVE_S EQU 0X23 DATO EQU 0X24 ROT EQU 0X25 PWM EQU 0X26 DUTY EQU 0X27 MIGLIAIA EQU 0X28 CENTINAIA EQU 0X29 DECINE EQU 0X2A UNITA EQU 0X2B SAVEL EQU 0X2C SAVEH EQU 0X2D BINARIO EQU 0X2E DECIMI EQU 0X2F MM EQU 0X30 MM10 EQU 0X31 MM100 EQU 0X32 MEM2 EQU 0X33 MEM8 EQU 0X34 MEM16 EQU 0X35 MEM32 EQU 0X36 MEM64 EQU 0X37 MEM128 EQU 0X38 MEM256 EQU 0X39 MEM512 EQU 0X3A MEMH32 EQU 0X3B MEMH64 EQU 0X3C MEMH128 EQU 0X3D MEMH256 EQU 0X3E MEMH512 EQU 0X3F IMPL EQU 0X40 IMPH EQU 0X41 MMH10 EQU 0X42 MMH100 EQU 0X43 FLAG EQU 0X44 TMR1L1 EQU 0X45 TMR1H1 EQU 0X46 TMR1LD EQU 0X47 TMR1HD EQU 0X48 DIFF EQU 0X49 DIF EQU 0X50 IMPHM EQU 0X51 ;********************* nomi simbolici pin controlli #DEFINE BREAK 3 #DEFINE OUT_PWM 2 #DEFINE DIRECTION 1 #DEFINE FC1 5 #DEFINE FC2 4 #DEFINE MASC_DIR 2
;*************** INIZIALIZZAZIONE VETTORI ******************** ORG 0 GOTO MAIN ORG 4 GOTO INTERRUPT ; *********************** PROGRAMMA PRINCIPALE ********************************* MAIN BSF PORTC,BREAK ;MOTORE OFF CLRF PORTA ;SPEGNI LED SEGNALAZIONE MOVLW 1 ;INIZIALIZZA FLAG MISURA MOVWF FLAG BSF STATUS,5 ;BANCO 1 BCF TRISC,OUT_PWM ;CONFIGURA CONTROLLI MOTORE COME OUT BCF TRISC,DIRECTION BCF TRISC,BREAK MOVLW B'00000100' ;SELEZIONA CLOCK PER TMR0 20MHz - ABILITA PULL UP MOVWF OPTION_REG ;ASSEGNA PRESCALE A TMR0 - CONFIGURA PRESCALER MOVLW B'00000110' ;CONFIGURA PORTA E PORTE COME LINEE DIGITALI MOVWF ADCON1 CLRF TRISA ;PORTA COME OUT BCF TRISE,1 ;CONFIGURA RE1 E RE2 COME USCITE CONTROLLO DISPLAY BCF TRISE,2 CLRF TRISD ;CONFIGURA PORTD COME OUT (BUS LCD) MOVLW B'11110000' ;CONFIGURA PORTB PER GESTIONE TASTIERA MOVWF TRISB BCF STATUS,5 ;BANCO 0 MOVLW 0XFF ;CONFIGURA PR2 PER USCITA RC2 DI TIPO PWM MOVWF PR2 MOVLW B'00000100' ;CONFIGURA T2CON MOVWF T2CON MOVLW 0XFF ; IMPONI DUTY CYCLE MASSIMO MOVWF CCPR1L MOVLW B'00001111' ;CONFIGURA CCP1CON PER PWM MOVWF CCP1CON MOVLW B'00000011' ;CONFIGURA T1CON PER CONTEGGIO IMPULSI ENCODER MOVWF T1CON MOVLW B'10100000' ;ABILITA INTERRUPT MOVWF INTCON CALL DS3 ;RITARDO PER ASSESTAMENTO TENSIONI SU LCD CLRF ROT ;AZZERA FLAG CONTROLLO VISUALIZZAZIONE ROTAZIONE BSF PORTA,0 ;SEGNALA ROTAZIONE + BSF PORTA,1 ;SEGNALA MOTORE OFF CALL CONFIGURA_LCD CALL RIGA1 ;INIZIALIZZA RIGA 1 LCD CALL RIGA2 ;INIZIALIZZA RIGA 2 LCD LOOP MOVLW B'00000111' ;CONTROLLA SE PREMUTO A - SE SI POSIZIONA QUOTA ZERO MOVWF PORTB BTFSC PORTB,4 ;PREMUTO A? GOTO AV_1 LOOP1 BTFSS PORTB,4 ;ATTENDI RILASCIO PULSANTE GOTO LOOP1 CALL QUOTA_0 ;POSIZIONA QUOTA ZERO AV_1 MOVLW B'00001011' ;CONTROLLA SE PREMUTO B - SE SI CHIEDI QUOTA MOVWF PORTB BTFSC PORTB,4 ;PREMUTO B? GOTO AV2 LOOP2 BTFSS PORTB,4 ;ATTENDI RILASCIO PULSANTE GOTO LOOP2 CALL QUOTA ;CHIEDI QUOTA E POSIZIONA AV2 MOVLW B'00001110' ;SPOSTAMENTO MANUALE VELOCE A DX? MOVWF PORTB BTFSS PORTB,5 ;PREMUTO #? SPOSTAMENTO A DX CALL MANV_DX BTFSS PORTB,7 ;PREMUTO *? SPOSTAMENTO A SX CALL MANV_SX MOVLW B'00001101' ;SPOSTAMENTO MANUALE LENTO MOVWF PORTB BTFSS PORTB,5 ;PREMUTO 9? ROTAZIONE DX CALL MANL_DX BTFSS PORTB,7 ;PREMUTO 7? SPOSTAMENTO A SX CALL MANL_SX GOTO LOOP ;RIPETI CICLO INDEFINITAMENTE
;********** ROUTINE QUOTA ZERO QUOTA_0 MOVLW 0XFF ; IMPONI MASSIMO DUTY CYCLE MOVWF CCPR1L CLRF FLAG ;SEGNALA MISURAZIONI ON CALL DISP_MOTOR_ON CLRF TMR1L ;AZZERA CONTEGGIO IMPULSI ENCODER CALL ROT_PIU ;ROTAZIONE MOTORE ORARIA LPQ_ENC BTFSS PORTC,FC2 ;CONTROLLA SE ARRIVATO A FINE CORSA GOTO ALT0 MOVLW D'240' ;CONTROLLA SE IL MOTORE HA FATTO 8 GIRI SUBWF TMR1L,0 BTFSS STATUS,2 GOTO LPQ_ENC ALT0 CALL ROT_MENO ;INVERTI MARCIA LP_FC1 BTFSC PORTC,FC1 ;ARRIVATO QUOTA 0? GOTO LP_FC1 CALL ROT_PIU ;INVERTI ROTAZIONE MOTORE CLRF TMR1L ;AZZERA CONTEGGIO IMPULSI LPQ_ENC1 MOVLW D'100' ;CONTROLLA SE IL MOTORE HA FATTO 100 PASSI SUBWF TMR1L,0 BTFSS STATUS,2 GOTO LPQ_ENC1 CALL ROT_MENO ;INVERTI MARCIA MOVLW 0XA0 ; AVVICINAMENTO LENTO MOVWF CCPR1L LP_FC11 BTFSC PORTC,FC1 ;ARRIVATO QUOTA 0? GOTO LP_FC11 CALL STOP_MOTOR CALL DISP_MOTOR_OFF1 ;MOTOR OFF E QUOTA 000.00 CLRF TMR1L ;AZZERA CONTEGGIO ENCODER CLRF TMR1H ;*******ROTAZIONE MOTORE POSITIVA ROT_PIU BSF PORTC,DIRECTION ;ROTAZIONE POSITIVA BCF PORTC,BREAK ;ROTAZIONE MOTORE BSF PORTA,0 ;SEGNALA ROTAZIONE + BCF PORTA,1 ;SPEGNI SEGNALAZIONE MOTORE OFF BSF PORTA,2 ;SEGNALA MOTORE ON ;*******ROTAZIONE MOTORE NEGATIVA ROT_MENO BCF PORTC,DIRECTION ;ROTAZIONE POSITIVA BCF PORTC,BREAK ;ROTAZIONE MOTORE BCF PORTA,0 ;SEGNALA ROTAZIONE - BCF PORTA,1 ;SPEGNI SEGNALAZIONE MOTORE OFF BSF PORTA,2 ;SEGNALA MOTORE ON ;********** ROUTINE MOTORE OFF STOP_MOTOR BSF PORTC,BREAK ;STOP MOTORE BSF PORTA,1 ;SEGNALAZIONE MOTORE OFF BCF PORTA,2 ;SPEGNI SEGNALAZIONE MOTORE ON CALL DISP_MOTOR_OFF ;********** SPOSTAMENTO MANUAL A DX VELOCE MANV_DX CALL RIGA1 CALL RIGA2 MOVLW 1 ;INIZIALIZZA FLAG MISURA MOVWF FLAG MANV_DX1 BTFSS PORTC,FC2 ;CONTROLLA SE ARRIVATO A FINE CORSA GOTO ALT1 MOVLW 0XFF ; IMPONI MASSIMO DUTY CYCLE MOVWF CCPR1L CALL ROT_PIU ;ROTAZIONE CALL DISP_MOTOR_ON BTFSS PORTB,5 ;FINE? GOTO MANV_DX1 ALT1
CALL STOP_MOTOR ;********** SPOSTAMENTO MANUALE A SX VELOCE MANV_SX CALL RIGA1 CALL RIGA2 MOVLW 1 ;INIZIALIZZA FLAG MISURA MOVWF FLAG MANV_SX1 BTFSS PORTC,FC1 ;CONTROLLA SE ARRIVATO A FINE CORSA GOTO ALT2 MOVLW 0XFF ; IMPONI MASSIMO DUTY CYCLE MOVWF CCPR1L CALL ROT_MENO ;ROTAZIONE CALL DISP_MOTOR_ON BTFSS PORTB,7 ;FINE? GOTO MANV_SX1 ALT2 CALL STOP_MOTOR ;********** SPOSTAMENTO MANUALE A DX LENTO MANL_DX BTFSS PORTC,FC2 ;CONTROLLA SE ARRIVATO A FINE CORSA GOTO ALT3 MOVLW 0X95 ; IMPONI DUTY CYCLE MOVWF CCPR1L CALL ROT_PIU ;ROTAZIONE CALL DISP_MOTOR_ON MOVF FLAG ;CONTROLLA SE VISUALIZZARE MISURA BTFSC STATUS,2 CALL MISURA BTFSS PORTB,5 ;FINE? GOTO MANL_DX ALT3 CALL STOP_MOTOR CALL MS_20 ;ELIMINA INERZIA MOVF FLAG ;CONTROLLA SE VISUALIZZARE MISURA BTFSC STATUS,2 CALL MISURA ;********** SPOSTAMENTO MANUALE A SX LENTO MANL_SX MOVF TMR1L,0 ;copia situazione impulsi MOVWF TMR1L1 BTFSS PORTC,FC1 ;CONTROLLA SE ARRIVATO A FINE CORSA GOTO ALT41 MOVLW 0X95 ; IMPONI DUTY CYCLE MOVWF CCPR1L CALL ROT_MENO ;ROTAZIONE CALL DISP_MOTOR_ON ASP1 BTFSS PORTC,0 ;ASPETTA CHE CI SIA ZONA D'OMBRA GOTO ASP1 MOVLW 0X75 ; TIENILO IN TRAZIIONE MOVWF CCPR1L MOVF TMR1L1,0 ;CALCOLA SPOSTAMENTO INDIETRO (DECREMENTA CONTEGGIO ) SUBWF TMR1L,0 SUBWF TMR1L BTFSS STATUS,0 DECF TMR1H SUBWF TMR1L BTFSS STATUS,0 DECF TMR1H MOVLW 0XFF ;CONTROLLA CHE NON OLTREPASSI SENSORE FC1 SUBWF TMR1H,0 BTFSC STATUS,2 GOTO ZERO OK MOVF FLAG ;CONTROLLA SE VISUALIZZARE MISURA BTFSC STATUS,2 CALL MISURA BTFSS PORTB,7 ;FINE? GOTO MANL_SX ALT4 CALL STOP_MOTOR CALL MS_20 ;ELIMINA INERZIA MOVF FLAG ;CONTROLLA SE VISUALIZZARE MISURA BTFSC STATUS,2
ZERO ALT41 CALL MISURA CLRF CLRF GOTO CLRF CLRF GOTO TMR1L TMR1H OK TMR1L TMR1H ALT4 ;********** ROUTINE QUOTA QUOTA CALL CHIEDI_QUOTA BTFSC PORTC,FC1 ;CONTROLLA SE IN QUOTA 0? CALL QUOTA_0 ;SE NO POSIZIONA CLRF TMR1L ;AZZERA CONTEGGIO ENCODER CLRF TMR1H CLRF FLAG ;SEGNALA MISURAZIONI ON CALL ELABORA MOVLW 0X08 ;CONTROLLA SE RICHIESTA MISURA ECCEDENTE LUNGHEZZA MACCHINA SUBWF IMPH,0 GOTO QUOTA1 LPP MOVF IMPH ;CONTROLLA QUANDO RALLENTARE BTFSC STATUS,2 GOTO ZAN2 ;SE PARTE ALTA CONTEGGIO IMPULSI è=0 CONTROLLA SOLO PARTE BASSA MOVF IMPH,0 ;ALTRIMENTI ESEGUI CONTROLLO SU ENTRAMBE LE PARTI MOVWF IMPHM ;MEMORIZZA PARTE ALTA CONTEGGIO FINALE MOVF TMR1L,0 ;CALCOLA LA DIFFERENZA TRA CONTEGGIO FINALE E QUELLO ATTUALE SUBWF IMPL,0 MOVWF DIFF BTFSS STATUS,0 DECF IMPHM MOVF TMR1H,0 SUBWF IMPHM MOVLW D'90' ;è minore di 90? (3 giri ) SUBWF DIFF GOTO ZAN1 MOVF IMPHM BTFSS STATUS,2 GOTO ZAN1 GOTO PIANO ZAN1 MOVLW 0XFF ; MASSIMA VELOCITà MOVWF CCPR1L CALL ROT_PIU ;PORTA MOTORE IN ROTAZIONE CALL DISP_MOTOR_ON CALL MISURA GOTO LPP PIANO MOVLW 0X96 ; RALLENTA MOVWF CCPR1L LOOP222 CALL ROT_PIU ;PORTA MOTORE IN ROTAZIONE CALL DISP_MOTOR_ON CALL MISURA MOVF TMR1H,0 SUBWF IMPH,0 BTFSS STATUS,2 GOTO LOOP222 MOVF TMR1L,0 ;CONTROLLA SE RAGGIUNTA QUOTA SUBWF IMPL,0 GOTO LOOP222 CALL STOP_MOTOR CALL MISURA ZAN2 MOVF TMR1L,0 ;CALCOLA LA DIFFERENZA TRA CONTEGGIO FINALE E QUELLO ATTUALE SUBWF IMPL,0 MOVWF DIF MOVLW D'90' SUBWF DIF BTFSS STATUS,0 GOTO PIANO GOTO ZAN1 QUOTA1 CALL ERRORE GOTO QUOTA
;********** ROUTINE ELABORA:CALCOLA QUANTI IMPULSI DEVE CONTARE L'ENCODER PER LA MISURA. ;********** LA VITE AVANZA DI 1.5 MM PER GIRO CIOè 1.5/30=0.05 MM PER IMPULSO (5 CENTESIMI ) ;********** DI CONSEGUENZA SI HA: MISURA=IMPULSI*5 IN CENTESIMI DI MM SEGUE QUINDI: ;********** N_IMPULSI=MISURA/5=2*MISURA/10 = 2*MISURA1 DOVE MISURA1 è IN DECIMI ;********** QUINDI LA RISOLUZIONE è DI 1 DECIMO DI MILLIMETRO E N_IMPULSI=2*MISURA1 ELABORA BCF STATUS,0 ;MOLTIPLICA MM PER 10 - MM*(2+8) RLF MM ;MOLTIPLICA MM PER 2 E SALVA MOVF MM,0 MOVWF MEM2 RLF MEM2 ;MOLTIPLICA PER 4 RLF MEM2,0 ;MOLTIPLICA PER 8 ADDWF MM ;TROVA DECIMI*10 BCF STATUS,0 ;MOLTIPLICA MM10 PER 100 - MM10*(64+32+4) RLF MM10 ;MOLTIPLICA MM10 PER 4 E SALVA RLF MM10 MOVF MM10,0 MOVWF MEM32 RLF MEM32 ;MOLTIPLICA PER 8 RLF MEM32 ;MOLTIPLICA PER 16 CLRF MEMH32 ;AZZERA PARTE ALTA MM RLF MEM32 ;MOLTIPLICA PER 32 RLF MEMH32 MOVF MEMH32,0 ;SALVA MOVWF MEMH64 MOVF MEM32,0 MOVWF MEM64 RLF MEM64 ;MOLTIPLICA PER 64 RLF MEMH64 CLRF MMH10 ;CALCOLA MM10*100 MOVF MM10,0 ADDWF MEM32,0 INCF MMH10 ADDWF MEM64,0 INCF MMH10 MOVWF MM10 MOVF MMH10,0 ADDWF MEMH32,0 ADDWF MEMH64,0 MOVWF MMH10 BCF STATUS,0 ;MOLTIPLICA MM10 PER 1000 - MM10*(512+256+128+64+32+8) RLF MM100 ;PER 2 RLF MM100 ;PER 4 RLF MM100 ;PER 8 MOVF MM100,0 ;SALVA MOVWF MEM32 CLRF MEMH32 ;AZZERA PARTE ALTA MM RLF MEM32 ;MOLTIPLICA PER 16 RLF MEM32 ;MOLTIPLICA PER 32 RLF MEMH32 MOVF MEMH32,0 ;SALVA MOVWF MEMH64 MOVF MEM32,0 MOVWF MEM64 RLF MEM64 ;MOLTIPLICA PER 64 RLF MEMH64 MOVF MEMH64,0 ;SALVA MOVWF MEMH128 MOVF MEM64,0 MOVWF MEM128 RLF MEM128 ;MOLTIPLICA PER 128 RLF MEMH128 MOVF MEMH128,0 ;SALVA MOVWF MEMH256 MOVF MEM128,0 MOVWF MEM256 RLF MEM256 ;MOLTIPLICA PER 256 RLF MEMH256 MOVF MEMH256,0 ;SALVA MOVWF MEMH512 MOVF MEM256,0 MOVWF MEM512 RLF MEM512 ;MOLTIPLICA PER 512 RLF MEMH512 CLRF MMH100 ;CALCOLA MM100*1000 MOVF MM100,0 ADDWF MEM32,0 INCF MMH100 ADDWF MEM64,0
INCF MMH100 ADDWF MEM128,0 INCF MMH100 ADDWF MEM256,0 INCF MMH100 ADDWF MEM512,0 INCF MMH100 MOVWF MM100 MOVF MMH100,0 ADDWF MEMH32,0 ADDWF MEMH64,0 ADDWF MEMH128,0 ADDWF MEMH256,0 ADDWF MEMH512,0 MOVWF MMH100 MOVF DECIMI,0 ;CALCOLA NUMERO IMPULSI ADDWF MM,0 INCF MMH100 ADDWF MM10,0 INCF MMH100 ADDWF MM100,0 INCF MMH100 MOVWF IMPL MOVF MMH100,0 ADDWF MMH10,0 MOVWF IMPH BCF STATUS,0 ;MOLTIPLICA PER 2 RLF IMPL RLF IMPH MOVLW 1 ;AGGIUSTA RISULTATO SUBWF IMPL BTFSS STATUS,0 DECF IMPH ;***** ROUTINE CHE MISURA SPOSTAMENTO MISURA CALL BCD ;CONVERTI CONTEGGIO IN BCD BCF PORTE,1 ;SPOSTA CURSORE COLONNA 8 NOP MOVLW 0x8A BSF PORTE,1 ;INVIA DATI MOVF MIGLIAIA,0 CALL TABELLA MOVF CENTINAIA,0 CALL TABELLA MOVF DECINE,0 CALL TABELLA MOVLW '.' MOVF UNITA,0 CALL TABELLA ;********ROUTINE CONVERSIONE BINARIO BCD (1000d=3E8h) BCD CLRF CENTINAIA ;INIZIALIZZA ALCUNE VARIABILI CLRF DECINE CLRF MIGLIAIA MOVF TMR1L,0 ;SALVA DATI MOVWF SAVEL MOVF TMR1H,0 MOVWF SAVEH BCF STATUS,0 MUL2 RRF SAVEH RRF SAVEL LPM MOVLW 3 ;MINORE DI 1000? SUBWF SAVEH,0 BTFSS STATUS,0 ;SE SI VAI A CALCOLARE CENTINAIA
GOTO LPC MOVLW 4 ;CONTROLLA SE SICURAMENTE MAGGIORE DI 1000 SUBWF SAVEH,0 BTFSS STATUS,0 ;SE SI TOGLI 1000 E INCREMENTA MIGLIAIA GOTO LPM2 ;ALTRIMENTI SE TMRIH=3 CONTROLLA CHE TMRIL SIA >=E8h LPM1 INCF MIGLIAIA MOVLW 0XE8 SUBWF SAVEL BTFSS STATUS,0 DECF SAVEH MOVLW 3 SUBWF SAVEH GOTO LPM LPM2 MOVLW 0XE8 SUBWF SAVEL,0 BTFSS STATUS,0 GOTO LPC INCF MIGLIAIA MOVLW 0XE8 SUBWF SAVEL MOVLW 3 SUBWF SAVEH GOTO LPM LPC MOVLW D'100' ;CALCOLA CENTINAIA SUBWF SAVEL,0 BTFSS STATUS,0 ;SE SAVEL MINORE DI 100 CONTROLLA SE SAVEH>0 GOTO LPC1 INCF CENTINAIA ;ALTRIMENTI TOGLI 100 E INCREMENTA CENTINAIA MOVLW D'100' SUBWF SAVEL GOTO LPC LPC1 MOVF SAVEH BTFSC STATUS,2 ;SE SAVEH>0 TOGLI 100 A SAVEL E DECREMENTA DI 1 SAVEH GOTO LPD MOVLW D'100' ;AGGIORNA CONTEGGIO CENTINAIA SUBWF SAVEL DECF SAVEH INCF CENTINAIA GOTO LPC LPD MOVLW D'10' ;CALCOLA DECINE SUBWF SAVEL,0 ;SE SAVEL >10 TOGLI 10 E INCREMENTA DECINE BTFSS STATUS,0 GOTO LPU ;ALTRIMENTI SAVEL CONTIENE LE UNITà INCF DECINE MOVLW D'10' SUBWF SAVEL GOTO LPD LPU MOVF SAVEL,0 ;SALVA UNITA' MOVWF UNITA ;********** ROUTINE RITARDO CIRCA 3 DECIMI DS3 CLRF DS LP_MSA MOVLW D'3' SUBWF DS,0 BTFSS STATUS,2 GOTO LP_MSA ;**********ROUTINE CONFIGURAZIONE LCD CONFIGURA_LCD BCF PORTE,1 ;PROGRAMMAZIONE LCD RS=0 MOVLW 0x38 ;DATI A 8 BIT - 2 RIGHE - FORMATO CARATTERE MOVLW 0x0C ;DISPLAY ON - CURSORE OFF - BLINKING OFF MOVLW 6 ;AVANZAMENTO AUTOMATICO CURSORE MOVLW 1 ;PULISCI DISPLAY CALL MS1 ;ULTERIORE RITARDO MOVLW 2 ;CURSORE INIZIO RIGA CALL MS1 ;ULTERIORE RITARDO MOVLW 0x40 ;INDIRIZZO CGRAM MOVLW 0X80 ;INDIRIZZO DDRAM
;**********ROUTINE INVIO DATI DISPLAY DISPLAY MOVWF PORTD ;PRESENTA DATO SU BUS LCD BSF PORTE,2 ;IMPULSO DI ABILITAZIONE LETTURA NOP BCF PORTE,2 CALL MS1 ;RITARDO 1 MS (CIRCA) ;**********ROUTINE COMANDO CURSORE INIZIO SECONDA RIGA HOME2 BCF PORTE,1 NOP MOVLW 0xC0 ;**********ROUTINE COMANDO CURSORE INIZIO PRIMA RIGA HOME1 BCF PORTE,1 NOP MOVLW 0x80 ;**********ROUTINE ATTIVA FUNZIONE BLINK BLINK BCF PORTE,1 ;ABILITA ISTRUZIONE NOP MOVLW 0x0D ;**********ROUTINE DISATTIVA FUNZIONE BLINK BLINK_OFF BCF PORTE,1 ;ABILITA ISTRUZIONE NOP MOVLW 0x0C ;DISPLAY ON - CURSORE OFF - BLINKING OFF ;********** ROUTINE RITARDO MINIMO 1 MS MS1 CLRF MS LP_MS MOVLW 2 SUBWF MS,0 BTFSS STATUS,2 GOTO LP_MS ;********** ROUTINE RITARDO 10 MS MS10 CLRF MS LP_MS10 MOVLW D'10' SUBWF MS,0 BTFSS STATUS,2 GOTO LP_MS10 ;**********ROUTINE INIZIALIZZAZIONE PRIMA RIGA RIGA1 CALL HOME1 BSF PORTE,1 ;INVIA DATI MOVLW 'M' MOVLW 'O' MOVLW 'T' MOVLW 'O' MOVLW 'R' MOVLW 'O' MOVLW 'F'
MOVLW 'F' MOVLW '*' MOVLW '*' MOVLW '*' MOVLW '.' MOVLW '*' ;**********ROUTINE INIZIALIZZAZIONE PRIMA RIGA RIGA2 CALL HOME2 BSF PORTE,1 ;INVIA DATI MOVLW 'I' MOVLW 'T' MOVLW 'I' MOVLW 'S' MOVLW 'P' MOVLW 'L' MOVLW 'A' MOVLW 'N' MOVLW 'C' MOVLW 'K' ;********** ROUTINE CHIEDI QUOTA CHIEDI_QUOTA CALL HOME2 BSF PORTE,1 ;INVIA DATI MOVLW 'M' MOVLW 'E' MOVLW 'A' MOVLW 'S' MOVLW 'U' MOVLW 'R' MOVLW 'E'
BCF PORTE,1 ;SPOSTA CURSORE COLONNA 8 NOP MOVLW 0xC8 CALL BLINK ;ABILITA LAMPEGGIO CURSORE BSF PORTE,1 ;INVIA DATI CALL TASTIERA ;CARICA MM100 MOVWF MM100 CALL TABELLA CALL TASTIERA ;CARICA MM10 MOVWF MM10 CALL TABELLA CALL TASTIERA ;CARICA MM MOVWF MM CALL TABELLA MOVLW '.' CALL TASTIERA ;CARICA DECIMI MOVWF DECIMI CALL TABELLA CALL BLINK_OFF ;DISABILITA LAMPEGGIO CURSORE ;**********ROUTINE CHE SEGNALA ERRORE DI QUOTA ERRORE CALL HOME2 BSF PORTE,1 ;INVIA DATI MOVLW 'E' MOVLW 'R' MOVLW 'R' MOVLW 'O' MOVLW 'R' CALL DS3 CALL DS3 ;************** ROUTINE CHE VISUALIZZA OFF SU DISPLAY DISP_MOTOR_OFF BCF PORTE,1 ;CURSORE SU COLONNA 6 NOP
MOVLW 0x86 BSF PORTE,1 ;INVIA DATI MOVLW 'O' MOVLW 'F' MOVLW 'F' ;************** ROUTINE CHE VISUALIZZA OFF SU DISPLAY E QUOTA 0 DISP_MOTOR_OFF1 BCF PORTE,1 ;CURSORE SU COLONNA 6 NOP MOVLW 0x86 BSF PORTE,1 ;INVIA DATI MOVLW 'O' MOVLW 'F' MOVLW 'F' MOVLW '0' MOVLW '0' MOVLW '0' MOVLW '.' MOVLW '0' ;************** ROUTINE CHE VISUALIZZA ON SU DISPLAY DISP_MOTOR_ON BCF PORTE,1 ;CURSORE SU COLONNA 6 NOP MOVLW 0x86 BSF PORTE,1 ;INVIA DATI MOVLW 'O' MOVLW 'N' ;************ROUTINE LETTURA TASTIERINO ESADECIMALE************* TASTIERA MOVLW B'00001110' ;SCANSIONE COLONNE MOVWF PORTB BTFSS PORTB,4 ;PREMUTO D? GOTO TASTOD BTFSS PORTB,5 ;PREMUTO #? GOTO TASTOCANC BTFSS PORTB,6 ;PREMUTO 0? GOTO TASTO0 BTFSS PORTB,7 ;PREMUTO *? GOTO TASTOAST MOVLW B'00001101' ;SCANSIONE COLONNE MOVWF PORTB BTFSS PORTB,4 ;PREMUTO C? GOTO TASTOC BTFSS PORTB,5 ;PREMUTO 9? GOTO TASTO9 BTFSS PORTB,6 ;PREMUTO 8? GOTO TASTO8 BTFSS PORTB,7 ;PREMUTO 7? GOTO TASTO7 MOVLW B'00001011' ;SCANSIONE COLONNE MOVWF PORTB BTFSS PORTB,4 ;PREMUTO B?
GOTO TASTOB BTFSS PORTB,5 ;PREMUTO 6? GOTO TASTO6 BTFSS PORTB,6 ;PREMUTO 5? GOTO TASTO5 BTFSS PORTB,7 ;PREMUTO 4? GOTO TASTO4 MOVLW B'00000111' ;SCANSIONE COLONNE MOVWF PORTB BTFSS PORTB,4 ;PREMUTO A? GOTO TASTOA BTFSS PORTB,5 ;PREMUTO 3? GOTO TASTO3 BTFSS PORTB,6 ;PREMUTO 2? GOTO TASTO2 BTFSS PORTB,7 ;PREMUTO 1? GOTO TASTO1 GOTO TASTIERA ;SE NESSUN TASTO PREMUTO, ESEGUI NUOVA SCANSIONE TASTO0 LP1 BTFSS PORTB,6 ;ATTENDI RILASCIO PULSANTE GOTO LP1 MOVLW 0 TASTO1 LP2 BTFSS PORTB,7 ;ATTENDI RILASCIO PULSANTE GOTO LP2 MOVLW 1 TASTO2 LP3 BTFSS PORTB,6 ;ATTENDI RILASCIO PULSANTE GOTO LP3 MOVLW 2 TASTO3 LP4 BTFSS PORTB,5 ;ATTENDI RILASCIO PULSANTE GOTO LP4 MOVLW 3 TASTO4 LP5 BTFSS PORTB,7 ;ATTENDI RILASCIO PULSANTE GOTO LP5 MOVLW 4 TASTO5 LP6 BTFSS PORTB,6 ;ATTENDI RILASCIO PULSANTE GOTO LP6 MOVLW 5 TASTO6 LP7 BTFSS PORTB,5 ;ATTENDI RILASCIO PULSANTE GOTO LP7 MOVLW 6 TASTO7 LP8 BTFSS PORTB,7 ;ATTENDI RILASCIO PULSANTE GOTO LP8 MOVLW 7 TASTO8 LP9 BTFSS PORTB,6 ;ATTENDI RILASCIO PULSANTE GOTO LP9 MOVLW 8 TASTO9 LP10 BTFSS PORTB,5 ;ATTENDI RILASCIO PULSANTE GOTO LP10 MOVLW 9 TASTOA LP11 BTFSS PORTB,4 ;ATTENDI RILASCIO PULSANTE
GOTO LP11 MOVLW 0X0A TASTOB LP12 BTFSS PORTB,4 ;ATTENDI RILASCIO PULSANTE GOTO LP12 MOVLW 0X0B TASTOC LP13 BTFSS PORTB,4 ;ATTENDI RILASCIO PULSANTE GOTO LP13 MOVLW 0X0C TASTOD LP14 BTFSS PORTB,4 ;ATTENDI RILASCIO PULSANTE GOTO LP14 MOVLW 0X0D TASTOCANC LP15 BTFSS PORTB,6 ;ATTENDI RILASCIO PULSANTE GOTO LP15 MOVLW 0X0E TASTOAST LP16 BTFSS PORTB,4 ;ATTENDI RILASCIO PULSANTE GOTO LP16 MOVLW 0X0F ;**********************ROUTINE DELAY 20MS*************************************** MS_20 CLRF MS LP_MS2 MOVLW D'20' SUBWF MS,0 BTFSS STATUS,2 GOTO LP_MS2 ;**************** ROUTINE RISPOSTA INTERRUPT ************************ INTERRUPT MOVWF SAVE_W ;SALVA CONTESTO SWAPF STATUS,0 MOVWF SAVE_S NOP MOVLW D'100' MOVWF TMR0 INCF MS ;AGGIORNA TEMPO MOVLW D'100' SUBWF MS,0 BTFSS STATUS,2 GOTO EXIT INCF DS CLRF MS EXIT BCF INTCON,2 ;Azzera flag interrupt SWAPF SAVE_S,0;Ripristina contesto MOVWF STATUS SWAPF SAVE_W SWAPF SAVE_W,0 RETFIE ORG 400 ;DATI DI TABELLA IN PAGINA 4 ;******** CODICI PER DISPLAY LCD TABELLA MOVWF DATO ;SALVA DATO MOVLW 4 ;PREDISPONI PCLATH MOVWF PCLATH MOVF DATO,0 ;RIPRENDI DATO ADDWF PCL RETLW '0' RETLW '1' RETLW '2' RETLW '3' RETLW '4' RETLW '5' RETLW '6' RETLW '7'
RETLW '8' RETLW '9' END