16届蓝桥杯模拟试题三-编程解析

一、题目展示

16届蓝桥杯模拟试题三-编程解析_第1张图片

16届蓝桥杯模拟试题三-编程解析_第2张图片

二、参考答案

1、主函数初始化

程序的相关初始化,记得引入自己的头文件,以及对下面会用lcd驱动的几个函数进行一定的修改,防止led出错,修改就不一一展示了,大致都是这样的,进入lcd驱动的相关函数时保存当前的led输出状态,即GPIOC的PIN15~8的输出值,退出lcd函数时再恢复GPIOC的引脚值。

HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
	LCD_Init();
	LCD_SetTextColor(White);
	LCD_SetBackColor(Black);
	LCD_Clear(Black);
	HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
	HAL_TIM_Base_Start(&htim4);

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		lcd_proc();
		key_proc();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
void LCD_Init(void)
{
		u16 a=GPIOC->ODR;
    LCD_CtrlLinesConfig();
    dummy = LCD_ReadReg(0);

    if(dummy == 0x8230)
    {
        REG_8230_Init();
    }
    else
    {
        REG_932X_Init();
    }
    dummy = LCD_ReadReg(0);
		GPIOC->ODR=a;

}

2、头文件的定义和相关函数的声明

#ifndef _code_h
#define _code_h

#include "stm32g4xx.h"                  // Device header
#include "stdio.h"
#include "string.h"
#include "stdint.h"

#include "main.h"
#include "gpio.h"
#include "lcd.h"
#include "tim.h"
#include "adc.h"

void lcd_proc(void);
void key_proc(void);
void led_proc(u8 led_x,u8 led_mode);
double adc_proc(ADC_HandleTypeDef *hadc);

#endif

3、各个模块编写

#include "code.h"

u8 PARA_key=1;
u8 PARA_up=1;
/*-----------------------------lcd---------------------------------*/
u8 ui;
u8 Con;
u32 Rate;
char lcd_val[20];
u8 RECORD[2];
u8 PARA[4]={60,100};
u8 Con_flag;
u8 Con_old_flag;
void lcd_proc(void)
{
	if(ui==0)
	{
		led_proc(3,0);
		led_proc(1,1);
		sprintf(lcd_val,"       HEART  ");
		LCD_DisplayStringLine(Line1,(u8 *)lcd_val);
		sprintf(lcd_val,"      Rate:%d   ",Rate);
		LCD_DisplayStringLine(Line3,(u8  *)lcd_val);
		sprintf(lcd_val,"       Con:%d   ",Con);
		LCD_DisplayStringLine(Line4,(u8 *)lcd_val);
		if(PARA_key==0)
		{
			PARA[0]=PARA[2];
			PARA[1]=PARA[3];
			PARA_key=1;
			PARA_up=1;
		}
	}
	else if(ui==1)
	{
		led_proc(1,0);
		led_proc(2,1);
		sprintf(lcd_val,"       RECORD  ");
		LCD_DisplayStringLine(Line1,(u8 *)lcd_val);
		sprintf(lcd_val,"       Max:%d     ",RECORD[0]);
		LCD_DisplayStringLine(Line3,(u8 *)lcd_val);
		sprintf(lcd_val,"       Min:%d     ",RECORD[1]);
		LCD_DisplayStringLine(Line4,(u8 *)lcd_val);
	}
	else
	{
		led_proc(2,0);
		led_proc(3,1);
		sprintf(lcd_val,"        PARA  ");
		LCD_DisplayStringLine(Line1,(u8 *)lcd_val);
		sprintf(lcd_val,"      High:%d   ",PARA[1]);
		LCD_DisplayStringLine(Line3,(u8 *)lcd_val);
		sprintf(lcd_val,"       Low:%d   ",PARA[0]);
		LCD_DisplayStringLine(Line4,(u8 *)lcd_val);
		if(PARA_key==1)
		{
			PARA[2]=PARA[0];
			PARA[3]=PARA[1];
			led_proc(4,0);
			led_proc(5,0);
		}
		else
		{
			PARA[PARA_up]=adc_proc(&hadc2);
			led_proc(4,PARA_up);
			led_proc(5,!PARA_up);
		}
	}
	if(RatePARA[1])
	{
		if(Con_flag==0)
		{
			Con_flag=1;
			Con++;
			TIM4->CNT=0;
			led_proc(6,1);
		}
	}
	else
	{
		Con_flag=0;
	}
	if(TIM4->CNT>50000)
	{
		led_proc(6,0);
	}
}





/*-----------------------------key---------------------------------*/
u8 key_val[4];
u8 key_old[4];
u8 key;


void key_proc(void)
{
	for(u8 i=0;i<3;i++)
	{
		key_val[i]=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0<Instance==TIM3)
	{
		Capture_val=TIM3->CCR1;
		TIM3->CNT=0;
		fre=80000000/(Capture_val*80);
		if(fre<1000)fre=1000;
		else if(fre>2000)fre=2000;
		Rate=fre*0.17-140;
//		30=1000k+b		170 b=-140
//		200=2000k+b
//		170=1000k
//		k=0.17
		if(i<5)
		{
			i++;
			RECORD[0]=Rate;
			RECORD[1]=RECORD[0];
		}
		if(RECORD[0]Rate)RECORD[1]=Rate;
	}
}

/*-----------------------------adc---------------------------------*/
double adc_val;
double adc_proc(ADC_HandleTypeDef *hadc)
{
	HAL_ADC_Start(hadc);
	adc_val=3.3*HAL_ADC_GetValue(hadc)/4095;
	if(adc_val<1)adc_val=1;
	else if(adc_val>3)adc_val=3;
//	60=1k+b		b=15
//	150=3k+b
//	90=2k		k=45
	return adc_val*45+15;
}

 三、结语

总的来说,还是非常简单常规的,2个多小时就做完了,被扣了一点分,在编写没有考虑到心率直接从小于到大于,跳过了标志复位,不能让Con加一,虽然板子上做不到,但,唉.....,最后也懒得再改了,如果大佬看后有好的想法可以在评论区帮忙指点一下,马上还有不到一个月的时间就省赛了,看能不能再提升一下代码的编写,优化优化一下自己的写法,先谢谢佬们,也祝各位比赛顺利。

你可能感兴趣的:(蓝桥杯)