全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:7601
推到 Plurk!
推到 Facebook!

有關RS232和電腦或是設備之間傳輸的一些問題

答題得分者是:derrenbol1
jerichowang
一般會員


發表:17
回覆:27
積分:8
註冊:2005-07-25

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-10-28 14:17:44 IP:140.114.xxx.xxx 未訂閱
大家好,想請教一下RS232傳輸的問題 (1)想請問一下當現在有一台A電腦和B電腦 ,當是A電腦送資料給 B電腦時,先指定了傳送的資料BYTE數,和資料array再執行WriteFile後,即可送出資料封包串到B電腦的輸入暫存buffer中,等B電腦的ReadFile讀取後,此暫存buffer中的資料會自動erase,不知道這觀念對不對 (2)那麼我可以自己指定這個暫存Buffer的大小嗎(byte數) 否則萬一欲送的資料量大, 那不就一下子就滿了,是不是用SetupComm()這個來指定呢??? (3)假設現在B電腦接收的buffer佔存區已滿,且未被ReadFile讀取資料,則A強制在傳送資料給B電腦,由於資料進不去,所以這些串列資料就自動被丟掉了呢 (4)假設今天是A電腦和外部裝置做傳輸(先不考慮交握,device的資料腳接RS232的RXD,兩著ground互接),而傳輸就只有外部裝置傳資料給A電腦,當A電腦上的讀取是用Timer元件控制他只要有資料出現在buffer中就自動讀取,是不是A電腦的RS232的RXD腳位上有電位的變化(外部裝置正在送出資料)就自動會接收了呢,還是說需額外的觸發某幾支RS232接腳,才能達到接收的 目的呢 不好意思,一下子問了這麼多 謝謝
阿信
版主


發表:111
回覆:983
積分:813
註冊:2005-03-10

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-10-28 16:28:44 IP:211.21.xxx.xxx 未訂閱
1.不對 Buffer滿時 A會等B回應再傳 2.不行 這是硬體 3.是也不是 沒交握就丟了 有交握A會等B回應再傳 4.會自動接收 但來不及收的就沒了
jerichowang
一般會員


發表:17
回覆:27
積分:8
註冊:2005-07-25

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-10-28 17:41:05 IP:140.114.xxx.xxx 未訂閱
1.不對 Buffer滿時 A會等B回應再傳 2.不行 這是硬體 3.是也不是 沒交握就丟了 有交握A會等B回應再傳 4.會自動接收 但來不及收的就沒了 回應2.那他最大可以儲存的Byte數目是多少呢,我看了一下MSDN他上面說 SetupComm()可以指定輸出和輸入buffer的大小,WriteFile()函式後 資料先被一整塊封包傳入buffer待接收端以ReadFile接收,此buffer 和這函式說的輸出和輸入buffer不同嗎 ??? 另外在請教一下,那這樣我是不是應該一個Byte一個Byte的接收資料(以後將要使用RS232連接CCD模組用電腦接收CCD所傳回的串列資料)...這樣才可以在接收到一個Byte的CCD資料時,在接收端程式timer元件中ReadFile自動接收,接收完後暫存區自動清空,以防止一次街收太大的封包造成暫存區填滿現象 謝謝你

版主


發表:261
回覆:2302
積分:1667
註冊:2005-01-04

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-10-30 17:25:28 IP:203.203.xxx.xxx 未訂閱
引言: 回應2.那他最大可以儲存的Byte數目是多少呢?
你可以設定它buffer的大小, 但有限制. 接收最大14, 傳送最大16. 去裝置管理員那邊看看你就知道了.
------
-------------------------------------------------------------------------
走是為了到另一境界,停是為了欣賞人生;未走過千山萬水,怎知生命的虛實與輕重!?
derrenbol1
中階會員


