局域网与单片机之间的通信
本文关键字:通信 之间 单片机 局域网 | 更新日期: 2023-09-27 17:50:32
所以我有一个奇怪的问题。我使用局域网与微控制器进行通信。一切都很顺利。含义:我可以发送和接收数据。对于接收数据,我使用一个简单的方法,这是Thread.sleep(1)
在for
循环中,我不断检查client.GetStream().DataAvailable
为真,而client
是TcpClient
现在,通过一个进程,我必须以更高的波特率发送和接收到微控制器。我使用9600进行所有其他操作,一切都很好。现在115200 client.GetStream().DataAvailable
似乎总是有false
的值。有什么问题吗?
PS:另一种与微控制器通信的方式(全部由用户选择)是串行通信。这在更高的波特率下仍然可以正常工作。
下面是一个代码片段:using (client = new TcpClient(IP_String, LAN_Port))`
{
client.SendTimeout = 200;
client.ReceiveTimeout = 200;
stream = client.GetStream();
.
.
bool OK = false;
stream.Write(ToSend, 0, ToSend.Length);
for (int j = 0; j < 1000; j++)
{
if (stream.DataAvailable)
{
OK = true;
break;
}
Thread.Sleep(1);
}
.
.
}
编辑:在监控与列表设备的通信时,我意识到比特确实到达了,并且设备确实回答了问题。唯一的问题似乎是DataAvailable
的旗帜没有升起。我应该找另一种方法来检查数据的可用性。什么好主意吗?
我一直在努力思考我所见过的这样的事情…
我见过串行芯片说它们能达到115,200,但实际上不会。看看如果你把波特率降低一个档次会发生什么。不管怎样,你都会学到一些东西。
一些微控制器通过让CPU升高和降低数据引脚来"敲打"串行端口,并且基本上通过位,将1或0敲打到串行引脚上。当一个字节进来时,它们读取它,并做同样的事情。这确实节省了钱(没有串行芯片),但要真正可靠地工作绝对是一个地狱般的噩梦。115,200可能会把一个小女孩逼得太紧。
这可能是一个微妙的微控制器问题。假设你有一个接收串行芯片,当一个字节进来时,它断言一个引脚,通常像DRQ*的"数据请求"(DRQ*中的*意味着0伏是"我们有一个字节"的条件)(来吧,人,a *并不总是一个指针:-)。好吧,DRQ*请求中断,固件&CPU中断,它读取串行芯片的字节,并将其存储到某个方便的内存缓冲区中。然后从中断返回。
如果你获取数据的速度非常快,可能会出现问题。让我们假设数据已经进来,串行芯片得到一个字节(在本例中为"#1"),断言DRQ*,我们中断,固件获取并存储字节#1,并从中断返回。一切都很好。但是,如果在第一个中断仍在运行时,另一个字节在中飞来,会发生什么?串行芯片现在有字节#2在里面,所以它再次断言已经断言的DRQ*引脚。第一个字节的中断完成。会发生什么呢?你挂。
这是因为DRQ*的-edge-,物理上从5V到0V,实际上导致CPU中断。在第二个字节上,DRQ*从0开始并被设置为0。所以DRQ*(仍然)是断言的,但是没有-edge-来告诉中断硬件/CPU另一个字节正在等待。现在,当然,所有其他传入的数据也被丢弃。
看到为什么速度越快越差了吗?中断例程越来越快地输出数据,并且通常在中断处理程序中进行循环I/O缓冲区计算,并且它必须快速有效,因为快速输入可以将中断处理程序推到在中断结束之前进入一个完整的新字节的地方。
这就是为什么在中断处理程序期间检查DRQ*以查看是否另一个字节(#2)已经在等待(如果是这样,只需读取它,以清除串行芯片的DRQ*,并将字节存储在内存中)是一个好主意,或者使用"电平触发"中断,而不是"边缘触发"。边缘触发确实有很好的用途,但你需要注意这个。
我希望这是有帮助的。我第一次确实花了很长时间才弄明白。现在我对这样的东西非常小心。祝你好运,让我知道你怎么样了。
- 谢谢,戴夫小