[問題] Linux C使用串列埠的問題..

看板C_and_CPP (C/C++)作者 (超越自己)時間12年前 (2014/03/07 20:54), 編輯推噓0(0018)
留言18則, 2人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Linux ----------------------- 各位板友大家好, 想請問大家使用Linux C來做串列傳輸的問題.. 裝置:USB轉UART的晶片是採用FT232RL 情況: 開埠的方式是用open、write、read, 通訊速率及通訊格式皆設定和裝置的需求符合, 程式內皆有錯誤偵測。 問題: 查找系統檔案有找到ttyUSB0,代表此裝置的驅動已正常被使用。 開ttyUSB埠時,並沒有產生錯誤代碼,而write命令過去的回傳值也不等於-1, 只是接下來一行的read,產生了錯誤代碼-1, 小弟實在是想不出來到底哪裡錯了, 懇請板上的先進能夠不吝分享經驗,謝謝大家.. :D 自行排除部份:檢查指令正確,同樣的指令用Modbus測試軟體在windows送出能得回應。 -- -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.124.42.70 ※ 編輯: BIAO 來自: 140.124.42.70 (03/07 21:21)

03/07 21:32, , 1F
stty -a /dev/ttyUSB0 貼出來看看 程式碼也放份簡單版看看
03/07 21:32, 1F

