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

时间:2009-10-24 19:10:49

标签: embedded serial-port wireless 8051 zigbee

我正在尝试让微控制器与桌面上的程序进行通信。我正在使用两端的Xbee无线电串口连接。

当我从微控制器向桌面发送内容并且桌面上的程序然后将某些内容发送回微控制器时,通信正常。

但是,当我要求将信息从控制器连续发送到桌面程序直到桌面程序发送特定答案时,它不起作用。

这是我正在谈论的代码:

    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];
    }


}

BuildString()函数只是根据一些传感器输入构造一个字符串。 发送和接收功能通常很好,但是当我需要它们连续发送和接收时,就像上面的Configure()函数一样,它不起作用。

有什么建议吗?我真的很感激他们。

2 个答案:

答案 0 :(得分:4)

问题是您的发送和接收功能都被轮询和阻止。当您调用receive函数时,它只会在收到完整的消息后返回。 Dito用于发送功能,但是在发送的情况下,持续时间可能更短(您的程序可能只在有消息要发送时调用发送,而接收可以在消息到达之前等待几天。

如果需要异步通信,最好使用基于中断的通信;至少对于接收而言理想的是发送和接收。

也可以使用轮询通信来强制执行此操作,但是您需要编写一个函数来检查字符是否可用于接收(或者如果tx-empty),从/向下读取/写入下一个字符缓冲液中。

基于中断的通信的优点是:

  • 全双工
  • 使用较少的cpu时间(无需等待循环)
  • 功耗更低(它允许cpu进入低功耗/待机模式,中断唤醒;轮询总是需要全功率)

作为第一步,我建议你实现(或获得)基于中断的接收;即使传输功能仍然被阻止,它也可以轻松实现全双工操作。如果你没有os(rtos / scheduler),你将不得不考虑同步机制。最简单的形式是,如果有可用消息,您的接收处理消息,并且如果没有(完整)消息则立即返回。

祝你好运。

在评论后修改 在逐个消息的基础上,如果桌面对控制器发送的消息作出反应,事情似乎可行。如果您的控制器在接收上有一个大的FIFO缓冲区(即64字节),这可能会起作用。我知道的大多数控制器都没有这个。许多人只有一个字符缓冲区。您可以使用寄存器中的OVERFLOW位检测到这一点;如果设置了这个,则接收时字符丢失。

一些用例:  *你想一次发送2条消息(比如:init + do_something)。电脑响应第一个消息,但控制器仍在发送和丢弃大部分数据。  * PC在控制器执行receive()函数之前开始发送。数据包开头的数据可能会丢失  *任何通信中断都可能导致死锁(即控制器和桌面都在等待另一端发送内容。

所以要诊断:检查溢出位。如果已设置,则表示您丢失了数据,并且需要处理中断函数。如果可能的话,监视两侧(至少是状态;闪烁一个led发送,一个用于接收)。

rs232显示器可以帮助你(你需要一些额外的端口。有很多(包括免费软件)应用程序可以监控多个rs232端口并提供时间戳。所以你可以观察通信的顺序。谷歌发现我:link;过去几年我使用了几种类似的工具。

答案 1 :(得分:1)

您编写的程序应该发送4个字节,然后读取2个字节。(假设您拥有的寄存器是正确的,但如果您完全可以使用它们可能是正确的)那么再次发送4个字节...它可能并没有挂在发送部分而是接收端,因为它总是等待读取两个字节,如果由于某种原因,两个字节没有到达输入寄存器,你将继续等待。

也许当你对系统施加压力(发送字节太快)时,你会溢出输入缓冲区并最终丢失一个字节?因此永远不会得到两个字节并且会卡住。

  1. 你可以调试你被卡住的地方吗?它实际上是在接收循环中吗?
  2. 你可以限制从个人电脑到微型电脑的传输,这样你可以一次手动发送一个字节吗?
  3. micro和xbee接口之间有没有握手?可以被微观扼杀吗?