stc8a8k_串口1,接收,截取数据

环境设置:
stc8a8k;
波特率115200;
晶振22.1184Mhz;
定时器2产生波特率;

代码例子
发送数据到电脑中,用printf函数;
将电脑发过来的字符串,按照指定格式,截取出数据;
将电脑发过来的字符串,按照指定命令,判断命令;
超时判断接收的思路。。

截取整数,
截取小数,
截取几个数,数组

//@22.1184M,stc8a8k
#include <stc8a8k.h>
#include <LCD12864B.h>
#include <delay.h>
#include <stdio.h>  
#include "stdlib.h"
#include "stdarg.h"
#include "string.h"  //str函数
//****************************************************************
#define Uart1_Rec_Maxlength 100
unsigned char Global_Uart1_Rec[Uart1_Rec_Maxlength];//串口1接收空间,100个字节
#define Uart1_END_CODE '#'  //帧尾自定义符号
unsigned char	  Uart1_Rec_Byte_Length=0;//动态长度,在0-最大Uart1_Rec_Maxlength=100之间
unsigned char		Uart1_Rec_Frame_Flag=0;//接收一帧标记,=1,接收到一帧数据,=0,没有接受一帧数据
unsigned Global_uart1cmdnum=0;//串口接收到的命令号
#define Uart1CMD_NULL  0 //串口接收到的命令
#define Uart1CMD_LED0  1 //串口接收到的命令
#define Uart1CMD_LED1  2 //串口接收到的命令
#define Uart1CMD_LED2  3 //串口接收到的命令
//************************
void UartInit(void);		//115200bps@11.0592MHz
void UART1_SendData(char dat);
void UartSendStr(char *p);
void Clear_Uart1_Rxbuff(void);
unsigned char Judge_Uart1_Response(char* fmt,...);
unsigned char Get_Uart1_AngleData(float *input_angle);
unsigned char Get_Uart1_Int_Data(int *input_data);
unsigned char  Get_Uart1_Many(int input_data[]);

void printf_char_int_long_test(void);
void printf_float_test(void); 		
void printf_String_test(void);
//*******************************主函数************************
int main()
{	
	float angle_x=0;
	int xmm;
	int input_dataRec[3];
	int i,j;
	UartInit();//串口1,波特率115200,定时器2产生,stc8a8k,22.1184Mhz
	ES = 1;
  EA = 1;
	//LCD12864_Init();	//初始化LCD  
	//LCD12864_Clr_Scr();//清屏函数		
	//LCD12864_Write_string(2, 3 ,"welcome");	
 // delay_ms(1000);
	//LCD12864_Clr_Scr();//清屏函数

	printf("LED=0\r\n");//给串口电脑发送,反应一下。
	printf_char_int_long_test();
	printf_float_test();
	printf_String_test();

  while(1)
  {
		if(Global_uart1cmdnum==Uart1CMD_LED0)  //获取浮点数
		{
			Global_uart1cmdnum=Uart1CMD_NULL;//清空命令,防止重复响应
			printf("Uart1CMD_LED0 \r\n");
			printf("angle cal");
			i=0;
			while(!Get_Uart1_AngleData(&angle_x))//	//电脑发过来的格式 angle_x=数据,超时监控
			{
				delay_ms(5);
				i++;
				if(i>3000)return 0;//超时监控
			}
			angle_x=angle_x+100;
			printf("angle_x=%.2f\r\n",angle_x);	 
		}
		
		
		else if(Global_uart1cmdnum==Uart1CMD_LED1)//超时监控
		{
			Global_uart1cmdnum=Uart1CMD_NULL;//清空命令,防止重复响应
			printf("Uart1CMD_LED1 \r\n");
			printf("xmm rec \r\n");
			i=0;
			while(! Get_Uart1_Int_Data(&xmm))//电脑发过来的格式 xmm=数据 ,超时监控
			{
				delay_ms(5);
				i++;
				if(i>3000)return 0;//超时监控
			}
			xmm=xmm+100;
			printf("xmm=%d\r\n",xmm);	 			
		}
		
		else if(Global_uart1cmdnum==Uart1CMD_LED2)
		{
			Global_uart1cmdnum=Uart1CMD_NULL;//清空命令,防止重复响应
			printf("Uart1CMD_LED2\r\n");
			printf("input_dataRec rec \r\n");
			i=0;
			while(!Get_Uart1_Many(input_dataRec))//电脑发过来的格式lr:数据,ud:数据,an:数据,超时监控
			{
				delay_ms(5);
				i++;
				if(i>3000)return 0;//超时监控
			}	
			printf("input_dataRec[0]=%d\r\n",input_dataRec[0]);	 		// LED=2#  
			printf("input_dataRec[1]=%d\r\n",input_dataRec[1]);	 		// 
			printf("input_dataRec[2]=%d\r\n",input_dataRec[2]);	 		// 
		}
	}
}

