0

好的,这是交易。我正在使用串行端口来调制 LED 灯阵列(使阵列可调光)。问题是阵列周期性闪烁,每 2-4 秒快速闪烁一次。

我使用 System.Timer 每 10 毫秒检查一次 Tx 缓冲区状态。如果缓冲区没有最少数量的未决字符,则例程会添加更多字符。从理论上讲,缓冲区永远不会用完字符,但确实如此,也就是 LED 阵列闪烁。我检测并计算这些事件,所以我知道正在发生欠载。此外,我测量了重新填充缓冲区所需的时间,有时需要超过 1000 毫秒才能添加更多字符。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;

有任何想法吗?

4

1 回答 1

0

对于我的使用,我找到了一种解决方法。基本上,我允许我的计时器服务路由的两个实例在任何时候都存在。此外,我用锁保护缓冲区重新填充代码,以便当一个实例位于锁定部分内(并且被牛屎阻塞写入阻止)时,另一个实例被锁定在锁定部分之外。

最终结果是,一旦被写阻塞的实例解除阻塞并退出锁定部分,另一个实例就会进入锁定并重新填充缓冲区。Net net LED 可能仍在闪烁(具体取决于驱动程序何时解除阻塞(UART 的 Txbuffer = 空,与 UART 的 TxShiftRegister = 空)。

只是现在你看不到他们这样做,所以结束它对我有用......

干杯,

基思

于 2013-04-05T20:24:18.803 回答