Vai al contenuto
PLC Forum


Programmazione pic


DavidOne71

Messaggi consigliati

Buongiorno a tutti, spero riesca a farmi capire perchè la cosa è abbastanza complicata, almeno credo.

Ho due schede e comunicano tra di loro in modo seriale usando 2 pic.

La scheda A invia una sequenza di byte 1 volta ogni 1/2 secondo circa, la scheda B è pronta a riceverli in qualsiasi momento usando l'interrupt sull'ingresso.

Appena ricevuti i byte la scheda B esegue una routine che impiega circa 3 secondi ovviamente questa verrà interrotta dalla trasmissione dati almeno qualche volta.

Per gestire errori di comunicazione e vari interruttori sulla scheda B, avrei bisogno che il programma principale (scorra) cioè eseguire istruzioni nei 3 secondi di cui sopra senza dover perdere la comunicazione seriale.

Qualcuno avrebbe qualche idea per implementare il codice?

Grazie mille

Saluti

Link al commento
Condividi su altri siti


Attivo un buzzer: 80ms on 80 ms off e questo si ripete x 20 volte più una pausa di 2 sec.

In effetti avevo detto circa 3 sec ma facendo i conti sono 5,2 s

Il buzzer viene attivato dalla seriale e in + accende anche un led.

Il led viene acceso per la durata effettiva del segnale proveniente dalla scheda A (può variare da 0 s a infinito) invece il buzzer viene attivato dal segnale della scheda A ma viene spento dalla scheda B nei tempi di cui sopra.

Intendi la B?

Fa quello che ho detto sopra e gestirà: degli interruttori, anomalie di trasmissione e ricezione ecc..

Link al commento
Condividi su altri siti

cosa usi come compilatore?

in che modo fai suonare il buzzer? con un interrupt o routine di delay? sarebbe meglio gestirlo con gli interrupt perlomeno il programma continua a girare e non dorme in quei ms del delay

Link al commento
Condividi su altri siti

MPASM penso huh.gif

Comunque l'assembler dentro MPLAB IDE 8.14

Una routine di delay

Sarei anche d'accordo, ma se l'interupt lo uso già per sentire l'ingresso seriale come fa a gestire anche il buzzer?

Ho appena finito ieri il codice per gestire il ritardo senza che dormi.

Un pò complicato direi, comunque rimango sempre in attesa di qualche idea..

Link al commento
Condividi su altri siti

#int_ext

void Timer10ms()

{

set_timer1(0xB1DF); // Caricato 15535 ==>

// 20.000 * 4 * 125nsec = 10msec

// 65535 - 20000 = 45535(0xB1DF)

rd_ad ();

if ( time_data >0)

{

time_data--;

}

else

{

time_data = 5;

}

}

#INT_RDA

Rx_232()

{

ibuff_Rx[iRxpnt] = getc();

iRxpnt++;

enable_interrupts (INT_RDA);

if (iRxpnt>=16){

iRxpnt = 0;

}

}

Sono due funzioni scritte in "C", io scrivo praticamente solo in "C" e, al limite, ottimizzo pezzi in asm, però la filosofia degli interrupts non cambia

Link al commento
Condividi su altri siti

Si il primo è l'interrupt ogni 10ms, con quarzo da 8 MHz.

In pratica abiliti l'interrupt di TMR1 e, quando scade TMR1, nella routine di servizio lo ricarichi con il complemento a FFFFh

Il secondo è l'interrupt di ricezione della seriale.

Link al commento
Condividi su altri siti

la domanda mi sorge spontanea!

Ma se si attiva l'interrupt dei 10ms e faccio suonare il buzzer, riesce a sentire anche l'interrupt della seriale? o deve prima finire l'interrupt di cui sopra huh.gif

Link al commento
Condividi su altri siti

In caso di concomitanza viene servito per primo l'interrupt con maggior priorità, l'altro (o gli altri) rimangono pendenti sino quando, terminata la routine di servizio, si riabilitano gli interrupts.

Puoi sceglere se riabilitare subito gli interrupt dopo la prima riga della routine di servizio, o immediatamente prima del ritorno, o in qualsiasi altro punto.

L'unico problema che può nascere con l'uso di interrupts multipli è che la coda di interruots pendenti si allunghi troppo. Per evitare uesto bisogna valutare bene l'impegno del tempo di CPU per ogni servizio all'interruot e la sua frequenza.

Da come descrivi il tuo problema non credo che tu possa incorrere in questa disavventura, a meno di errori di programamzione.

Link al commento
Condividi su altri siti

Questa cosa della priorità mi interessa, avevo letto qualcosa ma pensavo solo per certi pic, io uso il 16F690 e il 12F629.

Cavolo domani parto per le ferie biggrin.gif e torno fra due settimane, mi documenterò e se c'è qualcosa farò qualche prova ma penso che ci sentiremo ancora..

Per il momento 1000 grazie

Un saluto a tutti

Link al commento
Condividi su altri siti

  • 4 weeks later...

Ciao a tutti, eccomi ancora quà alle prese con questi maledetti interrupts.. wallbash.gif

ho fatto delle prove ed ho attivato l'interrupt del timer insieme all'interrupt della porta GP2 ext.

Se c'è una richiesta di interrupt da parte del tmr ed eseguo il codice e mettiamo il caso che impieghi una 50ina di us, in questo lasso di tempo arriva il segnale per la comunicazione seriale, l'interrupt della seriale non parte fino a quando non ha finito quella del timer, perdendo così la comunicazione huh.gif

Sbaglio qualcosa?

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...