發表:5
回覆:113
積分:93
註冊:2004-12-09

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-10-31 03:08:08 IP:210.202.xxx.xxx 未訂閱
To jerichowang: 你說的Buffer與正版主他們講的Buffer不同. 你用SetupComm所設定的Buffer大小是給驅動程式用的. 但你注意看一下MSDN的解說, 你給的大小參數值對驅動程式而言是"Recommend",也就是說實際上Buffer大小能不能給到你所想要的容量, 得看當時系統記憶體有沒有那麼大的空間; 驅動程式會跟作業系統要求一塊記憶體空間來當作緩衝區, 緩衝你的程式跟UART晶片間的傳送接收; 當UART晶片接收到一個字元或者是它的FIFO到了臨界值時, 會通知驅動程式來收資料, 該資料會存放在驅動程式的緩衝區內, 等你的應用程式來收, FIFO就是正版主他們所說的Buffer, 一般16550相容的UART晶片都會有16個, 好一點的還有64個Byte的晶片, 而FIFO的最大值都是固定的, 驅動程式可以調的只有選擇開不開FIFO, 若要開FIFO的話, 就再選擇臨限值是多少, 也就是正版主所說的去硬體裝置管理員調的那個東西. 從你的外部裝置到你的應用程式這條連線上, 我們會看到會有三個Buffer存在於中間這條通道; UART晶片會將從外裝置所收到的資料放到它的FIFO內, 到了臨限值時便通知(中斷)驅動程式來從最早進來的資料依序收到它的緩衝區內, 以免UART晶片發生Overrun, 當然再來就是你的程式中Timer事件所引起的接收, 你的程式也是必須要在一定的時間內去跟驅動程式收取資料到你程式內的緩衝區內; Buffer要設多大? 是跟你的程式"多久才去收資料"有關, 倘若你的程式開了RS232, 但撐了一天都不去收的話, 那Buffer設再大也會Data Loss的. 請參考. 發表人 - derrenbol1 於 2005/10/31 03:10:17
jerichowang
一般會員


發表:17
回覆:27
積分:8
註冊:2005-07-25

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-10-31 14:17:26 IP:140.114.xxx.xxx 未訂閱
您好,非常感謝您的回應,就您以上的觀念在驗證一下我的練習程式    以下是我用來傳送資料的Form (單台電腦使用一個com  2,3腳短路 或是雙台電腦的com port用RS232連接中間多加了一個NUll Modem的情況我都試過)     而程式如下
 
