搜索
bottom↓
回复: 16

51单片机串口通讯,接收多字节

[复制链接]

出0入0汤圆

发表于 2012-9-17 11:10:34 | 显示全部楼层 |阅读模式
本帖最后由 lanfengxun 于 2012-9-17 11:33 编辑

/*************************串口初始化*******************************************/

void Inituart()
{      
        IE=0x90;                            //打开中断总开关及串口中断开关
        SCON = 0x50;                        //设定串行口工作方式1 允许接受
        TMOD = 0x20;                  //定时器1,自动重载, 产生波特率
//    PCON=0x80;                  // 加上他后波特率是19200  SMOD为1
        TL1 = 0xfa;   
        TH1 = 0xfa;                 //波特率为9600 ,221184MHz
        TR1 = 1;         
}

/**************************接收上位机传送数据***************************************/

void uart_js() interrupt 4    //RI==1时执行串口中断
{        
    uchar  static i ;
        if(RI==1)
        {
                RI=0;
                RX_BUF=  SBUF; //保存数据
                i++;
               
        }
        if(i==10)
        {
            i=0;
            RXend = 1;
                LED0=0;  //LED长亮
        }
    }
void main()
{
    uchar  j;
    Inituart();

    while(1)
   {
       while(RXend==0);  //waiting receive end
       RXend=0;
      for(j=0;j<10;j++)
     {
         TxBuf[j] =  RX_BUF[j];  //将需发送数据存入无线发送缓冲区
   }
  }
}

利用串口助手,从上位机向单片机一次发送十个字节,单片机无法接收到,因为灯没亮。请问哪位知道什么原因,实在调试不出来了,跪求!!!

出0入0汤圆

发表于 2012-9-17 11:23:29 | 显示全部楼层
呵呵, 51 程序 还是蛮好解决的,也就百十来行。 那么呢,首先看看串口中断设置部分,对照书本来。串口波特率,晶振计算,上位机波特率,COM口。程序记得打开总中断,串口接收中断。。如果遇到问题,应该排除法,简化问题,那么首先测试单个字节接收,如果接收到一个正确的,那么灯亮。如果这部能够实验了,那么至少保证,你串口设置是对的。  那么多个字节接收也很简单,只是程序思路问题。我贴个我用了很久的程序,不敢说最好,但是我觉得人家设计思路还蛮好的。

出0入0汤圆

发表于 2012-9-17 11:24:10 | 显示全部楼层

void uart_rx_isr(void) //接收中断函数
{
        uchar c;       
        c=SBUF;//c等于接收的字节;
        switch (recv_state)
        {
                case 0:
                if (c==0x02) // 是数组第一字节
                {
                        recv_state=1; // 进入下一个状态
                }
                else
                        recv_state=0; // 回到初始状态
                break;
               
                case 1:
                if (c!=0xff)  // 是数组第二字节          拢共 3位数据  中间这位 为数据位 就不进行校验判断了
                {
                        recv_state=2; // 进入下一个状态
                        Rx_Data=SBUF;  //把 这个数据 纪录下来 作为 后面的判断
                }
                else
                {
                        recv_state=0; // 回到初始状态
                }
                break;
               
                case 2:
                if (c==0x03)   // 是数组第三字节
                {
                        // recv_state=3; // 进入下一个状态
                          Flag=1;
                        recv_state=0; // 回到初始状态
                 }
                else
                {
                        recv_state=0; // 回到初始状态
                }
                break;
        }
}

void UART_interrupt() interrupt 4
{
        if(RI==1)//如果接收了数据(RI会置1)
        {
                RI=0; //先清零,下次可以在接收数据
                uart_rx_isr();         //调用数据判断这个函数
        }       
}

出0入0汤圆

发表于 2012-9-17 11:26:20 | 显示全部楼层
上面是三个字节接收,并且判断数据, 如果你要多个可自行添加。虽然复杂些,繁琐些,但是觉得还是可以的。如果看不懂,请打印一份,认真的看几十遍。分析其思路。写程序就是思路问题,新手的话,只有多写程序才行。 希望意见对你有帮助。

出0入0汤圆

 楼主| 发表于 2012-9-17 11:27:17 | 显示全部楼层
