好的,這是交易。我正在使用串行端口來調製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;
任何想法?
這是什麼4KB「發送緩衝器」和實際的UART TXD寄存器之間的關係?是否UART有發送FIFO?是輸出這個「Tx緩衝區」的數據速率和/或功耗應該是連續和穩定的? – sawdust 2013-04-04 18:36:47
不確定在窗口下的實際UART緩衝區大小所有這一切都是假設被抽象掉的。在我的用例中,遠端沒有UART。我只是使用串口創建一個可變的佔空比脈衝寬度,然後將其用作控制信號來驅動一個LED陣列。 – 2013-04-05 20:02:06
經過一段時間後,PC上的驅動程序似乎會強制寫入方法阻塞,直到物理UART Tx緩衝區爲空,即使SW緩衝區有足夠的空間可用。所以我的指示燈熄滅,直到我的自由運行定時器路由再次觸發,然後重新填充緩衝區,導致「閃爍」。它太糟糕了驅動程序沒有一個事件發信號TxBuffer像硬件最有可能做空... – 2013-04-05 20:04:44