[STC单片机] 有关STC单片机与单片机之间,串口发送与接收16位数据问题

[复制链接]
 楼主| huzb11 发表于 2016-7-6 13:36 | 显示全部楼层 |阅读模式
本帖最后由 huzb11 于 2016-7-6 13:41 编辑

小弟在搞单片机与单片机通信,又遇到一个问题。

单片机与单片机间的串口通信,如何发送与接收16位的数据?
哪位大吓指点一下。下面是STC单片机程序,能正常发送与接收8位数据。。。

void send_com(u8 k)   //发送的数据长度为2^8-1=255
{
S2BUF=k;
while(!(S2CON&S2TI));
S2CON&=~S2TI;
}

u8 Recv_com(void)   //发送的数据长度为2^8-1=255
{
u8 dat;
while(!(S2CON&S2RI));
S2CON&=~S2RI;
return S2BUF;
}

后面经过反复修改,改成这样子,但只收到一个 个位数。其它都不显示

void send_com(u16 k)               
{
S2BUF=(k>>8)&0xff;
while(!(S2CON&S2TI));
S2CON&=~S2TI;

S2BUF=k&0xff;
while(!(S2CON&S2TI));
S2CON&=~S2TI;
}

u16 Recv_com(void)               
{
u16 dat;
u8 dat1;
u8 dat2;
while(!(S2CON&S2RI));
S2CON&=~S2RI;
dat1=S2BUF<<8;

while(!(S2CON&S2RI));
S2CON&=~S2RI;
dat2=S2BUF;

dat=dat1+dat2;
return dat;
}

这哪里又有问题?有兄弟搞过没?

bingg 发表于 2016-7-6 13:46 | 显示全部楼层
全部数据接收完后,再转换为16位数据
wangyy608 发表于 2016-7-6 13:56 | 显示全部楼层
先不说这样的流程有什么问题,功能能不能实现。

dat1=S2BUF<<8; 这个有问题
S2BUF是8位,左移8次?
 楼主| huzb11 发表于 2016-7-6 14:00 | 显示全部楼层
bingg 发表于 2016-7-6 13:46
全部数据接收完后,再转换为16位数据

如何得知数据没接收完?怎样修改呢?
ayb_ice 发表于 2016-7-6 15:11 来自手机 | 显示全部楼层
收发两个字节组合一下就可以了
NE5532 发表于 2016-7-6 15:24 | 显示全部楼层
哎,翻译一下楼主的问题——怎么才能吃完一碗饭?一口一口的吃呗。
 楼主| huzb11 发表于 2016-7-6 16:00 | 显示全部楼层
wangyy608 发表于 2016-7-6 13:56
先不说这样的流程有什么问题,功能能不能实现。

dat1=S2BUF

因为要发的数据为16位,移8次从高8移往低8,我是这样理解的。不知道错没错?
wangyy608 发表于 2016-7-6 18:21 | 显示全部楼层
你操作的数据都是8位的,哪来高8位低8位
huarana 发表于 2016-7-6 21:51 | 显示全部楼层
囧 为啥不能按字节发呢

就算你存成16位的,但是在内存里还是按高低字节存的 所以收的时候你收成数组 或者结构体 不久完了
 楼主| huzb11 发表于 2016-7-6 22:11 | 显示全部楼层
wangyy608 发表于 2016-7-6 18:21
你操作的数据都是8位的,哪来高8位低8位

因为我发送的是16位,两个字节的,如:我给Send_com(1234)函数,发送的是两个字节16位的数,而这16位的数,通过单片机串口8位发,通过移位,先把它拆成两个部分,那么就是高8位,移往低8位,先发出去,然后将低8发出去。其实就是做两次发。收的时候,像诸位说的一样,组合一下。
billliu66 发表于 2016-7-6 22:45 | 显示全部楼层
     单片机间通信要保证可靠发送与接收需自订通信协议.只发送与接收两个字节也可不定义.这样改试试.typedef union
{
   ui16 dat1;
   ui8   dat2[];
}dat;

void send_com1(u8 k)   //发送的数据长度为2^8-1=255
{
  if(S2CON&S2TI)
    S2CON&=~S2TI;
S2BUF=k;
while(!(S2CON&S2TI));
    S2CON&=~S2TI;
}