03/07 21:32, , 2F
是否裝該廠商的驅動? 或是哪邊的驅動?
03/07 21:32, 2F
感謝d大的回覆, 使用您說的指令後,得到『stty: when specifying an output style, modes may not be set』。 我沒裝廠商的驅動,因為曾經有查找過相關網頁,得知Ubuntu內建該晶片的驅動程式了, 而且也找的到ttyUSB0,所以小弟當時並沒有想太多.. 簡短程式碼如下,謝謝您: ----------------- float modbusrtu(int serial_number,int function_code,int address1,int address2,int data1,int data2){ // pthread_mutex_lock(&data_lock); int fd; struct termios T_new; fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { printf("open COM Failed, errno: %d\r\n", errno); return 1000; } if (tcgetattr(fd, &T_new) != 0){ printf("tcgetattr failed. errno: %d\r\n", errno); close(fd); return 1000; } T_new.c_cflag = (B9600 | CS8 | CREAD | CLOCAL); T_new.c_cflag &= ~PARENB; //No parity T_new.c_cflag &= ~CSTOPB; //Stop bit = 1 T_new.c_oflag = 0; T_new.c_lflag = 0; if (tcsetattr(fd, TCSANOW, &T_new) != 0){ printf("tcsetattr failed. errno: %d\r\n", errno); close(fd); return 1000; } usleep(1000000); //int fd, interface, ret; int recieve, ret_w; unsigned char buf[150]={0}; int crc1,crc2; char buf1[8]; char y1[2],y2[2],y3[2],y4[2]; int hi_crc1,hi_crc2,low_crc1,low_crc2; unsigned char crc_data[] = {serial_number, function_code, address1, address2, data1, data2}; unsigned int num; num = crc16(crc_data, 6); sprintf(buf1, "%04x", num); y1[0] = buf1[0]; y2[0] = buf1[1]; y3[0] = buf1[2]; y4[0] = buf1[3]; y1[1] = '\0'; y2[1] = '\0'; y3[1] = '\0'; y4[1] = '\0'; sscanf(y1,"%x",&low_crc1); sscanf(y2,"%x",&low_crc2); sscanf(y3,"%x",&hi_crc1); sscanf(y4,"%x",&hi_crc2); crc1 = hi_crc1*16+hi_crc2; crc2 = low_crc1*16+low_crc2; float computation,result; // unsigned char trans_data[] = {serial_number,function_code,address1,address2,data1,data2,crc1,crc2}; unsigned char trans_data[] = {0x12,0x03,0x00,0x02,0x00,0x01,0x27,0x69};//此行為測試用 ret_w = write(fd, trans_data, sizeof(trans_data)); if(ret_w==-1){ return 1000; } else{ recieve = read(fd, buf, sizeof(buf)); if(recieve == -1){ return 1001; } else{ if(function_code==3){ if(buf[0]==0){ return 2000; } else{ if(buf[1]==0x83 && buf[2]==0x04){ return 3000; } else{ computation = buf[3]*0x100+buf[4]; result = computation/100; return result; } } } if(function_code==6){ if(buf[0]==0){ return 2000; } else{ if(buf[1]==0x86 && buf[2]==0x04){ return 3000; } else{ return 0; } } } } } close(fd); return 1000; // pthread_mutex_unlock(&data_lock); } ※ 編輯: BIAO 來自: 140.124.42.70 (03/07 21:48)

03/08 18:19, , 3F
抱歉應該是 stty -F /dev/ttyUSB0 或 stty -a < /dev/XXX
03/08 18:19, 3F

03/08 18:28, , 4F
另外把write的回傳值印出來看是否跟你寫出長度一致
03/08 18:28, 4F

03/08 18:28, , 5F
你確定另一方裝置是沒有HW/SW flow control嗎
03/08 18:28, 5F

03/08 18:31, , 6F
再把receive == -1時的 errno印出來
03/08 18:31, 6F

03/08 18:47, , 7F
如果你read是想blocking到資料回來 再設定部分的最後加上
03/08 18:47, 7F

03/08 18:48, , 8F
fcntl(fd, F_SETFL, 0);
03/08 18:48, 8F

03/09 17:29, , 9F
謝謝d大的解說,我明白該怎麼處理了,再次謝謝您^^
03/09 17:29, 9F
先附上ssty -F /dev/ttyUSB0的結果(程式有在跑,也有設定串口的值): ----------------------------------- speed 9600 baud; line = 0; min = 1; time = 0; -brkint -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke ※ 編輯: BIAO 來自: 114.43.134.47 (03/09 19:15) 目前檢查送出的位元組數為8位元組無誤, 檢測到read函數的錯誤代碼為11,正在解決中。 ※ 編輯: BIAO 來自: 114.43.134.47 (03/09 19:33)

03/09 19:37, , 10F
此錯誤代碼為:資源暫時不可使用...
03/09 19:37, 10F

03/10 03:24, , 11F
先了解blocking I/O跟non-blocking的差異
03/10 03:24, 11F

03/10 03:25, , 12F
那錯誤代表你現在用non-blocking且現在沒資料
03/10 03:25, 12F

03/10 12:24, , 13F
感謝d大的再次回覆,我會去查找您所說的..
03/10 12:24, 13F

03/10 12:26, , 14F
如果您說我用non-blocking的方式,但write出去理論上會有資料
03/10 12:26, 14F

03/10 12:30, , 15F
抑或write的資料根本沒送出 XD
03/10 12:30, 15F
回應d大,感謝您的協助, 不過..問題依舊還沒解決, 採用了Blocking的方式,程序就直接掛在那裡等待, 沒有任何數值寫回資料庫。 使用Nonblocking的方式,設定有數值才讀取, 也一直沒有數值回應。 上網查找了許多資訊,送出的指令已先用軟體算好crc, 應該這部份不太會錯.. 有在網上查找到一篇關於FTDI晶片的文章, https://bugzilla.kernel.org/show_bug.cgi?id=23012 與您分享.. 目前正在想該如何編譯內核文件..冏 = =||| ※ 編輯: BIAO 來自: 118.168.204.19 (03/11 03:40)

03/11 21:15, , 16F
可以聯絡轉換器的廠商, 想辦法先確認你的driver是可運作的
03/11 21:15, 16F

03/11 21:18, , 17F
應該不用重編Kernel, 頂多拿新的driver來編就好
03/11 21:18, 17F

03/11 21:20, , 18F
如果你可以接到另一台電腦用終端機去try, 可以去試試看
03/11 21:20, 18F
很感謝d大的回覆, 問題已經找到了... 因為我是將設備的位址及參數存在資料庫內, 剛剛才發現.... 我的設備位址設錯了.. 應該要0x12的,打成0x01.. 感謝您的熱心協助,問題已解決:D ※ 編輯: BIAO 來自: 140.124.42.70 (03/14 22:22)
文章代碼(AID): #1J6S6TQ- (C_and_CPP)
文章代碼(AID): #1J6S6TQ- (C_and_CPP)