- Messaggi: 50
- Ringraziamenti ricevuti 0
Problema RS232 tra PIC e PC
- Ricky85
-
Autore della discussione
- Anziano Utente
-
Less
Di più
14 Anni 2 Mesi fa #1
da Ricky85
Problema RS232 tra PIC e PC è stato creato da Ricky85
Ciao a tutti!
Innanzitutto complimenti per il forum e per il sito, davvero geniale!
Sono un felicissimo "utente" della guida PIC18 step by step e possessore di Freedom II
Sto sviluppando un sistemino per comunicare tra PIC e PC tramite la seriale, l'obbiettivo è quello di poter comandare delle uscite del PIC dal PC e leggere sul PC i valori di alcuni sensori collegati al PIC.
Andando avanti nelle mie prove mi sono "arenato" cercando di mandare al PC il valore di un sensore di temperatura, in pratica quando "spedisco" il valore del sensore al PC a terminale riceve solamente simboli strani. Per inviare dati sulla seriale posso usare due comandi:
WriteUSART che puo spedire solamente un tipo char
putrsUSART che puo spedire stringhe (ma pare non gli piaccia spedire delle variabili)
Di seguito il listato
Sul lato PC sto utilizzando un simil-Hyperterminal che ho trovato in rete (ho i sorgenti e lo sto modificando per le mie esigenze)
Qualcuno puo darmi qualche consiglio per riuscire a mandare questo malefico dato della temperatura al PC?
L'unica possibilità che mi viene ancora in mente è provare a trasformare il dato int in una stringa (o meglio un array di char) e spedire un char per volta, ma non ci sono ancora riuscito!
Grazie! ^^
Innanzitutto complimenti per il forum e per il sito, davvero geniale!
Sono un felicissimo "utente" della guida PIC18 step by step e possessore di Freedom II
Sto sviluppando un sistemino per comunicare tra PIC e PC tramite la seriale, l'obbiettivo è quello di poter comandare delle uscite del PIC dal PC e leggere sul PC i valori di alcuni sensori collegati al PIC.
Andando avanti nelle mie prove mi sono "arenato" cercando di mandare al PC il valore di un sensore di temperatura, in pratica quando "spedisco" il valore del sensore al PC a terminale riceve solamente simboli strani. Per inviare dati sulla seriale posso usare due comandi:
WriteUSART che puo spedire solamente un tipo char
putrsUSART che puo spedire stringhe (ma pare non gli piaccia spedire delle variabili)
Di seguito il listato
Code:
#include <p18f4550.h>
#include <usart.h>
#define LCD_DEFAULT
#include <LCD_44780.h>
#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF
//Prototipo di funzione
int lett_temp0 ();
void main (void){
//*****************************************
// DICHIARAZIONI VARIABILI/COSTANTI
//*****************************************
// Variabile per salvare il dato di ritorno
unsigned char data = 0;
//*****************************************
// SETUP PORT
//*****************************************
// Imposto PORTA tutti ingressi
LATA = 0b00000000;
TRISA = 0b11111111;
// Imposto PORTB tutti ingressi
LATB = 0b00000000;
TRISB = 0b11111111;
// Imposto PORTC tutti ingressi
LATC = 0b00000000;
TRISC = 0b11111101;
// Imposto PORTD tutte uscite
LATD = 0b00000000;
TRISD = 0b00000000;
// Imposto PORTE tutti ingressi
LATE = 0b00000000;
TRISE = 0b11111111;
//*****************************************
// SETUP LCD
//*****************************************
OpenLCD (20);
BacklightLCD (TURN_ON);
//*****************************************
// SETUP ADC
//*****************************************
// Abilito AN0-AN1-AN2 come ingressi analogico
// VREF sono impostate a massa e VCC
ADCON1 = 0b00001101;
// Seleziono AN1 come ingresso
ADCON0 = 0b00001000;
// Imposto i tempi di conversione e giustificazione a destra
// TAD : FOSC/4
// TACQ: 16 TAD
ADCON2 = 0b10110100;
// Abilito l' ADC
ADCON0 |= 0b00000001;
//*****************************************
// SETUP USART
//*****************************************
// Configura l'USART
// 8 bit
// 19200 bit/s
// 1 bit stop
// 0 bit parità
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,
64 );
// Invio la stringa al terminale
putrsUSART ("...start writing: ");
// Invio la stringa all'LCD
WriteStringLCD ("...start writing");
// Attendo di ricevere un dato dal PC
while(!DataRdyUSART( ));
ClearLCD ();
// Ciclo infinito
while(1) {
// Leggo il dato dal buffer di ricezione
data = ReadUSART();
WriteCharLCD (data);
// Invio il carattere al terminale
WriteUSART (data);
// Attendo che il dato venga trasmesso
while (BusyUSART());
// Se premo Back Space pulisco lo schermo
if(data == 0x08) {
ClearLCD ();
}
// Se premo Esc termino l'applicazione
if(data == 0x2B) {
putrsUSART ("Vado a leggere la temp");
while (BusyUSART());
WriteIntLCD (lett_temp0(),2) ;
WriteUSART (lett_temp0());
while (BusyUSART());
}
// Se premo Esc termino l'applicazione
if(data == 0x1B) {
break;
}
// Attendo di ricevere un dato dal PC
while(!DataRdyUSART( ));
}
// Chiudo l'USART
CloseUSART();
// Ripulisco LCD prima di riscrivere
ClearLCD ();
// L'USART è stata chiusa
WriteStringLCD ("RS232 : Closed");
// Ciclo infinito
while (1) {
}
}
int lett_temp0 () {
int temp0;
// Avvio la conversione Analogico/Digitale
ADCON0bits.GO = 1;
// Attendo la fine della conversione
while(ADCON0bits.GO);
// Prelevo il valore della conversione
temp0 = (((int) ADRESH) << 8) | ADRESL;
// 1 shift per avere la temperatura in gradi
// divido cioè per 2
temp0 = temp0 >> 1;
return (temp0);
}
Sul lato PC sto utilizzando un simil-Hyperterminal che ho trovato in rete (ho i sorgenti e lo sto modificando per le mie esigenze)
Qualcuno puo darmi qualche consiglio per riuscire a mandare questo malefico dato della temperatura al PC?
L'unica possibilità che mi viene ancora in mente è provare a trasformare il dato int in una stringa (o meglio un array di char) e spedire un char per volta, ma non ci sono ancora riuscito!
Grazie! ^^
Si prega Accesso o Crea un account a partecipare alla conversazione.
14 Anni 2 Mesi fa #2
da Mauro Laurenti
Risposta da Mauro Laurenti al topic Re: Problema RS232 tra PIC e PC
Ciao Ricky,
benvenuto nel Forum.
Riguardo alla tua domanda assumo che la parte del programma relativa alla visualizzazione delle stringhe sul display funzioni correttamente, visualizzando anche la temperatura. Inoltre assumo che sul terminal riesci a visualizzare le stringhe che invii, eccetto la temperatura. Se non è così hai anche altri problemi.
Relativamente alla temperatura è normale che non riesci ad inviarla poiché il valore letto è un intero.
Mentre le funzioni che hai usato inviano rispettivamente un byte mentre un int è composto da due byte.
Nel caso specifico, visto che le temperature sono basse potresti anche fare un casting in char
WriteUSART ( (char) lett_temp0());
In ogni modo quello che otterresti sul terminal non sarebbe il valore della temperatura ma un carattere strano ASCII associato al valore della temperatura.
Per visualizzare sul terminal direttamente il valore della temperatura devi convertire il valore intero in stringa e poi usare la funzione per inviare la stringa (che di suo non converte in automatico in stringa il valore di un intero).
Per convertire un intero in stringa puoi far riferimento alla seguente funzione (usata nella libreria LCD)
in particolare la funzione di tuo interesse è :
per essere utilizzata devi includere il seguente file:
Saluti,
Mauro
benvenuto nel Forum.
Riguardo alla tua domanda assumo che la parte del programma relativa alla visualizzazione delle stringhe sul display funzioni correttamente, visualizzando anche la temperatura. Inoltre assumo che sul terminal riesci a visualizzare le stringhe che invii, eccetto la temperatura. Se non è così hai anche altri problemi.
Relativamente alla temperatura è normale che non riesci ad inviarla poiché il valore letto è un intero.
Mentre le funzioni che hai usato inviano rispettivamente un byte mentre un int è composto da due byte.
Nel caso specifico, visto che le temperature sono basse potresti anche fare un casting in char
WriteUSART ( (char) lett_temp0());
In ogni modo quello che otterresti sul terminal non sarebbe il valore della temperatura ma un carattere strano ASCII associato al valore della temperatura.
Per visualizzare sul terminal direttamente il valore della temperatura devi convertire il valore intero in stringa e poi usare la funzione per inviare la stringa (che di suo non converte in automatico in stringa il valore di un intero).
Per convertire un intero in stringa puoi far riferimento alla seguente funzione (usata nella libreria LCD)
Code:
//************************************************************
// WriteIntLCD Implementation
//************************************************************
void WriteIntLCD(int value, char number_of_digits){
// The array size is 5 plus end of string \0
unsigned char convertedInt [6];
// Index used to shift to the right the digit
char index;
// Integer is converted to string
itoa (value, (char*) convertedInt);
if (number_of_digits >0 ) {
convertedInt[number_of_digits] = '\0';
// Shift the digit to the right removing the empty one
while (!isdigit(convertedInt[number_of_digits-1])) {
for (index = number_of_digits-1; index > 0; index--){
convertedInt[index] = convertedInt[index-1];
convertedInt[index-1] = ' ';
}
}
}
WriteVarLCD (convertedInt);
}
in particolare la funzione di tuo interesse è :
Code:
// Integer is converted to string
itoa (value, (char*) convertedInt);
per essere utilizzata devi includere il seguente file:
Code:
#include <ctype.h>
Saluti,
Mauro
Si prega Accesso o Crea un account a partecipare alla conversazione.
- Ricky85
-
Autore della discussione
- Anziano Utente
-
Less
Di più
- Messaggi: 50
- Ringraziamenti ricevuti 0
14 Anni 2 Mesi fa #3
da Ricky85
Risposta da Ricky85 al topic Re: Problema RS232 tra PIC e PC
Ciao Mauro,
intanto grazie mille della risposta...
Stasera ho fatto un po di prove ma non ho ancora risolto...
Questo è il codice modificato
Ma quando compilo ricevo questo errore: type mismatch in argument 1
riferito alla chiamata della funzione WriteIntUSART
Mi sta dicendo che il tipo di dato del primo argomento non è giusto... ma la variabile "dato_da_convertire" è un int come richiesto...
Non ci sto capendo più nulla...
Sono ancora troppo "ignorante" in materia, perdonatemi ><
intanto grazie mille della risposta...
Stasera ho fatto un po di prove ma non ho ancora risolto...
Questo è il codice modificato
Code:
#include <p18f4550.h>
#include <usart.h>
#include <ctype.h>
#define LCD_DEFAULT
#include <LCD_44780.h>
#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF
//Prototipo di funzione
int lett_temp0 ();
void WriteIntUSART(int value, char number_of_digits);
void main (void){
//*****************************************
// DICHIARAZIONI VARIABILI/COSTANTI
//*****************************************
// Variabile per salvare il dato di ritorno
unsigned char data = 0;
int dato_da_convertire;
//*****************************************
// SETUP PORT
//*****************************************
// Imposto PORTA tutti ingressi
LATA = 0b00000000;
TRISA = 0b11111111;
// Imposto PORTB tutti ingressi
LATB = 0b00000000;
TRISB = 0b11111111;
// Imposto PORTC tutti ingressi
LATC = 0b00000000;
TRISC = 0b11111101;
// Imposto PORTD tutte uscite
LATD = 0b00000000;
TRISD = 0b00000000;
// Imposto PORTE tutti ingressi
LATE = 0b00000000;
TRISE = 0b11111111;
//*****************************************
// SETUP LCD
//*****************************************
OpenLCD (20);
BacklightLCD (TURN_ON);
//*****************************************
// SETUP ADC
//*****************************************
// Abilito AN0-AN1-AN2 come ingressi analogico
// VREF sono impostate a massa e VCC
ADCON1 = 0b00001101;
// Seleziono AN1 come ingresso
ADCON0 = 0b00001000;
// Imposto i tempi di conversione e giustificazione a destra
// TAD : FOSC/4
// TACQ: 16 TAD
ADCON2 = 0b10110100;
// Abilito l' ADC
ADCON0 |= 0b00000001;
//*****************************************
// SETUP USART
//*****************************************
// Configura l'USART
// 8 bit
// 19200 bit/s
// 1 bit stop
// 0 bit parità
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,
64 );
// Invio la stringa al terminale
putrsUSART ("...start writing: ");
// Invio la stringa all'LCD
WriteStringLCD ("...start writing");
// Attendo di ricevere un dato dal PC
while(!DataRdyUSART( ));
ClearLCD ();
// Ciclo infinito
while(1) {
// Leggo il dato dal buffer di ricezione
data = ReadUSART();
WriteCharLCD (data);
// Invio il carattere al terminale
WriteUSART (data);
// Attendo che il dato venga trasmesso
while (BusyUSART());
// Se premo Back Space pulisco lo schermo
if(data == 0x08) {
ClearLCD ();
}
// Se premo Esc termino l'applicazione
if(data == 0x2B) {
putrsUSART ("Vado a leggere la temp");
while (BusyUSART());
WriteIntLCD (lett_temp0(),2) ;
dato_da_convertire = (lett_temp0(),2);
WriteUSART (WriteIntUSART(dato_da_convertire,2));
while (BusyUSART());
}
// Se premo Esc termino l'applicazione
if(data == 0x1B) {
break;
}
// Attendo di ricevere un dato dal PC
while(!DataRdyUSART( ));
}
// Chiudo l'USART
CloseUSART();
// Ripulisco LCD prima di riscrivere
ClearLCD ();
// L'USART è stata chiusa
WriteStringLCD ("RS232 : Closed");
// Ciclo infinito
while (1) {
}
}
int lett_temp0 () {
int temp0;
// Avvio la conversione Analogico/Digitale
ADCON0bits.GO = 1;
// Attendo la fine della conversione
while(ADCON0bits.GO);
// Prelevo il valore della conversione
temp0 = (((int) ADRESH) << 8) | ADRESL;
// 1 shift per avere la temperatura in gradi
// divido cioè per 2
temp0 = temp0 >> 1;
return (temp0);
}
//************************************************************
// WriteIntLCD Implementation
//************************************************************
void WriteIntUSART(int value, char number_of_digits){
// The array size is 5 plus end of string \0
unsigned char convertedInt [6];
// Index used to shift to the right the digit
char index;
// Integer is converted to string
itoa (value, (char*) convertedInt);
if (number_of_digits >0 ) {
convertedInt[number_of_digits] = '\0';
// Shift the digit to the right removing the empty one
while (!isdigit(convertedInt[number_of_digits-1])) {
for (index = number_of_digits-1; index > 0; index--){
convertedInt[index] = convertedInt[index-1];
convertedInt[index-1] = ' ';
}
}
}
}
Ma quando compilo ricevo questo errore: type mismatch in argument 1
riferito alla chiamata della funzione WriteIntUSART
Mi sta dicendo che il tipo di dato del primo argomento non è giusto... ma la variabile "dato_da_convertire" è un int come richiesto...
Non ci sto capendo più nulla...
Sono ancora troppo "ignorante" in materia, perdonatemi ><
Si prega Accesso o Crea un account a partecipare alla conversazione.
14 Anni 2 Mesi fa - 14 Anni 2 Mesi fa #4
da Mauro Laurenti
Risposta da Mauro Laurenti al topic Re: Problema RS232 tra PIC e PC
Ciao,
districarsi nel programma che hai scritto richiede già una buona comprensione di quello che sia tra ha le mani, per cui sei già a buon punto.
Il compilatore fa bene a reclamare poiché hai usato impropriamente la funzione WriteIntUSART. Quella usata per LCD ritorna un void poiché scrive direttamente sull'LCD il valore d'interesse.
Nel tuo caso dei ritornare il valore della stringa convertita. In particolare poi non puoi usare writeUSART poiché invii solo un byte e non una stringa.
per il tuo esempio usa solo questo pezzo di codice:
in particolare la variabile convertedInt la devi scrivere subito dopo il main assieme alle altre variabili. Dopo itoa la variabile convertedInt contiene la stringa di tuo interesse.
Saluti,
Mauro
districarsi nel programma che hai scritto richiede già una buona comprensione di quello che sia tra ha le mani, per cui sei già a buon punto.
Il compilatore fa bene a reclamare poiché hai usato impropriamente la funzione WriteIntUSART. Quella usata per LCD ritorna un void poiché scrive direttamente sull'LCD il valore d'interesse.
Nel tuo caso dei ritornare il valore della stringa convertita. In particolare poi non puoi usare writeUSART poiché invii solo un byte e non una stringa.
per il tuo esempio usa solo questo pezzo di codice:
Code:
// The array size is 5 plus end of string \0
unsigned char convertedInt [6];
// Integer is converted to string
itoa (value, (char*) convertedInt);
in particolare la variabile convertedInt la devi scrivere subito dopo il main assieme alle altre variabili. Dopo itoa la variabile convertedInt contiene la stringa di tuo interesse.
Saluti,
Mauro
Ultima Modifica 14 Anni 2 Mesi fa da Mauro Laurenti.
Si prega Accesso o Crea un account a partecipare alla conversazione.
- Ricky85
-
Autore della discussione
- Anziano Utente
-
Less
Di più
- Messaggi: 50
- Ringraziamenti ricevuti 0
14 Anni 2 Mesi fa #5
da Ricky85
Risposta da Ricky85 al topic Re: Problema RS232 tra PIC e PC
Grazie ancora Mauro...
Ora sono riuscito ad ottenere qualcosa... ma... sul terminal mi esce una "D" (13 decimale) quando in realtà dovrebbe uscirmi un 23
Questo è il codice attuale...
p.s. ho messo la conversione direttamente nel main per non incasinarmi ulteriormente e fare una funzione extra e provare solamente il codice
Non capisco dove sbaglio... sono ancora "nabbo" per quanto riguarda la programmazione...
Ora sono riuscito ad ottenere qualcosa... ma... sul terminal mi esce una "D" (13 decimale) quando in realtà dovrebbe uscirmi un 23
Questo è il codice attuale...
Code:
#include <p18f4550.h>
#include <usart.h>
#include <ctype.h>
#define LCD_DEFAULT
#include <LCD_44780.h>
#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF
//Prototipo di funzione
int lett_temp0 ();
void WriteIntUSART(int value, char number_of_digits);
void main (void){
//*****************************************
// DICHIARAZIONI VARIABILI/COSTANTI
//*****************************************
// Variabile per salvare il dato di ritorno
unsigned char data = 0;
int dato_da_convertire;
char convertedInt;
//*****************************************
// SETUP PORT
//*****************************************
// Imposto PORTA tutti ingressi
LATA = 0b00000000;
TRISA = 0b11111111;
// Imposto PORTB tutti ingressi
LATB = 0b00000000;
TRISB = 0b11111111;
// Imposto PORTC tutti ingressi
LATC = 0b00000000;
TRISC = 0b11111101;
// Imposto PORTD tutte uscite
LATD = 0b00000000;
TRISD = 0b00000000;
// Imposto PORTE tutti ingressi
LATE = 0b00000000;
TRISE = 0b11111111;
//*****************************************
// SETUP LCD
//*****************************************
OpenLCD (20);
BacklightLCD (TURN_ON);
//*****************************************
// SETUP ADC
//*****************************************
// Abilito AN0-AN1-AN2 come ingressi analogico
// VREF sono impostate a massa e VCC
ADCON1 = 0b00001101;
// Seleziono AN1 come ingresso
ADCON0 = 0b00001000;
// Imposto i tempi di conversione e giustificazione a destra
// TAD : FOSC/4
// TACQ: 16 TAD
ADCON2 = 0b10110100;
// Abilito l' ADC
ADCON0 |= 0b00000001;
//*****************************************
// SETUP USART
//*****************************************
// Configura l'USART
// 8 bit
// 19200 bit/s
// 1 bit stop
// 0 bit parità
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,
64 );
// Invio la stringa al terminale
putrsUSART ("...start writing: ");
// Invio la stringa all'LCD
WriteStringLCD ("...start writing");
// Attendo di ricevere un dato dal PC
while(!DataRdyUSART( ));
ClearLCD ();
// Ciclo infinito
while(1) {
// Leggo il dato dal buffer di ricezione
data = ReadUSART();
WriteCharLCD (data);
// Invio il carattere al terminale
WriteUSART (data);
// Attendo che il dato venga trasmesso
while (BusyUSART());
// Se premo Back Space pulisco lo schermo
if(data == 0x08) {
ClearLCD ();
}
// Se premo Esc termino l'applicazione
if(data == 0x2B) {
putrsUSART ("Vado a leggere la temp");
while (BusyUSART());
WriteIntLCD (lett_temp0(),2) ;
dato_da_convertire = (lett_temp0(),2);
// Integer is converted to string
itoa (dato_da_convertire, (char*) convertedInt);
putrsUSART (convertedInt);
while (BusyUSART());
}
// Se premo Esc termino l'applicazione
if(data == 0x1B) {
break;
}
// Attendo di ricevere un dato dal PC
while(!DataRdyUSART( ));
}
// Chiudo l'USART
CloseUSART();
// Ripulisco LCD prima di riscrivere
ClearLCD ();
// L'USART è stata chiusa
WriteStringLCD ("RS232 : Closed");
// Ciclo infinito
while (1) {
}
}
int lett_temp0 () {
int temp0;
// Avvio la conversione Analogico/Digitale
ADCON0bits.GO = 1;
// Attendo la fine della conversione
while(ADCON0bits.GO);
// Prelevo il valore della conversione
temp0 = (((int) ADRESH) << 8) | ADRESL;
// 1 shift per avere la temperatura in gradi
// divido cioè per 2
temp0 = temp0 >> 1;
return (temp0);
}
p.s. ho messo la conversione direttamente nel main per non incasinarmi ulteriormente e fare una funzione extra e provare solamente il codice
Non capisco dove sbaglio... sono ancora "nabbo" per quanto riguarda la programmazione...
Si prega Accesso o Crea un account a partecipare alla conversazione.
Moderatori: Mauro Laurenti, Pinna, StefA, Matteo Garia
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.
Forum - Ultimi messaggi
-
- progetto can
- da marcelloraja
-
- MODULO GSM SIM900A
- da Mauro Laurenti
-
- Freedom III e compilazioni fallite
- da Mauro Laurenti
-
- Gestione degli errori su comunicazione seriale
- da Mauro Laurenti
-
- Timer0 e interrupt
- da Mauro Laurenti