草庐IT

【蓝桥杯嵌入式】蓝桥杯嵌入式第十二届省赛题,考点:模拟电压,串口通信,计时器

勾栏听曲_0 2023-04-12 原文

 🎊【蓝桥杯嵌入式】专题正在持续更新中,原理图解析✨,各模块分析✨以及历年真题讲解✨都在这儿哦,欢迎大家前往订阅本专题,获取更多详细信息哦🎏

🎏【蓝桥杯嵌入式】蓝桥杯第十届省赛真题

🎏【蓝桥杯嵌入式】蓝桥杯第十二届省赛程序真题

🎏【蓝桥杯嵌入式】蓝桥杯第十三届省赛程序真题

🪔本系列专栏 -   蓝桥杯嵌入式_勾栏听曲_0的博客

🍻欢迎大家  🏹  点赞👍  评论📨  收藏⭐️

📌个人主页 -  勾栏听曲_0的博客📝

🔑希望本文能对你有所帮助,如有不足请指正,共同进步吧🏆

🎇仰之弥高,钻之弥坚,瞻之在前,忽焉在后。📈

目录

题目

硬件框图

功能描述

赛题分析

代码实现

LCD模块

中断(按键与计时)模块

按键模块

串口模块


题目

硬件框图

功能描述

基本功能

        1)测量竞赛板上电位器R37输出的模拟电压信号Vwa;,并通过LCD 实现数据的
实时显示。

        2)通过按键完成显示界面切换、参数设置等功能。

        3)支持通过串口进行参数设置的功能。

        4)通过LED指示灯完成状态指示功能。

        5)设计要求
                电压数据刷新时间:≤0.5秒。
                按键响应时间:≤0.1秒。
                根据试题要求设计合理的电压数据采样频率,并对ADC采样到的电压数据进行有效的数字滤波。

显示功能

        1)数据界面
                通过液晶屏显示三个数据项,包括:界面名称Data、电位器R37输出的电压值V和计时结果T,电压值保留小数点后2位有效数字。

        2)参数界面
                通过液晶屏显示三个数据项,包括界面名称Para、电压参数Vmax和Vmin。电压参数保留小数点后1位有效数字。

        显示说明·
                显示背景色(BackColor):黑色。

                显示前景色(TextColor):白色。

                请严格按照图示要求设计各个信息项的名称(区分字母大小写)和行列位置。

                计时结果以秒为单位,计时条件下数据实时刷新。

        计时说明
                1)当电位器R37的输出电压上升到Vmin时,开始计时,声到电压上升到Vmax结束计时。

                2)满足开始计时条件,计时时间重置为0秒,并以秒单位开始计时。

        如上图所示的电压变化曲线中,从t1时刻开始以秒为单位计时,直到t2时刻触发停止计时条件,停止计时;t3时刻重新触发计时(计时时间重置为0),直到t4时刻停止计时。

         如上图所示的电压变化曲线中,从t1时刻开始以秒为单位计时,t2时刻再次触发计时条件,重置计时时间为0,直至t3时刻结束计时。

按键功能

        1) B1:界面切换按键.切换选择数据界面或参数界面。

        2) B2:每次按下B2按键,Vmax参数加0.1V,当参数加到3.3V,再次按下B2后返回0.0V。

        3) B3:每次按下B3按键,Vm参数加0.1V,当参数加到3.3V,再次按下B3后返回0.0V。

        4) 当设备从参数界面退出,返回数据界面时,自动判断当前设置的参数是否合理,如参数合理则使之生效,如不合理,则弃用本次设置的参数,使用进入参数界面前的原参数。

        备注:
                B2和B3按键仅在参数设置界面有效。
                要求Vmax ≥ Vmin + 1V.
                要求Vmax、Vmin可设置范围为0.0V-3.3V。

串口通信功能

        1)使用 STM32 USART2完成串口功能。

        2)通信波特率:9600bps。

        3)串口参数设置命令:“Vmax,Vmin”
                例如:“3.2,1.4”,将电压参数Vmax和Vmin分别设置为3.2V和1.4V。

                备注:示例中的双引号为字符串标识,非参数设置命令内容。

        4)如通过串口接收到的指令存在格式或逻辑错误,设备不执行该条命令。

LED指示灯功能

        1)LD1,若当前触发了计时功能,且计时尚未结束,LD1点亮,否则LD1熄灭。

        2)LD2,若通过按键设置的参数不合理,LD2点亮,直至下次设置了正确的参数后熄灭。

        3)LD3,若串口接收到格式错误指令或不满足参数合理性判断的要求时LD3点亮,直至下次接收到正确指令后熄灭。

