【蓝桥杯单片机国赛】串口通信

问题

第十届蓝桥杯单片机设计与开发项目决赛有这一部分
在这里插入图片描述

发送的指令是1个以上字符,如何判断上位机发送的指令是否正确?

解决思路

把接收到的字符串信息存储在数组中,在一定的时间段内判断一次接收字符的个数,如果符合要求则进行下一步操作处理,否则丢弃。

串口初始化函数可以用STC-SPI生成
在这里插入图片描述

记住要加上下列代码才可实现串口中断

	ES = 1;
	EA = 1;

例题

上位机发送一串字符给芯片,如果是10个字符,就把这一串字符发回给上位机,否则不发送
波特率:9600

定义:

char RevBuf[Data_SIZE]; //数据接收缓冲区
unsigned char data_count = 0; //计数

串口中断服务函数:

void Uart_ser()interrupt 4
{	
	if(RI == 1)
	{
	   	RI = 0;			   	
		RevBuf[data_count++] = SBUF;//把收到的数据存入数组
	}	
}

发送函数:

void Uart_Send(unsigned char dat)
{
	 SBUF = dat;
	 while(TI == 0);
	 TI = 0;
}

void Send_String(unsigned char *value)
{
	while(*value != '\0')
	{			  
		Uart_Send(*value++);
	}
}

数据处理:

      if(TF0 == 1) //开定时器,检测接收字符的个数
	   {
	   	   TF0 = 0;		   		   
		   if(data_count != 10)//如果不符合即清零
		   { 			  
			  for(i = 0;i < 11;i++)
			  	 RevBuf[i++] = 0;			  		  
		   }
		   else
		   {			 
			  RevBuf[10]='\0'; //如果符合要求,在数组的最后一位加上结束符,以便发送
			  Send_String(RevBuf);  
		        Send_String("\r\n");		      
		   }
		   data_count = 0; 		   
	   }

整体代码参考

#include <STC15F2K60S2.h>
#include "absacc.h"

/*======================================================
发送10个字符,如果不是10个字符,就不发送,如果是10个字符,就发送给电脑
========================================================*/

#define Data_SIZE 11 //数据长度 10位数据 + 1位结束符

unsigned char LED_dat = 0xff;

char RevBuf[Data_SIZE]; //数据接收缓冲区
unsigned char data_count = 0; //计数




void System_init()
{
   XBYTE[0x8000] = 0xff;
   XBYTE[0xa000] = 0x00;

}


void UartInit(void)		//9600bps@11.0592MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR |= 0x04;		//定时器2时钟为Fosc,即1T
	T2L = 0xE0;		//设定定时初值
	T2H = 0xFE;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2
	ES = 1;
	EA = 1;
}

void Uart_Send(unsigned char dat)
{
	 SBUF = dat;
	 while(TI == 0);
	 TI = 0;
}

void Send_String(unsigned char *value)
{
	while(*value != '\0')
	{			  
		Uart_Send(*value++);
	}
}
void Uart_ser()interrupt 4
{	
	if(RI == 1)
	{
	   	RI = 0;			   	
		RevBuf[data_count++] = SBUF;
	}	
}
void Time0_Init()
{
	TMOD = 0x01;
	TH0 = (65536-1500)/256;//10ms = 10000us
	TL0 = (65536-1500)%256;
	ET0 = 0;
	TR0 = 1;
	EA = 1;
}

void main()
{
	unsigned char i;
	System_init();	
	UartInit();
	Time0_Init();
	Send_String(" HELLO");		
	while(1)
	{
	   
	   if(TF0 == 1)
	   {
	   	   TF0 = 0;		   		   
		   if(data_count != 10)
		   { 			  
			  for(i = 0;i < 11;i++)
			  	 RevBuf[i++] = 0;			  		  
		   }
		   else
		   {			 
			  RevBuf[10]='\0';
			  Send_String(RevBuf);
		      Send_String("\r\n");		      
		   }
		   data_count = 0; 		   
	   }
	   
	}
}

  • 8
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值