void __fastcall TForm1::openClick(TObject *Sender)
{
char* comno;
DCB dcb;
String temp;
temp="Com"+IntToStr(rdCOM->ItemIndex+1);
comno=temp.c_str();
hComm=CreateFile(comno,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,0);
if(hComm==INVALID_HANDLE_VALUE)
{
 MessageBox(0,"Comm error","通訊錯誤",MB_OK);
 return;
}
 GetCommState(hComm,&dcb);
 dcb.BaudRate=CBR_115200;
 dcb.ByteSize=8;
 dcb.Parity=NOPARITY;
 dcb.StopBits=ONESTOPBIT;
  if(!SetCommState(hComm,&dcb))
 {
      MessageBox(0,"Comm error","通訊錯誤",MB_OK);
       CloseHandle(hComm);
       return;
 }
   if(!SetupComm(hComm,1024,1024))
        {
          MessageBox(0,"Comm error","通訊錯誤",MB_OK);
          CloseHandle(hComm);
          return;           }
 
    EscapeCommFunction(hComm,CLRDTR);
    Timer1->Enabled=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::trClick(TObject *Sender)
{
 String temp;     int in;
 unsigned long lrc,BS;
 if(hComm==0)
 return;
 temp= Msend->Text;
 BS=temp.Length();     char *senddata;
 
  senddata=temp.c_str();
  cbiq->Text=(BS);
  WriteFile(hComm,senddata,BS,&lrc,NULL);     }
//------------------------------------------------
void __fastcall TForm1::ReciveClick(TObject *Sender)
{
      DCB dcb;
         String temp;
char inbuff[49600];
DWORD nBytestRead,dwEvent,dwError;
COMSTAT cs;
ClearCommError(hComm,&dwError,&cs);
GetCommState(hComm,&dcb);
if(cs.cbInQue>sizeof(inbuff))
{
 PurgeComm(hComm,PURGE_RXCLEAR);
 return;
}
 ReadFile(hComm,inbuff,cs.cbInQue,&nBytestRead,NULL);
 inbuff[cs.cbInQue]='\0';
 mrecive->Text=inbuff;
}    
我於左邊傳送區內鍵入我欲傳送的文字,且在裝置管理員中分別將COM的FIFO Byte數傳送和接收都調至最高14和16Byte ,紅色的部分就是您文章中所說的 設定給驅動程式的buffer的大小,所以說不管外面送進來的資料多大,UART的FIFO(16Byte)的功能都只是當此FIFO buffer滿時把這些資料pass到驅動程式的buffer中嗎?? 所以說我程式用SetupComm()中設定1024 1024驅動程式從FIFO所收到的最大資料量就是1024Byte吧,那麼超過此範圍的話就不會在接收了嗎 可是為何我把這兩個參數改成2,2然後傳中文(一個中文字是2Byte)傳了 好幾個中文超過100多Byte了卻還是能正常接收呢????是不是他有設定最小值不得低於多少呢??? 謝謝你
derrenbol1
中階會員


發表:5
回覆:113
積分:93
註冊:2004-12-09

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-11-02 03:39:44 IP:210.202.xxx.xxx 未訂閱
To jerichowang:     你的結果沒錯, 我改了一下我的應用程式去收也是一樣的情況. 來自MSDN的說明:    The device driver receives the recommended buffer sizes, but is free to use any input and output (I/O) buffering scheme, as long as it provides reasonable performance and data is not lost due to overrun (except under extreme circumstances). For example, the function can succeed even though the driver does not allocate a buffer, as long as some other portion of the system provides equivalent functionality. 似乎uart的驅動程式並不會理會使用者所送過來的建議值大小.
jerichowang
一般會員


發表:17
回覆:27
積分:8
註冊:2005-07-25

發送簡訊給我
#8 引用回覆 回覆 發表時間:2005-11-05 14:59:17 IP:140.114.xxx.xxx 未訂閱
大家好...再請教一下各位!!當由外部裝置經由RS232送資料給電腦時 再RS232的RXD接腳上的對地電位若保持不變,即可能是hi也可能是low的情形 是不是資料就不會被送入RS232的緩衝區當中呢??? 謝謝
derrenbol1
中階會員


發表:5
回覆:113
積分:93
註冊:2004-12-09

發送簡訊給我
#9 引用回覆 回覆 發表時間:2005-11-06 16:23:58 IP:61.228.xxx.xxx 未訂閱
To jerichowang : 只要Start Bit沒有產生, UART晶片不會接收到資料; 而外部的電壓平常是不會在LOW的.
jerichowang
一般會員


發表:17
回覆:27
積分:8
註冊:2005-07-25

發送簡訊給我
#10 引用回覆 回覆 發表時間:2005-11-06 18:14:01 IP:211.76.xxx.xxx 未訂閱
那譬如說...我用指撥開關送出8bit的hi/lo資料到74LS165並列資料轉串列資料IC,將此IC輸出端連到RS232的RXD接腳,不知道您所說的startbit要如何產生呢 現在的資料是8bit,那麼我設定dcb.ByteSize=8;dcb.StopBits=ONESTOPBIT; 那麼我要如何產生stopbit呢,還是說只要電未一有變化,UART就自己會接收資料丟到驅動程式的緩衝區中了呢 謝謝你
derrenbol1
中階會員


發表:5
回覆:113
積分:93
註冊:2004-12-09

發送簡訊給我
#11 引用回覆 回覆 發表時間:2005-11-07 08:34:38 IP:210.202.xxx.xxx 未訂閱
To jerichowang:      平常UART的TX及RX的狀態都應該要維持在高電位, 當 要進行一個"FRAME"的傳輸時, 傳送端會將它的TX(當然 此連接到接收端的RX)拉到低電位, 維持一個Bit Rate 的時間, 此Bit Rate時間長度也就是你設的BaudRate的 倒數, 然後再來就是真正的資料會被以串列的方式傳送 出來, 一個"FRAME"指的是 :          
    1 StartBit(Keep low in 1/BaudRate sec)
    n Data Lenght
    1(1.5) StopBit (Keep High in (1/BaudRate)*1(or1.5) sec)
    
當然資料傳送的正確, 須兩端的設定一致來保證. 我知道你這個問題有發表另外的主題來問過, 應該是正版本有回答 說可採用一個具有UART功能的MCU(如8051)來做; 而你用並列傳串列 的IC? 我想不是MCU吧, 這樣會很... 艱苦哦.
jerichowang
一般會員


發表:17
回覆:27
積分:8
註冊:2005-07-25

發送簡訊給我
#12 引用回覆 回覆 發表時間:2005-11-07 10:45:40 IP:140.114.xxx.xxx 未訂閱
您好 您所謂的艱苦意思是說,若我使用MCU(如8051)的話..當我接收到一個8bit的併列輸入時,我用8051將此資料用UART的串列功能輸出給RS232時候,8051的UART 自動就會幫我加入start bit和stop bit了,或者是說當8051收到N個連續8bit 並列資料時候,當要串列傳送給232時候,自動就會變成 [start bit][N Byte data][stop bit]. 而若我單純使用74LS165並列轉串列IC..無法加入start bit和stop bit 所以RS232可能會收到不正確的資料囉???

版主


發表:261
回覆:2302
積分:1667
註冊:2005-01-04

發送簡訊給我
#13 引用回覆 回覆 發表時間:2005-11-07 11:19:11 IP:211.22.xxx.xxx 未訂閱
引言: 您好 您所謂的艱苦意思是說,若我使用MCU(如8051)的話..當我接收到一個8bit的併列輸入時,我用8051將此資料用UART的串列功能輸出給RS232時候,8051的UART 自動就會幫我加入start bit和stop bit了,或者是說當8051收到N個連續8bit 並列資料時候,當要串列傳送給232時候,自動就會變成 [start bit][N Byte data][stop bit]. 而若我單純使用74LS165並列轉串列IC..無法加入start bit和stop bit 所以RS232可能會收到不正確的資料囉???
是的. 且MCU傳完後會自動回到高電位, 並列轉串列不會喔.... 你try看看就知道了~~~會比較有sense..
------
-------------------------------------------------------------------------
走是為了到另一境界,停是為了欣賞人生;未走過千山萬水,怎知生命的虛實與輕重!?
derrenbol1
中階會員


發表:5
回覆:113
積分:93
註冊:2004-12-09

發送簡訊給我
#14 引用回覆 回覆 發表時間:2005-11-07 11:20:50 IP:210.202.xxx.xxx 未訂閱
To jerichowang: 是的.
jerichowang
一般會員


發表:17
回覆:27
積分:8
註冊:2005-07-25

發送簡訊給我
#15 引用回覆 回覆 發表時間:2005-11-08 00:41:09 IP:140.114.xxx.xxx 未訂閱
您好,謝謝你們的回應 想再請教一下,今天買了一本8051的書,其實我是需要把外部裝置CCD產生的連續高速8bit資料做個緩衝"減速"以配合RS232較低的速率 意思是...再8051內要先街收一組高速的影像然後用UART的串列傳輸低速的配合電腦端RS232的最大包率來傳送,因為8051似乎可以設定其傳送包率 , 等待傳送完再街收一組新影像 現在想請教的是,8051並列輸入端最快可以接收到多快的資料呢.. 假設CCD每秒30 Frame每筆資料8bit假設大小320*240,所以CCD每秒並列輸出上的資料變化是30*320*240一共2304000次 所以f=2.304MHZ,然後等待街收完一個完整影像 再以128000Bps/second的速度透過RS232給電腦(RS232速度慢的關係).. 然後以上過程一值循環讓電腦收到即時影像.. 書上只有提到設定串列的包率,我不知道是否併列輸入也是一起在這邊被設定的 那麼可以併列輸入和輸出設定兩種不同的包率嗎???又該如何設定呢 謝謝
derrenbol1
中階會員


發表:5
回覆:113
積分:93
註冊:2004-12-09

發送簡訊給我
#16 引用回覆 回覆 發表時間:2005-11-09 10:57:28 IP:210.202.xxx.xxx 未訂閱
To jerichowang: 就怕你要"即時"; 你一秒內要傳的資料量太大了. UART每秒可傳 的資料量, 假設在115200, 8, N, 1設定下, 115200代表每秒將可 有115200個Bit被傳輸, 而8N1則是指一個Frame的組合是10個Bits 所以你每秒能傳的是11520個Frame, 又每個Frame的有效資料是1 個Byte, 所以每秒的傳輸量是~~~ 11.52k ~~~ .... 所以別管並 列傳輸的速度了, 在UART部份就已經無法達到你的預期了.
系統時間:2024-05-17 18:32:20
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!