Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Programma 16f84a

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[1] Programma 16f84a

Messaggioda Foto Utentecarlomusumeci » 7 mar 2015, 19:43

salve a tutti.ho scritto questo programma,per una centralina di gioco luci...
il programma è abbastanza semplice;
tramite un pulsante cambio il gioco i esecuzione e tramite un altro pulsante scelgo 2 diversi tempi per l'esecuzione...sono 6 giochi luce,è un display 7 segmenti mi dice il gioco in esecuzione...
il problema nasce se viene via la luce,si ripartirebbe dal gioco 1...è possibile fare in modo che anche se manca la corrente al ripristino,riparta da dove si è fermata?

ad esempio se si utilizza il gioco " 5 " al ripristino della corrente continui il 5

non so come fare...è tutto funzionante per il resto

Codice: Seleziona tutto
;**************************************************
;CENTRALINA LUCI CARLO MUSUMECI
;**************************************************

        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        3FF1H

LED     EQU     0
NEXT   EQU      4
SPEED   EQU      7
        ORG     0CH

Count   RES     2
Shift   RES      1
nTick   RES      1

        ;Reset Vector
        ;Start point at CPU reset

        ORG     00H
      
        bsf     STATUS,RP0 ; seleziona banco registri 1

        movlw   00010000B  ;
        movwf   TRISA      ;assegna IN OUT in TRISA

        movlw   10000000B  ; //////
        movwf   TRISB      ; idem


      movlw   00000100B
        movwf   OPTION_REG

        ;Commuta sul primo banco dei registri

        bcf     STATUS,RP0 ;seleziona Banco registri 0

       movlw   00000001B 
      movwf   Shift     

      

Mainloop
GIOCO1
      call   GIOCOLUCI1
      btfsc   PORTA,NEXT
      goto   GIOCO2
      goto   GIOCO1
GIOCO2   
      call   GIOCOLUCI2
      btfsc   PORTA,NEXT
      goto   GIOCO3
      goto   GIOCO2
GIOCO3   
      call   GIOCOLUCI3
      btfsc   PORTA,NEXT
      goto   GIOCO4
      goto   GIOCO3
GIOCO4   
      call   GIOCOLUCI4
      btfsc   PORTA,NEXT
      goto   GIOCO5
      goto   GIOCO4
GIOCO5   
      call   GIOCOLUCI5
      btfsc   PORTA,NEXT
      goto   GIOCO6
      goto   GIOCO5
GIOCO6   
      call   GIOCOLUCI6
      btfsc   PORTA,NEXT
      goto   GIOCO1
      goto   GIOCO6


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,SOTTO PROGRAMMI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;














GIOCOLUCI1
      movlw   00000110B  ;mostra nel display 7 segmenti collegato in PORTB il numero " 1 "
      movwf   PORTB      ;//////////////////////////////////////////////////////////
      movlw   00000001B         
      movwf   PORTA
      call   Delay
      movlw   00000010B         
      movwf   PORTA   
      call   Delay
      movlw   00000100B         
      movwf   PORTA
      call   Delay
      movlw   00001000B         
      movwf   PORTA   
      call   Delay
      RETURN
      

      
GIOCOLUCI2
      movlw   01011011B
      movwf   PORTB
      movlw   00000001B         
      movwf   PORTA
      call   Delay
      movlw   00000011B         
      movwf   PORTA   
      call   Delay
      movlw   00000111B         
      movwf   PORTA
      call   Delay
      movlw   00001111B         
      movwf   PORTA   
      call   Delay
      
      RETURN
      


GIOCOLUCI3      
      movlw   01001111B          ; DISPLAY CHE TI DICE IL NUMERO DEL GIOCO
      movwf   PORTB
;SEQUENZA GIOCO 3
      movlw   00001110B         
      movwf   PORTA
      call   Delay
      movlw   00001101B         
      movwf   PORTA   
      call   Delay
      movlw   00001011B         
      movwf   PORTA
      call   Delay
      movlw   00000111B         
      movwf   PORTA   
      call   Delay
      return
   

