简体   繁体   English

如何在8051中使用无线串口连续发送和接收?

[英]How do I continuously send and receive with wireless serial-port in 8051?

I'm trying to make a microcontroller communicate with a program on my desktop. 我正在尝试让微控制器与桌面上的程序进行通信。 I'm using serial port connections with Xbee radios on both ends. 我正在使用两端的Xbee无线电串口连接。

The communication works fine when I send something from the microcontroller to the desktop and the program on the desktop then sends something back to the microcontroller. 当我从微控制器向桌面发送内容并且桌面上的程序然后将某些内容发送回微控制器时,通信正常。

However, when I require the information to be sent from the controller to the desktop program continuously until the desktop program sends a particular answer it doesn't work. 但是,当我要求将信息从控制器连续发送到桌面程序,直到桌面程序发送特定答案时,它不起作用。

Here's the code for what I'm talking about: 这是我正在谈论的代码:

    unsigned char ans = 'N';
    unsigned int count = 0;

    void main(void)
    {


        while(1)
        {
            if(count == 0)
            {
                Configure();
                count = 1;
            }

                  //there is some more code here but is irrelevant to the serial communication

         }

    }


void Configure()
{


    //Repeat this until the user accepts the sent string as correct
    while(ans == 'N')
    {

        BuildString();
        Send();
        Receive();
    }
}

void Send()
{
    unsigned int i;

    TMOD = 0x20;
    TH1 = 0xFD;
    SCON = 0x50;
    TR1 = 1;

    for(i=0; i<4; i++)
    {
        SBUF = toSend[i];
        while(TI == 0);
        TI = 0;
    }   

}

void Receive()
{
    unsigned int j;

    TMOD = 0x20;
    TH1 = 0xFD;
    SCON = 0x50;
    TR1 = 1;


    for(j=0; j<2; j++)
    {
        while(RI == 0);
        Received[j] = SBUF;
        RI = 0; 
    }


    if(count == 0)
        ans = Received[1];

    else
    {   
        RunType = Received[0];
        Move = Received[1];
    }


}

The BuildString() function simply constructs a string on the basis of some sensor inputs. BuildString()函数只是根据一些传感器输入构造一个字符串。 The send and receive functions work fine usually but when I need them to send and receive continuously, like in the Configure() function above, it doesn't work. 发送和接收功能通常很好,但是当我需要它们连续发送和接收时,就像上面的Configure()函数一样,它不起作用。

Any suggestions? 有什么建议? I'd really appreciate them. 我真的很感激他们。