//串口1,波特率115200,定时器2产生,
void UartInit(void)		//115200bps@22.1184Mhz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR &= 0xFB;		//定时器2时钟为Fosc/12,即12T
	T2L = 0xFC;		//设定定时初值
	T2H = 0xFF;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2
}

//UART1 发送串口数据,一个字节
void UART1_SendData(char dat)
 {
     ES=0;           //关串口中断
     SBUF=dat;           
     while(TI!=1);   //等待发送成功
     TI=0;           //清除发送中断标志
     ES=1;           //开串口中断
}
//UART1 发送串口数据,字符串
void UartSendStr(char *p)
{
    while (*p)
    {
        UART1_SendData(*p++);
    }
}
//重写putchar函数,可以用printf函数
char putchar(char c)
{
     UART1_SendData(c);
     return c;
}
//串口1中断服务函数
void Uart1Isr() interrupt 4 using 1
{
		unsigned char cmdtemp=0;
    if (TI)
    {
        TI = 0;
    }
    if (RI)
    {
			Global_Uart1_Rec[Uart1_Rec_Byte_Length]=SBUF;//将数据放到缓冲区中
		//	UART1_SendData(SBUF);//debug,给串口电脑发送,反应一下。
	 //   printf("\r\n");//debug给串口电脑发送,反应一下。
			if(Global_Uart1_Rec[Uart1_Rec_Byte_Length]==Uart1_END_CODE) //如果接收到的最后的数据是约定好的帧尾
			{
				Uart1_Rec_Byte_Length=0;//接收标记等于1,在哪里清0?在判断里面清0
				Uart1_Rec_Frame_Flag=1;//长度清零,给下次使用
				//判断命令,得到串口命令
				if(Judge_Uart1_Response("LED=0"))//如果一帧数据里面包括了LED=0
				{
					Clear_Uart1_Rxbuff(); //清空空间,下次接收
					Global_uart1cmdnum = Uart1CMD_LED0;
				}			
				else 	if(Judge_Uart1_Response("LED=1"))//如果一帧数据里面包括了LED=0
				{
					Clear_Uart1_Rxbuff(); //清空空间,下次接收
					Global_uart1cmdnum = Uart1CMD_LED1 ;
				}
				else 	if(Judge_Uart1_Response("LED=2"))//如果一帧数据里面包括了LED=0
				{
					Clear_Uart1_Rxbuff(); //清空空间,下次接收
					Global_uart1cmdnum = Uart1CMD_LED2 ;
				}
				
			}
			else
			{
			  Uart1_Rec_Byte_Length++;//递增,不断放到数组中
			  if(Uart1_Rec_Byte_Length>Uart1_Rec_Maxlength-1) Uart1_Rec_Byte_Length=0;
		  }	
			RI = 0;    
    }
}

