怎么我可以发送一串连续从一个8051只有一次?
-
06-07-2019 - |
题
我8051微控制器进行无线通信与计算机。微控制器,将发送一串到其串口(DB9)和计算机将收到这串和操纵。
我的问题是,我不知道如何使8051发射的串只有一次。因为我需要操纵串的电脑终端必须只收到一的时间。目前,即使在C码我送串一次,我的电脑上我收到同样的串连续进行。我假设这是因为,无论是在SBUF是连续传送。是否有任何办法,我可以送我的串只有一次?有一种空SBUF?
我试图使用RTS(发送请求)的销(第7销)在DB9因为我读的地方,如果我否定电压,在该销它将停止流动的数据序列港口。所以我做了什么是我的微控制器发送的串然后送逻辑级别0输出销,这是连接到我的DB9RTS销。然而,这没工作。
没有任何人有任何建议?我真的很感激他们。
编辑
软件,我使用电脑X-CTU为Xbee模块。这是码在我的微控制器:
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;
}
可能有人请确认这是在实际上只发送串一次?
编辑
看起来像史蒂夫,brookesmoses和Neil打钉子的头,当他们说这是发生了什么事之后,我的主要功能,是造成该问题。我只是试图建议的代码史蒂夫把(更具体地说for(;;);和定义serTX外的主要)和它的完美工作。控制器可能是重新启动,因此同样的代码不断重复本身。
谢谢你的帮助!:)
解决方案
你能确认8051真发送的数据仅仅一次?一的方式检查将使用一个范围来看看发生了什么事的串口的TX销。
什么软件的使用的电脑?我建议使用简单的通信软件,如超级终端或 腻子.如果他们表示的串被送到电脑多次,然后有机会的错误在上运行的软件8051.
编辑: 说实话,这听起来像是那种调试该工程师必须面对定期的基础上,因此,这是一个很好的机会,让你练习好的老式有条不紊地解决问题。
如果我可以非常直率,我建议你做到以下几点:
- 调试。尝试的东西出来,但是 不要猜测.实验。作很小的改变你的代码看看会发生什么。尝试一切你可以想到的。搜索网页的更多信息。
- 如果这不会产生一个解决方案,然后回到这里,为我们提供所有我们需要的信息。这包括有关代码,全部硬件的细节,你们使用和有关的信息什么你试图中的步骤1。
编辑: 我没有代表编辑的问题,因此,这里的代码的发布通过运算在评论她的问题:
#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; }
}
因为Neil和Brooksmoses提到在他们的答复,在一个嵌入式系统的主要功能是不允许的终止。所以你需要把你的代码,在一个死循环(可能是什么是无意中发生),或者添加一个无限循环结束时,因此该方案有效地暂停。
此外,功能SerTx应该定义之外。这可能是syntatically正确的,但它使事情简单不宣布职能的其他职能。
所以,试试这个(我还添加了一些意见在试图使代码更容易理解):
#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;
}
其他提示
您发布的代码在main()中没有循环,因此您需要确定在发送'Y'后main()返回时编译器的C运行时所执行的操作。鉴于你的问题,我想编译器生成一些代码来做一些清理,然后重启微(可能是硬件复位,也许只是重新启动C运行时)。看起来你的程序与你编写的程序完全一样,但是你忽略了调用main()之前和之后发生的事情。
如果你希望你的字符串只发送一次,那么你需要像这样的东西,而在发送最后一个字符后添加(1){}
。但是,那么你的程序什么都不做 - 它将永远执行一个空循环。需要重置(例如电源循环)才能再次启动,并发送字符串。
请注意,如果您的micro具有看门狗定时器,它可能会介入并强制意外重置。如果发生这种情况,您的字符串将在每次看门狗复位时发送一次(可能类似于每秒一次,速率取决于您的硬件)。
另外,将serTx()定义为嵌套在main()中可能不是你想要的。
如果没有看到任何8051代码,很难说出问题是什么。例如,该方面的逻辑错误可能导致数据被多次发送,或者8051软件可能正在等待从未收到的ACK等等。
通常在8051代码上必须显式发送每个字符,但我认为这是由C运行时为你处理的。
使用RTS / CTS(请求发送/清除发送)用于流量控制(即防止缓冲区溢出 - 这些微控制器上的缓冲区通常非常小),而不是完全停止传输。
回应Neil的回答(在回复中,因为我还没有代表发表评论):在没有操作系统的典型微控制器情况下,不能立即清楚在最后隐式调用的exit()函数是什么main()应该做 - 或者更准确地说,它不能做通常的“结束程序并返回到OS”,因为没有OS可以返回。
此外,在实际应用程序中,除非关闭系统,否则几乎不需要程序停止。因此,exit()实现绝对不应该做的一件事就是占用大量的代码空间。
在我曾经使用的一些系统中,exit()实际上根本没有实现 - 如果你不打算使用它,甚至不要在它上面浪费一个字节!结果是当执行路径到达main()的末尾时,芯片只是徘徊在执行下一位存储器中的任何事件的lala land中,并且通常很快就会陷入循环或者发生非法操作错误。非法操作码出错的通常结果是......重新启动芯片。
对于这里发生的事情,这似乎是一个可信的理论。
这篇特别的文章是用于汇编而不是C,但它可能有用: http://www.8052.com/tutser.phtml