void send_com(u16 k)               
{
   ui8 x = k;
  send_com1(x);
   x = k>>8;
  send_com1(x);
}

u16 Recv_com(void)               
{
  dat mydat;
mydat.dat1 = 0;
while(!(S2CON&S2RI));
S2CON&=~S2RI;
mydat.dat2[1]=S2BUF;

while(!(S2CON&S2RI));
S2CON&=~S2RI;
mydat.dat2[0]=S2BUF;

return mydat.dat1;
}

接收数据最好用中断函数实现,并设置其优先级为HIGH
justtest111 发表于 2016-7-7 08:21 | 显示全部楼层
void uartsend(unsigned int d)
{
        SBUF = (unsigned char)(d>>8);         //16位 发出高8位
        while(TI==0);
        TI=0;
        SBUF = (unsigned char)(d);                   //再发低8位
        while(TI==0);
        TI=0;
}
发送见上面的代码。
接收必须使用缓存并保存每一个字节,并按照通讯协议解析。
ningling_21 发表于 2016-7-7 08:39 | 显示全部楼层
huzb11 发表于 2016-7-6 22:11
因为我发送的是16位,两个字节的,如:我给Send_com(1234)函数,发送的是两个字节16位的数,而这16位的数 ...

发送端先发高8位,再发低8位,接收端相反,先收到的是高8位,后收到的是低8位再组装成16位
 楼主| huzb11 发表于 2016-7-7 21:38 | 显示全部楼层
billliu66 发表于 2016-7-6 22:45
单片机间通信要保证可靠发送与接收需自订通信协议.只发送与接收两个字节也可不定义.这样改试试.typede ...

协议如何做?我现在想做个串口通信协议。如A单片机发送一条指令给B单片机,B单片机,收到后,返回一条指令给A单片机,A单片机再发送一条指令给B单片机,如此这般通信。。。。我上面的第二个程序其实只要去掉&0xff就可以顺利收发16位数据了,而且程序很简接,但就是没协议。
ningling_21 发表于 2016-7-8 10:35 | 显示全部楼层
huzb11 发表于 2016-7-7 21:38
协议如何做?我现在想做个串口通信协议。如A单片机发送一条指令给B单片机,B单片机,收到后,返回一条指 ...

协议可以自己定义,一般包括帧头,数据,帧尾,校验 等几部分
或使用已有协议如MODBUS等等
 楼主| huzb11 发表于 2016-7-14 16:30 | 显示全部楼层
ningling_21 发表于 2016-7-8 10:35
协议可以自己定义,一般包括帧头,数据,帧尾,校验 等几部分
或使用已有协议如MODBUS等等 ...

论坛里有坛友做过两个单片机之间串口多字节通讯协议程序吗?有的话,能否分享一下经验呢?
changle11sdo5 发表于 2016-7-14 18:49 来自手机 | 显示全部楼层
都不是这样写
joyphp 发表于 2017-6-23 11:46 | 显示全部楼层
billliu66 发表于 2016-7-6 22:45
单片机间通信要保证可靠发送与接收需自订通信协议.只发送与接收两个字节也可不定义.这样改试试.typede ...

u16 Recv_com(void)               
{
  dat mydat;
mydat.dat1 = 0;
while(!(S2CON&S2RI));
S2CON&=~S2RI;
mydat.dat2[1]=S2BUF;

while(!(S2CON&S2RI));
S2CON&=~S2RI;
mydat.dat2[0]=S2BUF;

return mydat.dat1;
}
这个mydat.dat1不还是0吗?和dat2啥关系。?
joyphp 发表于 2017-6-23 11:48 | 显示全部楼层
楼主问题搞定没?接收部分是否是对的?
u16 Recv_com(void)               
{
u16 dat;
u8 dat1;
u8 dat2;
while(!(S2CON&S2RI));
S2CON&=~S2RI;
dat1=S2BUF<<8;

while(!(S2CON&S2RI));
S2CON&=~S2RI;
dat2=S2BUF;

dat=dat1+dat2;
return dat;
}
yjmdxp 发表于 2017-7-13 15:59 | 显示全部楼层
串口收发都是以字节为单位完成的,你只能按照这个思路去想办法解决问题
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

55

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部