Vai al contenuto
PLC Forum


Eeprom Del Pic16f876


Pablo78

Messaggi consigliati

Salve a tutti

Ragazzi ho un problema col PicfF876, io dovrei leggere dei caratteri dalla memoria eeeprom dello stesso 16F876

all'inizio carico l'indirizzo 0x80 per scrivere :"sistema pronto premere un tasto per continuare"...e va tutto bene...a questo punto carico 0x00 su EEADR e dovrei leggere altri dati dopo l'avvenuta pressione di un tasto della tastiera del PC,solo che a video mi spara tutti i dati consecutivi.... come se non vedesse il cambio di indirizzo tra l'altro a volte il sistema non si blocca e continua a sparare dati a volontà!! :(

Premetto che uso alla lettera le routine della microchip e di molte ho già provato l'efficacia specie quelle per la trasmissione col modulo usart..

vi ringrazio anticipatamente

Pablo

Link al commento
Condividi su altri siti


Ciao Pablo,

Per poterti aiutare , dovresti dirci quale programma stai usando.

Per esempio, carichi l'indirizzo 0x80 dove?

Caricando in EEADR 0x00 dici che vuoi leggere la prima locazione della EEPROM , ma poi come leggi questo dato?

Dicci qualche cosa di piu'

Saluti

Link al commento
Condividi su altri siti

Allora per editare in assembler uso l'MPLAB,di conseguenza l'assemblatore compreso nel pacchetto è l'MPASM

dopodichè programmo il chip (on board), con l'IC-PROG.

0x80 lo scrivo in EEADR,trasmetto i 47 caratteri seguenti a questo indirizzo, poi dovrei passare a 0x00(EEADR) per trasmetterne altri 20. Quello che succede,anche scrivendo su EEADR 0x00, è che legge i dati consecutivi senza passare a 0x00.

Se volete posso scrivere il file asm e potete controllarlo.

Vi ringrazio sempre.

Saluti :D

Pablo78

Paolo

Link al commento
Condividi su altri siti

Ragazzi io v mando l'asm se qualcuno di buona volontà vuole leggerlo e scova l'errore o magari ha qualche suggerimento..vi ringrazio sempre

list P=16F876

RADIX DEC

#include <P16f876.inc>

COUNT_CH EQU 0xA0 ;contatore numero caratteri

ADDR_CH EQU 0xA1 ;indirizzo iniziale dei caratteri da stampare

org 00h

goto start

org 04h

;*******************************

;* INTERRUPT HANDLER *

;*******************************

call TX_CH

movlw 20

banksel COUNT_CH

movwf COUNT_CH

movlw 0x00

movfw ADDR_CH

call TX_CH

call RX_ON

banksel PIR1

wait_RX

btfss PIR1,RCIF

goto wait_RX

call RX_OFF

call PWM_ON ;accensione segnale PWM con il duty cycle voluto

banksel INTCON

bsf INTCON,GIE

bcf INTCON,INTF

retfie

;**************************************

;* INIZIALIZZAZIONE REGISTRI *

;**************************************

;PORTB

;interrupt

;PORTC

;Modulo PWM

;Modulo USART

start

banksel TRISB

movlw b'00000001' ;RB0 input

bcf OPTION_REG,6 ;Interrupt --_

banksel INTCON

movlw 0x90 ;Interrupt sul cambiamento di stato --_ della linea RB0

movwf INTCON

;inizializzazione modulo USART

banksel SPBRG

movlw 25 ;velocità 9600 BAUD

movwf SPBRG

bsf TXSTA,BRGH ;High Speed

bcf TXSTA,SYNC ;Modo Asincrono

;Modulo CCP PWM Mode

clrf CCP1CON

clrf TMR2

banksel PR2

movlw 0xFF ;T_PWM=(PR2+1)4Tosc(prescalerTMR2) = 4.1E-3 s (244 Hz)

movwf PR2

banksel COUNT_CH ;Stampa a video della frase "Sistema pronto premi un tasto per continuare"

movlw 47

movwf COUNT_CH

movlw 0x80 ;locazione iniziale della E²PROM

banksel ADDR_CH

movwf ADDR_CH

;**********

;* MAIN *

;**********

mainloop

sleep

nop

goto mainloop

;******************************************************

;* Sub Routine per la Trasmissione carattere *

;******************************************************

TX_CH

banksel RCSTA

bsf RCSTA,SPEN

banksel TXSTA

bsf TXSTA,TXEN

repeat

call RD_EEPROM

banksel TXREG

movwf TXREG

banksel TXSTA

loop_TX btfss TXSTA,TRMT

goto loop_TX

banksel COUNT_CH

incf ADDR_CH

decfsz COUNT_CH,1

goto repeat

bcf TXSTA,TXEN

banksel RCSTA

bcf RCSTA,SPEN

return

;*****************************************************

;* Sub Routine per la lettura dati da E²PROM *

;*****************************************************

RD_EEPROM

;lettura da EEPROM dati

banksel ADDR_CH

movf ADDR_CH,W

banksel EEADR

movwf EEADR

banksel EECON1

bcf EECON1,EEPGD

bsf EECON1,RD

banksel EEDATA

movf EEDATA,W

return

;******************************************************************

;* Sub Routine per l'Abilitazione del modulo di ricezione *

;******************************************************************

RX_ON

banksel RCSTA

bsf RCSTA,SPEN ;Porta Seriale abilitata

bsf RCSTA,CREN

return

;******************************************************************

;* Sub Routine per l'Abilitazione del modulo di ricezione *

;******************************************************************

RX_OFF

banksel RCSTA

bcf RCSTA,SPEN ;Porta Seriale disabilitata

bcf RCSTA,CREN

return

;*************************************************

;Sub Routine di accensione modulo PWM *

;*************************************************

PWM_ON

banksel DC_VAL

movf DC_VAL,W

banksel CCPR1L

;vedi analisi dei parametri

movwf CCPR1L

banksel TRISC

bcf TRISC,2 ;RC2 out PWM

banksel T2CON ;bank0

movlw b'000***00'

movwf CCP1CON ;PWM mode,Duty Cycle

movlw 0x02 ;02 prescaler=16 - 00 prescaler=1

movwf T2CON

bsf T2CON,TMR2ON ;Start TIMER2 & PWM Signal

return

end

Link al commento
Condividi su altri siti

Iniziamo con ordine...

Ho postato il tuo programma corretto per fare quello che volevi....

Per prima cosa ti consiglio , quando usi un interrupt, di salvare i registri piu importanti come W , STATUS ecc.

Tu non sai quando avverra' l'interruzione , alla fine dell' int. dovrai ricaricare i registri con i valori che avevi all'inizio.

Eviterai bruttissime sorprese...

Come vedi dal listato , prima di riabilitare la chiave generale degli interrupt , devi PRIMA cancellare il flag che ha scatenato l'int , se no riparte con un altra int , sfalsando il ciclo.

c'e' anche un errore di battitura , quando vai a scrivere 0x00 nel COUNT_CH hai usato l'istruzione movfw invece che movwf .. cose che capitano. ;)

Ho provato questa versione nel simulatore e funziona...

Se hai dubbi chiedi pure....

    list P=16F876
    RADIX DEC
    #include <P16f876.inc>
errorlevel -302

    CBLOCK 0X20
  DC_VAL
    ENDC


COUNT_CH EQU 0xA0;contatore numero caratteri
ADDR_CH  EQU 0xA1;indirizzo iniziale dei caratteri da stampare

    org 00h
    goto start

    
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; *                VETTORE DI INTERRUPT DEL MICROCONTROLLER            *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;  POSIZIONE DEL DESVIO DEL PROGRAMMA QUANDO UNA INTERRUZZIONE ACCADE

    ORG    0X0004  ; INDIRIZZO DEL VETTORE DI INTERRUZZIONE

;  É MOLTO IMPORTANTE CHE I REGISTRI PRINCIPALI PER IL FUNZIONAMENTO DELLA
;  MACCHINA, E CHE POSSONO ESSERE ALTERATI TANTO DENTRO CHE FUORI DALL'INT SIANO
;  SALVATI IN REGISTRI TEMPORANEI PER POTER ESSERE POSTERIORMENTE
;  RECUPERATI.

SALVA_CONTESTO
    MOVWF    W_TEMP  ; COPIA W PER W_TEMP
    SWAPF    STATUS,W
    MOVWF    STATUS_TEMP    ; COPIA STATUS PER STATUS_TEMP
    MOVF    FSR,W
    MOVWF    FSR_TEMP    ; COPIA FSR
    MOVF    PCLATH,W
    MOVWF    PCLATH_TEMP    ; COPIA PCLATH
                CLRF    PCLATH    

                banksel COUNT_CH;Stampa a video della frase "Sistema pronto premi un tasto per continuare"
    movlw 47
    movwf COUNT_CH 
    movlw 0x80;locazione iniziale della E²PROM
    banksel ADDR_CH
    movwf ADDR_CH 
    call TX_CH
wait_RX 
    btfss PIR1,RCIF
    goto wait_RX
    call RX_OFF
    call PWM_ON;accensione segnale PWM con il duty cycle voluto
    banksel INTCON
    
    bcf INTCON,INTF
    bsf INTCON,GIE

    movlw 20
    banksel COUNT_CH
    movwf COUNT_CH
    movlw 0x00
    movwf ADDR_CH
    call TX_CH
    call RX_ON
    banksel PIR1

; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
; *                     FINE DELLA ROUTINE DI INTERRUZIONE                  *
; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;  RESTAURARE I VALORI DI "W" E "STATUS" PRIMA DI RITORNARE.

SAI_INT

    MOVF    PCLATH_TEMP,W    ; COPIA PCLATH
    MOVWF    PCLATH
    MOVF    FSR_TEMP,W    ; COPIA FSR
    MOVWF    FSR
    SWAPF    STATUS_TEMP,W
    MOVWF    STATUS  ; COPIA STATUS_TEMP PER STATUS
    SWAPF    W_TEMP,F
    SWAPF    W_TEMP,W                 ; COPIA W_TEMP PER W

    RETFIE      ; RITORNA DALL'INTERRUZIONE


;**************************************
;* INIZIALIZZAZIONE REGISTRI *
;**************************************

;PORTB
;interrupt
;PORTC
;Modulo PWM
;Modulo USART 

start 
    banksel TRISB
    movlw b'00000001';RB0 input
    bcf OPTION_REG,6;Interrupt --_ 
    banksel INTCON 
    movlw 0x90;Interrupt sul cambiamento di stato --_ della linea RB0
    movwf INTCON
;inizializzazione modulo USART
    banksel SPBRG
    movlw 25;velocità 9600 BAUD
    movwf SPBRG 
    bsf TXSTA,BRGH;High Speed
    bcf TXSTA,SYNC;Modo Asincrono

;Modulo CCP PWM Mode
    clrf CCP1CON
    clrf TMR2
    banksel PR2
    movlw 0xFF;T_PWM=(PR2+1)4Tosc(prescalerTMR2) = 4.1E-3 s (244 Hz)
    movwf PR2 

    
;**********
;* MAIN *
;**********
mainloop 
    sleep 
    nop
    goto mainloop 

;******************************************************
;* Sub Routine per la Trasmissione carattere *
;******************************************************
TX_CH
    banksel RCSTA
    bsf RCSTA,SPEN
    banksel TXSTA
    bsf TXSTA,TXEN
repeat
    call RD_EEPROM
    banksel TXREG
    movwf TXREG
    banksel TXSTA
loop_TX 
    btfss TXSTA,TRMT
    goto loop_TX
    banksel COUNT_CH
    incf ADDR_CH,f
    decfsz COUNT_CH,1
    goto repeat
    bcf TXSTA,TXEN
    banksel RCSTA
    bcf RCSTA,SPEN
    return

;***************************************************** 
;* Sub Routine per la lettura dati da E²PROM *
;*****************************************************
RD_EEPROM

;lettura da EEPROM dati
    banksel ADDR_CH
    movf ADDR_CH,W
    banksel EEADR
    movwf EEADR
    banksel EECON1
    bcf EECON1,EEPGD
    bsf EECON1,RD
    banksel EEDATA
    movf EEDATA,W
    return

;******************************************************************
;* Sub Routine per l'Abilitazione del modulo di ricezione *
;******************************************************************
RX_ON
    banksel RCSTA
    bsf RCSTA,SPEN;Porta Seriale abilitata
    bsf RCSTA,CREN
    return

;******************************************************************
;* Sub Routine per l'Abilitazione del modulo di ricezione *
;******************************************************************
RX_OFF
    banksel RCSTA
    bcf RCSTA,SPEN;Porta Seriale disabilitata
    bcf RCSTA,CREN
    return

;*************************************************
;Sub Routine di accensione modulo PWM * 
;*************************************************
PWM_ON
    banksel DC_VAL
    movf DC_VAL,W
    banksel CCPR1L 
;vedi analisi dei parametri 
    movwf CCPR1L 

    banksel TRISC
    bcf TRISC,2;RC2 out PWM

    banksel T2CON;bank0
    movlw b'00***100'
    movwf CCP1CON;PWM mode,Duty Cycle
    movlw 0x02;02 prescaler=16 - 00 prescaler=1
    movwf T2CON
    bsf T2CON,TMR2ON;Start TIMER2 & PWM Signal
    return



    end

Link al commento
Condividi su altri siti

Grazie DLGCOM!! :D

l'errore l'ho scovato ieri, infatti avevo scritto male "movwf" e stavo uscendo di senno!!! :o

quando l'ho scoperto ho dato letteralmente due testate al muro!! da adesso in poi cambierò religione visto che anche tu fai miracoli...Grazie infinite per aver provato il mio programma e avermi dedicato questo tempo..Seguirò comunque i tuoi preziosi consigli, sappi che adesso hai un discepolo!!! B)

Saluti alla prox

Paolo

Link al commento
Condividi su altri siti

Ok Pablo,

Non ti preoccupare , la legge di Murphy dice :

Piu' e semplice il problema piu' tempo servira' per scoprirlo.

Nel simulatore pero' ho visto che anche la gestione del flag di int. dava problemi .... :ph34r:

saluti

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...