Vai al contenuto
PLC Forum


Seriale 16F876 - ... sorry ancora io ...


Simons

Messaggi consigliati

Risalve... dopo aver risolto il problema dell'adc chiedo nuovamente consigli.

Vorrei usare il modulo uart che si trova nel pic per trasmettere dati al pc.

per il circuito ok so che ci vuole il RS232

ma per le routines di invio e ricezione non sono pratico.

potete illustrarmene qualcuna per favore?

uso CCS C Compiler...

grazie 1000 davvero a chi mi aiuta..

:)Simons

Link al commento
Condividi su altri siti


Se usi CCS hai parecchi esempi (quelli allegati nel direttorio "examples".

In pratica devi gestire solo laricezione usando l'interrupt, per la trasmissione ti basta usare "printf()" e fa tutto il compilatore.

Link al commento
Condividi su altri siti

grazie .. non ci avevo pensato..

secondo te potrebbe andare bene una routine così:

#int_RDA
RDA_isr()
{
char buffer;
long adc,i;
buffer=getch();
   if (buffer=="READ_TEMP")
      {
            adc=0;
            for(i=0;i<10;i++)
            {
                adc+=read_adc();
            }
            adc=adc/10;
            printf("Valore ADC: %lu",adc);
      }
}

grazie smile.gif

Link al commento
Condividi su altri siti

Se dichiari un buffer di un carattere la routine non funzionerà mai perchè non si realizza la condizione di eguaglianza "(buffer=="READ_TEMP")". Devi fare un array se vuoi confrontare la stringa. Io però ti consiglio di inviare un comando costituito da due caratteri più un Cr e Lf, sul tipo: "RT\r\n" Fai il test sull'uguaglianza di 4 caratteri in sequenza: 0x52, 0x54, 0x0A, 0x0D.

Poi la lettura e le stampa falli fuori dalla routin di interrupt come anche il test, magari nel main.

Ti allego il codice della mia routin standard di ricezione.

#int_RDA
RDA_isr()

{

     char ibuff_Rx[16]; //array di ricezione
     int iRxpnt = 0;  //puntatore all'array di ricezione

      ibuff_Rx[iRxpnt] = getc();
      iRxpnt++;
      enable_interrupts (INT_RDA);
      if (iRxpnt>=16){
                            iRxpnt = 0;
      }
}

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

Livio Orsini+7/06/2007, 16:23--> (Livio Orsini @ 7/06/2007, 16:23)

grazie...

puoi spiegarmi meglio la routine che mi hai postato? quando viene chiamata, ecc...

grazie 1000 Livio! smile.gif

Link al commento
Condividi su altri siti

la devi chiamare nel INR_RDA , in quanto acquisisce un carattere per volta .

Seno puoi usare una funzione che non ricordo , vedi manuale ccs , che restituisce true se nella uart c'e' un byte ricevuto e poi bufferizzi come postato .

Questo metodo , se hai un programma lungo , non va bene , in quanto prima che nel main ti accorga di avere un byte ricevuto , potresti averne ricevuto altri e perderli con tutto il disagio conseguente .

Quindi usa sempre l'interrupt in ricezione e poi bufferizzi come ti ha detto Livio .

Piccola parentesi , usare i puntatori o gli array e' la stessa cosa in ansi C .L'indice dell'array altra non e' che un putnatore ad un'area definita con la dichiarazione di array . wink.gif

In poche parole ricevi semrpe su interrupt, bufferizzi incrementando in contatore oppure controllando la stringa finale e crea una specie di protocollo tra chi riceve e chi spedisce , in modo tale da sincronizzare il tutto .

Magari implementa un protocollino , tipo modbus seriale , scaricabile gratis in rete , in modo tale che avere un sincronismo , seno rischi che uno scrive sempre , l'altro non riceve mai e cosi diventi pazzo .

Se poi hai diversi devices slaves con un master ti conviene creare e stabilire una tabella di comunicazione dove specifichi gli indirizzi dei nodi , cosa scrivere , perche , e quando con i rispettivi controlli.

Le risorse , in una comunicazione , vengono penalizzate quando devi eseguire l'algoritmo CRC per la verifica dei dati

ciao

walter

Link al commento
Condividi su altri siti

Ti ho modificato la routine perchè sia completa di interrupt.

Ogni volta che l?UART riceve un carattere scatta l'interrupt. Il carattere viene messo nell'elemento dell'array puntato da iRxpnt, iRxpnt viene incrementato, se raggiunge il valore limite (16 p.e.) viene riazzerato in modo che si abbia una spece di buffer circolare; l'interrupt viene riabilitato e, in attesa di un eventuale nuovo carattere ricevuto, il programma torna da dove era aprtito.

In un'altra routine andrai a verificare il contenuto del buffere, se il contenuto coincide, p.e., con il comando di lettura di temperatura azzeri puntatore e buffer ed esegui il comado.

La routune di servizio dell'interrupt deve essere sempre la più breve possibile per evitare di mettere il processore in hung-up

Link al commento
Condividi su altri siti

Grazie mille siete davvero un pozzo di scienza worthy.gifclap.gif

l'unica domanda:

queste due variabili

char ibuff_Rx[4]; //array di ricezione

int iRxpnt = 0; //puntatore all'array di ricezione

devo dichiararle fuori dallo scope di RDA_isr() altrimenti come faccio ad accedere all'array ad esempio nella main?

scusate l'ignoranza.. ma come mai se eseguo:

if(ibuff_Rx=="READ")

mi dà "Bad Expression syntax" ? e mi evidenzia l'ultima parentesi..

scusate sono proprio duro di comprendonio sad.gif

Modificato: da Simons
Link al commento
Condividi su altri siti

ibuff_Rx è l'indirizzo del primo elemento dell'array e quindi non può essere confrontato con la stringa "READ". Quello che puoi fare è del tipo

ibuff_Rx[0] == 'R'

cioè puoi operare solo su un elemento alla volta dell'array.

Per operare sulle stringhe il compilatore CCS mette a disposizione alcune funzioni che trovi nel manuale.

Se posso darti un consiglio inizia con l'inviare un comando di un solo carattere per iniziare, per esempio 'r' o 'R' poi quando la comunicazione funziona passi alle stringhe.

Ciao.

Link al commento
Condividi su altri siti

devi usare una funzione del compilatore per il confronto oppure scrivila tu

int CheckStringa(char *stringa1,char *stringa2)

{

int i;

if(stringa1[0]==stringa2[0] && stringa1[1]==stringa2[1] ...ect

return 1;

}

Puoi anche usare un ciclo for

Dall'esterno :

char stringa1[4]="READ";

char stringa2[4]=tuoArrayRicezione;

if CheckStringa(stringa1,stringa2)

{

//eseguo comando specifico

}

Prova a lavorarci sopra se non c'e' una funzione di compare di array di caratteri (stringa)

ciao

walter

Link al commento
Condividi su altri siti

Ti do il medesimo consiglio di giacomo56. Prova a lavorare iniziando con il riconoscimento di un singolo carattere. Tra l'altro la comparazione di stringhe mangia parecchia memoria e i PIC non ne hanno tanta. Il metodo più semplice è comparare i carateri uno alla volta facendo un "for".

Se dichiari l'array, ed il relativo puntatore, prima del codice assegni a queste variabili un'area di memoria statica e pubblica a cui possono accedere tutte le funzioni.

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