Forum » Programiranje » c++ serijski port
c++ serijski port
fogl ::
Zanima me, če ve kdo za kak programček, ki ti pošilje podatke na serijski port (pa da lahko določim protokol in hitrost).
lp, klemen
jype ::
Kaksen protokol? Saj serijski porti so RS232 protokol, a niso?
Na unixih je to razmeroma enostavno:
f = fopen("/dev/ttyS0", "r+");
fwrite(f, "to gre na serijski port\n");
fclose(f);
Ce zelis spreminjat hitrost, start bit, stop bits in parity, potem napisi man ioctl in preberi (mogoce ne pise v ioctl man page, tudi google zna pri tem pomagat).
Na unixih je to razmeroma enostavno:
f = fopen("/dev/ttyS0", "r+");
fwrite(f, "to gre na serijski port\n");
fclose(f);
Ce zelis spreminjat hitrost, start bit, stop bits in parity, potem napisi man ioctl in preberi (mogoce ne pise v ioctl man page, tudi google zna pri tem pomagat).
fogl ::
Kot protokol sem mislil stop bit, start bit, število data bitov...
Našel sem programček na http://www.codeproject.com/system/cserialport.asp , ki naj bi funkcioniral (dobil je dobre ocene), meni pa vrže 90 napak.
Mi lahko nekdo pove kako se to spravi skupej da deluje?
Našel sem programček na http://www.codeproject.com/system/cserialport.asp , ki naj bi funkcioniral (dobil je dobre ocene), meni pa vrže 90 napak.
Mi lahko nekdo pove kako se to spravi skupej da deluje?
lp, klemen
fogl ::
Sedaj mi najde samo še eno napako in dva opozorila:
--------------------Configuration: SerialPort - Win32 Unicode Debug--------------------
Compiling resources...
Compiling...
app.cpp
c:\documents and settings\klemen\desktop\serial port\kl\cserialport_src\app.cpp(103) : warning C4189: 'dwRead' : local variable is initialized but not referenced
SerialPort.cpp
c:\documents and settings\klemen\desktop\serial port\kl\cserialport_src\serialport.cpp(395) : warning C4189: 'dwBytesWritten' : local variable is initialized but not referenced
StdAfx.cpp
Linking...
xilink6: executing 'C:\PROGRA~1\MICROS~3\VC98\Bin\link.exe'
LINK : fatal error LNK1104: cannot open file "mfc42ud.lib"
Error executing xilink6.exe.
SerialPort.exe - 1 error(s), 2 warning(s)
Kaj to pomeni, od kje mu ta fajl?
--------------------Configuration: SerialPort - Win32 Unicode Debug--------------------
Compiling resources...
Compiling...
app.cpp
c:\documents and settings\klemen\desktop\serial port\kl\cserialport_src\app.cpp(103) : warning C4189: 'dwRead' : local variable is initialized but not referenced
SerialPort.cpp
c:\documents and settings\klemen\desktop\serial port\kl\cserialport_src\serialport.cpp(395) : warning C4189: 'dwBytesWritten' : local variable is initialized but not referenced
StdAfx.cpp
Linking...
xilink6: executing 'C:\PROGRA~1\MICROS~3\VC98\Bin\link.exe'
LINK : fatal error LNK1104: cannot open file "mfc42ud.lib"
Error executing xilink6.exe.
SerialPort.exe - 1 error(s), 2 warning(s)
Kaj to pomeni, od kje mu ta fajl?
lp, klemen
fx ::
jype jaz sem uporabil, to kar si napisal, samo nevem kako naj deklariram f, ker mi prevajalnik javi napako, ker ni deklariran.
lp
"Naj živ Unix"
lp
"Naj živ Unix"
fx ::
Mene pa zdaj zanima zakaj mi prevajalnik javlja napako, še pa sem tako naredil, kot mora biti, vse sem preveril in je ne najdem:
/usr/include/stdio.h: In function `void Send(int)':
/usr/include/stdio.h:609: error: too few arguments to function `size_t
fwrite(const void*, unsigned int, unsigned int, FILE*)'
slo_tech.cpp:64: error: at this point in file
to pa je koda:
/usr/include/stdio.h: In function `void Send(int)':
/usr/include/stdio.h:609: error: too few arguments to function `size_t
fwrite(const void*, unsigned int, unsigned int, FILE*)'
slo_tech.cpp:64: error: at this point in file
to pa je koda:
void Send(int number) { FILE *x; x = fopen("/dev/ttyS0", "r+"); fwrite(x, number); fclose(x); cout << "hex = " << hex << number << endl; cout << "dec = " << dec << number << endl; } lp <b>"Naj živi UNIX"</b>
Zgodovina sprememb…
- spremenil: fx ()
OwcA ::
Saj ti lepo pove, premalo (in za povrh še v napačnem redu) argumentov podaš fwrite().
Otroška radovednost - gonilo napredka.
fx ::
int serial_setspeed(int fd) { struct termios tc; tcgetattr(fd, &tc); cfsetspeed(&tc, B2400); tcsetattr(fd, TCSANOW, &tc); return 0; } void Send(int number) { serport = open("/dev/ttyS0", O_RDWR); serial_setspeed(serport); write(serport, &number, sizeof(number)); close(serport); }
To kodo je napisal trs, mislim da ga poznate iz irc, samo ga zdaj nemorem dobiti. In me zanima kako bi nastavo v tem podatkovni bit, parnost in zakljiučni bit.
lp
"Naj živi UNIX"
fx ::
Da ne boste mislili da nisem prebal ioctl page, sem samo to je tako splošno da si jaz nemorem nič pomagati.
lp
"Naj živi UnIX"
lp
"Naj živi UnIX"
Vesoljc ::
special bite (pariteta, zakljucni, itd...) so (kolikor je to meni jasno) vkljuceni v sporocilo, ki ga posljes. v tvojem primeru je to sporocilo dolgo 32bitov (int). imas torej vsaj dve moznosti, povecas velikost (64), ali pa zmanjsas "svoje" sporocilo, ki je v biti int. ko tako dobis prostor za dodatne bite, jih le-te vkljucis v spremenljivko sz pomocjo bitnih operacij (go google for bitwise operations).
pa se ena stvar: ko reces send, ji podas parameter po vrednosti. ustvari se zacasna spremenljivka znotraj tvoje funkcije, ki se ji pripise vrednost podanega parametra. zatorej sklicevanje na "&number" ni najbolj "cisto", ceprav v tem primeru verjetno dela...
pa se ena stvar: ko reces send, ji podas parameter po vrednosti. ustvari se zacasna spremenljivka znotraj tvoje funkcije, ki se ji pripise vrednost podanega parametra. zatorej sklicevanje na "&number" ni najbolj "cisto", ceprav v tem primeru verjetno dela...
Abnormal behavior of abnormal brain makes me normal...
fx ::
#include <unistd.h> #include <fcntl.h> #include <termios.h> #include <string.h> #include <errno.h> #include <stdio.h> #define SET_MASK(var, mask, bits) var = ((var) & ~(mask)) | ((bits) & (mask)) #define SET_BITS(var, mask) var |= ~(mask) #define CLR_BITS(var, mask) var &= ~(mask) /* * serial_setparam: * fd - this is the file descriptor of the serial port * baudrate - the desired baud rate, currently only 2400 bauds is * supported * bits - bit size, valid values are from 5 to 8 bits. * parity - this can be either 'N', 'E' or 'O' with the following * meanings: * 'N' - NO PARITY * 'E' - EVEN PARITY * 'O' - ODD PARITY * stopbits - either 1 or 2, representing the number of stop bits * softflow - boolean, 0 for hardware flow control, 1 for software */ int serial_setparam(int fd, int baudrate, int bits, char parity, int stopbits, int softflow) { struct termios tc; int retval; /* GET ATTRIBUTES */ retval = tcgetattr(fd, &tc); if (retval != 0) { fprintf(stderr, "tcgetattr() failed: %s\n", strerror(errno)); return 1; } /* SET BAUD RATE */ /* XXX: This sucks ;) */ if (baudrate != 2400) { fprintf(stderr, "Unsupported baud rate %d\n", baudrate); return 1; } retval = cfsetspeed(&tc, B2400); if (retval != 0) { fprintf(stderr, "cfsetspeed() failed: %s\n", strerror(errno)); return 1; } /* CLEAR ALL FLAGS */ CLR_BITS(tc.c_cflag, PARENB | PARODD | CSIZE | CSTOPB); /* SET BITS */ switch (bits) { case 5: SET_BITS(tc.c_cflag, CS5); break; case 6: SET_BITS(tc.c_cflag, CS6); break; case 7: SET_BITS(tc.c_cflag, CS7); break; case 8: SET_BITS(tc.c_cflag, CS8); break; default: fprintf(stderr, "Unsupported bit size: %d\n", bits); return 1; } /* SET PARITY */ switch (parity) { /* Disable parity */ case 'N': /* Nothing to do */ break; /* Enable parity, EVEN */ case 'E': SET_BITS(tc.c_cflag, PARENB); break; /* Enable parity, ODD */ case 'O': SET_BITS(tc.c_cflag, PARENB | PARODD); break; default: fprintf(stderr, "Unsupported parity: it souhld be 'N' - none, 'E' -even, 'O' - odd\n"); return 1; } /* SET STOP BITS */ switch (stopbits) { case 1: /* Nothing to do */ break; case 2: SET_BITS(tc.c_cflag, CSTOPB); break; default: fprintf(stderr, "Unsupporte stopbits number %d, use either 1 or 2\n", stopbits); return 1; } /* * ADDITIONAL STUFF: I'm not really sure why is this needed, I just copied * the stuff from minicom */ /* Set line to RAW, NOECHO mode */ tc.c_iflag = IGNBRK; /* IGNBRK, ignore break condition */ tc.c_lflag = 0; tc.c_oflag = 0; /* CLOCAL, ignore modem status line. CREAD, enable receiver, CRTSCTS, CTS * flow control of output */ SET_BITS(tc.c_cflag, CLOCAL | CREAD | CRTSCTS); tc.c_cc[VMIN] = 1; /* Minimum bytes recevied */ tc.c_cc[VTIME] = 5; /* Read delay in 0.1 seconds */ /* Software flow control */ if (softflow) { SET_BITS(tc.c_iflag, IXON | IXOFF); } else { CLR_BITS(tc.c_iflag, IXON | IXOFF | IXANY); } /* FINALLY, SET ATTRIBUTES */ retval = tcsetattr(fd, TCSANOW, &tc); if (retval != 0) { fprintf(stderr, "tcsetattr() failed: %s\n", strerror(errno)); return 1; } return 0; } int main(void) { int retval; int serial; int ii; serial = open("/dev/ttys0", O_RDWR); if (serial < 0) { fprintf(stderr, "cannot open /dev/ttys0: %s\n", strerror(errno)); return 1; } /* Set serial port parameters: 2400 baud, None parity, 1 stop bit, no * software flow control */ retval = serial_setparam(serial, 2400, 8, 'N', 1, 0); if (retval != 0) { fprintf(stderr, "serial_setparam() failed, exiting ...\n"); return 1; } for (ii = 0; ii < 99; ii++) { char c; c = ii; retval = write(serial, &c, sizeof(c)); if (retval < 0) { fprintf(stderr, "write() failed: %s\n", strerror(errno)); return 1; } sleep(1); /* 1 second delay between writes */ } close(serial); return 0; }
Zgoraj je koda, katero je zopet napisal trs, je zanimivo da zopet ne dela.
Namestil sem si minicom nastavil 2400 8N1 in deluje, a v programu pa ne deluje. Zdaj pa več ne vem kaj je narobe.
Zato bi prosil če bi kdo kodo preizkusil. A v linuxu tudi moram dodano nastaviti hitros, itd kot v win ali ni treba.
lp
"Naj živi UNIX"
Zgodovina sprememb…
- spremenil: fx ()
trs ::
Hmm... zanimivo, da ti je prvic delalo, pol pa je kar nehalo. Lahko pastas tocno kaj ti izpise ta program ko ga startas ... error, karkoli?
lp,
trs
lp,
trs
fx ::
Program se lepo prevede in ga zaženem, a neboš verjel nič ne izpiše nobenega errorja ven ne vrže nič, lahko pišeš cifre tlačiš enter in nič razen če pritisneš ctrl + c da zaključiš z programom to pa je vse.
lp
"Naj živi UNIX"
lp
"Naj živi UNIX"
fogl ::
Demo programček (ta naj bi deloval), ki je bil poleg knjižnice za serijski port mi javi napake:
ChildView.obj : error LNK2001: unresolved external symbol "public: static unsigned int const CSerialWnd::mg_nDefaultComMsg" (?mg_nDefaultComMsg@CSerialWnd@@2IB)
ChildView.obj : error LNK2001: unresolved external symbol "public: virtual long __thiscall CSerialWnd::Open(unsigned short const *,struct HWND__ *,unsigned int,long,unsigned long,unsigned long)" (?Open@CSerialWnd@@UAEJPBGPAUHWND__@@IJKK@Z)
ChildView.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall CSerialWnd::OnEvent(enum CSerial::EEvent,enum CSerial::EError)" (?OnEvent@CSerialWnd@@MAEXW4EEvent@CSerial@@W4EError@3@@Z)
ChildView.obj : error LNK2001: unresolved external symbol "public: virtual long __thiscall CSerialEx::StopListener(unsigned long)" (?StopListener@CSerialEx@@UAEJK@Z)
...
A kdo ve v čem je problem?
ChildView.obj : error LNK2001: unresolved external symbol "public: static unsigned int const CSerialWnd::mg_nDefaultComMsg" (?mg_nDefaultComMsg@CSerialWnd@@2IB)
ChildView.obj : error LNK2001: unresolved external symbol "public: virtual long __thiscall CSerialWnd::Open(unsigned short const *,struct HWND__ *,unsigned int,long,unsigned long,unsigned long)" (?Open@CSerialWnd@@UAEJPBGPAUHWND__@@IJKK@Z)
ChildView.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall CSerialWnd::OnEvent(enum CSerial::EEvent,enum CSerial::EError)" (?OnEvent@CSerialWnd@@MAEXW4EEvent@CSerial@@W4EError@3@@Z)
ChildView.obj : error LNK2001: unresolved external symbol "public: virtual long __thiscall CSerialEx::StopListener(unsigned long)" (?StopListener@CSerialEx@@UAEJK@Z)
...
A kdo ve v čem je problem?
lp, klemen
fogl ::
Kaj sploh pomeni da se neki linka, kaj prevajalnik takrat dela? Kaj lahko spremenim?
lp, klemen
BigWhale ::
Prevajalnik takrat ne pocne nicesar vec, takrat stopi v akcijo linker... oziroma povezovalnik ;)
BigWhale ::
Naredi pa to, da ti iz polno .o datotek, ki so ze prevedene .c/.cpp/.whatever naredi izvrsno datoteko.
fogl ::
Zdej sem našel odgovor zakaj pride do tezav pri linkanju:
I had a similar problem when I was playing with CSerial for the first time. All code examples are included in Serial.dsw and have dependencies. Try to open that file in your VC++. Then you'll find that all projects depend on Serial.dsp (small short-cut like icon) - that's your missing 'resource'. Compiling the examples from Serial.dsw should work.
Ampak meni še vedno ni jasno kaj bi moral narediti Bi lahko kdo to poskusi, vse je tukaj, rad bi zagnal demo programček SerialTestMFC.
I had a similar problem when I was playing with CSerial for the first time. All code examples are included in Serial.dsw and have dependencies. Try to open that file in your VC++. Then you'll find that all projects depend on Serial.dsp (small short-cut like icon) - that's your missing 'resource'. Compiling the examples from Serial.dsw should work.
Ampak meni še vedno ni jasno kaj bi moral narediti Bi lahko kdo to poskusi, vse je tukaj, rad bi zagnal demo programček SerialTestMFC.
lp, klemen
fx ::
#include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <termios.h> int main() { int fd; fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { perror ("open_port: Unable to open /dev/ttyS0 - "); exit(1); } else fcntl(fd, F_SETFL, 0); struct termios options; tcgetattr(fd, &options); cfsetispeed(&options, B9600); //vhodna hitraost cfsetospeed(&options, B9600); //izhodna hitrsot options.c_cflag |= (CLOCAL | CREAD); //Zacetek brez paritete 8N1 options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; //Konec brez paritete 8N1 options.c_cflag |= CRTSCTS; options.c_lflag |= (ICANON | ECHO | ECHOE); //Zacetek Input Options options.c_iflag |= (INPCK | ISTRIP); options.c_iflag |= (IXON | IXOFF | IXANY); //Konec Input Options //Zacetek Output Options options.c_oflag |= OPOST; //Konec Output Options options.c_cc[VMIN] = 0; //sprejem vse znake options.c_cc[VTIME] = 10; //cakalani cas na podatek tcsetattr(fd, TCSANOW, &options); int n; n = write(fd, "ATZ\r", 4); if (n < 0) fputs("Write() of 4 byte failed!\n", stderr); close(fd); return (0); }
Zgoraj je koda, ki sem jo sestavil s pomočjo tega linka in mi zadeva na drugi PC ne pošlje ukaza ATZ. Kabel je dobro narejen, saj sem ga preveril s pomočjo HT na dveh PC. Prosim za pomoč.
Nastavitve so tako - 9600 8N1 pa XON/XOFF nazdor.
lp
"UNIX & C++"
Gundolf ::
Pojma nimam o serijskih portih. Najdi knjižnico, ki zna delati prav to - komunicirati prek COM.
fx ::
jype kako pa so nastavitve pri tvoji možnosti?
f = fopen("/dev/ttyS0", "r+");
fwrite(f, "to gre na serijski port\n");
fclose(f);
lp
"UNIX & C++"
f = fopen("/dev/ttyS0", "r+");
fwrite(f, "to gre na serijski port\n");
fclose(f);
lp
"UNIX & C++"
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | Shell scriptaOddelek: Programiranje | 1447 (1051) | BigWhale |
» | [C] Kazalec tipa char na podatke iz datotekeOddelek: Programiranje | 1138 (1099) | Matako |
» | c++ vstavljanje knjižnice v kodoOddelek: Programiranje | 1624 (1283) | SasoS |
» | c++ datotekeOddelek: Programiranje | 4058 (3547) | Vesoljc |
» | LPT porti in linux...Oddelek: Operacijski sistemi | 2541 (2348) | Trojaner |