打印

51 单片机 串口通讯问题

[复制链接]
2026|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lxlfriend|  楼主 | 2007-5-23 11:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
源程序如下:
#include"reg51.h"
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
char temp;

char * data_string; 
char * data_back;

//******************函数声明******************
char Re_str(uchar *ans);
char Re_char(void); 
//void Data_deal(char *data2);
void Tr_char(char c);
char Tr_str(char *data1);
void Check_re(void);
void Check_tr(void);
void delay10mx(int count1);

void serial(void)interrupt 4 using 1  //串口中断服务程序

  
  uint i;
  ES=0;  //禁止串口中断
  P0=0xff;// 灯全灭,说明进入串口中断
 while(1){
  temp=Re_str(data_string);  // 接收数据,将接收到的数据给data_string字符串
  if(strncmp(data_string,"ok",2)==0)//判断接收到的字符串是否ok,若是,则处理该数据,然后返回
          {
        P0=0xfe;//最后一个灯亮,说明接收到“ok”,并成功判断出来
        Data_deal(data_back);//处理上次收到的字符串
        break;
        }
  else if(strncmp(data_string,"err",3)==0)//若接收到的数据是err,直接退出中断服务程序
         {
        P0=0xfd;//倒数第二个灯亮,说明接收到“err”并且成功判断出来
        break;
        }
  else
        {
        strcpy(data_back,data_string);
         P0=0xfb;//倒数第3个灯亮,说明接收到数据不是“ok”或“err”
              Tr_str(data_string);//若收到的数据既非ok亦非err,则将该数据原样返回
        }  
    for(i=0;i<temp;i++)
      { delay10mx(200);
        P0=data_string;
        }

      //P0=0x02;/
    }
  ES=1;                   //允许串口中断 
 } 


 void delay10mx(int count1)
  {
    int l ,j ,k;
       for (l=0;l<count1;l++)
       for (j=0;j<10;j++)
       for (k=0;k<120;k++)
       ;
  }
/**********接收一个字符****************************/
char Re_char(){
    char c;
    Check_re();
    c=SBUF;
    return c;
    }


/************ 接收字符串*************************/
char Re_str(uchar *ans)
{
   char i=0;
   while(1){
   P0=0x7f;// 第一个灯亮,说明进入字符串接收
   ans=Re_char();                    //接收字符
   P0=0xbf;//第2个灯亮,说明接收完一个字符
   if(i>2&&((ans==0x0a)||(ans==0x0d)||(ans==0x00))) 
   break;      //收到3个以上字符并收到回车返回
   else
   i++;
   }
   i++;
   ans=0x00;                      //末字节加0x00
   P0=0xdf;                //第3个灯亮,说明接收完一串
   return i;                            //接收字符串长度
}

/***********判断是否接收完一个字符********** di****/
void Check_re(){
   while(RI==0);
  RI=0;//  清接收完毕标志位
}
 
/***********判断是否发送完一个字符*******************/
void Check_tr(){
   while(TI==0);
  TI=0;//  清发送完毕标志位

}

/************发送一个字符*************************/
void Tr_char(uchar c){
    SBUF=c;              //发送字符
    Check_tr();         //等待发送完毕
    return;
}
/***********发送一个字符串***********************/
void Tr_str(uchar *data1){
   char i=0;
   while(data1!=0x00)
   {
   Tr_char(data1);
   i++;
   }
   return;
}

  
main(void)
{
  P0=0x00;
  TMOD=0x20;             //T1工作方式2
  TH1=0xfd;              //串口波特率为9600
  SCON=0x50;             //串口工作于方式1并允许接受
  TR1=1;                 //启动T1
  ES=1;                  //允许串口中断
  EA=1;                  //允许全部外设中断
  while(1);
 }

相关帖子

沙发
lxlfriend|  楼主 | 2007-5-23 11:09 | 只看该作者

串口通讯问题

编译通过,运行时用电脑通过串口调试助手发送A123回车,应该原样返回才对。结果一直是第一个灯亮,停在了ans=Re_char();  //接收字符
那里

使用特权

评论回复
板凳
救火车| | 2007-5-23 11:09 | 只看该作者

什么问题呀?说说现象!

使用特权

评论回复
地板
lxlfriend|  楼主 | 2007-5-23 11:35 | 只看该作者

51 串口通讯

发送 F100 
灯亮的次序为 01111111,11111101,11110001,00000000,11110001,回到01111111。
发送 A100 灯亮的次序为 01111111,11111101,01011110,00000000,01011110,回到01111111。
第一个灯亮说明进入了
P0=0x7f;// 第一个灯亮,说明进入字符串接收
   ans=Re_char();                    //接收字符
   P0=0xbf;//第2个灯亮,说明接收完一个字符
后面的就全部不对了。也没有返回数据给pc机

使用特权

评论回复
5
lxlfriend|  楼主 | 2007-5-23 11:45 | 只看该作者

51单片机串口通讯

/**********接收一个字符****************************/
char Re_char(){
    char c;
    Check_re();
    c=SBUF;
    return c;
    }

/***********判断是否接收完一个字符********** di****/
void Check_re(){
   while(RI==0);
  RI=0;//  清接收完毕标志位
}

这两个函数不该有问题的阿

使用特权

评论回复
6
lxlfriend|  楼主 | 2007-5-23 11:54 | 只看该作者

51 单片机 串口通讯问题

是用keil c开发的

使用特权

评论回复
7
lxlfriend|  楼主 | 2007-5-23 12:59 | 只看该作者

51 串口通讯

各位大侠帮忙看一下,多谢

使用特权

评论回复
8
infree| | 2007-5-23 15:47 | 只看该作者

你在中断里搞起了死循环

while(1){
这是很糟糕的程序结构。
建议你参考别人有关串口通信分层设计的思想,重新设计程序结构。
另:顺便说一下,根据我的经验,在中断服务例程中调用其它函数不是一个很好的作法。

使用特权

评论回复
9
古道热肠| | 2007-5-23 16:01 | 只看该作者

楼上说得对,要分层

  串口中断只管收发数据,设置接收与发送缓冲区,主程序分析协议比较好,简单的用查询法处理串口通讯,简单有时是可靠的同义词。

使用特权

评论回复
10
ww4u| | 2007-5-23 19:51 | 只看该作者

TI,RI必须软件清“0”

使用特权

评论回复
11
lxlfriend|  楼主 | 2007-5-24 08:50 | 只看该作者

51 单片机串口通讯

请问怎么分层?
是每来一个字节就产生一次中断的方式吗?
我现在的思路是来一串字符时用一次中断接收

使用特权

评论回复
12
conwh| | 2007-5-24 09:20 | 只看该作者

那是不可能的

使用特权

评论回复
13
lxlfriend|  楼主 | 2007-5-24 09:36 | 只看该作者

51 单片机串口通讯

就是说每次串口中断只能接收一个字符?
每来一个字符就要产生一次新的串口中断?

使用特权

评论回复
14
infree| | 2007-5-24 12:38 | 只看该作者

每来一个字符就要产生一次新的串口中断

是这样的,每发完一个字符也会产生一个中断

使用特权

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

本版积分规则

20

主题

58

帖子

0

粉丝