The problem is that both your send and receive functions are polled and blocking. 问题是您的发送和接收功能都被轮询和阻止。 When you call the receive function, it will only return after a complete message is received. 当您调用receive函数时,它只会在收到完整的消息后返回。 Dito for the send function, but in case of send the duration is propably shorter (your program will propably only call send when there is a message to be sent, while receive can wait for days before a message arrives. Dito用于发送功能,但是在发送的情况下,持续时间可能更短(您的程序将仅在有消息要发送时调用发送,而接收可以在消息到达之前等待几天。

If you require asynchronous commmunication, the best is to use interrupt based communications; 如果需要异步通信,最好使用基于中断的通信; at least for the receive and ideally for both send and receive. 至少对于接收和理想的发送和接收。

It is also possible to impement this using polled communications, but then you need to write a function which checks if a character is available for receive (or if tx-empty), to read/write the next character from/to the buffer. 也可以使用轮询通信来强制执行此操作,但是您需要编写一个函数来检查字符是否可用于接收(或者如果tx-empty),从缓冲区读取/写入下一个字符。

The advantages of interrupt based communication are: 基于中断的通信的优点是:

  • full duplex 全双工
  • less cpu time is used (no wait loops necessary) 使用较少的cpu时间(不需要等待循环)
  • less power (it allows the cpu to go to a low power/standby mode, with wakeup on interrupt; polling always requires full power) 更少的功率(它允许CPU进入低功耗/待机模式,中断唤醒;轮询总是需要全功率)

As a first step I advise you to implement (or get) a interrupt based receive; 作为第一步,我建议您实现(或获得)基于中断的接收; even when the transmit function is still blocked, it will allow full duplex operation with minimal effort. 即使传输功能仍然被阻止,它也可以轻松实现全双工操作。 If you haven't got a os (rtos/scheduler) you'll have to think of a synchronisation mechanism. 如果你没有os(rtos / scheduler),你将不得不考虑同步机制。 The simplest form is for your receive to handle a message if there is one available, and to return immediately if there isn't a (complete) message. 最简单的形式是,如果有可用消息,您的接收处理消息,如果没有(完整)消息则立即返回。

good luck. 祝好运。

Edit after comments On a message-by-message basis, things may seem to work if the desktop is reacting on messages sent by the controller. 在评论后编辑在逐个消息的基础上,如果桌面对控制器发送的消息作出反应,事情似乎有效。 If your controller has a large FIFO buffer (ie 64 bytes) on the receive, this may work. 如果您的控制器在接收上有一个大的FIFO缓冲区(即64字节),这可能会起作用。 Most controllers I know haven't got this. 我知道的大多数控制器都没有这个。 Many have only a single character buffer. 许多人只有一个字符缓冲区。 You can detect this using an OVERFLOW bit in the registers; 您可以使用寄存器中的OVERFLOW位检测到这一点; if this is set, then characters were lost on receive. 如果设置了这个,则接收时字符丢失。

Some usecases: * you want to send 2 messages in one go (say: init + do_something). 一些用例:*你想一次发送2条消息(比如:init + do_something)。 The pc responds to the first msg, but the controller is still sending and drops most of the data. 电脑响应第一个消息,但控制器仍在发送和丢弃大部分数据。 * PC starts sending before controller is executing the receive() function. * PC在控制器执行receive()函数之前开始发送。 Data at the beginning of the packet may get lost * any drop in communication may cause a deadlock (ie controller and desktop are both waiting for the other end to send something. 数据包开头的数据可能会丢失*通信中的任何丢失都可能导致死锁(即控制器和桌面都在等待另一端发送内容。

So to diagnose: check the overflow bit. 所以要诊断:检查溢出位。 If it is set, you have lost data and you need to work on the interrupt functions. 如果已设置,则表示您丢失了数据,并且需要处理中断函数。 If possible, monitor both sides (at least the state; a blink a led for send, and one for receive for instance). 如果可能的话,监视两侧(至少是状态;闪烁一个led发送,一个用于接收)。

A rs232 monitor may help you (you'll need some additional ports for this. There are many (including freeware) applications which can monitor multiple rs232 ports and provide timestamps. So you can observe the order of communications. Google found me : link ; I've used several similar utilities in the past years. 一个rs232监视器可以帮助你(你需要一些额外的端口。有很多(包括免费软件)应用程序可以监视多个rs232端口并提供时间戳。所以你可以观察通信的顺序。谷歌发现我: 链接 ;在过去的几年里,我使用了几种类似的工具。

Your program as written should send 4 bytes and then read 2 bytes.(assuming the registers you have are correct, but if you got it to work at all they are probably correct) then send 4 bytes again... It probably isn't hanging on the send part but the receiving side as it will always be waiting to read two bytes, and if for some reason two bytes don't arrive at the input register you will continue to wait for ever. 您编写的程序应该发送4个字节,然后读取2个字节。(假设您拥有的寄存器是正确的,但如果您完全可以工作它们可能是正确的)那么再次发送4个字节...它可能不是挂在发送部分但接收端,因为它总是等待读取两个字节,如果由于某种原因,两个字节没有到达输入寄存器,你将继续等待。

It maybe when you stress the system(send byte too quickly) you are overflowing the input buffer and end up loosing a byte? 也许当你对系统施加压力(发送字节太快)时,你会溢出输入缓冲区并最终丢失一个字节? thus never getting two bytes. 因此永远不会得到两个字节 and will get stuck. 并会陷入困境。

  1. can you debug where you are getting stuck? 你可以调试你被卡住的地方吗? is it in fact in the receive loop? 它实际上是在接收循环中吗?
  2. can you throttle the transmission from the pc to the micro so you can manually send one byte at a time? 你可以限制从个人电脑到微型的传输,这样你可以一次手动发送一个字节吗?
  3. is there any handshaking between the micro and xbee interface? micro和xbee接口之间有没有握手? can that be throttled by the micro? 可以被微观扼杀吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM