2012-07-16 51 views
3

我試圖建立一個以10-20 kHz的速率傳輸16位數據包的串行端口連接。我用C++/CLI編程。發送者在收到字母「s」後才進入infinite while循環,並不斷髮送2個字節的數據。從C++中的串行端口快速讀取常量數據流。網絡

發送端的問題是不太可能的,因爲更簡單的方法完美但速度太慢(在這種方法中,接收者首先發送一個「a」,然後得到1個包含2個字節的包。導致500Hz左右的速度)。 下面是這個工作,但是進展緩慢辦法的重要組成部分:迅速在18472的速度

static int values[1000000]; 
static int counter = 0; 

void reader(void) 
    { 
     SerialPort^ port; 
     Parity p = (Parity)Enum::Parse(Parity::typeid, "None"); 
     StopBits s = (StopBits)Enum::Parse(StopBits::typeid, "1"); 
     port = gcnew SerialPort("COM16",384000,p,8,s); 
     port->Open(); 
     unsigned int i = 0; 
     unsigned int j = 0; 
     port->Write("s"); //with this command, the sender starts to send constantly 
     while(true) 
     { 
      i = port->ReadByte(); 
      j = port->ReadByte(); 
      values[counter] = j + (i*256); 
      counter++; 
     } 
    } 

in main: 
Thread^ readThread = gcnew Thread(gcnew ThreadStart(reader)); 
readThread->Start(); 

計數器增加(更多):

public: SerialPort^ port; 

in main: 
Parity p = (Parity)Enum::Parse(Parity::typeid, "None"); 
StopBits s = (StopBits)Enum::Parse(StopBits::typeid, "1"); 
port = gcnew SerialPort("COM16",384000,p,8,s); 
port->Open(); 

and then doing as often as wanted: 
port->Write("a"); 
int i = port->ReadByte(); 
int j = port->ReadByte(); 

這是現在的實際做法IM與合作packages/s,但是這些值有點不對。 下面是一個例子: 值應該是這樣的,與所述最後4位改變隨機(其一個模擬 - 數字轉換器的信號):

111111001100111 

下面是在給定螺紋溶液的一些值代碼:

1110011001100111 
1110011000100111 
1110011000100111 
1110011000100111 

所以它看起來像連接讀取包中間的數據(確切地說:3位太晚)。我能做什麼?我想避免一個解決方案,稍後在代碼中解決這個錯誤,同時閱讀這樣的包,因爲我不知道當我稍後編輯閱讀代碼時,移位錯誤是否會變得更糟,我最有可能這樣做。

由於提前,

尼古拉斯

PS:如果這有助於,這裏是發送器側(一個ATmega168的)的代碼,寫在C.

uint8_t activate = 0; 

void uart_puti16(uint16_t val) //function that writes the data to serial port 
{ 

    while (!(UCSR0A & (1<<UDRE0))) //wait until serial port is ready 
      nop(); // wait 1 cycle 
      UDR0 = val >> 8; //write first byte to sending register 
    while (!(UCSR0A & (1<<UDRE0))) //wait until serial port is ready 
      nop(); // wait 1 cycle 
      UDR0 = val & 0xFF; //write second byte to sending register 
} 

in main: 
while(1) 
{ 
     if(active == 1) 
     { 
      uart_puti16(read()); //read is the function that gives a 16bit data set 
     }    
} 

ISR(USART_RX_vect) //interrupt-handler for a recieved byte 
{ 
     if(UDR0 == 'a') //if only 1 single data package is requested 
     { 
      uart_puti16(read()); 
     } 
     if(UDR0 == 's') //for activating constant sending 
     { 
      active = 1; 
     } 
     if(UDR0 == 'e') //for deactivating constant sending 
     { 
      active = 0; 
     } 
} 
+0

什麼能防止'counter ++'溢出'values []'數組? – sarnold 2012-07-16 23:33:48

+0

什麼都沒有。我在這種情況發生之前關閉程序:)這只是爲了測試目的,最終的程序不會包含這樣的內容。 – user1530242 2012-07-16 23:41:41

+0

Hehehe,好吧,只要確保在發貨之前解決這個問題...... :) – sarnold 2012-07-16 23:42:16

回答

2

在在給定384,000比特率的情況下,您應該每秒獲得38,400字節的數據(8位真實數據加2個成幀位),或每秒19,200個雙字節值。

counter在兩種情況下增加速度有多快?我希望任何現代計算機都能跟上這個速度,無論是使用事件還是直接進行輪詢。

你不顯示你說的工作更簡單的方法。我建議你發佈。

而且,在該行

values[counter] = j + (i*256); 

有設置斷點,檢查ij。在循環的第一次迭代中分享您所看到的這些變量的值。

+0

現在就做那個,給我一下。 – user1530242 2012-07-16 23:45:21

+0

速度現在給出,請參閱編輯版本。休息儘快。 – user1530242 2012-07-16 23:55:09

+0

給出的工作代碼。現在即時嘗試發佈我的價值觀我和j。 – user1530242 2012-07-17 00:03:54

0

這完全在上讀取http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived.aspx#Y228代碼基於猜測。有了這個警告的出路,這是我的猜測:

數據可用時閱讀您的事件處理程序被調用 - 但你只消耗兩個字節可用數據的。您的事件處理程序只能每1024字節調用一次。或類似的東西。您可能需要使用全部事件處理程序中的可用數據才能按預期繼續執行。

嘗試重新編寫您的處理程序以包含一個讀取循環,直到沒有更多數據可用爲止。

+0

正如我所說,這是基於_guess_。如果不是這樣,請讓我知道,這樣我可以刪除我的答案。 – sarnold 2012-07-16 23:46:43

+0

好點,雖然它不能解釋爲什麼數組爲0.每當事件處理程序觸發時,他會佔用兩個字節的可用數據,更新數組,並增加計數器一次。 – 2012-07-16 23:47:07

+0

@Eric:哦,好點。 :/至少第一個值應該是不同的...... – sarnold 2012-07-16 23:48:03