专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
51单片机
关于串口通讯的收发问题
2019-07-15 12:03
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
51单片机
5276
5
1374
我用485模块,无线传输模块,
单片机
双机通讯都出现了这样的问题:就是发送多次数据,才能接收一次。有时候发送两次接收一次,有时候三次接收一次。一般出现这种情况是什么问题?请各位大神解答。谢谢
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
左耳朵的耗子
1楼-- · 2019-07-15 17:28
很笼统的问题,怎么解答,只能猜了。查一查你的程序对不对
加载中...
缘起的风1111
2楼-- · 2019-07-15 19:57
左耳朵的耗子 发表于 2017-2-3 08:17
很笼统的问题,怎么解答,只能猜了。查一查你的程序对不对
前辈,这是我的485程序
#include <STC15F2K60S2.H>
#define uchar unsigned char
#define INBUF_LEN 5 //数据长度
unsigned char flag1=0;
unsigned char buffer[INBUF_LEN];
unsigned char checksum,point;
uchar bdata flag;
sbit tx_ok= flag ^ 2;
sbit RE_DE=P5^5;
sbit P3_5=P3^5;
sbit P3_4=P3^4;
bit read_flag= 0 ;
void delay(unsigned char n)
{
unsigned char i,j;
for(i=n;i>0;i--)
for(j=110;j>0;j--)
{
}
}
//发送单字符
void send_char_com( unsigned char ch)
{
tx_ok=0;
RE_DE=1;//开发送
TI=0;
SBUF=ch;
while(!tx_ok); //等待发送完成
delay(5);
RE_DE=0;
delay(2);
}
//向串口发送一个字符串,strlen为该字符串长度
void send_string_com( unsigned char *str, unsigned int strlen)
{
unsigned int k= 0 ;
do {
send_char_com(*(str + k));
k++;
} while (k < strlen);
}
void SerialIni(){
//SCON &= 0x2E; //先对需要设置的位进行清零 0010 1110 因为SCON所有位都是用于设置串行口1,所以这句可省略。
SCON = 0x50; /* SM0/FE | SM1 | SM2 | REN | TB8 | RB8 | TI | RI 设置串行口的工作方式1(SM0 SM1 0 1)即8位可变波特率方式;允许接收)*/
AUXR &= 0xBE; //先对需要设置的位进行清零 1011 1110
AUXR |= 0x00; /* T0x12 | T1x12 | UART_M0x6 | T2R | T2_C/T(T上画) | T2x12 | EXTRAM | S1ST2 定时器1时钟为Focs/12,即12T;串口1选择定时器1为波特率发生器。S1ST2:串行口1波特率发生器选择位。0:选择定时器1作为串行口1波特率发生器。 1:选择定时器2作为串行口1的波特率发生器,此时定时器1得到释放,可以作为独立的定时器使用。*/
TMOD &= 0x0F; //先清零定时器1的设置(高4位设置定时器1,低4位设置定时器0)
TMOD |= 0x20; /* GATE | C/T(T上画) | M1 | M0 | GATE | C/T(T上画) | M1 | M0 (定时器工作方式2)使用定时器1作为波特率发生器。*/
TH1 = 0xfd; //8位自动重装方式,TH1用于重置TL1初值。2的SMOD次方/32*(定时器1的溢出率或定时器2的溢出率)
TL1 = 0xfd; //晶振11.0592MHz,设置波特率为9600bps。SMOD属于PCON寄存器,为1时,波特率翻倍。
TR1=1; //定时器1启动
ES = 1; //开放串口中断
EA = 1; //开放CPU中断
}
void COM_send(void)
{
uchar i;
delay(1);
RE_DE=1;
delay(10);
for(i=1;i<9;i++)
{
TI=0;
tx_ok=0;
SBUF =buffer
;
while(!tx_ok);
}
TI=0;
delay(5);
RE_DE=0;
delay(2);
}
//主程序
void main(void)
{
RE_DE=0; //开接收
SerialIni(); //运行串口初始化函数
RE_DE=0;
delay(1);
P3_4=1;
while(1)
{
if(read_flag==1)
{
send_string_com(buffer,INBUF_LEN);
read_flag=0;
}
}
} //等待中断()
//中断函数
void Uart2(void) interrupt 4 using 1
{ unsigned char mydata;
if(RI) //如果是接收中断
{
RI=0;
mydata = SBUF; //将接收缓冲区的数据保存到mydata变量中
if( point==0 )
{
if(mydata==0x55)
{
buffer[point++]= mydata;}
else
{point=0; }
}
else
if(point>0&&point<4)
{ buffer[point++]= mydata; }
else
{
if (point==4)
{
if(mydata==0x11)
{
buffer[point]=mydata;
read_flag= 1 ;
}
else
point=0;
}
else
point=0;
}
}
// if (buffer[point] ==0x11)
// {
// read_flag= 1 ; //如果串口接收的数据达到INBUF_LEN个,且校验没错,
//就置位取数标志
// }
// }
// }
if(TI) //如果是发送中断,将TI清0
{
TI = 0;
tx_ok=1;
}
}
加载中...
海滨
3楼-- · 2019-07-16 00:06
单片机和通讯模块之间稳定性怎样?可以做个测试程序测一下稳定性。 如果怀疑通讯模块之间通讯问题,无线模块有没有带天线?如果没有带天线,通讯距离太短
加载中...
tatto_chen
4楼-- · 2019-07-16 05:47
精彩回答 2 元偷偷看……
加载中...
gniquhs
5楼-- · 2019-07-16 09:14
把波特率调小试试呗
加载中...
一周热门
更多
>
相关问题
【东软载波ESF0654 PDS开发板活动】开箱
1 个回答
东软载波ESF0654 PDS开发板外部中断
1 个回答
东软载波ESF0654 PDS开发板高级控制定时器AD16C4T
1 个回答
用串口调试助手为什么只能在hex模式接收发送而在文本模式不行
9 个回答
触摸芯片SC02B/SC04B在地砖灯的设计方案
1 个回答
东软载波ESF0654 PDS开发板串口USART0代码分享
1 个回答
普通32位单片机使用linux的应用代码
5 个回答
东软载波ESF0654 PDS开发板AT24C04的调试
9 个回答
相关文章
51单片机与蓝牙模块连接
0个评论
51单片机的硬件结构
0个评论
基于51单片机的无线遥控器制作
0个评论
51单片机 AD转换
0个评论
51单片机数码管递增显示
0个评论
如何实现对单片机寄存器的访问
0个评论
基于51单片机的指纹密码锁
0个评论
×
关闭
采纳回答
向帮助了您的网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
51单片机
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
关闭
您已邀请
15
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
前辈,这是我的485程序
#include <STC15F2K60S2.H>
#define uchar unsigned char
#define INBUF_LEN 5 //数据长度
unsigned char flag1=0;
unsigned char buffer[INBUF_LEN];
unsigned char checksum,point;
uchar bdata flag;
sbit tx_ok= flag ^ 2;
sbit RE_DE=P5^5;
sbit P3_5=P3^5;
sbit P3_4=P3^4;
bit read_flag= 0 ;
void delay(unsigned char n)
{
unsigned char i,j;
for(i=n;i>0;i--)
for(j=110;j>0;j--)
{
}
}
//发送单字符
void send_char_com( unsigned char ch)
{
tx_ok=0;
RE_DE=1;//开发送
TI=0;
SBUF=ch;
while(!tx_ok); //等待发送完成
delay(5);
RE_DE=0;
delay(2);
}
//向串口发送一个字符串,strlen为该字符串长度
void send_string_com( unsigned char *str, unsigned int strlen)
{
unsigned int k= 0 ;
do {
send_char_com(*(str + k));
k++;
} while (k < strlen);
}
void SerialIni(){
//SCON &= 0x2E; //先对需要设置的位进行清零 0010 1110 因为SCON所有位都是用于设置串行口1,所以这句可省略。
SCON = 0x50; /* SM0/FE | SM1 | SM2 | REN | TB8 | RB8 | TI | RI 设置串行口的工作方式1(SM0 SM1 0 1)即8位可变波特率方式;允许接收)*/
AUXR &= 0xBE; //先对需要设置的位进行清零 1011 1110
AUXR |= 0x00; /* T0x12 | T1x12 | UART_M0x6 | T2R | T2_C/T(T上画) | T2x12 | EXTRAM | S1ST2 定时器1时钟为Focs/12,即12T;串口1选择定时器1为波特率发生器。S1ST2:串行口1波特率发生器选择位。0:选择定时器1作为串行口1波特率发生器。 1:选择定时器2作为串行口1的波特率发生器,此时定时器1得到释放,可以作为独立的定时器使用。*/
TMOD &= 0x0F; //先清零定时器1的设置(高4位设置定时器1,低4位设置定时器0)
TMOD |= 0x20; /* GATE | C/T(T上画) | M1 | M0 | GATE | C/T(T上画) | M1 | M0 (定时器工作方式2)使用定时器1作为波特率发生器。*/
TH1 = 0xfd; //8位自动重装方式,TH1用于重置TL1初值。2的SMOD次方/32*(定时器1的溢出率或定时器2的溢出率)
TL1 = 0xfd; //晶振11.0592MHz,设置波特率为9600bps。SMOD属于PCON寄存器,为1时,波特率翻倍。
TR1=1; //定时器1启动
ES = 1; //开放串口中断
EA = 1; //开放CPU中断
}
void COM_send(void)
{
uchar i;
delay(1);
RE_DE=1;
delay(10);
for(i=1;i<9;i++)
{
TI=0;
tx_ok=0;
SBUF =buffer;
while(!tx_ok);
}
TI=0;
delay(5);
RE_DE=0;
delay(2);
}
//主程序
void main(void)
{
RE_DE=0; //开接收
SerialIni(); //运行串口初始化函数
RE_DE=0;
delay(1);
P3_4=1;
while(1)
{
if(read_flag==1)
{
send_string_com(buffer,INBUF_LEN);
read_flag=0;
}
}
} //等待中断()
//中断函数
void Uart2(void) interrupt 4 using 1
{ unsigned char mydata;
if(RI) //如果是接收中断
{
RI=0;
mydata = SBUF; //将接收缓冲区的数据保存到mydata变量中
if( point==0 )
{
if(mydata==0x55)
{
buffer[point++]= mydata;}
else
{point=0; }
}
else
if(point>0&&point<4)
{ buffer[point++]= mydata; }
else
{
if (point==4)
{
if(mydata==0x11)
{
buffer[point]=mydata;
read_flag= 1 ;
}
else
point=0;
}
else
point=0;
}
}
// if (buffer[point] ==0x11)
// {
// read_flag= 1 ; //如果串口接收的数据达到INBUF_LEN个,且校验没错,
//就置位取数标志
// }
// }
// }
if(TI) //如果是发送中断,将TI清0
{
TI = 0;
tx_ok=1;
}
}
一周热门 更多>