首页 > 其他分享 >蓝桥杯嵌入式第十届省赛解析

蓝桥杯嵌入式第十届省赛解析

时间:2023-06-18 10:35:36浏览次数:33  
标签:CODE Min Max 嵌入式 蓝桥 Volt LCD USER 省赛

(文章目录)


前言

本篇文章将为大家讲解第十届省赛题目,总的来说题目的难点就是EEPROM的数据存储,因为这里涉及到了小数的部分,其他的其实都是不难的。

一、题目解析

本届题目主要考察了LCD显示,LED控制,模拟电压输入,按键输入E2PROM数据存储,这些都是非常常规的操作起来并不难,值得一讲的就是数据存储和LCD高亮显示。 在这里插入图片描述

二、LCD高亮显示

在赛题的这一部分需要我们高亮显示一行数据,这里是很多同学没有接触过的现在就给大家讲解一下如何高亮显示吧。 在这里插入图片描述 代码: 我想要高亮显示的是Max_Volt_buf,操作如下: 首先先将背景色设置为想要高亮的颜色,然后再去显示想要显示的字符串,最后将颜色重置为白色那么这样就达到了高亮显示的效果了。

LCD_SetBackColor(Green);		
LCD_DisplayStringLine(Line2, (u8*)Max_Volt_buf);
LCD_SetBackColor(White);

三、E2PROM如何存储小数部分

E2PROM存储的类型是unsigned char类型的存储的范围是0-255,所以直接使用他存储小数是不可能的。有很多同学就会卡在这里,这里教大家一个好的方法。 既然E2PROM只能够存储u8类型的那么我们就将小数变成整数来存储进去,读取的时候再将整数换算为小数 在这里插入图片描述 这里我们需要存储的是Max Volt和Min Volt这两个小数。 代码: 存储: 首先先定义两个整数类型的write_Max_Volt 和write_Min_Volt ,使用他们来保存从小数转换为整数的Max Volt和Min Volt。 这里直接让Max_Volt *10强制变为整数存储进去。因为电压的范围是0-3.3V所以这里我们并不需要担心范围的问题,可以直接进行乘法操作。 注意点: 为什么这里需要加一个0.01呢因为Max_Volt 是一个小数他乘10后不一定可以得到正确的数值,所以这里需要加一个0.01进行补偿,当然了也不一定是加0.01这个数值大家可以通过调试测试出来

int write_Max_Volt = 0;
int write_Min_Volt = 0;

write_Max_Volt = (Max_Volt + 0.01) * 10;
EEPROM_Write(0x02, (u8)write_Max_Volt);

write_Min_Volt = (Min_Volt + 0.01) * 10;
EEPROM_Write(0x03, (u8)write_Min_Volt);

读取: 和上面一样我们需要先定义read_Max_Volt 和read_Min_Volt 两个变量来保存读取出来的整数值。 读取出来的数值为整数我们需要对他进行转换。

这个代码的目的是将一个整数转换为一个浮点数,整数的高位作为浮点数的整数部分,低位作为浮点数的小数部分,例如: 如果read_Max_Volt的值为30,则按照下面代码的转换规则,可以得到Max_Volt的值为3.0。 这个转换应该是很简单的,不熟练的同学再回去看看C语言知识。

int read_Max_Volt = 0;
int read_Min_Volt = 0;

read_Max_Volt = EEPROM_Read(0x02);
HAL_Delay(5);
read_Min_Volt = EEPROM_Read(0x03);
HAL_Delay(5);

Max_Volt = (float)(read_Max_Volt / 10) + (float)(read_Max_Volt % 10) / 10.0f;
Min_Volt = (float)(read_Min_Volt / 10) + (float)(read_Min_Volt % 10) / 10.0f;

四、参数合理性判断

这一部分需要大家注意,上限值电压参数肯定是不难比下限电压参数 在这里插入图片描述 这里先定义两个old变量用来保存Max_Volt和Min_Volt,当从参数设置界面退出时判断参数是否正确,如果不正确那么就将old_Max_Volt和old_Min_Volt赋值给Max_Volt和Min_Volt 恢复原来正确的值。

float old_Max_Volt = 0;
float old_Min_Volt = 0;

if(key_val == 1)
{
	UI = !UI;
	if(UI)
	{
		old_Max_Volt = Max_Volt;
		old_Min_Volt = Min_Volt;
	}
	else
	{
		if(Max_Volt < Min_Volt)
		{
			Max_Volt = old_Max_Volt;
			Min_Volt = old_Min_Volt;			
		}
	}		
	LCD_Clear(White);
}

