home | area personale         schemi | tutorial | robotica | pic micro | recensioni         forum | chat irc         faq | contatti         store | Ordina PCB
username
password
cerca

 
FORUM: Pic Micro
Tutto quanto riguarda questi microprocessori... progetti, suggerimenti, aiuti, discussioni...ecc


I2C - PIC16f877 - assembly
     
Autore Messaggio opzioni
picmicro675




una ogni 10 livelli


postato il:
19.09.2018, alle ore 22:30
Ho fatto le prove.
Il primo tentativo ho scoperto che SSPIF non viene cambiato, come si suppone debba succedere al ricevimento di un ACK/NACK. Per questo invia solo il primo byte e si ferma nella routine di attesa.
Mi domando come avranno fatto quelli della Microchip a farlo funzionare.
Io ho messo una pezza, ma non ho perfettamente chiarito quale potrebbero essere gli effetti collaterali.
        #define        LC01CTRLIN    H'A0'
        #define        LC01CTRLOUT   H'A1'
        #define        LC01ADDR      H'12'
        #define        LC01DATA      H'34'

        #define        BAUD          D'100'
        #define        FOSC          D'4000'


        PROCESSOR      16F877A
        RADIX          DEC
        INCLUDE        "P16F877A.INC"
        ERRORLEVEL     -302
        __CONFIG       0x3D39     ;_CP_OFF   _DEBUG_OFF   _WRT_ENABLE_OFF
        ; _CPD_OFF   _LVP_OFF   _BODEN_OFF   _PWRTE_OFF   _WDT_OFF   _XT_OSC

        CBLOCK 30H
        Dly0
        Dly1
        Timer1                  ; contatore    per DelayP
        Timer2                  ;    "              "
        Timer3                  ;    "              "
        DispTemp                ; contenitore temporaneo per calcoli routine display
        DispCnt
        TabTemp
        Varie                  ; subroutine bip
        F20
        Temp
        ADD_DS1307_PICRX       ; indirizzo nel caso in cui il up legga i dati dall'orologio
        ADD_DS1307_PICTX       ; indirizzo nel caso in cui il up scriva i dati sull'orologio
        ENDC

;***************************************************************
;      PROGRAMMA PRINCIPALE
;***************************************************************
Start   CODE
        org       0x00
;***************************************************************
;        Inizializzazione sistema e variabili
;***************************************************************
Inizializzazione

        clrf       PORTA        ; port A = 0
        clrf       PORTB        ; port B = 0
        clrf       PORTC        ; port C = 0
        clrf       PORTD        ; port D = 0
        ;-------------------
        BANKSEL    ADCON0
        movlw      00000000b
        movwf      ADCON0
        BANKSEL    ADCON1
        movlw      00000111b
        movwf      ADCON1
;--------------------------------------------------------------------------------------------------
;             0=uscita  1=ingresso
;--------------------------------------------------------------------------------------------------

        BANKSEL    TRISB
        movlw      00001111b
        movwf      TRISB
        ;------------------
        BANKSEL    TRISC
        movlw      00011000b
        movwf      TRISC
        ;------------------
        BANKSEL    TRISD
        movlw      00000000b
        movwf      TRISD
        ;------------------
        BANKSEL    SSPCON
        movlw      00101000b   ; xxxxxxxxxxx
        MOVWF      SSPCON
        BANKSEL    SSPSTAT
        MOVLW      10000000b
        MOVWF      SSPSTAT
        BANKSEL    SSPADD
        MOVLW      (FOSC / (4 * BAUD)) - 1
        MOVWF      SSPADD
;--------------------------------------------------------------------------------------------------
        BANKSEL    PORTB
        Btfsc      PORTB,3
        GOTO       $-1
        CALL       RITARDO_30ms
        BTFSS      PORTB,3
        GOTO       $-1
        CALL       RITARDO_30ms

        BANKSEL    PORTD
        MOVLW      00H
        MOVWF      PORTD
        CALL       ritardo_secondo
        MOVLW      0XFF
        MOVWF      PORTD
        ;CALL       ritardo_secondo
        ;GOTO       $-6
