打印
[51单片机]

51串口通信问题

[复制链接]
919|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
圣灵枫|  楼主 | 2015-4-23 09:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
刚接触串口通信,PC给单片机发送一串数据,单片机接收后返还给PC机,用串口调试助手来收发数据,中断接收,查询发送,用超时法判断数据接收完成,但是程序调试一直没反应,求大家帮帮忙,看看是什么问题。下面附程序:
#include<STC12C5A32S2.H>
#include<INTRINS.H>
bit flag=0;
unsigned char idata tab[];  //定义数组用于存放数据
unsigned char j,cnt=0;
unsigned char i=0;

void UART_Rountine(void);   //串口中断函数声明

void Timer0_Rountine(void); //定时器中断函数声明

void UART_INIT()
{
  SCON=0X50;            //工作方式1,发送使能
  TMOD|=0X21;           //定时器1,工作方式2
  AUXR&=0x3F;                    //定时器0,1时钟为Fosc/12,即12T
  AUXR&=0xFE;                    //串口1选择定时器1为波特率发生器
  PCON&=0x7F;                    //波特率不加倍
  TH1=0XFC;             //波特率9600,时钟频率14.7456MHz
  TL1=0XFC;
  TH0=0XFB;             //定时长度1ms
  TL0=0X33;
  TR0=1;                //定时器0不使能,接收到数据在开始计时
  TR1=1;                //定时器1使能
  PS=1;                 //串口中断设为高优先级
  ES=1;                 //开串口中断
  ET1=0;                        //禁止定时器1中断
  ET0=1;                //开定时器0中断
  EA=1;                 //开总中断
}

void delay_1ms(unsigned int t)          //软件延时1ms
{
  unsigned int a,b;
  for(a=0;a<t;a++)
  for(b=0;b<1167;b++);
}

void mian(void)
{
  delay_1ms(100);                  //单片机上电延时
  UART_INIT();                     //初始化
  while(1)
    {
          if(flag==1)                  //检测到接收成功标志
            {
          flag=0;
                  ES=0;                    //关串口中断,查询法置TI也会产生中断,防止干扰
                  for(j=0;j<cnt;j++)       //查询法发送数据
                        {
                      SBUF=tab[j];
                      while(!TI);
                      TI=0;
                        }
                  cnt=0;                   //接收计数清零,等待下一次接收
                  ES=1;                    //发送完毕打开串口中断,等待下一帧数据接收
            }
    }
}

void UART_Rountine() interrupt 4
{
  if(RI)
    {
          TR0=0;                      //接收数据过程中定时器不工作
          i=0;                        //计数清0
          RI=0;
          tab[cnt++]=SBUF;            //接收数据
        }
  TR0=1;                          //接收完一个字节数据打开定时器,等待下一字节数据

}


void Timer0_Rountine() interrupt 1
{
  TH0=0XFB;             //定时长度1ms
  TL0=0X33;
  TF0=0;                //清除溢出标志
  i++;                  //没产生一次溢出中断,递增一次
  if(i==50)             //发送一个字节数据大概1ms,等待50ms还没有数据判断接收完毕
    {
      i=0;              //计数清零
          TR0=0;            //关定时器
      flag=1;           //接收成功标志
    }
}
大家帮忙看看,谢谢!

相关帖子

沙发
ningling_21| | 2015-4-23 09:46 | 只看该作者
定时器0是起什么作用?

使用特权

评论回复
板凳
圣灵枫|  楼主 | 2015-4-23 09:49 | 只看该作者
ningling_21 发表于 2015-4-23 09:46
定时器0是起什么作用?

超时法判断数据接收完毕,定时器0做延时的

使用特权

评论回复
地板
ningling_21| | 2015-4-23 10:03 | 只看该作者
圣灵枫 发表于 2015-4-23 09:49
超时法判断数据接收完毕,定时器0做延时的

这不是多此一举吗

使用特权

评论回复
5
圣灵枫|  楼主 | 2015-4-23 10:20 | 只看该作者
ningling_21 发表于 2015-4-23 10:03
这不是多此一举吗

不太明白您的意思,您说话太简洁了,我初学串口通信,不太懂这方面,看过很多论坛,都说数据接收是要用超时或帧头帧尾来判断接的,因为我发的数据长度是不定的,就用这种方法了。

使用特权

评论回复
6
ningling_21| | 2015-4-23 10:55 | 只看该作者
圣灵枫 发表于 2015-4-23 10:20
不太明白您的意思,您说话太简洁了,我初学串口通信,不太懂这方面,看过很多论坛,都说数据接收是要用超 ...

改一下主程序和串口中断程序  试试
while(1)
{
    ;
}

串口中断程序
{
   if(RI)
{
    RI=0;
    SBUF=SBUF;
}
  if(TI)
{
    TI=0;
}
}

使用特权

评论回复
7
xjyabc| | 2015-4-23 14:26 | 只看该作者
UART_INIT() 里面的TR0 = 1是不是错了。

使用特权

评论回复
8
圣灵枫|  楼主 | 2015-4-23 16:02 | 只看该作者
xjyabc 发表于 2015-4-23 14:26
UART_INIT() 里面的TR0 = 1是不是错了。

那个是我笔误,改过来了,不是这个问题

使用特权

评论回复
9
xujinxinyw| | 2015-4-23 16:55 | 只看该作者
什么是数据位不一定啊?当你使用串口发送数据时,无所谓是数字和字符,如果以十六进制发送,如果你发456987,那么程序就会将45发送出去,后面的数据虽然也发送给了SBUF,但你只读取了一次值,如果你的程序是在循环运行的话,那么就可以将剩下的值也接受,如果你发字符串的话,比如happy,那么如果程序在大循环中,一样可以将你发的数据以ASCLL码的形式完全接受并反馈给上位机!所以对于单片机来说,只要你打开了串口通信的功能,无所谓你发送了多少东西,只要你接受一次,他就会在发送下一位,而且,一旦SBUF的空间填满就会拉高RI并申请中断,此时后面的数据等待写入!直到你把SBUF的值读走并拉低RI,后面的数据才写入以供下次读取!所以不管你在上位机上发送多少数据,只要程序是循环的!那么他就可以读取多少并且反馈多少!
所以完全没必要那么写!附赠一个简单的串口通信的小程序!



#include<reg51.h>
void init_timer()
{
        TMOD=0x20;
        TH1=0xfd;
        TL1=0xfd;
        TR1=1;
        SM0=0;
        SM1=1;
        REN=1;

}


void main()
{
unsigned int temp=0;
        init_timer();
        while(1)
        {
                if(RI==1)
                {
                RI=0;
                temp=SBUF;
                 
                SBUF=temp;
                }
        }
}

使用特权

评论回复
10
diy1997| | 2015-4-23 18:21 | 只看该作者
长度不定,可以在开头把要发送的数据长度先发给接收方。

使用特权

评论回复
11
benbpig| | 2015-4-23 18:42 | 只看该作者
楼主你是试着用软件来模拟串口,没有把单片机串口当做硬件资源……

使用特权

评论回复
12
彭--博| | 2015-4-23 20:04 | 只看该作者
本帖最后由 彭--博 于 2015-4-23 20:05 编辑

楼主可以这样调试一把,先MCU发PC,看看正常不正常,然后232上RX和TX短接,看看能不能收到单片机自己发的数据。我对51已经忘个差不多了嘿嘿。可以在一帧数据收完之后,翻转一下LED,做个标示。

使用特权

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

本版积分规则

2

主题

9

帖子

0

粉丝