打印

这个双机通信为什么有问题?

[复制链接]
1974|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhangxxyuan|  楼主 | 2010-5-28 21:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zhangxxyuan 于 2010-5-28 21:52 编辑

主机每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);
  
}

相关帖子

沙发
ayb_ice| | 2010-5-29 08:31 | 只看该作者
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;
        ...
    }
}

使用特权

评论回复
板凳
冷漠| | 2010-5-29 10:37 | 只看该作者
/****************** 发送数据 **********************/
void send_data(unsigned char *data1)
{
/* 发送数据 */
for(i=0; i<5; i++)
{
TI = 0;
SBUF = data1;    // 发送数据  
while(!TI);
TI = 0;
}
}           


类似错误太多了吧。一个一个改?

使用特权

评论回复
地板
zhangxxyuan|  楼主 | 2010-5-29 15:13 | 只看该作者
3# 冷漠 编辑里面有那个中括号的,只是正常的页面却不显示,应该是网站的问题

使用特权

评论回复
5
zhangxxyuan|  楼主 | 2010-5-29 15:14 | 只看该作者
2# ayb_ice 那是不是只要把这改了就应该没问题了?我也是在书上看到的接收数据的程序代码,只是那个原本有通信的握手协议的,我没有用握手协议

使用特权

评论回复
6
冷漠| | 2010-5-30 19:40 | 只看该作者
本帖最后由 冷漠 于 2010-5-30 22:57 编辑

下面的错误太明显了吧?这不等于串口最终没有时钟?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能启动发送,没有波特率时钟,也发不出来呀。

使用特权

评论回复
7
ayb_ice| | 2010-5-31 09:22 | 只看该作者
根本没有仔细看你的程序
因为粗略看就有很多问题

使用特权

评论回复
8
zhangxxyuan|  楼主 | 2010-5-31 18:32 | 只看该作者
问题解决了,一个是TMOD重载的问题,一个是定时器0中断程序里代码太多,一个是串口中断代码没有写对,

使用特权

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

本版积分规则

0

主题

15

帖子

1

粉丝