GIOCOLUCI4      
      movlw   01100110B         
      movwf   PORTB
;SEQUENZA GIOCO 4
      movlw   00000001B         
      movwf   PORTA
      call   Delay
      movlw   00000011B         
      movwf   PORTA   
      call   Delay
      movlw   00000111B         
      movwf   PORTA
      call   Delay
      movlw   00001111B         
      movwf   PORTA   
      call   Delay
        movlw   00000111B         
      movwf   PORTA
      call   Delay
      movlw   00000011B         
      movwf   PORTA   
      call   Delay
      movlw   00000001B         
      movwf   PORTA
      call   Delay
      movlw   00000000B         
      movwf   PORTA   
      call   Delay
      RETURN

GIOCOLUCI5      
      movlw   01101101B          ; DISPLAY CHE TI DICE IL NUMERO DEL GIOCO
      movwf   PORTB
;SEQUENZA LUCI 5
      movlw   00000001B         
      movwf   PORTA
      call   Delay
      movlw   00000011B         
      movwf   PORTA   
      call   Delay
      movlw   00000111B         
      movwf   PORTA
      call   Delay
      movlw   00001111B         
      movwf   PORTA   
      call   Delay
      movlw   00001110B         
      movwf   PORTA
      call   Delay
      movlw   00001100B         
      movwf   PORTA   
      call   Delay
      movlw   00001000B         
      movwf   PORTA
      call   Delay
      RETURN
      
GIOCOLUCI6
      movlw   01111101B          ; DISPLAY CHE TI DICE IL NUMERO DEL GIOCO
      movwf   PORTB
;SEQUENZALUCI
      movlw   00000001B         
      movwf   PORTA
      call   Delay
      movlw   00000011B         
      movwf   PORTA   
      call   Delay
      movlw   00000110B         
      movwf   PORTA
      call   Delay
      movlw   00001100B         
      movwf   PORTA   
      call   Delay
        movlw   00001000B         
      movwf   PORTA   
      call   Delay
      RETURN

Delay
       
      movlw   6
        movwf   TMR0
      

      btfsc   PORTB,SPEED
        goto    tm1
      goto    tm2
tm1
      movlw   40
      movwf   Count
      goto    DelayLoop
tm2
      movlw   16
      movwf   Count
      goto   DelayLoop


DelayLoop
      movf    TMR0,W
        btfss   STATUS,Z
        goto    DelayLoop       

        movlw   6               
        movwf   TMR0           

        decfsz  Count,1
        goto    DelayLoop

        return

        END
Avatar utente
Foto Utentecarlomusumeci
353 5 7
Sostenitore
Sostenitore
 
Messaggi: 526
Iscritto il: 8 apr 2011, 0:35

0
voti

[2] Re: Programma 16f84a

Messaggioda Foto Utentealle96 » 7 mar 2015, 20:14

Per sapere dove ti sei fermato e ripartire ti serve ricordare in un qualche modo dove eri rimasto. Puoi utilizzare la eeprom interna al micro per ricordarti e all'inizio del programma vai a leggere l'indirizzo di memoria corrispondente. Se non vuoi utilizzare la eeprom interna puoi prevederne un espansione con comunicazione SPI ecc.

Spero di esserti stato utile :ok:
Avatar utente
Foto Utentealle96
15 4
 
Messaggi: 47
Iscritto il: 21 feb 2012, 16:21

0
voti

[3] Re: Programma 16f84a

Messaggioda Foto Utentecarlomusumeci » 7 mar 2015, 21:40

Grazie mille alle96 ....ma infatti sto cercando di capire il funzionamento della eprom...con quale flag del registro eprom riesco a copiare istruzione seguente?
Avatar utente
Foto Utentecarlomusumeci
353 5 7
Sostenitore
Sostenitore
 
Messaggi: 526
Iscritto il: 8 apr 2011, 0:35

