打印

求助:各位大哥怎么会出现这样的问题呢?(串口问题)

[复制链接]
1244|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
星星电灯|  楼主 | 2007-5-29 20:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//-------------------------------------头文件--------------------------------------
#include <reg52.h>
#include <absacc.h>
#include <intrins.h>
//-------------------------------------头文件--------------------------------------

//********定义引脚*************************************
sbit   P33      =    P3^3;    //喂狗
sbit   P23      =    P2^3;
sbit   D2       =    P0^2;    
//********定义引脚*************************************

//**************定义变量*************************************************
int WDogZdJs;   //喂狗中断计数
char  rece[5];      //接收的字符
int   j;
bit   receive;
//**************定义变量*************************************************


void delay()
{
    int i,j;
    for(i=0;i<100;i++)
       {
           for(j=0;j<10;j++)
              {
                  ;
              }
           }
}

void delay2()
{
    int i,j;
    for(i=0;i<100;i++)
       {
           for(j=0;j<500;j++)
              {
                  ;
              }
           }
}


void Sendtex() //向电脑发送字符 '1'
{
    SBUF='1';
  while(!TI)P33=~P33;
  TI=0;
}


void ComInStr() interrupt 4 //串行口中断
{
  if(RI)   //接收
  {
     if (j>4)
       {
               j=0;        
          }
     rece[j]=SBUF;
       j++;
     if(j>4)
       receive=1; //接收标志置位
     RI=0;
  }
   
}


void timer0(void) interrupt 1   //喂狗中断程序
{
  TH0 = (65536-5000)/256;     //重载计数初值 每 5 ms 中断一次
  TL0 = (65536-5000)%256;     //这是手动装置,如果 T0 为模式 1 的话,必须要手动装入
                              //如果如果 T0 为模式 2 的话,只要初始化了,
                              //则在这里可以不要 TH0 = (65536-5000)/256; TL0 = (65536-5000)%256;
  WDogZdJs ++;
  if ( WDogZdJs >= 10 )
       {
       P33 =! P33;  //不停喂狗
       WDogZdJs = 0;
    }
}


void main()
{
  delay();
  P0 = 0xff;
  P1 = 0xff;
  P2 = 0xff;
  P3 = 0xff;      
  P33 =! P33;
   
   EA = 0;
   
  
  TMOD=0x21;                  //定时器1模式1  定时器0模式1 
   //---------------------------处理串口中断---------------------------------------
      SCON=0x50;                  //串行口工作方式1, 10 位异步收发,波特率由定时器控制
   PCON |= 0x00;
   TL1=0xFA; 
   TH1=0xFA;                   //22.1184M晶振 波特率9600
   
   //---------------------------处理串口中断---------------------------------------
   
   //------------------------------处理中断喂狗------------------------------------  
   TH0 = (65536-1000)/256;     //预置计数初值,每 5 ms 中断一次
   TL0 = (65536-1000)%256;
   
   //------------------------------处理中断喂狗------------------------------------ 
   
   EA = 1 ;                    //允许中断
   ES = 1 ;                    //允许串行中断
   ET0 = 1;                    //T/C0 开中断(定时器0/计数器0)
   ET1 = 0;                    //T/C0 开中断(定时器0/计数器0)
   
   TR1=1;                      //启动定时器1/计数器1
   TR0 = 1;                   //启动定时器0/计数器0

   while(1)
    {
          if(receive)
              {
                Sendtex();
            receive = 0;         
              }                  
     }
}


请教:
void ComInStr() interrupt 4 //串行口中断
{
  if(RI)   //接收
  {
     if (j>4)
       {
               j=0;        
          }
     rece[j]=SBUF;
       j++;
     if(j>4)
     receive=1; //接收标志置位
     RI=0;
  }
   
}

说明介绍 5 个字符则  receive 置为 1

现在情况是这样的:
现象1:
当我用串口调试软件 发 '11111' 则 执行了 Sendtex();
是正确的
现象2:
我首先发送字符串 '111' ,没有执行 Sendtex(),
可是然后我发 字符串 '11' ,则执行 Sendtex(),
是两次总共发了 5 个字符啊。

是不是我需要自己写一个东西
表示多久没有接收到 新星,则把
前面的清空,

一般是多久啊?
这样的程序怎么写?

谢谢!

相关帖子

沙发
lbx_00| | 2007-5-29 20:41 | 只看该作者

为什么要用字符,用数

使用特权

评论回复
板凳
星星电灯|  楼主 | 2007-5-30 08:27 | 只看该作者

谢谢 为什么要用字符,用数,不明白啊

谢谢 
为什么要用字符,用数,
不明白啊

使用特权

评论回复
地板
infree| | 2007-5-30 11:33 | 只看该作者

为了解析简单,最好在串口接收空闲一段时间后将接收区清

最简单的方式是你在最后一个接收到字符后面加上'\0',然后用字符串函数strstr()来查找一个特定的字符串,你那个直接进行字节计数的方法太不可靠了。

直正用在控制方法时,一般是需要组织成一个帧的格式:包括帧头,帧尾,序号,校验等,根据这些来判断是否收到一个合格的帧。这是后话。

再有就是一般这种程序是分层来写的,在中断中收数,放入一个环型缓冲区,然后在主循环中进行解帧,进行命令判断等。

使用特权

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

本版积分规则

74

主题

121

帖子

1

粉丝