Newsgroup: it.hobby.elettronica.digitale
Titolo: Sincronizzarsi con il clock

Ciao,
domanda forse ingenua, ma pur conoscendo l'ASM non l'ho mai usato molto
nella pratica. 
Ho un dispositivo master che mi invia periodicamente dei cicli di clock con
periodo di 4 us; su una linea dati devo scrivere i bit sul fronte di
discesa del clock, dati che verranno letti sul fronte di salita successivo.
Premetto che non è un protocollo standard per cui non ci sono funzioncine
già pronte (Ci sono altre linee da gestire per la comunicazione).
Ad ogni modo, nella mia ingenuità per sincronizzarmi con il clock ho fatto
una cosa del genere (uso MPASM della Microchip):
write   bcf     STATUS, RP0
        movlw   8
        movwf   i               ; i = 8
 
ready   btfsc   vDTA, 0         ; if (vDTA == 1)
        goto    send1   
 
send0   btfsc   PORTC, CLK      ; while(clk == 1)
        goto    send0
 
        bsf     STATUS, RP0
        bcf     TRISC, DTA
        bcf     STATUS, RP0
        goto    next
 
send1   btfsc   PORTC, CLK      ; while(clk == 1)
        goto    send1
        bsf     STATUS, RP0
        bsf     TRISC, DTA
        bcf     STATUS, RP0
 
next    rrf     vDTA, 1         ; vDTA >> 1
wclk0   btfss   PORTC, CLK      ; while(clk == 0)
        goto    wclk0
        decfsz  i, 1            ; if (--i == 0)
        goto    ready           ; 
        return
Il PIC ha un quarzo da 20MHz -> 200 ns a istruzione. Ogni stato logico del
clock dura 2 us, considerando i tempi di salita sul bus (quando imposto il
pin come ingresso la velocità di salita è definita dal pull-up del bus. Ho
messo anche resistenze di basso valore per diminuire i tempi) dell'ordine
di almeno un centinaio di ns, restano poche istruzioni prima del fronte di
salita successivo.
Come si può ottimizzare la routine sopra scritta? In particolare non mi
piacciono:
+ i cicli di attesa per i fronti del clock ma non ho idea se ci sono
alternative.
+ con btfss (o btfsc) posso verificare lo stato di un bit, ma deve essere
per forza 'literal'? Non posso passargli una variabile (contenente un
valore tra 0 e 7)?
+ perdo un sacco di tempo a dover a selezionare il bank per accedere a PORTC
o a TRISC... non si può fare nulla in proposito?
Ciao e grazie in anticipo
Marco / iw2nzm




 Ciao, Riccardo.
Si, ma io parlavo si scrittura sul bus. Ho provato a usare gli interrupt ma
sono lenti e non è definito con certezza il numero di istruzioni che
passano dal cambio fisico del fronte del clock sul pin a quando verrà
gestito l'interrupt. Avrei quindi un jitter che mi può portare nel caso
peggiore oltre il fronte di salita successivo. Ricordo che ho 2 us di
tempo, meno il tempo di commutazione del bus, a 20 MHz restano 7-8
istruzioni... scatenare l'int, gestirlo e scrivere sul bus non mi sembra
fattibile.
Ciao!
Marco / iw2nzm
ps. ovvio che potrei usare un micro più veloce.... ma dovrei proprio
cambiare famiglia!

 fattibile.
La latenza dell'interrupt del pin RB0 è descritta bene nel datasheet del
micro.
Ad esempio 
http://ww1.microchip.com/downloads/en/DeviceDoc/30235j.pdf
,
(pag.56).
Come si vede dalla figura il numero di istruzioni che passano dall'evento di
interrupt a quando verrà eseguita la prima istruzione dell'interrupt è un
numero deterministico ed è definito con certezza.
Nel caso dell'interrupt questo numero di istruzioni potrà essere troppo
grande per la tua applicazione, ma è sempre lo stesso.
Quindi non si hanno jitter o meglio hai lo stesso jitter che hai nel caso in
cui non usi l'interrupt come stai facendo ora.

 "Marco Trapanese" ha scritto


 in cui non usi l'interrupt come stai facendo ora.
Giusto, hai ragione. Avevo letto un documento che lamentava un'incertezza di
1-2 istruzioni sulla latenza dell'interrupt. Ma allora ricordo male io e
non si riferiva all'int esterno.
Quello che mi preme capire è se il codice che ho postato è scritto
decentemente oppure si presta a ulteriori ottimizzazioni (in termini di
tempi).
Grazie a entrambi per gli interventi
Marco / iw2nzm