0
voti

[4] Re: Programma 16f84a

Messaggioda Foto Utentecarlomusumeci » 7 mar 2015, 22:21

come fa la eeprom a capire quale punto memorizzare alla pressione del pulsante?
Codice: Seleziona tutto
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;scrittura dato su eeprom;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

            movlw  .............. ;indirizzo locazione memoria
            movwf     EEADR      ;registro utilizzato per indirizzare una delle 64 locazioni della EEPROM
            movlw  .............. ;valore da inviare alla locazione EEPROM indirizzata con il registro EEADR
            movwf     EEDATA
                               
                               ;ABILITARE OPERAZIONI DI SCRITTURA
            bsf      STATUS,RP0  ;indirizzamento banco 1
            bsf      EECON1,WREN
                               ;Per evitare scritture accidentali nella EEPRON seguono queste 2 istruzioni
            movlw 0x55
            movwf EECON2         ;registro di controllo
            movlw 0xAA
            movwf EECON2         ;registro di controllo
                                ; eseguite queste operazioni e possibile avviare la scrittura;;;;;;;;;;;;;;;;;;;;;;;;;;;;
            bsf     EECON1,WR
Writedoneloop
            btfsc  EECON1,WR      ;finito di scrivere?
            goto   Writedoneloop  ;no aspetta...
                                             ;si continua con le seguenti istruzioni   



questo per quanto riguarda la scrittura...ma come dovrei compilare EEADR e EEDATA?
Avatar utente
Foto Utentecarlomusumeci
353 5 7
Sostenitore
Sostenitore
 
Messaggi: 526
Iscritto il: 8 apr 2011, 0:35

1
voti

[5] Re: Programma 16f84a

Messaggioda Foto Utentefloppinoo » 8 mar 2015, 0:33

Queste sono alcune mie procedure usate nell'eprom dei PIC 16f84a
attenzione per alcuni PIC i registri di controllo potrebbere essere su banchi diversi quindi controllare
i relativi datasheet.. Queste macro e procedure sono testate efunzionati sui PIC 16f84

Codice: Seleziona tutto
      Valore              EQU 30h
      Index_Memoria               EQU 2Eh
…………………………………………………………………………

;============================ MACRO UTILIZZATE ====================
settaEepromL macro I_Index, V_Valore
      movlw I_Index
      movwf Index
      movlw V_Valore
      movwf ValoreE
      call scriviEEprom
      endm

settaEeprom macro I_Index, V_Valore
      movf I_Index,W
      movwf Index
      movf V_Valore,W
      movwf ValoreE
      call scriviEEprom
      endm



scrivoEEprom   macro indirizzo, E_Valore
      bcf STATUS,RP0 ;bank 0
      movf indirizzo,w
      movwf EEADR ;first addr to eeadr
      movf E_Valore,w
      movwf EEDATA ;first data to eedata
      bsf STATUS,RP0 ;bank 1
      bsf EECON1,   WREN ;enable write
      movlw 0x55
      movwf EECON2 ;write 55h
      movlw 0xAA
      movwf EECON2 ;write AAh
      bsf EECON1,WR ;set wr bit begin wrt
      call ritardaEEIF
      bcf STATUS,RP0 ;bank 0
      endm

leggoEEprom macro indirizzo
      movf      indirizzo,w
        call      leggoEEpromM
      endm


leggoEEpromL macro indirizzo
      movlw      indirizzo
        call       leggoEEpromM
      endm

;============================ FINE MACRO ====================









;============================ Procedura usata dalla MACRO ==================

;Indice del valore da scrivere in index_menu, valore in valore
scriviEEprom
      controlla
      scrivoEEprom  Index,  ValoreE
      movf ValoreE,w
      movwf temp
      leggoEEprom Index
      subwf temp, w
      btfss STATUS,Z
      goto controlla
      return

ritardaEEIF
      btfss  EECON1,EEIF
      goto ritardaEEIF
      BCF EECON1,EEIF
      return