五、完整代码

全部代码展示:

  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "tim.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "led.h"
#include "key.h"
#include "i2c.h"
#include <stdio.h>
#include <string.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/*R38电压变量(因为板子的R37坏掉了所以只有R38了)*/
int volt_value = 0;
float volt_R38 = 0;
/*电压上限下限变量*/
char volt_buf[16] = {0};
float Max_Volt = 2.4;
float Min_Volt = 1.2;
/*定义这两个变量是为了当Max和Min参数错误的时候恢复原变量的(例如Max < Min)时就会使用到这两个变量*/
float old_Max_Volt = 0;
float old_Min_Volt = 0;
char Max_Volt_buf[16] = {0};
char Min_Volt_buf[16] = {0};
/*界面切换变量*/
int UI = 0;
int select = 0;
/*上下限LED控制变量*/
int upled = 1;
int lowled = 2;
char upled_buf[16] = {0};
char lowled_buf[16] = {0};

/*操作E2PROM变量*/
int write_Max_Volt = 0;
int write_Min_Volt = 0;

int read_Max_Volt = 0;
int read_Min_Volt = 0;

// 按键执行程序
__IO uint32_t keyTick = 0;
u16 key_val = 0;
void Key_Scan(void)
{
	if(uwTick - keyTick < 10) return ; 
	keyTick = uwTick; 
	
	Key_Read();
	if(Trg & 0x01)	//B1
	{
		key_val = 1; 
	}
	if(Trg & 0x02)	//B2
	{
		key_val = 2;
	}
	if(Trg & 0x04)	//B3
	{
		key_val = 3;
	}
	if(Trg & 0x08)	//B4
	{
		key_val = 4;
	}
}

__IO uint32_t ledTick = 0;
void LED(void)
{
	static int status = 0;
	if(uwTick - ledTick < 200) return ; 
	ledTick = uwTick;
	status = !status; 	
	if(volt_R38 > Max_Volt)
	{
		Led_Set_Status(upled, status);
		if(UI == 0)
		{
			LCD_DisplayStringLine(Line5, (u8*)"    Status: Upper");
		}		
	}
	else if(volt_R38 < Min_Volt)
	{
		Led_Set_Status(lowled, status);
		if(UI == 0)
		{
			LCD_DisplayStringLine(Line5, (u8*)"    Status: Lower");
		}
	}
	else if(volt_R38 >= Min_Volt && volt_R38 <= Max_Volt)
	{
		if(UI == 0)
		{
			LCD_DisplayStringLine(Line5, (u8*)"    Status: Nomal");			
		}		
		HAL_GPIO_WritePin(GPIOC,0xff00,GPIO_PIN_SET);//关闭全部LED
		
		HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);//打开锁存器
		HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);//关闭锁存器
	}
}

void key_dispose(void)
{
	if(key_val == 1)
	{
		UI = !UI;
		if(UI)
		{
			old_Max_Volt = Max_Volt;
			old_Min_Volt = Min_Volt;
		}
		else
		{
			if(Max_Volt < Min_Volt)
			{
				Max_Volt = old_Max_Volt;
				Min_Volt = old_Min_Volt;			
			}
		}		
		LCD_Clear(White);
	}
	if(key_val == 2)
	{
		if(UI)
		{
			select++;
			select = select % 4;
		}
	}	
	if(key_val == 3)
	{
		if(UI)
		{
			if(select == 0)
			{
				if(Max_Volt < 3.29)
				{
					Max_Volt += 0.3;
				}
				write_Max_Volt = (Max_Volt + 0.01) * 10;
				EEPROM_Write(0x02, (u8)write_Max_Volt);
			}
			else if(select == 1)
			{
				if(Min_Volt < 3.29)
				{
					Min_Volt += 0.3;
				}
				write_Min_Volt = (Min_Volt + 0.01) * 10;
				EEPROM_Write(0x03, (u8)write_Min_Volt);
			}
			else if(select == 2)
			{
				if(upled < 8)
				{
					upled++;
				}				
			}
			else if(select == 3)
			{
				if(lowled < 8)
				{
					lowled++;
				}					
			}
		}
		EEPROM_Write(0x00, (u8)upled);
		HAL_Delay(2);
		EEPROM_Write(0x01, (u8)lowled);
	}
	if(key_val == 4)
	{
		if(UI)
		{
			if(select == 0)
			{
				if(Max_Volt > 0.1)
				{
					Max_Volt -= 0.3;
				}
				write_Max_Volt = (Max_Volt + 0.01) * 10;
				EEPROM_Write(0x02, (u8)write_Max_Volt);				
			}
			else if(select == 1)
			{
				if(Min_Volt > 0.1)
				{
					Min_Volt -= 0.3;
				}
				write_Min_Volt = (Min_Volt + 0.01) * 10;
				EEPROM_Write(0x03, (u8)write_Min_Volt);				
			}
			else if(select == 2)
			{
				if(upled > 1)
				{
					upled--;
				}
			}
			else if(select == 3)
			{
				if(lowled > 1)
				{
					lowled--;
				}
			}			
		}
		EEPROM_Write(0x00, (u8)upled);
		HAL_Delay(2);
		EEPROM_Write(0x01, (u8)lowled);		
	}
	key_val = 0;
}