lyg407 发表于 2012-9-17 11:26
上面是三个字节接收,并且判断数据, 如果你要多个可自行添加。虽然复杂些,繁琐些,但是觉得还是可以的。 ...

好的,谢谢,我接收一个,灯是亮的。我在看看吧,多些

出0入0汤圆

发表于 2012-9-17 13:19:03 | 显示全部楼层
我自己焊接了一个串口小板子,一个串口接头和一个MAX232(四个104和一个47uF的电容),直接连接P3.0和P3.1,由于笔记本没有电脑没有串口,所以加了一根USB转串口线,USB转串口线连接上后就直接显示COM口,然后连接上我焊接的板子后就没有任何反映,串口调试助手接收不到任何数据,而且232有点微热,但是不烫。

出0入0汤圆

 楼主| 发表于 2012-9-17 13:31:27 | 显示全部楼层
Andy_MCU 发表于 2012-9-17 13:19
我自己焊接了一个串口小板子,一个串口接头和一个MAX232(四个104和一个47uF的电容),直接连接P3.0和P3.1, ...

你想表达?

出0入0汤圆

发表于 2012-11-8 17:45:22 | 显示全部楼层
lyg407 发表于 2012-9-17 11:24
void uart_rx_isr(void) //接收中断函数
{
        uchar c;       

你好 我正在找这种判断方式 我想问你下 如果我接收到的数据是多位的  尾数的数据还是用来设置用的 请问下 我可以怎么处理呢

出0入0汤圆

发表于 2013-7-14 10:53:08 | 显示全部楼层
mark            

出0入0汤圆

发表于 2013-7-15 10:10:28 | 显示全部楼层
      make

出0入59汤圆

发表于 2014-6-21 17:19:22 | 显示全部楼层
lyg407 发表于 2012-9-17 11:24
void uart_rx_isr(void) //接收中断函数
{
        uchar c;       

这个串口多字节通信方式不错!学习了

出0入0汤圆

发表于 2015-1-7 16:49:02 | 显示全部楼层
本帖最后由 changshs 于 2015-1-7 16:50 编辑

多字节数组可以考虑以帧的格式来发送/接收。
比如定义帧格式如下:
引导码+帧长度+帧长度+重复引导码+数据0+数据1.+。。。。数据n+校验高字节+校验低字节+结束码
设引导码=0xaa
帧长度=len
结束码=0xbb
串口中断接收函数如下:
void UART_interrupt() interrupt 4 using 2
{ unsigned char dat;
  
   if(RI)
   {  dat=SBUF;
      RI=0;
      }
  if(dat==0xaa)//接收到第一个0xaa 帧头
  { Recv_start_flag=1;//开始接收位
     }
  if(dat==0xbb)//接收到帧尾
{  Recv_start_flag=0;//
     dat_buff[Recvcount]=dat;//保存帧尾
     Recvcount=0;
     Recv_end_flag=1;//帧接收结束位 在主程序中用此位判断是否进行数据解析
     }
  if(Recv_start_flag)//开始接收
{  dat_buff[Recvcount]=dat;//保存接收的数据
   Recvcount++;
   if( Recvcount>n)//n数组的长度 防止接收的数据超长
   {  Recvcount=0;
        Recv_start_flag=0;
         }
   if(Recvcount==5)//已经接收了6个数据,判断帧格式是否正常
   {  if((dat_buff[0]!=dat_buff[3])&&(dat_buff[1]!=dat_buff[2]))//帧格式不对
        {   Recvcount=0;//清接收计数器
        Recv_start_flag=0;
            }
        }
      }
  
  }

出0入0汤圆

发表于 2015-9-26 10:40:28 | 显示全部楼层
                                                mark!

出50入0汤圆

发表于 2015-9-26 10:50:34 | 显示全部楼层
                    多谢分享!

出0入0汤圆

发表于 2015-9-28 16:35:15 | 显示全部楼层
纠结是实时处理还是缓存后处理接收到的数据。

出0入0汤圆

发表于 2015-12-3 16:40:05 | 显示全部楼层
lyg407 发表于 2012-9-17 11:24
void uart_rx_isr(void) //接收中断函数
{
        uchar c;       

这个c从SBUFF得到的,为啥要判断它,来决定是第几个字节

出0入0汤圆

发表于 2020-12-18 15:14:03 | 显示全部楼层
                                          MARK
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-20 03:02

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表