;============================ fine Procedura usata dalla MACRO ==================





;============================ esempi di uso comune Main ==================
1°) metodo (L)
Qui leggo dei valori usando direttamente gli indirizzi espressi direttamente come indici 0x1 0x2 (leggerò rispettivamente nel primo e secondo registro eeproom Lettura diretta e passo nelle variabili
val_Irig_1,val_Irig_Concime_1 :

Codice: Seleziona tutto
   leggoEEpromL 0x1
      movwf val_Irig_1
            
      leggoEEpromL 0x2      
      movwf val_Irig_Concime_1



Qui setto nel primo registro eeproom il valore 1 Scrittura diretta:
Codice: Seleziona tutto
settaEepromL 0x01, 1



2*) secondo metodo (M) passo direttamente il nome dei registri, utile se devo richiamare
Eeprom più volte in una procedura all’interno di un ciclo, dando naturalmente ad ogni ciclo dei valori diversi sia di indice o di valore

Scrittura :
Codice: Seleziona tutto
settaEeprom Index_Memoria, Valore


Lettura:
Codice: Seleziona tutto
leggoEEprom Index_Memoria


Naturalmente le due variabili devono essere dichiarate all’inzio del codice con le due istruzioni
Codice: Seleziona tutto
      Valore              EQU 30h
      Index_Memoria               EQU 2Eh


E valorizzati all’interno delle tue procedure nel programma assembly



La procedura scriviEEprom verifica che la scrittura è avvenuta correttamente in pratica controlla che i valori passati siano uguali ai valori scritti sulla eeporom dalla macro madre scrivoEEprom e se è diverso dal valore atteso riscrive il risultato, esce dal ciclo solo se i valori sono esatti.

Ora devo lasciarti magari usa questo mio codice miglioralo ... provalo se trovi problemi scri qui domani pomeriggio potro risponderti ... ho preso il codice da un mio vecchio assembly funzionante (un po velocemente
ma penso che siano tutti :)) ... magari se noti qualcosa di strano dimmelo, domani pomeriggio potro riponderti
con calma ... magari incomingia a provarli e dimmi se risolvi con questo codice O_/ io generalmente li riuso queste procedure ovunque e mai dato problemi
Avatar utente
Foto Utentefloppinoo
205 1 3 7
Sostenitore
Sostenitore
 
Messaggi: 508
Iscritto il: 24 lug 2010, 9:26

0
voti

[6] Re: Programma 16f84a

Messaggioda Foto Utentefloppinoo » 8 mar 2015, 0:52

Attenzione ho riaggiornato il codice ora ...
mancava questa procedura
ritardaEEIF

ora è completa o modificato il post sopra .. ora penso ci sia tutto
Codice: Seleziona tutto
ritardaEEIF
      btfss  EECON1,EEIF
      goto ritardaEEIF
      BCF EECON1,EEIF
      return


Buon divertimento a domani !!!
Avatar utente
Foto Utentefloppinoo
205 1 3 7
Sostenitore
Sostenitore
 
Messaggi: 508
Iscritto il: 24 lug 2010, 9:26

0
voti

[7] Re: Programma 16f84a

Messaggioda Foto Utentecarlomusumeci » 8 mar 2015, 0:54

grazie mille Foto Utentefloppinoo
ho notato questa parte per scrivere nella eeprom (simile alla mia)...
Codice: Seleziona tutto
scrivoEEprom   macro indirizzo, E_Valore
      bcf STATUS,RP0 ;bank 0
      movf indirizzo,w
      movwf EEADR ;first addr to eeadr
      movf E_Valore,w
      movwf EEDATA ;first data to eedata
      bsf STATUS,RP0 ;bank 1
      bsf EECON1,   WREN ;enable write
      movlw 0x55
      movwf EECON2 ;write 55h
      movlw 0xAA
      movwf EECON2 ;write AAh
      bsf EECON1,WR ;set wr bit begin wrt
      call ritardaEEIF
      bcf STATUS,RP0 ;bank 0
      endm


