串口收发字符串

本文介绍了一种使用STM32处理串口接收字符串指令的方法,包括解析和响应特定指令,如ST和PARE。通过中断服务函数实现串口数据接收,并使用printf重定向发送字符串。程序中涉及串口配置、字符串比较和数据发送,适用于蓝桥杯竞赛环境或其他串口通信场景。
摘要由CSDN通过智能技术生成

准备蓝桥杯国赛的时候刷到往届真题,其中有一个使用串口来接收字符串指令的要求。当时没写出来,就把它单独拎出来解决。写了一两天终于是写出了一个简短易懂的程序。

拟定题目要求

*使用串口收发数据。接收两个指令:指令一:ST\r\n,指令二:PARE\r\n
当串口接收到指令一则回复当前DS18B20的温度值(小数点后保留两位)和超声波距离值。格式:$距离值,温度值\r\n.
接收到指令二回复当前设置的温度参数和距离参数,格式:#距离参数,温度参数\r\n.

51串口的配置啥的我就不说了,重点讲解如何处理接受的字符串,以及如何发送字符串数据。

串口发送字符串

#include“stc15f2k60s2.h”
#include<stdio.h>
//一个串口发送数据的函数,把数据给SBUF等待发送完成即可。
void SendDat(unsigned char data)
{
	SBUF=data;
	while(TI==0);          
	TI=0;
}

//因为回传数据,建议使用printf函数,毕竟简单又实用,不用白不用。
//要想让printf打印数据给串口,需要改变它打印的方向,即重定向
//printf打印数据调用的是c库函数putchar
char putchar(char ch)
{
	 SendDat(ch);//打印数据到SBUF
	 return ch;
}

对接收字符指令进行处理

void Usart() interrupt 4
{
	static unsigend char a=0;//定义一个静态变量来保存接受的字符串
	char temp;
	if(RI)
	{
		temp=SBUF;
		
		if(temp != '\n')//不等于\n说明没接收完
		{
			receive[a]=temp;
			a++;
		}
		else
		{
			receive[a]='\n';//因为判断漏掉了
			receive[a+1]='\0';//加上结束符号
			a=0;
			flag=1;//接收指令完成标志位
		}
	}
	
}

主函数

在主函数中对接收指令进行判断和发送对应数据

#include "stc15f2k60s2.h"
#include <stdio.h>
#include <string.h>

void Deal_String();
void Init();
//因为下面使用了strcmp函数,所以把指令和接收数组统一长度
char order1[8]="ST\r\n";
char order2[8]="PARA\r\n";
char receive[8];
bit flag=0;
uint can_wendu=24,can_juli=35;
float wendu=25.36;
uchar dis=40;

void main()
{
	Init();
	while(1)
	{
		Deal_String();
	}	
}


void Init()//使用下载器复制粘贴即可,配置9600波特率
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器时钟1T模式
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xC7;		//设置定时初始值
	TH1 = 0xFE;		//设置定时初始值
	ET1 = 0;		//禁止定时器%d中断
	TR1 = 1;		//定时器1开始计时
	ES=1;
	EA=1;
}

void Deal_String()
{
	uchar i;
	uint  ret1,ret2;
	if(flag)
	{
		flag=0;
		ret1=strcpm(order1,receive); //比较两个字符串数组,相等返回0
		ret2=strcpm(order2,receive);
		if(ret1==0)
			printf("$%d,%0.2f",dis,wendu);
		else if(ret2==0)
			printf("#%d,%d",can_juli,can_wendu);
		else
			printf("REEOR");
		for(i=0;i<8;i++)
		{
			receive[i]='\0';//执行完一次清空所有数据
		}
	}
}

这些函数需要大家组合一下,就是把巉口中断程序放在main里,建议串口发送和重定向函数单独放在一个文件里调用。

在蓝桥杯V1开发板上实测,任意有串口的设备都可

发送指令二:PARA

在这里插入图片描述

发送指令一:ST

在这里插入图片描述

发送随意错误指令

在这里插入图片描述

下面是一个简单的示例代码,实现51单片机通过串口接收字符串: ```c #include <reg51.h> #define FOSC 11059200L // 定义晶振频率 #define BAUD 9600 // 定义波特率 #define MAX_LEN 20 // 定义接收的最大长度 unsigned char RxdBuf[MAX_LEN]; // 定义接收缓冲区 unsigned char RxdLen = 0; // 定义接收长度 void InitUART() // 初始化串口 { SCON = 0x50; // 设置串口工作方式 TMOD &= 0x0F; // 清除T1工作方式 TMOD |= 0x20; // 设置T1为模式2 TH1 = TL1 = -(FOSC / 12 / 32 / BAUD); // 计算T1重载值 TR1 = 1; // 启动T1计数器 ES = 1; // 使能串口中断 EA = 1; // 使能总中断 } void UART_Isr() interrupt 4 // 串口中断处理函数 { if (RI) // 如果收到数据 { RI = 0; RxdBuf[RxdLen] = SBUF; // 将数据存入接收缓冲区 if (RxdBuf[RxdLen] == '\0') // 如果接收到字符串结束符 { RxdLen = 0; // 清空接收长度 } else if (RxdLen < MAX_LEN - 1) // 如果接收长度未达到最大值 { RxdLen++; // 接收长度加1 } } } void main() { InitUART(); // 初始化串口 while (1) { if (RxdLen > 0) // 如果接收到数据 { // 处理接收到的字符串 // ... RxdLen = 0; // 清空接收长度 } } } ``` 这段代码通过中断方式接收串口数据,并将数据存入接收缓冲区。当接收到字符串结束符时,将会清空接收长度,并可以对接收到的字符串进行处理。需要注意的是,由于51单片机的RAM较小,所以接收缓冲区大小需要适当设置,以免超出RAM容量。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值