单片机与电脑通信,字符串处理问题
时间:10-02
整理:3721RD
点击:
程序功能: 从串口接收数据,并将数据转换为十进制数,然后提取位权数,将每位转换为四个Bit 然后每八个Bit为一组,分别输出至P0,P1,P2;
数据结构: 第一个字节为命令字,设定命令为0xAA, 2~5为需要转换的十六进制数,数据范围是 0~999999,最后一个是结束字符'Z';
问题 : 在提取字符串时候出现问题,具体问题看程序,是不是不使用串口中断会好一点?
程 序:
数据结构: 第一个字节为命令字,设定命令为0xAA, 2~5为需要转换的十六进制数,数据范围是 0~999999,最后一个是结束字符'Z';
问题 : 在提取字符串时候出现问题,具体问题看程序,是不是不使用串口中断会好一点?
程 序:
-
- /*-----------------------------------------------
- 名称:串口通信,数据转换输出
- 内容:通过串口通信,将数据每一位输出至端口P0,P1,P2
- 没位占四个Bit,数据范围0~999999
- ------------------------------------------------*/
- #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
- #include "string.h"
- /*------------------------------------------------
- 变量声明
- ------------------------------------------------*/
- #define uchar unsigned char ;
- #define uint unsigned int ;
- uchar Temp[32],*c;
- uint flag=0;
- /*------------------------------------------------
- 函数声明
- ------------------------------------------------*/
- void Communicate(void);
- void SendStr(unsigned char *s);
- int SET_RES(unsigned char *r);
- /*------------------------------------------------
- 串口初始化
- ------------------------------------------------*/
- void InitUART (void)
- {
- SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
- TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
- TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
- TR1 = 1; // TR1: timer 1 打开
- EA = 1; //打开总中断
- ES = 1; //打开串口中断
- REN=1;
- }
- /*------------------------------------------------
- 主函数
- ------------------------------------------------*/
- void main (void)
- {
- InitUART();
- c = Temp; //初始化地址,相等。
- P1=0x00;
- SendStr("UART test");
- ES=1; //打开串口中断
- while (1)
- {
- if (flag==1) //flag: 接收完字符串标示
- {
- //SendStr(c); //? 只收到首地址一个字符
- //SendStr(Temp); //? 返回16进制0x08 为什么?
- SBUF=*c; //? 返回首地址一个字符
- flag=0;
- REN=1;
- }
- }
- }
- /*------------------------------------------------
- 发送一个字节
- ------------------------------------------------*/
- void SendByte(unsigned char dat)
- {
- SBUF = dat;
- while(!TI);
- TI = 0;
- }
- /*------------------------------------------------
- 发送一个字符串
- ------------------------------------------------*/
- void SendStr(unsigned char *s)
- {
- while(*s!='\0')// \0 表示字符串结束标志,通过检测是否字符串末尾
- {
- SendByte(*s);
- s++;
- }
- }
- /*------------------------------------------------
- 串口中断程序
- ------------------------------------------------*/
- void UART_SER (void) interrupt 4 //串行中断服务程序
- {
- unsigned int i=0;
-
- if (RI) //判断是接收中断产生
- {
- *c = SBUF;
- Temp[i]=SBUF; //试验用,返回一直是0x08,很奇怪
- if (*c == 'Z')
- {
- RI=0;
- c=Temp;
- REN=0;
- Communicate();
- flag=1; //标示符,在Main函数中返回,试验用的
- //SendStr(c);
- //SBUF=Temp;
- }
- else
- {
- c++;
- i++;
- RI=0; //标志位清零
- flag=0; //在Main函数中返回,试验用的
- //Temp=SBUF; //读入缓冲区的值
- //SBUF=Temp; //把接收到的值再发回电脑端
- }
- }
- if(TI) //如果是发送标志位,清零
- TI=0;
- }
- /*------------------------------------------------------------------------------
- 串口接受数据
- 数据结构为: 第一个字节为设定命令字0xAA, 第二个至第五个为四个字节十六进制数
- xx xx xx xx ; 第六个字节为结束字'Z';
- -------------------------------------------------------------------------------*/
- void Communicate(void)
- {
- unsigned int NegCode = 0;
-
- NegCode = SET_RES(Temp);
- if (!NegCode)
- //SendStr("5555555555");
- SBUF='F'; //失败返回
- else
- SBUF='K'; //成功返回
- }
- /*-----------------------------------------------------------------------------
- 转换数据位权,个,十,百,千,万,十万; 每位占四个bit,将其输出到P0,P1,P2
- ------------------------------------------------------------------------------*/
- int SET_RES(unsigned char *r)
- {
- unsigned int FrameLength=0,ResInteger=0;
- unsigned char ResByte[10];
- unsigned char _Res,Res01,Res10,Res100,Res1K,Res10K;
- unsigned char Data_Port1,Data_Port2,Data_Port3;
-
- while (*r!='\0')
- {
- ResByte[FrameLength] = *r;
- FrameLength++;
- r++;
-
- }
- if (FrameLength !=5)
- return -100; //NG-CODE 数据长度错误
- if (ResByte[0] != 0xAA)
- return -101; //NG-CODE 命令字检查,设定字为0xAA
- if (ResByte[FrameLength] != 'Z')
- { return -102; } //NG-CODE 结束字符检查,结束字符为'Z'
- else
- {
- //SendStr(Temp);
- ResInteger = ResByte[FrameLength] + ResByte[3]&0xFF00 + ResByte[2]&0xFF0000 + ResByte[1]&0xFF000000;
- _Res = (ResInteger%10);
- Res01 = (ResInteger%100)/10;
- Res10 = (ResInteger%1000)/100;
- Res100 = (ResInteger%10000)/1000;
- Res1K = (ResInteger%100000)/10000;
- Res10K = (ResInteger%1000000)/100000;
- Data_Port1 = _Res&0x0F + (Res01<<4)&0xF0;
- Data_Port2 = Res10&0x0F + (Res100<<4)&0xF0;
- Data_Port3 = Res1K&0x0F + (Res10K<<4)&0xF0;
- P0 = Data_Port1;
- P1 = Data_Port2;
- P2 = Data_Port3;
- return 1;
- }
- }
串口肯定是用中断最好了呀
接收到的数据放缓冲区里,要有个数据指针指示要放置的位置,然后在主程序里面判断头尾数据,必须保证头和尾的数据是唯一的,就是说中间不能有相同的数据,判断收到一帧数据后进行处理