mettiamo caso che mentre sta eseguendo il programma,premo un pulsante che chiamerò "MEMORIZZA"che si trova al settimo bit di PORTB...al momento che premo questo pulsante...come faccio a copiare l'indirizzo seguente in EEADR ,e il valore in EEDATA ?
Avatar utente
Foto Utentecarlomusumeci
353 5 7
Sostenitore
Sostenitore
 
Messaggi: 526
Iscritto il: 8 apr 2011, 0:35

0
voti

[8] Re: Programma 16f84a

Messaggioda Foto Utentefloppinoo » 8 mar 2015, 1:04

in questo caso puoi fare semplicemnte , memorizza PortB nel primo registro utile (se una costante)
settaEepromL 0x01, (valore letterale di PortB)

oppure(se una variabile) (naturalmente qui Index_Memoria dev'essere istanziato nel ciclo del programma)
metti 0x01 -->> in Index_Memoria e poi usi
Codice: Seleziona tutto
settaEeprom Index_Memoria, PortB


Memorizzi tutto il registro PortB nella eeprom e poi nel programma rileggi il valore dell'eprom e
ne prendi il bit che ti serve

Usando le macro che ti ho dato non ti serve più sapere ne di EEADR ,e ne di EEDATA
quelle macro le devi modificare solo se usi PIC diversi ... e ti cambiano i banchi e i registri
di configurazione hardware in pratica le macro le usi come se sono una specie di interfaccia
tra il tuo sw e hardware del PIC .

Ma nei tuoi programmi usando quelle macro non ti serve pensare più ne a EEADR ,e ne a EEDATA
perche gia le macro si occupano di spostare i valori nei due casi possibili o che sono costanti (L) o che sono variabili
Avatar utente
Foto Utentefloppinoo
205 1 3 7
Sostenitore
Sostenitore
 
Messaggi: 508
Iscritto il: 24 lug 2010, 9:26

0
voti

[9] Re: Programma 16f84a

Messaggioda Foto Utentecarlomusumeci » 8 mar 2015, 1:24

non sto capendo molto...che vuoi dire con Index_Memoria?
a EEADR e EEDATA quindi che cosa dovrei assegnare?
Avatar utente
Foto Utentecarlomusumeci
353 5 7
Sostenitore
Sostenitore
 
Messaggi: 526
Iscritto il: 8 apr 2011, 0:35

0
voti

[10] Re: Programma 16f84a

Messaggioda Foto Utentefloppinoo » 8 mar 2015, 1:38

Index_Memoria è un registro che usi nel tuo programma dichiarato inizialmente
con le istruzioni iniziali del PIC

Codice: Seleziona tutto
  ORG     0CH
      Index_Memoria               EQU 2Eh
           ..............


Eprom del PIC 16f se non ricordo male ha 64 registri da 8 bit
quindi usi Index_Memoria per memorizare indice del registro eeprom da usare supponiamo
che vuoi memorizzare un valore nel banco eprom numero 4 il valore di PORTB
allora scrivi

Decido in che banco della eeprom memrizzare da 1 a 64
Codice: Seleziona tutto
       movlw 0x04
      movwf Index_Memoria


Quindi con questa semplice istruzione memorizzo nel banco 4 della eeprom il valore di PORTB
Codice: Seleziona tutto
settaEeprom Index_Memoria, Valore



Con 3 istruzioni memorizzo nelleeprom fregandomene di EEADR e EEDATA
tutto il ragionamento lo fanno le macro che ti ho postato sopra
a me basta semprerichiamare quelle 3 istruzioni dove voglio e come voglio
senza pensare ai registri EEADR e EEDATA

Sèero di essere stato chiaro :(
Avatar utente
Foto Utentefloppinoo
205 1 3 7
Sostenitore
Sostenitore
 
Messaggi: 508
Iscritto il: 24 lug 2010, 9:26

Prossimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 4 ospiti