初始状态说明
        1)上电后,默认处于数据界面。

        2)上电默认参数:

                Vmax: 3.0V

                Vmin: 1.0v


赛题分析

        实现看硬件框图,了解考点,本次赛题的考点除了老三样(LED,按键,LCD)以外,主要的考点就是模拟电压输入与串口通信了。

        再往下看,就能看到功能描述,就能知道本题大概方向了。主要是测量R37的模拟电压信号,然后串口有一些接收的功能要求。

        我们接着往下面看,来到LCD模块,其主要就是把每行每列的字母数值的位置确定。有需要实时显示的就要实时刷新。

        再往下的计时,就是本次考题比较核心的内容了,什么时候开始计时,什么时候结束,这两个是很好判断的,但是什么条件时是需要将计时重置为0,这个就需要注意一下了,有两种情况:第一,计时正常结束后,重新开始新一轮的计时;第二,计时开始后,未到计时结束,又重新开始计时。计时是实用中断来实现。

        按键与平常也有一些区别,就是在参数界面将参数调好之后,并不会立刻改变真实的参数值,而是需要先进性参数合理性判断,符合要求的参数变动才会保存,否则还是沿用未进行调整时的参数。

        串口模块也是用于参数设置,同样的,也需要对参数的合理性进行判断,不合理则不采用,合理则改变参数为串口接收到的数值。

        LED模块就是一些指示功能,穿插在其他模块中得以体现。

代码实现

LCD模块

        LCD模块就是将各个参数完全按照赛题上的规格来显示即可。

void disp_proc()
{
	if(view==0)
	{
		char text[30];
		sprintf(text,"      Data   ");
		LCD_DisplayStringLine(Line0, (uint8_t *)text);
		sprintf(text," V:%.2fV",R37_v);
		LCD_DisplayStringLine(Line2, (uint8_t *)text);
		
		sprintf(text," T:%ds",times);
		LCD_DisplayStringLine(Line3, (uint8_t *)text);		
	}
	else if(view==1)
	{
		char text[30];
		sprintf(text,"      Para    ");
		LCD_DisplayStringLine(Line0, (uint8_t *)text);
		sprintf(text," Vmax:%.1fV     ",max_v);
		LCD_DisplayStringLine(Line2, (uint8_t *)text);
		sprintf(text," Vmin:%.1fV     ",min_v);
		LCD_DisplayStringLine(Line3, (uint8_t *)text);
	}
}

中断(按键与计时)模块

        中断中,包含了本次赛题多个重点:R37模拟电压信号的获取,计时器计时,计时器何时开始计时,何时结束计时,何时重置计时器。外加一些LED的操作。

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(a++ >20)
	{
		R37_v = getADC(&hadc2);
		if(R37_f < min_v && R37_v >= min_v)
		{
			times = 0;
			flag_t = 1;
			TurnOn_LED(1);
		}
		else if(flag_t == 1 && R37_v < min_v)
		{
			flag_t = 0;
			TurnOff_LED(1);
		}
		else if(flag_t == 1 && R37_v >= max_v)
		{
			flag_t = 2;
			TurnOff_LED(1);
		}
		a = 0;
		R37_f = getADC(&hadc2);
		
	}
	if(flag_t == 1)
	{
		if(s++ == 100)
		{
			times++;
			s = 0;
		}
	}
	else if(flag_t == 2)
	{
		flag_t = 0;
	}
	
	if(htim->Instance==TIM3)
	{
		key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
		key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
		key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
		key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
		
		for(int i = 0;i < 4; i++ )
		{
			switch (key[i].judge_sta)
			{
				case 0:
				{
					if(key[i].key_sta==0) 
					{
						key[i].judge_sta = 1;	//第一次判断是否按下
						key[i].key_time = 0;
					}
				}
				break;
				case 1:
				{
					if(key[i].key_sta==0)	//进入下一次定时器扫描,按键还是按下状态,那么就确认为按下,以此来消抖
					{
						key[i].judge_sta = 2;
					}
					else
						key[i].judge_sta = 0;
				}
				break;
				case 2:
				{				
					if(key[i].key_sta==1) 		//判断是否松手
					{
						if(key[i].key_time < 100)
						{
							key[i].key_flag = 1;
						}
						key[i].judge_sta = 0;		
					}
					else
					{
						key[i].key_time++;
						if(key[i].key_time > 100)				//一次扫描10毫秒,100次1000毫秒,就是判断是否长按超过1000毫秒//未松手时,就会执行相应反应
						{
							key[i].long_flag = 1;
						}
					}
				}
				break;
			}
		}
	}
}

