PDA

View Full Version : Seriale


LimiT-MaTz
22-02-2006, 11:35
Ciao a tutti,

Ho "costruito" un device composto da 2 microcontrollori che devono lavorare (cooperare).

Dapprima mi son occupato della parte ricevente, invio dati dal pc sulla porta seriale e questi vengono analizzati perfettamente e processati dal microcontrollore.
Ok la parte ricevente del dispositivo sono sicuro al 100% che funzioni correttamente.

Ora andiamo a occuparci della parte trasmittente, per prova ora impostiamo il tutto in modo che mandi sulla Seriale una Serie di ('A') infinite.
Ok, a questo punto proviamo a collegare l'uscita del dispositivo trasmittente a quello ricevente.
Il dispositivo si "accorge" che sta ricevendo una serie di 'A'
Ora colleghiamo il tutto a un PC.
Con windows => apro hyperterminal e imposto 9600 bps 8 bit no bit parità
e vedo lo schermo riempirsi di 'A'
Perfetto funziona.
Ora andiamo a scrivere un programmino Prova per linux:


#include <iostream>
#include <stdio.h>
#include <cstring>
#include <cstdlib>
#include <fstream.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>

using namespace std;


int main(int argc , char **argv)
{
char *buff;
int cont=0;
buff = new char[10];
int seriale = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if(seriale == -1){
cout<<"ERROR:"<<endl;
cout<<" Cannot Open Device < "<<endl;
exit(1);
}
struct termios options;
tcgetattr(seriale, &options);
cfsetispeed(&options ,B9600);
cfsetospeed(&options ,B9600);
// struttura lungezza
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
// struttura tempi
options.c_cc[VMIN]=0;
options.c_cc[VTIME]=1;
//
options.c_cflag |= (CLOCAL | CREAD);
if(tcsetattr(seriale, TCSANOW, &options) != 0){
cout<<"ERRORE"<<endl;}
while(1)
{
if(cont=read(seriale,buff,10)>0)
cout<<buff<<endl;
cout<<c
}
return 0;
}


A prescindere dalla schifezza in se (mi serve solo da test) andiamo a leggere...
e voila:
Non legge nulla
Cosa peggiore manda una serie di segnali (che non mi e' facile decifrare) sulla linea di send

il problema quindi e' sicuramente di impostazione della seriale

Ho scritto anche un altro programmino (che da pc invia alla seriale) con le stesse opzioni di sopra e questo va a scrivere perfettamente.

Sapreste aiutarmi?

ilsensine
22-02-2006, 12:27
Io toglierei anche CRTSCTS da c_cflag. CLOCAL disabilita le linee di controllo dei modem (DTR/DSR/RI), ma non ha effetti su RTS e CTS.

Già che ci sei, togli anche IXON|IXOFF e imposta
options.c_cc[VSTART] = _POSIX_VDISABLE;
options.c_cc[VSTOP] = _POSIX_VDISABLE;


Provato anche con minicom se riceve qualcosa?

LimiT-MaTz
22-02-2006, 12:59
minicom impostato con (9600 bps no bit parità 8 bit nessun controllo del flusso)
non mi visualizza nulla ma mi permette di scrivere.

#include <iostream>
#include <stdio.h>
#include <cstring>
#include <cstdlib>
#include <fstream.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>

using namespace std;


int main(int argc , char **argv)
{
char *buff;
int cont=0;
buff = new char[10];
int seriale = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
if(seriale == -1){
cout<<"ERROR:"<<endl;
cout<<" Cannot Open Device < "<<endl;
exit(1);
}
struct termios options;
tcgetattr(seriale, &options);
cfsetispeed(&options ,B9600);
cfsetospeed(&options ,B9600);
// struttura lungezza
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag &= ~CRTSCTS;
options.c_cflag &= ~IXON;
options.c_cflag &= IXOFF;
options.c_cflag |= CS8;
// struttura tempi
options.c_cc[VMIN]=0;
options.c_cc[VTIME]=1;
options.c_cc[VSTART] = _POSIX_VDISABLE;
options.c_cc[VSTOP] = _POSIX_VDISABLE;
//
options.c_cflag |= (CLOCAL | CREAD);
if(tcsetattr(seriale, TCSANOW, &options) != 0){
cout<<"ERRORE"<<endl;}
while(1)
{
if(cont=read(seriale,buff,10)>0)
cout<<buff<<endl;
cout<<"cont -> "<<cont<<endl;
}
return 0;
}

con questo codice continuo a vedere usa serie di "segnali" in uscita dal pc.
la situazione si fa drammatica :)

