蓝桥杯单片机串口通信学习提升笔记——部分2

这篇具有很好参考价值的文章主要介绍了蓝桥杯单片机串口通信学习提升笔记——部分2。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

今日继续学习提升蓝桥杯国赛能力水平。

有道是:卜心事、灯花无语,百感孤单,鸳被羞展......

                梦方圆,又丛钟、声声惊断。

诗人杨玉衔孤单影只,偏偏又多遭磨难,一路坎坷......

正如我近日来学习提升串口通信技能一样,遇到诸多设计上的险阻。

本篇主要解决以下串口通信方面的问题:

1.上位主机发送命令字符串,单片机接收校对后执行指令

2.单片机某个变量在改变,要求与字符串拼接后发送给主机

注意:本文不是零基础开始的,需要对串口有基础认识,会用串口收发单八位字节

目录

如零基础学习串口,请传送到这篇文章:

本文提供问题解决的工程文件:

 关于单片机接收字符串指令问题的解决:

关于拼接变量与字符串发送的问题:


如零基础学习串口,请传送到这篇文章:

蓝桥杯单片机串口通信学习提升笔记_NULL指向我的博客-CSDN博客

本文提供问题解决的工程文件:

问题一过程文件:

https://download.csdn.net/download/qq_64257614/87808393?spm=1001.2014.3001.5503

问题二过程文件:

https://download.csdn.net/download/qq_64257614/87809191?spm=1001.2014.3001.5503

 关于单片机接收字符串指令问题的解决:

你是否也困扰于某些省赛国赛题目(第十届)中,有上位机发送字符串命令

单片机接受并处理的要求,比如:

“单片机接收到上位机指令“START\r\n”,上报XXX数据”

“如设备接收到错误指令,返回“ERROR\r\n” ”

其实他们本意就是考察我们对串口收发的熟悉程度。

下表是printf函数的

蓝桥杯单片机串口通信学习提升笔记——部分2

我们可以从以下实验来学习强化这方面的知识:

/*
	本实验练习串口通信:主要练习以下内容:		 
	数组接收判断上位机的命令
		收到	START\r\n    就  打印 OVER\r\n
		其余都打印   ERROR\r\n
*/

  我们首先在变量定义来讲解:

bit URX_Over = 0;                   
unsigned char idata URX[10] = 0;
unsigned char idata URX_Num = 0;
unsigned char idata URX_tt = 0;

1.URX_Over是标志位,当其值为1时,会进入函数处理比较字符串,PS:它将在定时器中出现,  

2.URX[10] 是字符串数组,他用于接受上位机发来的字符串命令,接收处理完后要全部清零,

                   因为有些命令比较长,而有些比较短,在接受了一个长的字符串后,不清空数组

                   的话,短命令就无法正常比较了.

                    比如第一次接收到了长命令START\r\n,第二次发来短命令ST\r\n,但因为没清空数组                    所以第二次数组内的情况是ST\r\nT\r\n,这就会被判断为是一个错误指令。

memset(URX,0,sizeof(URX));//处理完命令别忘了将其清零,以便接收下个命令

3.URX_Num 用来辅助字符串数组URX[10] 接收SBUF寄存器的内容

4.URX_tt 用来标记接收是否完成,它同时在定时器中会进行自加,

                每次RI不为0,接收数据时,它都会被清零, 直到接收完毕,

                接收完毕后它就不会再被清零了

                此时的它在定时器中不断自加,到一定值后 就会 刷新标志位URX_Over,

                从而推动 字符串比较进程的开展。

涉及以上过程的代码如下贴出:

此段代码对应串口中断的过程:

bit URX_Over = 0;
unsigned char idata URX[10] = 0;
unsigned char idata URX_Num = 0;
unsigned char idata URX_tt = 0;

//串口1中断服务函数
void Uart_1_serv() interrupt 4
{
 	if(RI)
	{
		RI=0;  URX_tt = 0;
		if(URX_Num < 10) { URX[URX_Num++] = SBUF;	}		
	}
}

此段代码是定时器中的过程:

void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0x01;		//设置定时器模式
	TL0 = 0x20;		//设置定时初始值
	TH0 = 0xD1;		//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	EA=1;
	ET0=1;
}
void Timer0(void) interrupt 1
{
	
	TL0 = 0x20;		//设置定时初始值
	TH0 = 0xD1;		//设置定时初始值
	if(URX_Num > 0){if(++URX_tt == 30) { URX_Over = 1;} }			
}

最后是主程序While()循环中,对字符串命令的判断:

#include "stdio.h"
#include "string.h"

u8 str1[ ]="START\r\n";

