打印

发送和接收都实现不了

[复制链接]
1156|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yufe|  楼主 | 2021-11-13 17:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
主机每200ms向从机发送一次数据,从机接收到后,如果判断数据接收没有错误,就将数据返回到主机使主机的LED1灯亮。但是现在发送和接收都实现不了,我看到SBUF里没有数据。好像一用定时器定时发送数据就有问题,不知道是怎么回事。
1,主机程序:
#include<REG52.H>
sbit         LED1=P0^0;
unsigned char data1[6]; //发送协议
unsigned char data2[6]; //接收协议
void init_serial0();         //定时器0初始化
void init_serial1(); // 串口初始化
unsigned char ecc=0x00;
int i,a=0;

/****************** 发送数据 **********************/
void send_data(unsigned char *data1)
{
/* 发送数据 */
for(i=0; i<5; i++)
{
TI = 0;
SBUF = data1; // 发送数据        
while(!TI);
TI = 0;
}
}           
   /****************初始化串口 ********************/
void init_serial1()
{
TMOD = 0x20;        //定时器T1使用工作方式2
TH1 = 250; // 设置定时器T1初值250,是波特率为4800bps,
TL1 = 250;        
TR1 = 1; // T1开始计时
PCON = 0x80; // SMOD = 1        ,波特率4800加倍
SCON = 0x50;        //工作方式1,波特率9600bps,允许接收
}
/* *****************定时器0 **********************/
void init_serial0()
{
TMOD = 0x10;        //定时器T0使用工作方式1
TH0 = 0xB8; // 设置定时器T0初值20ms,
TL0 = 0x00;        
TR0 = 1; // T0开始计时        
ET0=1;        //允许定时器0中断
EA=1;        //CPU开放中断   
}
/*************** T0溢出中断,使用工作模式1,每20ms发送一次数据*********** */
void timer0_int () interrupt 1 //using 0         // T0溢出中断,使用工作模式1
{           
TH0 = 0xB8; // 重新装入初值
TL0 = 0x00;  
   a++;
   if(a==10)
   {
send_data(data1);//发送数据
   a=0;        
   }
/* **********************主程序******************** */
void main(void)
{
   
         data1[0]=0xC5;//包头  
data1[1]=0x08;//数据内容
data1[2]=0xF6;
data1[3]=0xC8;
data1[4]=0xC5+ data1[1]+ 0xF6+0xC8;//校验字节,和自动溢出取最低8位           
   init_serial1(); // 串口初始化
   init_serial0(); //定时器0初始化
   TI=0;
RI=0;        
IE=0x9A; //开所有中断
IP=0x01; //定时器0中断优先

while(1)        //循环等待
   {

  }
}

void Serial_INT() interrupt 4        //串口中断服务程序
{        int i;         
        /* 接收数据 */
for(i=0; i<5; i++)
{         RI=0;
while(!RI);
data2 = SBUF; // 接收数据
RI = 0;        
}
ecc=0xC5+ data1[1]+ 0xF6+0xC8;//校验字节,和自动溢出取最低8位
data2[5]=0;         // 表示数据结束
   
/* 进行数据校验《若正确则控制相对应的指示灯 */
if((data2[0]==0xC5)&&(data2[4]==ecc))        
{
   if((data2[1]&0x80)==0x80) //高电平灭
   LED1=1;
   else
   LED1=0;         //低电平亮   
}           
}

2,从机程序:
#include<REG52.H>
sbit         LED1=P0^0;
unsigned char data2[6]; //接收协议
void init_serial0();         //定时器0初始化
void init_serial1(); // 串口初始化
unsigned char ecc=0x00;
int i;

/****************** 发送数据 **********************/
void send_data(unsigned char *data1)
{
int i;        
/* 发送数据 */
for(i=0; i<5; i++)
{
TI = 0;
SBUF = data1; // 发送数据         while(!TI);
TI = 0;
}
}           
   /****************初始化串口 ********************/
void init_serial1()
{
TMOD = 0x20;        //定时器T1使用工作方式2
TH1 = 250; // 设置定时器T1初值250,是波特率为4800bps,
TL1 = 250;        
TR1 = 1; // T1开始计时
PCON = 0x80; // SMOD = 1        ,波特率4800加倍
SCON = 0x50;        //工作方式1,波特率9600bps,允许接收
}
/* **********************主程序******************** */
void main(void)
{           
   init_serial1(); // 串口初始化
   TI=0;
RI=0;        
IE=0x98; //开所有中断(除过定时器0)
IP=0x10; //串口中断优先

while(1)        //循环等待
   {

  }
}

void Serial_INT() interrupt 4        //串口中断服务程序
{           
         /* 接收数据 */
for(i=0; i<5; i++)
{         RI=0;
while(!RI);
data2 = SBUF; // 接收数据
RI = 0;        
}
ecc=0xC5+ data2[1]+ 0xF6+0xC8;//校验字节,和自动溢出取最低8位
data2[5]=0;         // 表示数据结束         
/* 进行数据校验,若正确则返回到主机 */
if((data2[0]==0xC5)&&(data2[4]==ecc))           
          send_data(data2);
   
}

使用特权

评论回复
沙发
dengdc| | 2021-11-13 17:38 | 只看该作者
void Serial_INT() interrupt 4        //串口中断服务程序
{           
         /* 接收数据 */
for(i=0; i<5; i++)
{         RI=0;
while(!RI);
data2 = SBUF; // 接收数据
RI = 0;        
}
ecc=0xC5+ data2[1]+ 0xF6+0xC8;//校验字节,和自动溢出取最低8位
data2[5]=0;         // 表示数据结束         
/* 进行数据校验,若正确则返回到主机 */
if((data2[0]==0xC5)&&(data2[4]==ecc))           
          send_data(data2);
   
}
以上代码乱七八糟,逻辑严重错误,串口中断的基本架构一定是
void uart_isr(void) interrupt 4
{
     if(RI){
         RI = 0;
         ...
     }

    if(TI){
         TI = 0;
         ...
     }
}

使用特权

评论回复
板凳
jiajs| | 2021-11-13 17:40 | 只看该作者
/****************** 发送数据 **********************/
void send_data(unsigned char *data1)
{
/* 发送数据 */
for(i=0; i<5; i++)
{
TI = 0;
SBUF = data1;    // 发送数据  
while(!TI);
TI = 0;
}
}           
类似错误太多了吧。一个一个改?

使用特权

评论回复
地板
yufe|  楼主 | 2021-11-13 17:43 | 只看该作者
那是不是只要把这改了就应该没问题了?我也是在书上看到的接收数据的程序代码,只是那个原本有通信的握手协议的,我没有用握手协议

使用特权

评论回复
5
renyaq| | 2021-11-13 17:45 | 只看该作者

下面的错误太明显了吧?这不等于串口最终没有时钟?TMOD=0x10;第二个TMOD是不是应该写成TMOD|=0x01;

/****************初始化串口 ********************/
void init_serial1()
{
TMOD = 0x20;        //定时器T1使用工作方式2
TH1 = 250; // 设置定时器T1初值250,是波特率为4800bps,
TL1 = 250;        
TR1 = 1; // T1开始计时
PCON = 0x80; // SMOD = 1        ,波特率4800加倍
SCON = 0x50;        //工作方式1,波特率9600bps,允许接收
}
/* *****************定时器0 **********************/
void init_serial0()
{
TMOD = 0x10;     //  把前面的0x20覆盖了!   //定时器T0使用工作方式1
定时器0没设置好,如何定时发送?
定时器1又覆盖了,即使定时200ms能启动发送,没有波特率时钟,也发不出来呀。

使用特权

评论回复
6
renyaq| | 2021-11-13 17:47 | 只看该作者
根本没有仔细看你的程序
因为粗略看就有很多问题

使用特权

评论回复
7
dengdc| | 2021-11-13 17:51 | 只看该作者
TMOD重载

使用特权

评论回复
8
shimx| | 2021-11-13 17:53 | 只看该作者
定时器0中断程序里代码太多了吧

使用特权

评论回复
9
午夜粪车| | 2021-11-13 17:56 | 只看该作者
串口中断代码没有写对

使用特权

评论回复
10
yufe|  楼主 | 2021-11-13 17:58 | 只看该作者
好的,我明天去单位试一下,多谢各位大侠了哈

使用特权

评论回复
11
llia| | 2021-11-13 18:01 | 只看该作者
蜂鸣器
扬声器

使用特权

评论回复
12
huangchui| | 2021-11-13 18:06 | 只看该作者
没有区别,只是不同的符号罢了。

使用特权

评论回复
13
chuxh| | 2021-11-13 18:11 | 只看该作者
没有区别,只是不同的符号罢了。

使用特权

评论回复
14
jlyuan| | 2021-11-13 18:13 | 只看该作者
要那么多当然是各取所需了,不同元器件的封装当然不同,可能只是你用到这个元器件,但也可能有人用到另一个呢

使用特权

评论回复
15
llia| | 2021-11-13 18:16 | 只看该作者
呵呵,了解了,我就是好奇,呵呵

使用特权

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

本版积分规则

983

主题

10170

帖子

1

粉丝