2013-04-04 40 views
0

好的,這是交易。我正在使用串行端口來調製LED燈陣列(使陣列可調光)。問題是陣列週期性閃爍,每2-4秒快速閃爍一次。儘管構建代碼以嘗試並保持Tx緩衝區已滿,但串行端口仍在運行。

我使用System.Timer每10毫秒檢查Tx緩衝區狀態。如果緩衝區沒有最少數量的待處理字符,則例程會添加更多。從理論上講,緩衝區不應該耗盡字符,但它確實會閃爍,即LED陣列。我檢測並計數這些事件,所以我知道發生了欠載運行。此外,我測量了重新填充緩衝區所需的時間,有時需要超過1000 mS才能添加更多字符。 TxBuffer的大小設置爲4096,我希望的緩衝區計數爲2000.對於我來說,我不明白爲什麼串口在理論上阻塞時間長達一秒鐘......

設置代碼:

charsSent = 0; 
myPort.PortName = commPort; 
myPort.Encoding = new UTF8Encoding(); 
myPort.BaudRate = 19200; 
myPort.DataBits = 8; 
myPort.Parity = Parity.None; 
myPort.StopBits = StopBits.One; 
myPort.Handshake = Handshake.None; 
myPort.DtrEnable = false; 
myPort.RtsEnable = false; 
myPort.ReadTimeout = 500; // SerialPort.InfiniteTimeout; 
myPort.WriteTimeout = 500; // SerialPort.InfiniteTimeout; 

myPort.ReadBufferSize = 4096; 
myPort.WriteBufferSize = 4096; 

myPort.Open(); 

定時器代碼:

myPort.BreakState = false; 
int txBufferCount = myPort.BytesToWrite; 
if (txBufferCount == 0) 
    ++underRuns; 
// refill the xmit buffer if needed... 
int bytesNeeded = (txBufferCount > MaxTxLoadCount) ? 0 : MaxTxLoadCount - txBufferCount; 
DateTime start = DateTime.Now; 
while (bytesNeeded > 0) 
{ 
    myPort.Write (charbuf, 0, 5); 
    charsSent += 5; 
    bytesNeeded -= 5; 
} 
if (DateTime.Now - start > maxWriteTime) 
    maxWriteTime = DateTime.Now - start; 

任何想法?

+0

這是什麼4KB「發送緩衝器」和實際的UART TXD寄存器之間的關係?是否UART有發送FIFO?是輸出這個「Tx緩衝區」的數據速率和/或功耗應該是連續和穩定的? – sawdust 2013-04-04 18:36:47

+0

不確定在窗口下的實際UART緩衝區大小所有這一切都是假設被抽象掉的。在我的用例中,遠端沒有UART。我只是使用串口創建一個可變的佔空比脈衝寬度,然後將其用作控制信號來驅動一個LED陣列。 – 2013-04-05 20:02:06

+0

經過一段時間後,PC上的驅動程序似乎會強制寫入方法阻塞,直到物理UART Tx緩衝區爲空,即使SW緩衝區有足夠的空間可用。所以我的指示燈熄滅,直到我的自由運行定時器路由再次觸發,然後重新填充緩衝區,導致「閃爍」。它太糟糕了驅動程序沒有一個事件發信號TxBuffer像硬件最有可能做空... – 2013-04-05 20:04:44

回答

0

對於我的用法,我找到了解決方法。基本上我允許我的定時器服務路由的兩個實例在任何時候都存在。此外,我用一把鎖來保護緩衝區再填充代碼,以便當一個實例位於鎖定部分內部(並且被公牛狗屎阻止寫入時),另一個實例被鎖定在鎖定部分的外部。結果是,只要實例被寫入阻塞,解除鎖定並退出鎖定部分,另一個實例就會進入鎖定並重新填充緩衝區。淨網絡的LED可能仍然在閃爍(具體取決於驅動器解鎖時的確切時間(UART的Txbuffer =空,與UART的TxShiftRegister =空)。

剛纔你看不到它們,所以最後結束它爲我的作品...

歡呼聲,

基思

相關問題