打印

一用定时器定时发送数据就有问题

[复制链接]
1516|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wyjie|  楼主 | 2012-12-15 10:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
主机每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);
  
}
沙发
yszong| | 2012-12-15 10:30 | 只看该作者
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;
        ...
    }
}

使用特权

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

使用特权

评论回复
地板
wyjie|  楼主 | 2012-12-15 11:19 | 只看该作者
/****************** 发送数据 **********************/
void send_data(unsigned char *data1)
{
/* 发送数据 */
for(i=0; i<5; i++)
{
TI = 0;
SBUF = data1;    // 发送数据  
while(!TI);
TI = 0;
}
}           
类似错误太多了吧。一个一个改?

使用特权

评论回复
5
wyjie|  楼主 | 2012-12-15 11:22 | 只看该作者
dengdc 发表于 2012-12-15 11:18
/****************** 发送数据 **********************/
void send_data(unsigned char *data1)
{

那是不是只要把这改了就应该没问题了?我也是在书上看到的接收数据的程序代码,只是那个原本有通信的握手协议的,我没有用握手协议

使用特权

评论回复
6
wuhany| | 2012-12-15 11:23 | 只看该作者
下面的错误太明显了吧?这不等于串口最终没有时钟?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
jiahy| | 2012-12-15 11:26 | 只看该作者
根本没有仔细看你的程序
因为粗略看就有很多问题

使用特权

评论回复
8
lizye| | 2012-12-15 11:26 | 只看该作者
TMOD重载

使用特权

评论回复
9
shimx| | 2012-12-15 11:28 | 只看该作者
定时器0中断程序里代码太多了吧

使用特权

评论回复
10
jiaxw| | 2012-12-15 11:28 | 只看该作者
串口中断代码没有写对

使用特权

评论回复
11
wyjie|  楼主 | 2012-12-15 11:29 | 只看该作者
多谢大家,解决了

使用特权

评论回复
12
wyjie|  楼主 | 2012-12-15 11:30 | 只看该作者
结贴了啊

使用特权

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

本版积分规则

927

主题

12706

帖子

5

粉丝