微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 单片机与电脑通信,字符串处理问题

单片机与电脑通信,字符串处理问题

时间:10-02 整理:3721RD 点击:
程序功能: 从串口接收数据,并将数据转换为十进制数,然后提取位权数,将每位转换为四个Bit               然后每八个Bit为一组,分别输出至P0,P1,P2;

数据结构: 第一个字节为命令字,设定命令为0xAA, 2~5为需要转换的十六进制数,数据范围是                          0~999999,最后一个是结束字符'Z';

问题    :  在提取字符串时候出现问题,具体问题看程序,是不是不使用串口中断会好一点?


程   序:



  1. /*-----------------------------------------------
  2.   名称:串口通信,数据转换输出
  3.   内容:通过串口通信,将数据每一位输出至端口P0,P1,P2
  4.         没位占四个Bit,数据范围0~999999

  5. ------------------------------------------------*/

  6. #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义                        
  7. #include "string.h"
  8. /*------------------------------------------------
  9.                    变量声明
  10. ------------------------------------------------*/
  11. #define uchar unsigned char ;
  12. #define uint unsigned int ;

  13. uchar Temp[32],*c;
  14. uint flag=0;
  15. /*------------------------------------------------
  16.                    函数声明
  17. ------------------------------------------------*/
  18. void Communicate(void);
  19. void SendStr(unsigned char *s);
  20. int  SET_RES(unsigned char *r);
  21. /*------------------------------------------------
  22.                     串口初始化
  23. ------------------------------------------------*/
  24. void InitUART  (void)
  25. {

  26.     SCON  = 0x50;                        // SCON: 模式 1, 8-bit UART, 使能接收  
  27.     TMOD |= 0x20;               // TMOD: timer 1, mode 2, 8-bit 重装
  28.     TH1   = 0xFD;               // TH1:  重装值 9600 波特率 晶振 11.0592MHz  
  29.     TR1   = 1;                  // TR1:  timer 1 打开                        
  30.     EA    = 1;                  //打开总中断
  31.     ES    = 1;                  //打开串口中断
  32.     REN=1;
  33. }                           
  34. /*------------------------------------------------
  35.                     主函数
  36. ------------------------------------------------*/
  37. void main (void)
  38. {

  39. InitUART();
  40. c = Temp;                        //初始化地址,相等。
  41. P1=0x00;
  42. SendStr("UART test");

  43. ES=1;                  //打开串口中断

  44. while (1)                       
  45.     {
  46.        if (flag==1)               //flag: 接收完字符串标示
  47.            {
  48.            //SendStr(c);          //?  只收到首地址一个字符
  49.            //SendStr(Temp);       //? 返回16进制0x08 为什么?
  50.                    SBUF=*c;               //? 返回首地址一个字符
  51.                    flag=0;
  52.                    REN=1;
  53.            }
  54.     }
  55. }

  56. /*------------------------------------------------
  57.                     发送一个字节
  58. ------------------------------------------------*/
  59. void SendByte(unsigned char dat)
  60. {
  61. SBUF = dat;
  62. while(!TI);
  63.       TI = 0;
  64. }
  65. /*------------------------------------------------
  66.                     发送一个字符串
  67. ------------------------------------------------*/
  68. void SendStr(unsigned char *s)
  69. {
  70. while(*s!='\0')// \0 表示字符串结束标志,通过检测是否字符串末尾
  71.   {
  72.   SendByte(*s);
  73.   s++;
  74.   }
  75. }
  76. /*------------------------------------------------
  77.                      串口中断程序
  78. ------------------------------------------------*/
  79. void UART_SER (void) interrupt 4 //串行中断服务程序
  80. {
  81.    unsigned int i=0;
  82.   
  83.    if (RI)                        //判断是接收中断产生
  84.      {
  85.             *c = SBUF;
  86.                 Temp[i]=SBUF;             //试验用,返回一直是0x08,很奇怪
  87.             if (*c == 'Z')
  88.                 {  
  89.                    RI=0;
  90.                    c=Temp;
  91.                    REN=0;
  92.                    Communicate();
  93.                    flag=1;                     //标示符,在Main函数中返回,试验用的
  94.                    //SendStr(c);
  95.            //SBUF=Temp;
  96.                 }
  97.                 else
  98.                 {
  99.                c++;
  100.                    i++;
  101.                    RI=0;                        //标志位清零
  102.                    flag=0;                      //在Main函数中返回,试验用的
  103.                    //Temp=SBUF;                 //读入缓冲区的值
  104.            //SBUF=Temp;                 //把接收到的值再发回电脑端
  105.             }
  106.          }
  107.    if(TI)                        //如果是发送标志位,清零
  108.      TI=0;
  109. }

  110. /*------------------------------------------------------------------------------
  111. 串口接受数据
  112. 数据结构为:  第一个字节为设定命令字0xAA, 第二个至第五个为四个字节十六进制数
  113.              xx xx xx xx ; 第六个字节为结束字'Z';
  114. -------------------------------------------------------------------------------*/
  115. void Communicate(void)
  116. {
  117.     unsigned int NegCode = 0;
  118.    
  119.     NegCode = SET_RES(Temp);
  120.     if (!NegCode)
  121.          //SendStr("5555555555");
  122.                  SBUF='F';             //失败返回
  123.     else
  124.          SBUF='K';             //成功返回

  125. }

  126. /*-----------------------------------------------------------------------------
  127. 转换数据位权,个,十,百,千,万,十万; 每位占四个bit,将其输出到P0,P1,P2
  128. ------------------------------------------------------------------------------*/

  129. int SET_RES(unsigned char *r)
  130. {
  131.     unsigned int FrameLength=0,ResInteger=0;
  132.         unsigned char ResByte[10];
  133.         unsigned char _Res,Res01,Res10,Res100,Res1K,Res10K;

  134.         unsigned char Data_Port1,Data_Port2,Data_Port3;
  135.    
  136.     while (*r!='\0')
  137.         {
  138.            ResByte[FrameLength] = *r;
  139.            FrameLength++;
  140.            r++;
  141.        
  142.         }

  143.     if (FrameLength !=5)
  144.        return -100;                        //NG-CODE 数据长度错误
  145.         if (ResByte[0] != 0xAA)
  146.            return -101;                        //NG-CODE 命令字检查,设定字为0xAA
  147.     if (ResByte[FrameLength] != 'Z')
  148.         {   return -102; }                     //NG-CODE 结束字符检查,结束字符为'Z'
  149.     else
  150.         {
  151.         //SendStr(Temp);
  152.     ResInteger = ResByte[FrameLength] + ResByte[3]&0xFF00 + ResByte[2]&0xFF0000 + ResByte[1]&0xFF000000;
  153.     _Res   = (ResInteger%10);
  154.     Res01  = (ResInteger%100)/10;
  155.     Res10  = (ResInteger%1000)/100;
  156.         Res100 = (ResInteger%10000)/1000;
  157.         Res1K  = (ResInteger%100000)/10000;
  158.         Res10K = (ResInteger%1000000)/100000;

  159.     Data_Port1 = _Res&0x0F + (Res01<<4)&0xF0;
  160.     Data_Port2 = Res10&0x0F + (Res100<<4)&0xF0;
  161.         Data_Port3 = Res1K&0x0F + (Res10K<<4)&0xF0;

  162.         P0 = Data_Port1;
  163.         P1 = Data_Port2;
  164.         P2 = Data_Port3;

  165.         return 1;
  166.     }
  167. }

复制代码



串口肯定是用中断最好了呀

接收到的数据放缓冲区里,要有个数据指针指示要放置的位置,然后在主程序里面判断头尾数据,必须保证头和尾的数据是唯一的,就是说中间不能有相同的数据,判断收到一帧数据后进行处理

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top