日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

rs485编程java_串行编程RS485

發(fā)布時(shí)間:2024/9/19 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 rs485编程java_串行编程RS485 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

我的任務(wù)是通過(guò)RS485 2線系統(tǒng)實(shí)現(xiàn)ModBus協(xié)議 . (實(shí)際上它是三根線,A / B和GND) . 雖然ModBus不是重點(diǎn),但是之前的步驟......界面上的簡(jiǎn)單I / O.

我正在使用FTDI USB-RS485轉(zhuǎn)換器將Linux主機(jī)(不可互換)連接到Windows主機(jī)(可與其他Linux主機(jī)互換,但我想避免這種情況)

編碼應(yīng)該是19200,8,n,1 . 但它似乎不起作用 .

我沒(méi)有準(zhǔn)確的代碼,但在Linux上我這樣做:

int fd = open("/dev/ttyS3", O_RDWR | O_CTTY);

if(fd == -1) return "Error while opening the port";

接下來(lái),我配置端口 .

struct termios tty;

tcgetattr(fd, &tty);

cfsetispeed(&tty, B19200);

cfsetospeed(&tty, B19200);

tty.c_cflag = CS8; //Empties the cflags and sets the character width.

tty.c_cflag |= (CLOCAL | CREAD); //Sets 'recommended' options.

tty.c_lflag = 0;

tty.c_iflag = 0;

tty.c_oflag = 0;

tcgetattr(fd, TCSANOW, &tty);

奇偶校驗(yàn)和流量控制目前尚未規(guī)劃,因?yàn)樽罱K結(jié)果將連接到低級(jí)別的電路板,我需要自己處理信號(hào) . 此外,沒(méi)有任何電線可以實(shí)現(xiàn)“不受約束的通信” . (畢竟我不希望XON / XOFF字符限制我可以傳輸?shù)淖止?jié)范圍)

所有這些功能都能正常運(yùn)行并設(shè)置數(shù)據(jù) .

在Windows上,我打開(kāi)這樣的串口:

DCB SP;

HANDLE hSerial = CreateFile("COM6", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

if(hSerial == INVALID_HANDLE_VALUE) return "Error while opening the port";

GetCommState(hSerial, &SP);

奇偶校驗(yàn)被禁用,以及流量控制 . 字節(jié)大小設(shè)置為8 .

編輯:因?yàn)橐呀?jīng)被問(wèn)到,這是我的Windows上的波特率代碼(來(lái)自內(nèi)存)SP.DCBlength = sizeof(SP); SP.BaudRate = 19200; SP.Parity = NOPARITY; SP.StopBits = ONESTOPBIT; SetCommState(hSerial,&SP);

同樣,所有這些功能都運(yùn)行得很完美 .

現(xiàn)在,對(duì)于讓我頭疼的測(cè)試用例 .

在Linux主機(jī)上,我創(chuàng)建了一個(gè)256字節(jié)大小的字節(jié)緩沖區(qū) . 該緩沖區(qū)填充0-255的字符值...然后通過(guò)寫(xiě)入發(fā)送 . 與此同時(shí),另一方正在等待“ReadFile”數(shù)據(jù)到達(dá) .

使用此配置,對(duì)于“其他Linux主機(jī)”以及Windows主機(jī),256字節(jié)到達(dá)...但是它不是0-255的數(shù)字,而是00 06等 .

當(dāng)我在設(shè)置我真正想要的選項(xiàng)之前將termios結(jié)構(gòu)的所有成員設(shè)置為0時(shí),我可以讓Linux主機(jī)工作 . 我猜,這是因?yàn)榭刂谱址?..但是如果我這樣做,Windows主機(jī)要么只接收256個(gè)字節(jié)中的4個(gè) .

正如我所說(shuō),不幸的是我沒(méi)有方便的代碼 . 如果有人知道我能從哪個(gè)方面解決這個(gè)問(wèn)題,我將非常感激 . 一旦我再次訪問(wèn)它,我將發(fā)布更多代碼 .

我是如何實(shí)現(xiàn)讀取操作的:

DWORD nBytes = 0;

char Buffer[256], *ptr = Buffer;

int Rem = 256;