I2CWrite
        BANKSEL    SSPCON2
        BSF        SSPCON2,SEN
        CALL       WaitMSSP
        ;---------------------
        MOVLW      LC01CTRLIN
        CALL       Send_I2C_Byte

        BANKSEL    SSPCON2
        BTFSC      SSPCON2,ACKSTAT
        GOTO       I2CFail

        MOVLW      LC01ADDR
        CALL       Send_I2C_Byte

        BANKSEL    SSPCON2
        BTFSC      SSPCON2,ACKSTAT
        GOTO       I2CFail

        MOVLW      LC01DATA
        CALL       Send_I2C_Byte

        BANKSEL    SSPCON2
        BTFSC      SSPCON2,ACKSTAT
        GOTO       I2CFail

        BANKSEL    SSPCON2
        BSF        SSPCON2,PEN
        CALL       WaitMSSP

I2CRead
        BANKSEL    SSPCON2
        BSF        SSPCON2,RSEN
        CALL       WaitMSSP

        MOVLW      LC01CTRLIN
        CALL       Send_I2C_Byte

        BANKSEL    SSPCON2
        BTFSC      SSPCON2,ACKSTAT
        GOTO       I2CRead

        MOVLW      LC01ADDR
        CALL       Send_I2C_Byte

        BANKSEL    SSPCON2
        BTFSC      SSPCON2,ACKSTAT
        GOTO       I2CFail

        BSF        SSPCON2,RSEN
        CALL       WaitMSSP2

        MOVLW      LC01CTRLOUT
        CALL       Send_I2C_Byte

        BANKSEL    SSPCON2
        BTFSC      SSPCON2,ACKSTAT
        GOTO       I2CFail

        BSF        SSPCON2,RCEN

        CALL       WaitMSSP2

        BANKSEL    SSPCON2
        BSF        SSPCON2,ACKDT
        BSF        SSPCON2,ACKEN

        BSF        SSPCON2,PEN
        CALL       WaitMSSP2

        BANKSEL    SSPBUF
        MOVF       SSPBUF,W
        MOVF       PORTD,F

LOOP
        GOTO       LOOP

I2CFail
        BANKSEL    SSPCON2
        BSF        SSPCON2,PEN
        CALL       WaitMSSP2

        BANKSEL    PORTD
        MOVLW      00H
        MOVWF      PORTD
        CALL       ritardo_secondo
        MOVLW      0XFF
        MOVWF      PORTD
        CALL       ritardo_secondo
        GOTO       $-6
Send_I2C_Byte
        BANKSEL    SSPBUF
        MOVWF      SSPBUF

WaitMSSP
        BANKSEL    SSPSTAT
        BTFSC      SSPSTAT,BF
        GOTO        $-1
WaitMSSP2      
        BANKSEL    PIR1
        BCF        PIR1,SSPIF
        BTFSC      PIR1,SSPIF
        GOTO       WaitMSSP
        BCF        PIR1,SSPIF
        RETLW      0


;-------------------- SUBROUTINE RITARDO (30 millisecondi)--------------
RITARDO_30ms
        movlw     1
        movwf     Timer1
loopp1        movlw     39
        movwf     Timer2
loopp2        movlw     255
        movwf     Timer3
loopp3
        decfsz    Timer3,F
        goto      loopp3
        decfsz    Timer2,F
        goto      loopp2
        decfsz    Timer1,F
        goto      loopp1
        return
;-------------------- SUBROUTINE UN SECONDO --------------------------
ritardo_secondo
        movlw     5
        movwf     Timer1
laap1         movlw     199
        movwf     Timer2
laap2         movlw     143
        movwf     Timer3
laap3         nop
        nop
        nop
        nop
        decfsz    Timer3,F
        goto      laap3
        decfsz    Timer2,F
        goto      laap2
        decfsz    Timer1,F
        goto      laap1
        return
;---------------------------------------------------------------------
        end

