打印
[STC单片机]

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

[复制链接]
5601|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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位数据

如何得知数据没接收完?怎样修改呢?

使用特权

评论回复
5
ayb_ice| | 2016-7-6 15:11 | 只看该作者
收发两个字节组合一下就可以了

使用特权

评论回复
6
NE5532| | 2016-7-6 15:24 | 只看该作者
哎,翻译一下楼主的问题——怎么才能吃完一碗饭?一口一口的吃呗。

使用特权

评论回复
7
huzb11|  楼主 | 2016-7-6 16:00 | 只看该作者
wangyy608 发表于 2016-7-6 13:56
先不说这样的流程有什么问题,功能能不能实现。

dat1=S2BUF

因为要发的数据为16位,移8次从高8移往低8,我是这样理解的。不知道错没错?

使用特权

评论回复
8
wangyy608| | 2016-7-6 18:21 | 只看该作者
你操作的数据都是8位的,哪来高8位低8位

使用特权

评论回复
9
huarana| | 2016-7-6 21:51 | 只看该作者
囧 为啥不能按字节发呢

就算你存成16位的,但是在内存里还是按高低字节存的 所以收的时候你收成数组 或者结构体 不久完了

使用特权

评论回复
10
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发出去。其实就是做两次发。收的时候,像诸位说的一样,组合一下。

使用特权

评论回复
11
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

使用特权

评论回复
12
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;
}
发送见上面的代码。
接收必须使用缓存并保存每一个字节,并按照通讯协议解析。

使用特权

评论回复
13
ningling_21| | 2016-7-7 08:39 | 只看该作者
huzb11 发表于 2016-7-6 22:11
因为我发送的是16位,两个字节的,如:我给Send_com(1234)函数,发送的是两个字节16位的数,而这16位的数 ...

发送端先发高8位,再发低8位,接收端相反,先收到的是高8位,后收到的是低8位再组装成16位

使用特权

评论回复
14
huzb11|  楼主 | 2016-7-7 21:38 | 只看该作者
billliu66 发表于 2016-7-6 22:45
单片机间通信要保证可靠发送与接收需自订通信协议.只发送与接收两个字节也可不定义.这样改试试.typede ...

协议如何做?我现在想做个串口通信协议。如A单片机发送一条指令给B单片机,B单片机,收到后,返回一条指令给A单片机,A单片机再发送一条指令给B单片机,如此这般通信。。。。我上面的第二个程序其实只要去掉&0xff就可以顺利收发16位数据了,而且程序很简接,但就是没协议。

使用特权

评论回复
15
ningling_21| | 2016-7-8 10:35 | 只看该作者
huzb11 发表于 2016-7-7 21:38
协议如何做?我现在想做个串口通信协议。如A单片机发送一条指令给B单片机,B单片机,收到后,返回一条指 ...

协议可以自己定义,一般包括帧头,数据,帧尾,校验 等几部分
或使用已有协议如MODBUS等等

使用特权

评论回复
16
huzb11|  楼主 | 2016-7-14 16:30 | 只看该作者
ningling_21 发表于 2016-7-8 10:35
协议可以自己定义,一般包括帧头,数据,帧尾,校验 等几部分
或使用已有协议如MODBUS等等 ...

论坛里有坛友做过两个单片机之间串口多字节通讯协议程序吗?有的话,能否分享一下经验呢?

使用特权

评论回复
17
changle11sdo5| | 2016-7-14 18:49 | 只看该作者
都不是这样写

使用特权

评论回复
18
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啥关系。?

使用特权

评论回复
19
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;
}

使用特权

评论回复
20
yjmdxp| | 2017-7-13 15:59 | 只看该作者
串口收发都是以字节为单位完成的,你只能按照这个思路去想办法解决问题

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

55

帖子

1

粉丝