ilsensine
22-02-2006, 15:09
options.c_cflag &= IXOFF;

typo?

ilsensine
22-02-2006, 15:10
con questo codice continuo a vedere usa serie di "segnali" in uscita dal pc.

Cosa intendi per..."in uscita"?

LimiT-MaTz
22-02-2006, 15:21
Cosa intendi per..."in uscita"?

se avessi un oscilloscopio sarebbe tutto piu' semplice.
Comunque intendo dire che se invio da dispositivo a pc succede che mi trovo una serie di segnali per me anomali che non vorrei assolutamente sul "filo" che viene usato dal PC per mandare dati al dispositivo.

Capito cosa intendo? (sono molto contorto lo capisco).

Per quanto riguarda minicom funziona perfettamente vedo (una serie di AAAAAAAA).
Il problema risiede quindi nel mio programma.

LimiT-MaTz
22-02-2006, 15:25
typo?

options.c_iflag &= IXOFF;

da man termios


c_iflag flag constants:
...
IXOFF Enable XON/XOFF flow control on input.

LimiT-MaTz
22-02-2006, 15:33
per errore ho lanciato il mio programmino mentre minicom era in esecuzione e ... in questo caso funziona correttamente, boh vai a sapere.

non ci capisco piu' nullla :doh:

ilsensine
22-02-2006, 16:55
se avessi un oscilloscopio sarebbe tutto piu' semplice.
Comunque intendo dire che se invio da dispositivo a pc succede che mi trovo una serie di segnali per me anomali che non vorrei assolutamente sul "filo" che viene usato dal PC per mandare dati al dispositivo.

Sicuro che sta sul pin tx e non gli altri? (ad es. quelli di controllo, che dovrebbero essere defunti)

options.c_iflag &= IXOFF;
options.c_iflag &= ~IXOFF;

ilsensine
22-02-2006, 16:59
per errore ho lanciato il mio programmino mentre minicom era in esecuzione e ... in questo caso funziona correttamente, boh vai a sapere.

Fai un programmino che esegue una tcgetattr e stampa i risultati; eseguilo mentre minicom è in esecuzione e controlla come viene impostata la porta...

VICIUS
22-02-2006, 17:04
[...]
options.c_cflag &= ~CSIZE;
[...]
Probabilmente anche questa è sbagliata. Dovrebbe essere una mask per ricavare la dimensione del frame.

ciao ;)

ilsensine
22-02-2006, 17:12
Probabilmente anche questa è sbagliata. Dovrebbe essere una mask per ricavare la dimensione del frame.

Infatti dopo imposta CS8

LimiT-MaTz
22-02-2006, 17:58
Fai un programmino che esegue una tcgetattr e stampa i risultati; eseguilo mentre minicom è in esecuzione e controlla come viene impostata la porta...

questo e' il risultato:

tcgetattr
c_cflag -> 10111101001101111111111111111110
c_iflag -> 10000000000000000000000000000000
c_oflag -> 00000000000000000000000000000000
c_lflag -> 00000000000000000000000000000000

ora devo impostare questi valori nella struttura ma non so come fare.

ilsensine
23-02-2006, 08:14
Ehm...ho il dubbio che la posizione dei bit l'hai invertita in qualche modo...a meno che non stai usando la seriale alla velocità di 3.5Mbit :D

Puoi far stampare i valori in esadecimale (printf("%08x\n", val) ) così non ci sono ambiguità?

LimiT-MaTz
23-02-2006, 09:21
eh eh :)

c_cflag -> 00000cbd
c_iflag -> 00000001
c_oflag -> 00000000
c_lflag -> 00000000


cmq con queste flag sembra funzionare:

options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;

options.c_iflag &= ~(IXON | IXOFF | IXANY);
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;

ilsensine
23-02-2006, 09:49
Ahh così è meglio.
0xcbd = B9600|CS8|CREAD|HUPCL|CLOCAL

Chissà perché pima non funzionava...credo per ICANON (mi sono scordato di dirti di levarlo)

LimiT-MaTz
23-02-2006, 09:53
bene, ti ringrazio.
ora sono al punto di partenza :)

Grazie ancora per il tempo "perso".!!!