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)并且它工作得很好.控制器可能重新启动,因此相同的代码不断重复.
非常感谢你的帮助!:)
你能确认8051真的只发送一次数据吗?一种检查方法是使用示波器来查看UART TX引脚上发生的情况.
你在PC上使用什么软件?我建议使用HyperTerminal或PuTTY等简单的通讯软件.如果他们多次显示发送到PC的字符串,则可能是8051上运行的软件出现故障.
编辑:说实话,这听起来像是工程师必须定期面对的那种调试,因此这是一个很好的机会让你练习老式的有条理的问题解决方法.
如果我可能非常生硬,我建议你做以下事情:
编辑:我没有编辑问题的代表,所以这里是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)
您发布的代码在main()中没有循环,因此您需要确定在发送'Y'后main()返回时编译器的C运行时所执行的操作.鉴于你的问题,我想编译器会生成一些代码来进行一些清理,然后重新启动微控制器(可能是硬件复位,也许只是重新启动C运行时).看起来你的程序与你编写的程序完全一样,但你忽略了调用main()之前和之后发生的事情.
如果您希望您的字符串只发送一次,那么您需要while(1) {}在发送最后一个字符后添加类似的内容.但是,那么你的程序什么都不做 - 它将永远执行一个空循环.需要重置(例如电源循环)才能重新启动,并发送字符串.
请注意,如果您的micro具有看门狗定时器,它可能会介入并强制意外重置.如果发生这种情况,您的字符串将在每次看门狗复位时发送一次(这可能类似于每秒一次,速率取决于您的硬件).
另外,serTx()定义嵌套在main()中可能不是你想要的.