按键模块

        按键模块包括判断按键界面上调整参数是否合理的判断,判断后参数的改动。

void key_proc()
{
	if(key[0].key_flag == 1)
	{
		if(view == 1)
		{
			if(max_v < min_v + 0.99)
			{
				max_v = max;
				min_v = min;
				TurnOn_LED(2);
			}
			else
			{
				TurnOff_LED(2);
			}
		}
		else if(view == 0)
		{
			max = max_v;
			min = min_v;
		}
		view = !view;
		LCD_Clear(Black);
		key[0].key_flag = 0;
	}
	
	if(key[1].key_flag == 1)
	{
		if(view == 1)
		{
			max_v += 0.1;
			if(max_v > 3.3)
			{
				max_v = 0;
			}
		}
		key[1].key_flag = 0;
	}
	
	if(key[2].key_flag == 1)
	{
		if(view == 1)
		{
			min_v += 0.1;
			if(max_v > 3.3)
			{
				min_v = 0;
			}
		}
		key[2].key_flag = 0;
	}

}

串口模块

        串口模块只用实现接收功能,接收并判断参数是否合理,合理就对参数进行改变,不合理参数就不做改变。

void uart_rx_proc()
{
	if(rx_pointer>0)
	{
		if(rx_pointer==7)	//如果接收到的是7个字符
		{
			sscanf(rxdata,"%c.%c,%c.%c",&max_g,&max_x,&min_g,&min_x);	//将字符串拆分
			max_g1 = atoi(&max_g);
			max_x1 = atoi(&max_x);
			min_g1 = atoi(&min_g);
			min_x1 = atoi(&min_x);
			if(max_g1 + max_x1/10 >= min_g1 +min_x1/10 +1)
			{
				max_v = max_g1 + max_x1/10;
				min_v = min_g1 +min_x1/10;
				TurnOff_LED(3);
			}
			else
			{
				TurnOn_LED(3);
			}
		}
		rx_pointer=0;
		memset(rxdata,0,30);
	}
}

        望本篇文章对你有所帮助,并在比赛中取得佳绩 👑

