蓝桥杯嵌入式2021年第十二届第二场省赛主观题解析

本文介绍了在STM32平台上,通过ADC进行电压采样并利用TIM模块测量信号频率和占空比,同时实现按键控制和LCD显示功能的嵌入式系统设计。
摘要由CSDN通过智能技术生成

1  题目 

2  解析

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "tim.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "string.h"
#include "i2c_hal.h"
#include "lcd.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
int cnt1,cnt_down1,f1,cnt2,cnt_down2,f2;
double duty1,val[20],val_avg,duty2;
int num=1;
char buf1[20],buf2[20],buf3[20],buf4[20],buf5[20],buf6[20],buf7[20];
struct keys{
	int step;
	int state;
	int cnt;
}key[5];
int R=4;
int sta;
int comp;
/* 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 */
void LCD_close()
{
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM2&&htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2)//PA1测量外加信号频率和占空比
	{
		cnt1=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);
		cnt_down1=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
		f1=80000000/cnt1;
		duty1=(double)cnt_down1/(double)cnt1;
		__HAL_TIM_SetCounter(&htim2,0);
	}
	if(htim->Instance==TIM3&&htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2)//PA4测量PA7输出信号的频率和占空比
	{
		cnt2=HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_2);
		cnt_down2=HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1);
		f2=1000000/cnt2;
		duty2=(double)cnt_down2/(double)cnt2;
		__HAL_TIM_SetCounter(&htim3,0);
	}
}

void ADC()//电压采样(经过数据处理)
{
	HAL_ADC_Start(&hadc2);
	for(int i=0;i<20;i++)
	{
		val[i]=HAL_ADC_GetValue(&hadc2);
	}
	for(int i=0;i<20;i++)
	{
		for(int j=0;j<20;j++)
		{
			if(val[i]>val[j]) 
			{
				double temp=val[i];
				val[i]=val[j];
				val[j]=temp;
			}
		}
	}
	val_avg=0;
	for(int i=5;i<15;i++)
	{
		val_avg+=val[i];
	}
	val_avg/=10;
	//memset(val,0,sizeof(val));
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM1)//按键处理
	{
		key[1].state=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
		key[2].state=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
		key[3].state=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
		key[4].state=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
		switch(key[1].step)
		{
			case 0:
			{
				if(key[1].state==GPIO_PIN_RESET)
				{
					key[1].step=1;
				}
			}
			break;
			case 1:
			{
				if(key[1].state==GPIO_PIN_RESET)
				{
					key[1].step=2;
				}
				else
				{
					key[1].step=0;
				}
			}
			break;
			case 2:
			{
				if(key[1].state==GPIO_PIN_SET)
				{
					key[1].step=0;
					key[1].cnt++;
					if(key[1].cnt%2==0) num=1;
					else num=2;
				}
			}
			break;
		}
		switch(key[2].step)
		{
			case 0:
			{
				if(key[2].state==GPIO_PIN_RESET)
				{
					key[2].step=1;
				}
			}
			break;
			case 1:
			{
				if(key[2].state==GPIO_PIN_RESET)
				{
					key[2].step=2;
				}
				else
				{
					key[2].step=0;
				}
			}
			break;
			case 2:
			{
				if(key[2].state==GPIO_PIN_SET)
				{
					key[2].step=0;
					R+=2;
					if(R==12) R=2;
				}
			}
			break;
		}
		switch(key[3].step)
		{
			case 0:
			{
				if(key[3].state==GPIO_PIN_RESET)
				{
					key[3].step=1;
				}
			}
			break;
			case 1:
			{
				if(key[3].state==GPIO_PIN_RESET)
				{
					key[3].step=2;
				}
				else
				{
					key[3].step=0;
				}
			}
			break;
			case 2:
			{
				if(key[3].state==GPIO_PIN_SET)
				{
					key[3].step=0;
					R-=2;
					if(R==0) R=10;
				}
			}
			break;
		}
		switch(key[4].step)
		{
			case 0:
			{
				if(key[4].state==GPIO_PIN_RESET)
				{
					key[4].step=1;
				}
			}
			break;
			case 1:
			{
				if(key[4].state==GPIO_PIN_RESET)
				{
					key[4].step=2;
				}
				else
				{
					key[4].step=0;
				}
			}
			break;
			case 2:
			{
				if(key[4].state==GPIO_PIN_SET)
				{
					key[4].step=0;
					key[4].cnt++;
					if(key[4].cnt%2==0)
					{
						HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
						HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15,GPIO_PIN_SET);
						sta=0;
					}
					if(key[4].cnt%2==1) 
					{
						LCD_close();
						HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
						sta=1;
					}
				}
			}
			break;
		}
	}
	
}
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* 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_ADC2_Init();
  MX_TIM2_Init();
  MX_TIM17_Init();
  MX_TIM1_Init();
  MX_TIM15_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
	LCD_Init();
	LCD_close();
	LCD_Clear(White);
	LCD_SetBackColor(Black);
	LCD_SetTextColor(White);
	sprintf(buf1,"       Data");
	sprintf(buf4,"       Para");
	HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);
	HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
	HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_2);
	HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
	HAL_TIM_Base_Start_IT(&htim1);
	HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);//外加产生PWM
	HAL_TIM_PWM_Start(&htim15,TIM_CHANNEL_2);//PA7输出PWM
  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
		ADC();
		comp=1000*val_avg/4096;
	__HAL_TIM_PRESCALER(&htim17,80000 * R / f1);
	__HAL_TIM_SetCounter(&htim17,0);
	__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,comp);
		sprintf(buf3,"   R37:%.2lfV",val_avg*3.3/4096);
		sprintf(buf2,"   FRQ:%dHz",f1);
		sprintf(buf5,"      R:%d",R);
		sprintf(buf6,"   PA7:%dHz",f2);
		sprintf(buf7,"   duty:%.4lf",duty2);
		HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
		if(num==1)
		{
			LCD_Clear(Black);
			LCD_DisplayStringLine(Line1,(uint8_t*)buf1);
			LCD_DisplayStringLine(Line3,(uint8_t*)buf2);
			LCD_DisplayStringLine(Line5,(uint8_t*)buf3);
			LCD_DisplayStringLine(Line7,(uint8_t*)buf6);
			LCD_DisplayStringLine(Line9,(uint8_t*)buf7);
			if(sta==0)
			{
				HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
				HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET);
				HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_SET);
				HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
			}
		}
		if(num==2)
		{
			LCD_Clear(Black);
			LCD_DisplayStringLine(Line1,(uint8_t*)buf4);
			LCD_DisplayStringLine(Line3,(uint8_t*)buf5);
			if(sta==0)
			{
				HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
				HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET);
				HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_SET);
				HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
			}
		}
		if(val_avg*3.3/4096>=3||val_avg*3.3/4096<1)
		{
			if(sta==0)
			{
				HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
				HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET);
				HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
			}
		}
		else 
		{
			if(sta==0)
			{
				HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
				HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_SET);
				HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
			}
		}
		if(f1>=5000||f1<1000)
		{
			if(sta==0)
			{
				HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
				HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_RESET);
				HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
			}
		}
		else
		{
			if(sta==0)
			{
				HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
				HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_SET);
				HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
			}
		}
		HAL_Delay(300);
  }
  /* USER CODE END 3 */
}

  • 46
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜只因C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值