关于逻辑电路和串行通信的建议
据我目前对串口的了解,数据传输是通过引脚3完成的。如下所示:
有两件事让我对此感到不舒服。第一个是,这似乎意味着两个连接的设备在信号速度上达成一致,第二个是,即使它们配置为以相同的速度运行,您也会遇到可能的同步问题......对吗?我想这样的事情是可以处理的,但似乎必须有一个更简单的方法。
对我来说,更好的方法是让一个串行端口引脚发送一个脉冲,指示下一位已准备好存储。因此,如果我们将这些引脚连接到移位寄存器,我们基本上有:(某些脉冲引脚)->clk,tx->d
这是常见做法吗?有什么理由不这样做吗?
编辑
迈克不应该删除他的答案。这种I2C(2针串行)方法似乎与我所做的相当接近。串行端口没有时钟,你是对的,nobugz,但这基本上就是我所做的。请参阅此处:
private void SendBytes(byte[] data)
{
int baudRate = 0;
int byteToSend = 0;
int bitToSend = 0;
byte bitmask = 0;
byte[] trigger = new byte[1];
trigger[0] = 0;
SerialPort p;
try
{
p = new SerialPort(cmbPorts.Text);
}
catch
{
return;
}
if (!int.TryParse(txtBaudRate.Text, out baudRate)) return;
if (baudRate < 100) return;
p.BaudRate = baudRate;
for (int index = 0; index < data.Length * 8; index++)
{
byteToSend = (int)(index / 8);
bitToSend = index - (byteToSend * 8);
bitmask = (byte)System.Math.Pow(2, bitToSend);
p.Open();
p.Parity = Parity.Space;
p.RtsEnable = (byte)(data[byteToSend] & bitmask) > 0;
s = p.BaseStream;
s.WriteByte(trigger[0]);
p.Close();
}
}
在有人告诉我这有多丑陋或我如何破坏我的传输速度之前,我的快速回答是我不在乎。我的观点是,这似乎比您在答案 nobugz 中描述的方法简单得多。如果 .Net SerialPort 类让我能够更好地控制引脚信号,事情就不会那么难看了。还有其他串口API可以实现吗?
As far as I understand the serial port so far, transferring data is done over pin 3. As shown here:
There are two things that make me uncomfortable about this. The first is that it seems to imply that the two connected devices agree on a signal speed and the second is that even if they are configured to run at the same speed you run into possible synchronization issues... right? Such things can be handled I suppose but it seems like there must be a simpler method.
What seems like a better approach to me would be to have one of the serial port pins send a pulse that indicates that the next bit is ready to be stored. So if we're hooking these pins up to a shift register we basically have: (some pulse pin)->clk, tx->d
Is this a common practice? Is there some reason not to do this?
EDIT
Mike shouldn't have deleted his answer. This I2C (2 pin serial) approach seems fairly close to what I did. The serial port doesn't have a clock you're right nobugz but that's basically what I've done. See here:
private void SendBytes(byte[] data)
{
int baudRate = 0;
int byteToSend = 0;
int bitToSend = 0;
byte bitmask = 0;
byte[] trigger = new byte[1];
trigger[0] = 0;
SerialPort p;
try
{
p = new SerialPort(cmbPorts.Text);
}
catch
{
return;
}
if (!int.TryParse(txtBaudRate.Text, out baudRate)) return;
if (baudRate < 100) return;
p.BaudRate = baudRate;
for (int index = 0; index < data.Length * 8; index++)
{
byteToSend = (int)(index / 8);
bitToSend = index - (byteToSend * 8);
bitmask = (byte)System.Math.Pow(2, bitToSend);
p.Open();
p.Parity = Parity.Space;
p.RtsEnable = (byte)(data[byteToSend] & bitmask) > 0;
s = p.BaseStream;
s.WriteByte(trigger[0]);
p.Close();
}
}
Before anyone tells me how ugly this is or how I'm destroying my transfer speeds my quick answer is I don't care about that. My point is this seems much much simpler than the method you described in your answer nobugz. And it wouldn't be as ugly if the .Net SerialPort class gave me more control over the pin signals. Are there other serial port APIs that do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
它已经这样工作了。每个字节首先以非数据起始位传输。这使得接收器可以同步其时钟。并且至少有一个停止位,可以让接收器验证波特率是否相差太大,以致最后传输的数据位不可靠。使用 8 个数据位,总共产生 10 个位,提供 10% 的波特率容差。偏离更多会产生帧错误。
早期的 PC 设计很容易利用这一点。 UART 的时钟由便宜的晶体生成,任何电视机中都存在这种晶体,用于将色度载波与色同步同步,频率为 3.579545 MHz。振荡器将其除以 2,UART 将输入时钟除以 16,产生 3579545 / 32 = 111861 Hz。然后波特率除数选择频率,9600 波特的除数为 12。111861 / 12 = 9322 波特,误差为 2.9%。完全在 10% 的公差范围内。还解释了为什么 110,000 波特是最大值。
It already works this way. Each byte is transmitted with a non-data start bit first. That lets the receiver synchronize its clock. And there's at least one stop bit, that lets the receiver verify that the baudrate is not so much off that the last transmitted data bit is unreliable. With 8 data bits, that yields 10 total bits, providing 10% tolerance on the baudrate. Being off more generates a framing error.
Early PC designs readily took advantage of this. The UART's clock was generated by a cheap crystal, present in any TV set to synch the chrominance carrier off the color burst, 3.579545 MHz. The oscillator divides it by two, the UART divides the input clock by 16, yielding 3579545 / 32 = 111861 Hz. The baudrate divisor then selects the frequency, the divisor for 9600 baud is 12. 111861 / 12 = 9322 baud, a 2.9% error. Well within the 10% tolerance. Also explains why 110,000 baud was the maximum.
据我所知,该方法类似于描述的I2C方法这里。
As far as I can tell, the approach is similar to the I2C approach described here.