/*数据界面*/
void Data_Show(void)
{
	LCD_DisplayStringLine(Line1, (u8*)"        Main");
	sprintf(volt_buf, "    Volt: %3.2fV", volt_R38);
	LCD_DisplayStringLine(Line4, (u8*)volt_buf);
}

/*参数设置界面*/
void Para_Show(void)
{
	LCD_DisplayStringLine(Line1, (u8*)"        Setting");		
	if(select == 0)
	{
		sprintf(Max_Volt_buf, "   Max Volt: %3.1fV", Max_Volt);
		LCD_SetBackColor(Green);		
		LCD_DisplayStringLine(Line2, (u8*)Max_Volt_buf);
		LCD_SetBackColor(White);
	}
	else 
	{
		sprintf(Max_Volt_buf, "   Max Volt: %3.1fV", Max_Volt);
		LCD_DisplayStringLine(Line2, (u8*)Max_Volt_buf);
	}
	if(select == 1)
	{
		sprintf(Min_Volt_buf, "   Min Volt: %3.1fV", Min_Volt);
		LCD_SetBackColor(Green);		
		LCD_DisplayStringLine(Line3, (u8*)Min_Volt_buf);
		LCD_SetBackColor(White);
	}
	else 
	{
		sprintf(Min_Volt_buf, "   Min Volt: %3.1fV", Min_Volt);
		LCD_DisplayStringLine(Line3, (u8*)Min_Volt_buf);
	}
	if(select == 2)
	{
		LCD_SetBackColor(Green);
		sprintf(upled_buf, "   Upper:LD%d", upled);
		LCD_DisplayStringLine(Line4, (u8*)upled_buf);
		LCD_SetBackColor(White);
	}
	else 
	{
		sprintf(upled_buf, "   Upper:LD%d", upled);
		LCD_DisplayStringLine(Line4, (u8*)upled_buf);
	}	
	if(select == 3)
	{
		LCD_SetBackColor(Green);
		sprintf(lowled_buf, "   Lower:LD%d", lowled);
		LCD_DisplayStringLine(Line5, (u8*)lowled_buf);	
		LCD_SetBackColor(White);
	}
	else 
	{
		sprintf(lowled_buf, "   Lower:LD%d", lowled);
		LCD_DisplayStringLine(Line5, (u8*)lowled_buf);	
	}			
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */
	
	LCD_Init();
	I2CInit();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

	LCD_Clear(White);
	LCD_SetTextColor(Blue);
	LCD_SetBackColor(White);

	upled = EEPROM_Read(0x00);
	HAL_Delay(5);
	lowled = EEPROM_Read(0x01);
	HAL_Delay(5);
	
//	EEPROM_Write(0x02, 30);
//	EEPROM_Write(0x03, 21);
	
	read_Max_Volt = EEPROM_Read(0x02);
	HAL_Delay(5);
	read_Min_Volt = EEPROM_Read(0x03);
	HAL_Delay(5);
	
	Max_Volt = (float)(read_Max_Volt / 10) + (float)(read_Max_Volt % 10) / 10.0f;
	Min_Volt = (float)(read_Min_Volt / 10) + (float)(read_Min_Volt % 10) / 10.0f;
	
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		HAL_ADC_Start(&hadc1);
		volt_value = HAL_ADC_GetValue(&hadc1);
		volt_R38 = volt_value / 4096.0f * 3.3f;
		Key_Scan();
		key_dispose();
		if(UI)
		{
			Para_Show();
		}
		else
		{
			Data_Show();
		}
		LED();
  }
  /* USER CODE END 3 */
}

总结

需要完整的工程的小伙伴可以私信我,或者下方留言,公众号回复:蓝桥杯嵌入式即可获得完整代码。