Quello che ho scoperto, si basa sul fatto che il flag BF (Buffer Full), viene azzerato all' ottavo bit trasmesso. Di conseguenza se al non bit si rileva un ACK/NACK il flag SSPIF dovrebbe esser azzerato anche lui, ma lo è già alla istruzione precedente. Questo non dovrebbe dare risultati aspettati. Se non sbaglio in lettura si riceve solo il primo byte.

Allora voglio vedere, quello che ho scritto nell' articolo precedente, che è estratto dal proton basic.



Anno nuovo, forum nuovo.
Mi sa che lascio.
picmicro675




una ogni 10 livelli


postato il:
19.09.2018, alle ore 23:28
Ho verificato anche quelle del proton basic e fanno il lavoro giusto.
In pratica hai solo i due comandi HBUSIN e HBUSOUT che ricevono e mandano un byte. C'è anche le fasi di controllo ma non mi ricordo.
Ri-vedo che non c'è il controllo di SSPIF, ma direi che sta ad aspettare il BF in ricezione e controlla ACKSTAT per la scruttura.
Mi sovviene che si possa avere il cambio di SSPIF se verrebbe attivato l' interrupt SSPEN.



Anno nuovo, forum nuovo.
Mi sa che lascio.
angelole





postato il:
21.09.2018, alle ore 15:45
picmicro675:
Ci sono le possibilità di usare il debug. Quello hardware (se hai il pickit3 o ICD3) oppure tramite simulatore. Quello compreso in MPLAB (alquanto rustico da usare) oppure quello che uso io.


Di solito un pickit2 microchip ma ho anche un pickit3 (clone), è possibile effettuare un debug hardware? non lo sapevo, come si fa???

[quote]
Comunque mi pare di capire che vuoi fare un orologio con interfaccia LCD, che si trovano a bizzeffe in rete, basta prenderne uno e caricare il codice.
[quote]

Sto realizzando una centralina per il comando di una pompa sommersa, l'orologio serve per attivare la centralina ad una data ora. Gran parte del programma, ivi compresa la gestione dell'orologio, l'ho realizzata e funziona molto bene; manca soltanto l'accesso all'rtc tramite protocollo i2C!
Comunque, se dovessero continuare i problemi col modulo MSSP lo tralascierei scrivendo il codice in maniera diversa! Oggi non posso fare le prove, ma domani dedicherò buona parte della giornata.

Grazie per l'aiuto.

angelole





postato il:
21.09.2018, alle ore 15:48
[quote](picmicro675):Ci sono le possibilità di usare il debug. Quello hardware (se hai il pickit3 o ICD3) oppure tramite simulatore. Quello compreso in MPLAB (alquanto rustico da usare) oppure quello che uso io.
Ora provo a vedere i sorgente e se si trova il problema.
[quote]

Di solito uso un pickit2 microchip ma ho anche un pickit3 (clone), è possibile effettuare un debug hardware? non lo sapevo, come si fa???

[quote](picmicro675):Comunque mi pare di capire che vuoi fare un orologio con interfaccia LCD, che si trovano a bizzeffe in rete, basta prenderne uno e caricare il codice. Per il tuo micro comunque ho visto 2 o 3 progetti, ma difficile che siano scritti in assembly.[quote]

Sto realizzando una centralina per il comando di una pompa sommersa, l'orologio serve per attivare la centralina ad una data ora. Gran parte del programma, ivi compresa la gestione dell'orologio, l'ho realizzata e funziona molto bene; manca soltanto l'accesso all'rtc tramite protocollo i2C!
Comunque, se dovessero continuare i problemi col modulo MSSP lo tralascierei scrivendo il codice in maniera diversa! Oggi non posso fare le prove, ma domani dedicherò buona parte della giornata.

Grazie per l'aiuto.









picmicro675




una ogni 10 livelli


postato il:
21.09.2018, alle ore 20:53
angelole:
Di solito uso un pickit2 microchip ma ho anche un pickit3 (clone), è possibile effettuare un debug hardware? non lo sapevo, come si fa???

