关于单片机串口通讯:上位机发送数据到下位机,单片机保存数据到24c512;

关于单片机串口通讯:上位机发送数据到下位机,单片机保存数据到24c512;,第1张

看你主程序循环时间了,如果比整个数据包接收下来的时间要短的话,你可以建立两个缓冲区,对换进行接收数据。
一个数据包完成后建立一个标志,换一个缓冲接收;主程序一旦查到有标志位被置位,刚把相应缓冲区的内容写到EEPROM,再把标志清零。
程序需要两个缓冲区,一个缓冲标识位和一个接收完成标志位。
一般来说,主程序循环时间太长说明你的程序有些地方处理不好,可以把占用时间较长的函数进行分片处理。

下面是波特率9600的串口收发数据单片机程序,不知道不用的什么单片机,就没头文件了你自己给上。可以再电脑上用串口工具往单片机发数据,单片机在收到上位机数据的同时将数据送回上位机
char nCountRx,rec_1;
char TxBuffer1[8], RxBuffer1[8];
void Port_Init(void)
{
AUXR = 0x1D; //串口1,2使用独立波特率发生器1T模式,T0 T1 12T模式,S2SMOD = 1
//---定时器0,1------
TMOD=0x11; //定时器1为模式1,16位计数方式;定时器0设置为模式2,8位自动装载
SCON=0x50; //设置串口1为方式3,11位异步收发,1101 0000 - 9位可变波特率, 标志位,允许串口接受使能
PCON=PCON|0x80; //波特率加倍,9600;不加倍,4800 TR0=1; //启动定时器0
TR1=1; //启动定时器1
BRT=0xB8;//独立波特率发生器溢出率设定 SMOD=0 baundrate=4800
ES=1; //串口1中断允许位
EA=1; //中断总控制开关
}
//------------发送检查----------------------------
void Check_Uart() //判断串口中数据是否发送完毕
{
while(TI==0); // 等待数据发送结束
TI=0; //软件清零
}
//-------------发送一个字节到串口-----------------
void Write_Byte_Uart(unsigned char byte)
{
SBUF = byte; //发送的字节送串口缓存区保存
Check_Uart(); //检查串口数据是否发送完毕
}
//---------------------串口中断函数---用于接收串口数据-----------------
void UART_int() interrupt 4
{
if(RI)
{
nRxBuf[nCountRx]=SBUF;
for(i=0; i< nCountRx; i++) TxBuffer1[i] = RxBuffer1[i];
nCountRx++;
RI = 0;
}
nRxTime1=0;
}
void main(void)
{
char i;
Port_Init();
while(1)
{
if(rec_f==1)
{
for(i=0;i<8;i++)Write_Byte_Uart(TxBuffer1[i]);
rec_f=0;
}
}
}

这两个软件原理不一样,单片机应该和超级终端比较匹配吧!
超级终端的原理
超级终端的原理是将用户输入随时发向串口(采用TCP协议时是发往网口,这里只说串口的情况),但并不显示输入。它显示的是从串口接收到的字符。所以,嵌入式系统的相应程序应该完成的任务便是:
1、将自己的启动信息、过程信息主动发到运行有超级终端的主机;
2、将接收到的字符返回到主机,同时发送需要显示的字符(如命令的响应等)到主机。
串口调试助手的原理
一个很好而小巧的串口调试助手,支持常用的300-115200bps波特率,能设置校验、数据位和停止位,能以ASCII码或十六进制接收或发送任何数据或字符(包括中文),可以任意设定自动发送周期,并能将接收数据保存成文本文件,能发送任意大小的文本文件。
当然了,还有其它版本的相同功能的工具,也都叫 串口调试助手例如:
超级终端一般用于ASCII收发,并你按一个键该字符立刻发送,同时不会显示回车键;串口调试助手在你写完命令后还应加一个回车字符,而键盘上没有回车字符,这样你就必须有二进制方式。

在while(1);前面加一句 TI=1; 就可以了自己发送了。

不过这样的中断服务程序千万别拿去面试,很多人技术领导一看到写的代码中断服务程序中有delay()一类的东西就直接毙掉。

你可以在你的电脑和单品机通信的时候,自己定义一个通信协议——也就是定义一种通信格式:以什么字符作为一个数据包的开始如(0x66 0xab)代表数据帧的开头,之后的一个自己单表数据帧的总长度(如果所有的数据包是定长的可以不需要该字段),之后一个自己定义为命令的类型(如:0x01 表示电动机的转动方向;0x02 代表转动圈数等),之后跟上实际要发送给单品机的数据,如正传还是反转,转动的圈数是多少等。如果不放心你可以在最后加上数据帧的校验和,用来保证数据再传输过程中没有出错。

下位机只有一个吗,那你直接可以发送了,
Private Sub MSComm1_OnComm()
Dim temp As String
If MSComm1CommEvent = comEvReceive Then
temp = Asc(MSComm1Input)
//自定义
End If
MSComm1InBufferCount = 0
End Sub
注意你自定义的协议问题和进制的问题即可


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/10499475.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-09
下一篇 2023-05-09

发表评论

登录后才能评论

评论列表(0条)

保存