如何从仅8011的ONCE串行发送字符串?

Cod*_*sed 6 c embedded microcontroller serial-port 8051

我正在使8051微控制器与计算机进行无线通信.微控制器将字符串发送到其串行端口(DB9),计算机将接收该字符串并对其进行操作.

我的问题是我不知道如何让8051只传输一次字符串.由于我需要在PC端操作字符串,因此必须只接收一次.目前,即使在C代码中我发送一次字符串,在我的计算机上我连续收到相同的字符串.我认为这是因为SBUF中的任何内容都是连续传输的.有什么方法可以只发送一次我的字符串吗?有没有办法清空SBUF?

我试图在DB9上使用RTS(请求发送)引脚(第7个引脚),因为我读到某个地方,如果我否定了该引脚上的电压,它将阻止数据流到串行端口.所以我所做的是编程我的微控制器发送字符串,然后将逻辑电平0发送到连接到我的DB9 RTS引脚的输出引脚.但是,这没有用.

有没有人有什么建议?我真的很感激他们.

编辑

我在PC上使用的软件是Xbee模块的X-CTU.这是我的微控制器上的代码:

include reg51.h 
void SerTx(unsigned char);  
void main(void)  
{  
  TMOD = 0x20;  
  TH1 = 0xFD;  
  SCON = 0x50;  
  TR1 = 1;   

  SerTx('O');  
  SerTx('N');  
  SerTx('L');  
  SerTx('Y'); 

}

void SerTx(unsigned char x)  
{  
  SBUF = x;  
  while(TI==0);   
  TI = 0;   
}  
Run Code Online (Sandbox Code Playgroud)

有人可以验证它实际上只发送一次字符串吗?

编辑

看起来像史蒂夫,布鲁克斯和尼尔,当他们说这是我的主要功能导致问题之后发生的事情时,头部钉在头上.我刚刚尝试了Steve提出的建议代码(更具体地说是for(;;);并在main之外定义了serTX)并且它工作得很好.控制器可能重新启动,因此相同的代码不断重复.

非常感谢你的帮助!:)

Ste*_*off 6

你能确认8051真的只发送一次数据吗?一种检查方法是使用示波器来查看UART TX引脚上发生的情况.

你在PC上使用什么软件?我建议使用HyperTerminal或PuTTY等简单的通讯软件.如果他们多次显示发送到PC的字符串,则可能是8051上运行的软件出现故障.

编辑:说实话,这听起来像是工程师必须定期面对的那种调试,因此这是一个很好的机会让你练习老式的有条理的问题解决方法.

如果我可能非常生硬,我建议你做以下事情:

  1. 调试.尝试一下,但不要猜.实验.对代码进行细微更改,看看会发生什么.尝试你能想到的一切.在网上搜索更多信息.
  2. 如果这不能产生解决方案,那么请返回此处,并向我们提供我们需要的所有信息.这包括代码的相关部分,您正在使用的硬件的完整详细信息,以及您在步骤1中尝试的内容的相关信息.

编辑:我没有编辑问题的代表,所以这里是OP在她的问题评论中发布的代码:

#include<reg51.h>

void SerTx(unsigned char);

void main(void)
{
    TMOD = 0x20; TH1 = 0xFD; SCON = 0x50; TR1 = 1;
    SerTx('O'); SerTx('N'); SerTx('L'); SerTx('Y');

    void SerTx(unsigned char x)
        { SBUF = x; while(TI==0); TI = 0; } 
}
Run Code Online (Sandbox Code Playgroud)

正如Neil和Brooksmoses在他们的答案中提到的那样,在嵌入式系统中,主要功能永远不会被终止.因此,您需要将代码置于无限循环中(这可能是无意中发生的),或者在末尾添加无限循环,因此程序有效地停止.

此外,函数SerTx应该在main之外定义.这可能在语法上是正确的,但它使事情变得简单,而不是在其他函数中声明函数.

所以试试这个(我还添加了一些注释,试图让代码更容易理解):

#include<reg51.h>

void SerTx(unsigned char);

void main(void)
{
    /* Initialise (need to add more explanation as to what
        each line means, perhaps by replacing these "magic
        numbers" with some #defines) */
    TMOD = 0x20;
    TH1  = 0xFD;
    SCON = 0x50;
    TR1  = 1;

    /* Transmit data */
    SerTx('O'); SerTx('N'); SerTx('L'); SerTx('Y');

    /* Stay here forever */
    for(;;) {}

}

void SerTx(unsigned char x)
{
    /* Transmit byte */
    SBUF = x;

    /* Wait for byte to be transmitted */
    while(TI==0) {}

    /* Clear transmit interrupt flag */
    TI = 0;
} 
Run Code Online (Sandbox Code Playgroud)


Nei*_*eil 6

您发布的代码在main()中没有循环,因此您需要确定在发送'Y'后main()返回时编译器的C运行时所执行的操作.鉴于你的问题,我想编译器会生成一些代码来进行一些清理,然后重新启动微控制器(可能是硬件复位,也许只是重新启动C运行时).看起来你的程序与你编写的程序完全一样,但你忽略了调用main()之前和之后发生的事情.

如果您希望您的字符串只发送一次,那么您需要while(1) {}在发送最后一个字符后添加类似的内容.但是,那么你的程序什么都不做 - 它将永远执行一个空循环.需要重置(例如电源循环)才能重新启动,并发送字符串.

请注意,如果您的micro具有看门狗定时器,它可能会介入并强制意外重置.如果发生这种情况,您的字符串将在每次看门狗复位时发送一次(这可能类似于每秒一次,速率取决于您的硬件).

另外,serTx()定义嵌套在main()中可能不是你想要的.