while(Rem) {

ReadFile(hSerial, ptr, Rem, &nBytes, 0);

Rem -= nBytes;

ptr += nBytes;

}

//Evaluate Buffer

需要注意的是,我確實(shí)設(shè)置了超時(shí),但不記得確切的值 .

編輯:因?yàn)槲椰F(xiàn)在可以再次訪問(wèn)我的工作地點(diǎn),這是實(shí)際(當(dāng)前)代碼 .

const char *InitCOM(const char *TTY) {

struct termios tty;

hSerial = open(TTY, O_RDWR | O_NOCTTY | O_NDELAY);

if(hSerial == -1) return "Opening of the port failed";

fcntl(hSerial, F_SETFL, 0);

if(tcgetattr(hSerial, &tty) != 0) return "Getting the parameters failed.";

if(cfsetispeed(&tty, B19200) != 0 || cfsetospeed(&tty, B19200) != 0) return "Setting the baud rate failed.";

//CFlags

//Note: I am full aware, that there's an '=', and that it makes the '&=' obsolete, but they're in there for the sake of completeness.

tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; //8-bit characters

tty.c_cflag |= (CLOCAL | CREAD);und erlaubt 'Lesen'.

tty.c_cflag &= ~(PARENB | PARODD);

tty.c_cflag &= ~CSTOPB;

tty.c_cflag &= ~CRTSCTS;

//Input Flags

tty.c_iflag &= ~IGNBRK;

tty.c_iflag &= ~(IXON | IXOFF | IXANY);

//Local Flags

tty.c_lflag = 0;

//Output Flags

tty.c_oflag = 0;

//Control-Characters

tty.c_cc[VMIN] = 0;

tty.c_cc[VTIME] = 5;

if(tcsetattr(hSerial, TCSAFLUSH, &tty) != 0) return "Setting the new parameters failed";

return NULL;

}

至于實(shí)際的發(fā)送/接收代碼:

int main(int argc, char* argv[]) {

#if defined FOR_PC

const char *err = InitCOM("/dev/ttyUSB0");

#else

const char *err = InitCOM("/dev/ttyS3");

#endif

if(err) printf("Error while initalizing: %s ErrNum: %d\n", err, errno);

else {

/*unsigned char C[256]; //Original code with the array

int nBytes;

#ifdef FOR_PC

int Rem = 256, ReqCount = 0;

unsigned char *ptr = C;

while(Rem > 0) {

fd_set fds;

FD_ZERO(&fds);

FD_SET(hSerial, &fds);

select(hSerial+1, &fds, NULL, NULL, NULL);

nBytes = read(hSerial, ptr, Rem);

if(nBytes > 0) {

Rem -= nBytes;

ptr += nBytes;

++ReqCount;

}

}

printf("Number of received Bytes: %d in %d sends.\n\n", 256 - Rem, ReqCount);

for(int i = 0; i < 256; ++i) {

printf("%02X ", C[i]);

if((i%32) == 31) printf("\n");

}

#else

for(int i = 0; i < 256; ++i) C[i] = i;

nBytes = write(hSerial, C, 256);

printf("\nWritten Bytes: %d\n", nBytes);

#endif*/

//Single-Byte Code

unsigned char C = 0x55;

#ifdef FOR_PC

while(true) { //Keeps listening

fd_set fds;

FD_ZERO(&fds);

FD_SET(hSerial, &fds);

select(hSerial+1, &fds, NULL, NULL, NULL);

read(hSerial, &C, 1);

printf("Received value 0x%02X\n", C);

}

#else

write(hSerial, &C, 1); //Sends one byte

#endif

close(hSerial);

}

return 0;

}

至于示波器:我已經(jīng)通過(guò)發(fā)送測(cè)試了兩個(gè)方向 . 他們的工作非常令人欽佩 .

0x55的信號(hào)是50微秒長(zhǎng)度的常數(shù)上/下(應(yīng)該如此,所以設(shè)置波特率也沒(méi)問(wèn)題) .

那么我的'接收'代碼中有什么東西我做錯(cuò)了嗎? '選擇'錯(cuò)了嗎?

總結(jié)

以上是生活随笔為你收集整理的rs485编程java_串行编程RS485的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。