if(URX_Over == 1)
{
	URX_Over =0;
	if(strncmp(URX,str1,7)==0) Uart_Sendstring("OVER\r\n");
	else   Uart_Sendstring("ERROR\r\n");
	URX_Num = 0;
}

此处需要注意:URX_Num = 0;  这句

表示处理完了字符串命令,就清零,以便URX[10] 接收下个命令字符串

下载后进行调试,效果如下:

蓝桥杯单片机串口通信学习提升笔记——部分2

 证明我们的串口字符串命令收发非常顺利!!!

如果字符串命令种类不止一条:

我们在处理接收的if(URX_Over == 1)语句中就需要加上一些if语句:

 下段代码就是接收START\r\n 与 HI\r\n并做相应回复的例子

 蓝桥杯单片机串口通信学习提升笔记——部分2

蓝桥杯单片机串口通信学习提升笔记——部分2

 

关于拼接变量与字符串发送的问题:

这个问题我习惯用的有俩种解决方式:

1.用重定向的printf()函数

2.使用senddata()函数,但需要另外定义数组和写函数进行拼接字符串与变量值

但此处建议与介绍 使用printf(),虽然占用多些资源,但不影响竞赛要求!

我们都知道printf 函数的一般调用格式为:printf("<格式化字符串>", <参量表>)

以下为在chitgpt搜索到的关于%bu格式转换字符的原理与应用:

在Keil编程中,使用printf函数的%bu格式转换字符是用于

将一个unsigned char类型的整数十进制的形式输出。

%bu是printf函数的格式控制字符串中的占位符,

用于指示需要输出一个unsigned char类型的整数。

在基础知识方面,

unsigned char类型是一种无符号字符类型,它可以存储0到255之间的整数。它通常用于表示二进制数据的字节和字符。

在C语言中,

可以使用%u格式控制字符串输出unsigned char类型的整数,但是由于printf函数默认将char类型看作有符号类型,因此使用%u格式控制字符串输出unsigned char类型的整数时可能会出现问题。因此,为了避免这种问题,可以使用%bu格式控制字符串来输出unsigned char类型的整数。

下面是一个使用%bu格式控制字符串输出unsigned char类型的整数的例子:

unsigned char value = 255;
printf("The value is %bu\n", value);

输出结果为:

The value is 255

于是,我们便知道了该如何拼接变量与字符了

以下为实践内容要求:

		定义test1与 test2,每300ms自加,每次自加后发送:
			
		the new test1 is (test1的值)\r\n	the new test2 is (test2的值)\r\n	

我们只需对照着要求,在定时器中使他们自加,然后附上printf函数格式化输出即可:

定时器中并没有直接放printf函数,因为主函数也调用该函数,为防止报错重入警告,我们将printf的操作放在主函数,定时器刷新标志给主函数决定是不是该进行printf的操作了:

bit test_flag=0;


void Timer0(void) interrupt 1
{
	u16 i;
	TL0 = 0x20;		//设置定时初始值
	TH0 = 0xD1;		//设置定时初始值
	i++;
	if(URX_Num > 0){if(++URX_tt == 30) { URX_Over = 1;} }			
	if(i==300)
	{
		i=0;
		test1++;test2++;
		if(test1==10) test1=0;
		if(test2==10) test2=0;
    test_flag=1;		           //打印标志位——传给主函数
	}	
}

 以下为主函数:

void main()
{
	u8 test=2;
	
	cls_buzz_led();				//关闭外设
	UartInit();						//初始化串口
	Timer0Init();
	
	//以下三句是开机串口功能初始化测试用:
	printf("Welcome to stc15f2k60s2\n");
	printf("%c",test+'0');
	SendData(test+'0');
	
	while(1)
	{	
		if(URX_Over == 1)
		{
			URX_Over =0;
			if(strncmp(URX,str1,7)==0) Uart_Sendstring("OVER\r\n");
			else   Uart_Sendstring("ERROR\r\n");
			URX_Num = 0;
		}
		if(test_flag==1)
		{
			test_flag=0;
		printf("the new test1 is %02bu\r\n	the new test2 is %02bu\r\n	",(unsigned char)test1,(unsigned char)test2);
		}
	}
}

 其中最重要的拼接部分就是:

		printf("the new test1 is %02bu\r\n	the new test2 is %02bu\r\n	",(unsigned char)test1,(unsigned char)test2);

 下载后进行串口调试:效果如下:

蓝桥杯单片机串口通信学习提升笔记——部分2

在此,我们的所有问题就这么解决了,希望各位看官多多三连支持!!文章来源地址https://www.toymoban.com/news/detail-459930.html