有关【蓝桥杯嵌入式】蓝桥杯嵌入式第十二届省赛题,考点:模拟电压,串口通信,计时器的更多相关文章

  1. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  2. ruby - Ruby 性能中的计时器 - 2

    我正在寻找一个用ruby​​演示计时器的在线示例,并发现了下面的代码。它按预期工作,但这个简单的程序使用30Mo内存(如Windows任务管理器中所示)和太多CPU有意义吗?非常感谢deftime_blockstart_time=Time.nowThread.new{yield}Time.now-start_timeenddefrepeat_every(seconds)whiletruedotime_spent=time_block{yield}#Tohandle-vesleepinteravalsleep(seconds-time_spent)iftime_spent

  3. 蓝桥杯备赛(二) - 2

    目录前言: 一、ASC分析代码实现二、 卡片分析代码实现三、 直线分析代码实现四、货物摆放分析代码实现小结:前言:  在刷题的过程中,发现蓝桥杯的题目和力扣的差别很大。让人有一种不一样的感觉,蓝桥杯题目偏向对于实际问题用编程去的解决,而力扣给人感觉很锻炼自己的编程思维,逻辑能力。两者结合去刷,相信会有不一样的收获。 一、ASC  已知大写字母A的ASCII码为65,请问大写字母L的ASCII码是多少?分析  这道题目看上去很简单,我们需确定自己计算的准确,所以我建议用编程去解决。代码实现publicclassTest8{publicstaticvoidmain(String[]args){Sy

  4. 蓝桥杯C/C++VIP试题每日一练之报时助手 - 2

    ?作者主页:静Yu?简介:CSDN全栈优质创作者、华为云享专家、阿里云社区博客专家,前端知识交流社区创建者?社区地址:前端知识交流社区?博主的个人博客:静Yu的个人博客?博主的个人笔记本:前端面试题个人笔记本只记录前端领域的面试题目,项目总结,面试技巧等等。接下来会更新蓝桥杯官方系统基础练习的VIP试题,依然包括解题思路,源代码等等。问题描述:给定当前的时间,请用英文的读法将它读出来。时间用时h和分m表示,在英文的读法中,读一个时间的方法是:  如果m为0,则将时读出来,然后加上“o’clock”,如3:00读作“threeo’clock”。  如果m不为0,则将时读出来,然后将分读出来,如5

  5. 1个串口用1根线实现多机半双工通信+开机控制电路 - 2

    功能需求:主机使用一个串口,与两个从机进行双向通信,主机向从机发送数据,从机能够返回数据,由于结构限制,主机与从机之间只有3根线(电源、地、数据线),并且从机上没有设物理的电源开关,需要通过与主机连接的数据线来控制开机,总结如下:1、数据线只有1根2、能够双向通信3、主机能够控制从机开机4、主机可以单独向1个从机发数据,也可以同时向两个从机发送数据根据需求,设计出如下电路:工作原理分析:VCC_24V_IN、GND、LINE_L(LINE_R)三根线接线连接到从机,电源开启电路是从机内部的电源控制。开机的逻辑:*主机先上电,LINE_L因为主机的R1上拉而有高电平,使Q6导通,Q5的G极电压被

  6. ruby-on-rails - 如何在 RoR 中使用 content_tag 嵌入标签? - 2

    我有这个可以为我生成一个超链接:我希望它显示在td标签中,所以我想使用这个content_tag来帮助我:"example")%>我想要我的td中的超链接,所以我有这样的东西:,:class=>"example")%>但是我收到语法错误,我该怎么办? 最佳答案 内联:'example')%>或block形式:'example')do%> 关于ruby-on-rails-如何在RoR中使用content_tag嵌入标签?,我们在StackOverflow上找到一个类似的问题:

  7. ruby-on-rails - 遵循 DCI 设计时在哪里进行验证? - 2

    我正在按照DCI构建新Rails应用程序的行为,但我对将验证放在哪里有一些疑问。传统上,如果您要使用ActiveRecord模型管理您的数据,验证是在继承自AR的特定类中定义的,并且它们似乎适合作为数据层的一部分。然而,在我看来,只在特定角色下进行某些验证是有意义的,并且只有当对象在该上下文中时才应检查它们,在所有其他情况下都将被忽略。这基本上意味着这些验证应该在特定角色上定义,并且当对象在有意义的上下文中使用时,应该使用这些角色模块扩展对象。您认为将这些验证保留在角色上是个好主意吗?如果是这样,您如何声明它们而不污染与对象相同的类的其他实例?如果我想使用ActiveRecord验证,

  8. 十四届蓝桥青少组模拟赛Python-20221108 - 2

    十四届蓝桥青少组模拟赛Python-20221108T1.二进制位数十进制整数2在十进制中是1位数,在二进制中对应10,是2位数。十进制整数22在十进制中是2位数,在二进制中对应10110,是5位数。请问十进制整数2022在二进制中是几位数?print(len(bin(2022))-2)#运行结果:11T2.晨跑小蓝每周六、周日都晨跑,每月的1、11、21、31日也晨跑。其它时间不晨跑。已知2022年1月1日是周六,请问小蓝整个2022年晨跑多少天?#样例代码1ls=[0,31,28,31,30,31,30,31,31,30,31,30,31]ans=0k=6foriinrange(1,13)

  9. 蓝桥杯 stm32 MCP4017 - 2

    本文代码使用HAL库。文章目录前言一、MCP4017的重要特性二、MCP4017计算RBW阻值三、MCP4017地址四、MCP4017读写函数五、CubeMX创建工程(利用ADC测量MCP4017电压)、对应代码:总结前言一、MCP4017的重要特性蓝桥杯板子上的是MCP4017T-104ELT,如图1。MCP4017是一个可编程电阻,通过写入的数值可以改变电阻的大小。重点在于6引脚(W),5引脚(B&#

  10. [蓝桥杯单片机]学习笔记——串口通信的基本原理与应用 - 2

    目录一、原理部分1、什么是串行通信(1)并行通信与串行通信(2)串行通信的制式(3)串行通信的主要方式  2、配置串口(1)SCON和PCON:串行口1的控制寄存器(2)SBUF:串行口数据缓冲寄存器 (3)AUXR:辅助寄存器​编辑(4)ES、PS:与串行口1中断相关的寄存器(5)波特率设置  3、串口框架编写二、程序案例一、原理部分1、什么是串行通信(1)并行通信与串行通信微控制器与外部设备的数据通信,根据连线结构和传送方式的不同,可以分为两种:并行通信和串行通信。并行通信:数据的各位同时发送与接收,每个数据位使用一条导线,这种方式传输快,但是需要多条导线进行信号传输。串行通信:数据一位一

随机推荐