Innanzitutto devi attivare il fuse DEBUG_ON, quindi devi predisporre i piedini di programmazione per tenere il debug e in MPLAB(X) configurare il dispositivo di debug e le funzioni di debug.
Ci dovrebbero essere anche le spiegazioni nei fogli dati del 16F87x.

Se poi non riesci a fare la comunicazione con l' MSSP, si trova la versione puramente software in bitbanging.
Sebbene la mia conversione dal proton basic fa il suo dannato lavoro e ti riporta i dati letti nella posizione assegnata all' array DS1307_Array.

Senza contare che potresti convertire il tuo programma in basic e toglierti dagli impicci in "tre balletti". Perché la gestione dei periodi, del display e di lettura e aggiornamento RTC trovi già tutto compreso nei comandi del basic.
Vedi questo orologio
http://digitaldiy.io/articles/mcu-programming/proton-basic/3…
Senza contare che hai già delle routine in assembler funzionanti le puoi includere nel basic e chiamarle come se fossero in basic. Mancherà un certo controllo per quello che è scritto in asm. Comunque si può farlo passare tramite mpasm e rifarlo compilare in MPLAB, O forse l' ultima versione di Proton Basic permette la generazione del COFF, che serve per verificare al simulatore. Se lo usassi.
Le variabili si possono definire in basic e quindi accessibili anche in assembly con lo stesso nome.

Comunque qui ci sono varie routine incluso I2C
http://www.grix.it/UserFiles/picmicro675/File/TransitFiles/a…
Prendi un po di tempo ad individuare la routine che ti serve.

Poi per il progetto che prevedi, direi che anche un 16F628A potrebbe fare il suo lavoro, per comandare una uscita e magari 4 ingressi per i pulsanti del menu. Eccetto se hai già il micro in questione, non vale la pena cambiare.
Se vuoi un aiuto per risolvere il programma nel suo completo, magari metti a disposizione tutto il lavoro (su file hosting da scaricare). Cosicché si possa redarre le problematiche nel suo ambiente reale e possibilmente dare il risultato funzionante nella sua completezza.

una nota: ho cercato di dare delle soluzioni, ma mi sembra che non ha ancora provato ad applicarle. Forse servono maggiori chiarimenti, questo non lo so.



Anno nuovo, forum nuovo.
Mi sa che lascio.
angelole





postato il:
23.09.2018, alle ore 11:10
picmicro675:
una nota: ho cercato di dare delle soluzioni, ma mi sembra che non ha ancora provato ad applicarle. Forse servono maggiori chiarimenti, questo non lo so.


Ti ringrazio veramente, sei stato disponibilissimo. Ho provato i tuoi codici ma non vanno così come non vanno i miei e sinceramente non riesco più a capirne il motivo. Purtroppo non è neppure adottabile un cambio di linguaggio perchè gran parte del lavoro è fatto e funziona bene. Forse l'unica soluzione che rimane è il bitbanging...

Non so, rifletto un po' magari mi viene in mente qualcosa... Ritengo che il problema sia nei settaggi dei registri forse c'è qualcosa che sfugge!

picmicro675




una ogni 10 livelli


postato il:
23.09.2018, alle ore 12:12
angelole:
Purtroppo non è neppure adottabile un cambio di linguaggio perchè gran parte del lavoro è fatto e funziona bene.

Se ci pensi, in genere tutti i linguaggi ad alto livello permetto di inserire routines in assembler. Solo non avviene un controllo. Ma dato che sono già provate non hai rischi.
Ho riprovato le routine convertite dal basic senza avere problemi. Ho notato che non si fa uso di una verifica di SSPIF, che sembra non avere l' effetto dichiarato. Che lo fanno anche le Application Note citate, ma il simulatore non da risposta.
Adesso non capisco perché torturarsi a trovare una circonvallazione al problema.
Ti scrivo due routines da provare.



Anno nuovo, forum nuovo.
Mi sa che lascio.
picmicro675




una ogni 10 livelli


