我必须逐字节地将文件发送到来自计算机(VB.NET)的串行连接的AT89s52 每个发送字节在微控制器中都有一些工作要做,需要一些时间 以下是我接收字节的C代码的相关部分:
SCON = 0x50;
TMOD = 0x20; // timer 1, mode 2, 8-bit reload
TH1 = 0xFD; // reload value for 9600 baud
TR1 = 1;
TI = 1;
again:
while(RI!=0)
{
P1=SBUF; // show data on led's
RI=0;
receivedBytes++;
}
if (key1==0)
{
goto exitreceive; // break receiving
}
show_lcd_received_bytes(receivedBytes);
// here is one more loop
// with different duration for every byte
goto again;
这是用于发送字节的VB.NET代码:
For a As Integer = 1 To 10
For t As Integer = 0 To 255
SerialPort1.Write(Chr(t))
Next t
Next a
问题是mC在每个接收到的字节后都有一些工作要做,VB.NET不知道这个并且发送字节太快,所以在mC中只完成所有字节的一部分(大约10%)。 我可以在VB循环蚂蚁中加入“Sleep(20)”然后事情会起作用,但是我有很多浪费的时间,因为每个字节需要不同的时间来处理,这将是不可接受的慢速通信。
现在,我的问题是8051是否可以在UART上设置一些忙状态,VB可以在发送之前读取以决定是否发送字节。 或者如何设置如上所述的这种通信? 我也尝试在mC端接收带有串行中断的字节,结果相同。
硬件肯定没错,因为我可以很好地将数据发送到计算机(如预期的那样)。
答案 0 :(得分:1)
从过去爆炸,我记得使用分线盒来串行线跟踪器调试这种东西。
通过串行通信,如果您使用了所有引脚/线路,则通过RTS(准备发送)和DTR(数据终端就绪)进行流量控制,用于发送可以发送更多数据的信号。您是否可以通过C对您编码的设备进行控制?在VB.NET中,有一些事件用于接收这些信号,或者可以使用SerialPort对象上的属性查询它们。
答案 1 :(得分:1)
你的问题是建筑。不要尝试对处理字节Rx的中断中的接收数据进行处理。让你的字节Rx中断只将接收到的字节复制到一个单独的Rx数据缓冲区,并有一个后台任务,可以在不阻塞Rx中断处理程序的情况下对输入数据进行实际处理。如果由于整体吞吐量问题无法跟上,那么RTS / CTS流量控制是适当的机制。例如,当您的Rx缓冲区满90%时,取消断言流量控制信号以暂停发送端。
答案 2 :(得分:1)
如@TJD所述,硬件流控制可用于在微机处理接收到的字节时阻止PC发送字符。在过去,我通过使用可用的端口线作为输出来实现硬件流程。输出需要连接到TTL到RS-232驱动程序(如果您当前使用的是RS-232,则可能有额外的驱动程序)。如果您使用的是USB虚拟串行端口或RS-422/485,则需要实施软件流控制。通常,发送控制-S以告知PC停止发送并且控制-Q继续。为了充分利用流量控制,您很可能还需要实现一个完全中断驱动的FIFO来接收/发送字符。
如果您想了解有关硬件流控制的其他信息,请查看http://electronics.stackexchange.com。
答案 3 :(得分:0)
很多这些答案都建议硬件流控制,但您也可以选择使用软件流控制来增强传输效率。目前,您的通信非常强大,但如果您开始运行更高的波特率或更长的距离,或者甚至只是连接噪音,则可能会收到不正确的字符,或者字符可能被丢弃。
您可以在完成设置的任何操作后添加一个简单的双字节ACK序列。它可能看起来像这样:
主机发送命令字节:< 0x00> 设备回应命令字节:< 0x00> 设备执行所需的任何操作 设备发送ACK / NAK字节(基于结果):
这将允许您在主机端查看通信是否中断。回显的字符可能与发送的内容不匹配,这会提醒您一个问题。此外,如果主机在某些超时内未收到某个字符,则主机可以尝试重新传输。最后,ACK / NAK为您提供了返回状态的选项,但最重要的是它会让主机知道您已完成操作并且它可以发送另一个命令。
这可以扩展为包括校验和,以便为设备提供验证接收到的命令是否有效的方法(与命令字节一起发送的简单逻辑逆就足够了。)
此解决方案的优势在于它不需要额外的线路或UART支持两端用于硬件流控制。