到了这里,关于蓝桥杯单片机串口通信学习提升笔记——部分2的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【个人笔记】51单片机串口通信的字符串接收和发送,串口通信调节数码管显示时钟(串口通信,定时器,数码管)

           目的:利用PROTUES仿真软件、串口调试助手、虚拟串口,搭建单片机与PC通信仿真平台,熟悉单片机串口的配置及与PC机的通信方法;尝试制定通信协议,单片机根据通信协议解析接收到的内容,并根据接收的指令执行相应的操作。 基本功能: 1.时分秒的动态显示。

    2024年02月11日
    浏览(63)
  • [蓝桥杯单片机]学习笔记——555定时器与频率测量

    目录 一、原理部分 1、什么是555定时器 2、频率测量  3、频率测量相关配置 二、程序案例 555定时器是一种集成电路芯片,常被用于定时器、脉冲产生器和振荡电路。555可被作为电路中的延时器件、触发器或起振元件。而在蓝桥杯的板子上,555定时器是一个信号发生电路,通

    2023年04月12日
    浏览(67)
  • 51单片机学习笔记_6 IO通信:电脑与单片机之间的通信

    单片机还可以通过IO口实现多种通信。 串行通信 :一条数据线,一次发1bit,发很久。 并行通信 :多条数据线,同时发送,发的速度快多了但是费用高、接收困难、抗干扰性差。 异步通信 :发送和接收方时钟可以不用完全一致。 同步通信 :发送和接收方时钟要完全一致。

    2024年02月08日
    浏览(49)
  • 【蓝桥杯-单片机学习笔记(十三)】DS18B20温度传感器

    一、温度传感器-DS18B20介绍 DS18B20是单总线数字化温度传感器,测量温度范围是-55℃~+125℃,在-10℃~+85℃范围内,精度为±0.5℃。支持3V~5.5V的供电电压范围。DS18B20可以程序设定9~12位的分辨率,精度为±0.5℃。 1.DS18B20内部结构 DS18B20内部结构主要由四部分组成:64位光刻ROM、温度

    2023年04月09日
    浏览(64)
  • 51单片机-串口通信

    目录 1.什么是通信 1.1.通信的概念 1.2.传送方式 1.3.同步方式 1.4.传送方向 1.5.校验方式 2.单片机串口介绍 2.1.硬件电路 2.2.电平标准 2.3.常见接口 2.4.内部结构 2.5.相关寄存器 2.6.工作模式(模式1) 2.7.如何配置串口中断 3.实际应用 3.1.单片机向电脑发送数据 3.2.电脑向单片机发送

    2024年02月01日
    浏览(50)
  • 单片机串口通信程序

    本文总结了两种比较简单的关于串口发送接收的程序,以下是步骤: 定义数据: 首先要串口初始化:(以9600波特率为例) 串口中断:  在定时器0扫描里加入,或者主函数while(1)里加入: (其中++URX_tt=(1000/波特率),数要接近,否则会有小小干扰。) 接下来关于串口通信

    2024年02月10日
    浏览(49)
  • 单片机的串口通信

            今天,完整地总结一下普中科技的单片机的串口通信的硬件与编程,记录一下以后如果需要也比较方便捡起来。         单片机的串口部分的电路图。开发板上集成了 1 个串口通信电路,是 USB 转串口模块,它既可下载程序也可实现串口通信功能。         对这

    2024年02月11日
    浏览(45)
  • 51单片机串口通信

    串口通信(serial communication)是指外设和计算机间通过数据信号线、地线等按位进行传输数据的一种通信方式,属于串行通信方式。 接口标准:常用RS-232和RS-485 RS-232C有一种9针的非标准连接器口,简称DB9。串口通信使用的大多都是DB9接口。在串口通信中,通常我们只使用2、

    2024年02月05日
    浏览(49)
  • 【51单片机系列】proteus仿真单片机的串口通信

    本文参考:https://zhuanlan.zhihu.com/p/425809292。 在proteus之外使用串口软件和单片机通信。通过在proteus设计一个单片机接收PC发送的数据,并将接收的数据发送出去,利用软件【Configure Virtual Serial Port Driver】创建一对虚拟串口,利用软件【串口助手】向单片机发送数据。 proteus仿真

    2024年01月17日
    浏览(53)
  • 【51单片机】串口通信&&使用串口通信控制LED灯

    🎊专栏【51单片机】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【Promise】 🥰大一同学小吉,欢迎并且感谢大家指出我的问题🥰 目录 🍔串口通信 😎代码   🍔串口初始化 ⭐分析  🏳️‍🌈确定T1的工作方式 🎈TMOD=0X20;  🏳️‍🌈确定T1的初值 🎈

    2024年02月17日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包