postato il:
23.09.2018, alle ore 13:19
Ho preso dalle routine del Proton Basic e qui ci sono due routines che puoi innestare nel tuo programma.
http://www.grix.it/UserFiles/picmicro675/File/TransitFiles/r…
Forse ci vuole un po di attenzione col fatto di saltare da un banco di memoria ad un altro. Fai attenzione se la compilazione da dei messaggi.
Brevemente spiegato:
ReadRTC :
legge i dati dell' orologio e li copia in RAM in 8 bytes contigui che sono definiti con DS1307_array. La lunghezza è definita fissa, sebbene si potrebbe anche farne una in memoria e alla bisogna variarne la lunghezza per leggere o scrivere dati sul bus I2C. Ovvio che per un singolo byte non conviene chiamare questa routine. si usa direttamente Hbusin.

WriteRTC:
all' incirca come la lettura. Basta preparare i dati nelle locazioni specificate con DS1307_array. e chiamare la routine. Se per una certa necessità non si vuole usare gli stessi bytes, allora si assegna un altro blocco di dati e si cambia il nome che viene caricato nella prima istruzione della routine.

Notare di ricordarsi di impostare l' MSSP. Io ho fatto una prova che mi ero dimenticato e mi stupivo perché non funzionasse.

In somma, certe volte si devono prendere certi pezzi di programma a scatola chiusa (una libreria). Come fosse un trapano, per esempio. Si sa che fa il suo lavoro e si usa come é fatto. Ovvio che per certe condizioni non sarà completamente adatto.

Se trovi dei difetti, chiedi pure.



Anno nuovo, forum nuovo.
Mi sa che lascio.
angelole





postato il:
28.09.2018, alle ore 11:30
Picmicro675: Ti aggiorno...

Ho per il momento usato il metodo bitbanging implementando delle subroutine di prelevate in rete alle quali ho duvuto effettuare opportune (anzi dovute) modifiche. Non volevo fossilizzarmi sul problema del modulo MSSP, figurati che - fatta eccezione del bit start - non sono ancora riusito con detto modulo ad inviare il primo blocco di dati (ossia l'indirizzo deello slave); e siccome devo andare avanti perchè non ho molto tempo, ho deciso di ripiegare sul metodo bitbanging per poi, in un prossimo futuro (quando avrò più tempo), riprendere i codici per cercare di capire quale possa essere il problema!

Detto ciò, come dicevo ho prelevato in rete alcune routine di Davide Bucci, gentilmente messe a disposizione sul web. Purtroppo però ho dovuto modificarle in quanto in alcune circostanze presentavano mal funzionamenti (del resto anche l'autore riferisce che le sue routine "sono presentate così come sono, senza nessuna garanzia di buon funzionamento"). Ho quasi completato tali modifiche manca solo un piccolo problemino che conto di risolvere in queste ore, per il resto riesco a leggere e scrivere col modulo rtc abbastanza agevolmente e correntemente.

Conto, non appena possibile e con i limiti dovuti alla mia cronica mancanza di tempo, di pubblicare su questo sito delle pagine sull'argomento (e sulle modifiche apportate alle routine in questione) in maniera tale da poter essere utile ad eventuali utenti.

Ti ringrazio per la pazienza
picmicro675




una ogni 10 livelli


postato il:
28.09.2018, alle ore 15:55
Se hai bisogno di far presto, forse scrivere in assembly è il meno indicato.
Tenuto conto che altri linguaggi permettono di aggiungere le routine in assembly, forse avresti già completato.
Del resto, ho offerto di dare una mano.



Anno nuovo, forum nuovo.
Mi sa che lascio.
segui questo thread con grixFC, per questa funzione devi aver installato il software grixFC

torna su
     

Come utente anonimo puoi leggere il contenuto di questo forum ma per aprire una discussione
o per partecipare ad una discussione esistente devi essere registrato ed accedere al sito




 







 
 
indietro | homepage | torna su copyright © 2004/2024 GRIX.IT - La community dell'elettronica Amatoriale