【问题标题】:How do I continuously send and receive with wireless serial-port in 8051?如何在 8051 中使用无线串口连续发送和接收?
【发布时间】:2009-10-24 19:10:49
【问题描述】:

我正在尝试让微控制器与我桌面上的程序进行通信。我在两端都使用带有 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() 函数一样,它不起作用。

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

【问题讨论】:

  • 一个快速而肮脏的 hack 可以让你的代码更可靠,它是限制等待 RI 设置为 true 的时间。将变量设置为 65535 并递减。如果在你得到一个字节之前它达到 0,放弃并再次尝试发送。如果您确实需要基于中断的代码版本,我可以为您提供帮助 - 通常这些更可靠。

标签: embedded serial-port wireless 8051 zigbee


【解决方案1】:

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

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

也可以使用轮询通信来实现这一点,但是您需要编写一个函数来检查字符是否可用于接收(或 tx-empty),以读取/写入下一个字符缓冲区。

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

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

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

祝你好运。

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

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

所以要诊断:检查溢出位。如果它被设置,你已经丢失了数据,你需要处理中断函数。如果可能,监视双方(至少是状态;例如,一个 LED 闪烁表示发送,一个表示接收)。

rs232 监视器可能会帮助您(为此您需要一些额外的端口。有许多(包括免费软件)应用程序可以监控多个 rs232 端口并提供时间戳。因此您可以观察通信顺序。Google 找到了我:link;过去几年我用过几个类似的实用程序。

【讨论】:

  • 非常感谢您对 Adriaan 的建议。但我很困惑。我有一种预感,它可能由于阻塞方面而无法工作,但我认为我编写程序的方式会绕过它。看到我让控制器发送一个消息,而桌面程序正在使用 Receive() 等待它然后桌面程序检查消息,看看它是否可以接受(所有这些都在控制器程序等待接收时),然后发送一个消息信号接受或拒绝味精。被阻塞的控制器中的 Receive() 现在被解除阻塞了不是吗?
  • 那么它不应该继续处理其余的代码吗?那就是检查收到的消息是接受还是拒绝(在此期间台式计算机正在等待接收阻塞)然后再次发送消息?我确信异步通信会像你说的那样解决这个问题,但是我的这个项目有点截止日期,我从来没有尝试过异步通信。如果您能通过同步解决这个问题,我将非常感激!
  • 嗯...我认为这很可能就是这里发生的事情。虽然我不完全理解如何将两条消息从控制器发送到桌面以及将两条消息从桌面发送回控制器可以一次工作,而不是当我将相同的代码放在一个循环中时,我想我只需要假设消息在连续发送和接收中丢失,最终都在阻塞的接收函数中等待。 :( 我会按照你的建议尝试监控双方。谢谢!
【解决方案2】:

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

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

  1. 你能调试你卡住的地方吗?实际上是在接收循环中吗?
  2. 能否限制从 pc 到 micro 的传输,以便一次手动发送一个字节?
  3. micro 和 xbee 接口之间是否有任何握手?能被微管节制吗?

【讨论】:

  • 是的,西蒙,你是对的,它应该发送 4 个字节然后接收 2 个字节,依此类推,直到收到某个答案。我很确定问题确实出在接收部分,仅仅是因为 Xbee 在发送或接收时会亮起。所以我可以“看到”桌面程序的 2 个字节已经离开桌面,也可以“看到”它们到达微控制器。之后控制器代码不再处理它。正如你所说,我确实尝试通过手动发送一个字节来进行调试。但是还是不行。
  • 我不确定 micro 和 Xbee 之间的握手。但我很确定没有。
  • @CudeConfused,你能确定 RI 位是否/多少次被更改?有时当您发送一个字节时,RI 位未设置。在你清除它之前有什么东西会触发 RI 从而错过第二个字节吗?
  • 如果 RI 位没有被设置,那么它对于单个两个消息的发送和接收也不起作用,对吗?但这确实有效。只有当我将相同的代码放入循环时它才不起作用。
  • @CodeConfused (抱歉最后一条评论中的错字,无法编辑 cmets ;))我不太了解工作与非工作情况?我认为你需要更具体。我喜欢 Adriaan 的建议,即在接收循环中读取溢出位。我认为为收到的每个字节闪烁 LED,将确认您只读取一个字节,然后永远等待。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多