标签:CODE,Min,Max,嵌入式,蓝桥,Volt,LCD,USER,省赛
From: https://blog.51cto.com/u_16153875/6507474

相关文章

  • 蓝桥杯嵌入式第十三届客观题解析
    (文章目录)前言本篇文章将带大家来学习蓝桥杯嵌入式的客观题了,蓝桥杯嵌入式的客观题涉及到模电,数电,单片机等知识,需要非常扎实的基础,客观题不能急于求成只能脚踏实地一步步的积累,下面就让我们正式进入客观题的讲解。一、题目1第一题是一个多选题选ABC在参考手册中我们可以清......
  • 路径之谜(DFS)-2016年蓝桥杯国赛
    路径之谜-2016年国赛1、题目描述2、解题思路3、代码实现1、题目描述  小明冒充X星球的骑士,进入了一个奇怪的城堡。  城堡里边什么都没有,只有方形石头铺成的地面。  假设城堡地面是n×n*个方格。如下图所示。  按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但......
  • 十一届蓝桥杯研究生组国赛-循环小数(数论)
    十一届蓝桥杯研究生组国赛-循环小数1、题目描述2、解题思路3、代码实现1、题目描述  已知S是一个小于11的循环小数,请计算与S相等的最简真分数是多少。  例如0.3333⋯0.3333⋯等于1331,0.1666⋯0.1666⋯等于1661。输入描述  输入第一行包含两个整数p和q,表示......
  • 实验三 嵌入式SQL与数据库连接
    一、数据库连接技术简介本实验在Java程序中采用JDBC连接openGauss。Java数据库连接是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。我们通常说的JDBC是面向关系型数据库的。JDBC有五种连接方式,分别是直接实例化Driver,......
  • 痞子衡嵌入式:主流QuadSPI NOR Flash厂商关于QE位与IO功能复用关联设计
    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家讲的是几家主流QuadSPINORFlash厂商关于QE位与IO功能复用关联设计。痞子衡之前写过一篇文章《串行NORFlash下载/启动常见影响因素之QEbit》,这篇文章介绍了几家主流厂商关于QEbit在Flash内部寄存器位置以......
  • 《安富莱嵌入式周报》第315期:开源USB高速分析仪,8GHz示波器开发, 600行C编写RISC-V内
    周报汇总地址:http://www.armbbs.cn/forum.php?mod=forumdisplay&fid=12&filter=typeid&typeid=104 视频版:https://www.bilibili.com/video/BV1gV4y117UD/1、开源USB2.0高速分析仪https://github.com/ataradov/usb-snifferusb-sniffer-main.zip(2.05MB)分析仪上位机......
  • 实验三 嵌入式SQL与数据库连接
    **实验三嵌入式SQL与数据库连接**一、实验要求掌握嵌入式SQL的使用方法,通过数据库连接技术连接DBMS,访问数据库并实现存储过程调用,完成简易数据库应用系统的模拟实现。二、实验目的·理解嵌入式SQL;·理解数据库连接技术;·掌握基于特定宿主语言的数据库连接与访问;·设计......
  • Linux下嵌入式Web服务器BOA和CGI编程开发
    https://blog.csdn.net/Ikaros_521/article/details/102610768一、环境搭建操作系统:Ubuntu12.04LTS(CentOS7类似0.0)boa下载地址(网址突然又挂了):http://www.boa.org/官方文档:http://www.boa.org/documentation/boa-2.htmlGitHub仓库:https://github.com/gpg/boa我是其他网站找......
  • RK3568 vs 树莓派4: 嵌入式计算的巅峰之争
    ▎引言  嵌入式计算领域一直以来都有着激烈的竞争,RK3568和树莓派4作为两个备受瞩目的平台,引起了广泛的关注。本文将以处理器性能、扩展性、功耗和软件支持等方面对RK3568和树莓派4进行综合比较,以帮助读者更好的了解这两个平台的优势和适用场景。  ▎RK3568   经......
  • STM32嵌入式面试知识点总结
    一、STM32F1和F4的区别?解答:参看:STM32开发–STM32初识内核不同:F1是Cortex-M3内核,F4是Cortex-M4内核;主频不同:F1主频72MHz,F4主频168MHz;浮点运算:F1无浮点运算单位,F4有;功能性能:F4外设比F1丰富且功能更强大,比如GPIO翻转速率、上下拉电阻配置、ADC精度等;内存大小:F1内部SRAM最大64K,F4有1......