//清除串口1的内存
void Clear_Uart1_Rxbuff(void)
{
	unsigned char *p,i;
	p=Global_Uart1_Rec;
	for(i=0;i<Uart1_Rec_Maxlength;i++)
	{
		*p++=0;
	}
	Uart1_Rec_Byte_Length=0;
	Uart1_Rec_Frame_Flag=0;
}
//判断命令,这里注意,必须全部包括
unsigned char Judge_Uart1_Response(char* fmt,...)
{	
	va_list ap;
	char p[30];
	if(!Uart1_Rec_Frame_Flag) return 0;

	va_start(ap,fmt);
	vsprintf((char*)p,fmt,ap);
	va_end(ap); 
	if(strstr((char*)Global_Uart1_Rec,p)==NULL) return 0;
	else return 1;
}

//实例,获取串口传来的角度,angle=325.56
unsigned char Get_Uart1_AngleData(float *input_angle)
{
	float angletemp;
	if(!Uart1_Rec_Frame_Flag) return 0;
	sscanf((const char *)Global_Uart1_Rec,"angle_x=%f",&angletemp);//angle=325.56
	*input_angle=(float)angletemp;
	return 1;
}
//实例,获取串口传来的整数,intdata=13568
unsigned char Get_Uart1_Int_Data(int *input_data)
{
	int inttemp;
	if(!Uart1_Rec_Frame_Flag) return 0;
	sscanf((const char *)Global_Uart1_Rec,"xmm=%d",&inttemp);//xmm=8756
	*input_data=(float)inttemp;
	return 1;
}
//接收一系列,截取出来数据lr:%d,ud:%d,an:%d
unsigned char  Get_Uart1_Many(int input_data[])
{
	int input_dataTemp[3];
	if(!Uart1_Rec_Frame_Flag) return 0;
	sscanf((const char *)Global_Uart1_Rec,"lr:%d,ud:%d,an:%d",&input_dataTemp[0],&input_dataTemp[1],&input_dataTemp[2]);
	input_data[0]=input_dataTemp[0];
	input_data[1]=input_dataTemp[1];
	input_data[2]=input_dataTemp[2];
	return 1;
}


//测试给串口发送字符,整数和长整数
void printf_char_int_long_test(void)
{
	char a=-100;
	int b=-2000;
	long c=6553600;
	printf ("char %bd  int %d  long %ld\r\n",a,b,c); 	       // 10进制输出
	// 输出带符号10进制整数(正数不输出符号)
  // 实际输出:char -100  int -2000 long 6553600 
	printf ("char_0x%bx  int_0x%x  long_0x%lx\r\n",a,b,c);   // 16进制输出	
	// 输出无符号16进制整数,x表示按小写输出,X表示按大写输出
  // 实际输出:char_0x9c  int_0xf830 long_0x640000  
  printf ("a_int %d\r\n",(int)(a)); 	           // 不用宽度标识符
	// 实际输出:a_int -100	
	printf ("char %bd,int %d,long %ld\r\n",a,b,c);   // %bd后也可以有其它普通字符
	// 输出带符号10进制整数(正数不输出符号)
    // 实际输出:char -100,int -2000,long 6553600 
}
//测试发送浮点数到串口
void printf_float_test(void) 		
{
	float a= 3.14159265798932;
	float  f = 10.0,g = 22.95;
	printf("Max is %f\r\n",a);    // Max is 3.141593,	默认小数点后6位
	printf("%.4f\r\n",a);	 		// 3.1416
	printf("%.12f\r\n",a);	    // 3.140593000000
	//%.4f 表示按小数点后4 位数据输出,%.12f表示按小数点后12位数据输出
	printf ("%f , %g\r\n", f, g);	  //输出:10.000000 , 22.95 
} 
//测试发送字符串
void printf_String_test(void) 
{
	char buf [] = "Test String";
	char *p = buf;
	printf ("String %s is at address %p\r\n",buf,p);
   //输出:String Test String is at address i:0022    
} 	


在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值