;************************************************** ; Pic by example ; SEQTMR0.ASM ; Luci sequenziali con temporizzazione via TIMER 0 ; ; (c) 2004, Sergio Tanzilli ; http://www.tanzilli.com ;************************************************** PROCESSOR 16F84A RADIX DEC INCLUDE "P16F84A.INC" ERRORLEVEL -302 ;Setup of PIC configuration flags ;XT oscillator ;Disable watch dog timer ;Enable power up timer ;Disable code protect __CONFIG 0x3FF1 ORG 0CH Count RES 1 Shift RES 1 ;Reset Vector - Punto di inizio del programma al reset della CPU ORG 00H ;Commuta sul secondo banco dei registri bsf STATUS,RP0 ;Definizione delle linee di I/O (0=Uscita, 1=Ingresso) movlw 00011111B movwf TRISA movlw 11110000B movwf TRISB ;Assegna il PRESCALER a TMR0 e lo configura a 1:32 ;Vedi subroutine Delay per maggiori chiarimenti movlw 00000100B movwf OPTION_REG ;Commuta sul primo banco dei registri bcf STATUS,RP0 ;Il registro Shift viene utilizzato per rappresentare internamente ;lo stato delle linee di uscita della porta B dove sono collegati i led. ;Il bit 0 del registro Shift viene settato ad uno per iniziare il ciclo ;dal primo led. movlw 00000001B movwf Shift ;Loop di scorrimento MainLoop ;Invia sulla porta B il registro Shift cosi che ogni bit settato ad uno in Shift ;fara' accendere il led relativo movf Shift,W movwf PORTB ;Per ruotare le luci usa l'istruzione rlf che effettua lo shift a sinistra dei bit ;contenuti nel registro ed inserisce nel bit 0 lo stato del bit di carry. Per ;questo motivo prima di effettuare l'istruzione rlf azzera il bit di carry con l'istruzione ;bcf STATUS,C. bcf STATUS,C rlf Shift,F ;Quando lo shift raggiunge il bit 4 vengono invertiti i primi quattro bit del registro ;Shift con i secondi quattro bit in modo da ricominciare il ciclo dal bit 0. ; ; Ecco cosa succede ai bit del registro Shift durante l'esecuzione di questo loop: ; ; 00000001 <--- Valore iniziale (primo led acceso) ; 00000010 rlf ; 00000100 rlf ; 00001000 rlf ; 00010000 rlf a questo punto viene eseguita l'istruzione swapf ottenendo: ; 00000001 ...e cosi' via btfsc Shift,4 swapf Shift,F ;Inserisce un ritardo tra una accensione e l'altra call Delay ;Torna ad eseguire nuovamente il loop goto MainLoop ;************** ; Subroutines ;************** ; Inserimento di un ritardo pari ad un secondo ; utilizzando il registro TMR0 ; ; Il ritardo viene ottenuto dalla frequenza in uscita al PRESCALER pari a: ; 4Mhz / 4 / 32 = 31.250 Hz ; ... divisa per 250 dal TMR0 32.250 / 250 = 125 Hz ; ... e per 125 dal contatore Count 125 / 125 = 1Hz Delay ; Inizializza TMR0 per ottenere 250 conteggi prima di arrivare a zero. ; Il registro TMR0 e' un registro ad 8 bit quindi se viene incrementato ; nuovamentre quando arriva a 255 ricomincia a contare da zero. ; Se lo si inizializza a 6 dovra' essere incrementato 256 - 6 = 250 volte ; prima passare per lo zero. movlw 6 movwf TMR0 ; Il registro Count viene inizializzato a 125 in quanto il suo scopo e' far ; uscire il loop movlw 125 movwf Count ;Loop di conteggio DelayLoop ;TMR0 vale 0 ? movf TMR0,W btfss STATUS,Z goto DelayLoop ;No, aspetta... movlw 6 ;Si, reimposta TMR0 e controlla se movwf TMR0 ;e' passato per 125 volte per lo zero decfsz Count,1 goto DelayLoop return END