14届蓝桥杯嵌入式国赛

楼主为13届蓝桥杯单片机组国二得主,14届参加蓝桥杯嵌入式组决赛,分享比赛代码如下。

硬件框图

在这里插入图片描述
总体框架较为简单,考到了DS18B20、单路PWM捕获、ADC采集、PWM生成等模块。细节上东西比较多,处理记录波形和产生波形的时序、温度的温定读取、双按键长按、时间准确控制等。
14届国赛省赛都在PWM生成上作文章,控制好变化时间还是可以很丝滑的,楼主把PWM控制放在了systick中断里,采集播放脉冲、电压信号效果较好。
以下代码为楼主上午在现场写的,时间较紧张没有写注释,仅给出main.c文件(基本都在main.c实现),有bug和不足之处请大家指出!!!

CubeMX配置

在这里插入图片描述
按键,LED,LCD;PA1是PWM采集,PA7是PWM输出,PB15采集R37,单总线PA6直接移植。

main.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "tim.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "lcd.h"
#include "stdio.h"
#include "ds18b20_hal.h"
#include "key.h"
#include "led.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 */

float volt_r37,volt_r37_last;
float temp,temp_last;

u16 adc_val;

u8 interface;
//interface 2
u16 FH=2000,FH_set=2000;
float AH=3.0,AH_set=3.0;
u8 TH=30,TH_set=30;
//interface 3
u8 FN,AN,TN;
//interface 4
u8 FP=1,FP_set=1;
float VP=0.9,VP_set=0.9;
u8 TT=6,TT_set=6;

//1.ADC
void ADC_Process()
{
	HAL_ADC_Start(&hadc2);
  adc_val = HAL_ADC_GetValue(&hadc2);
	volt_r37_last = volt_r37;
	volt_r37 = adc_val/4095.0f*3.3f;
	if(volt_r37>AH_set&&volt_r37_last<AH_set)
		AN++;
}

//2.PWM IC
u8 state_tim2;
u16 cnt1_tim2,cnt2_tim2;

u16 freq_PA1_r,freq_PA1,freq_PA1_last;
u8 duty_PA1_R,duty_PA1;
u32 freq;
u8 i;
u16 duty;
u8 j;

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(state_tim2==0)
	{
		__HAL_TIM_SetCounter(&htim2,0);
		TIM2->CCER |= 0x02;
		state_tim2 =1;
	}
	else if(state_tim2==1)
	{
		cnt1_tim2 = __HAL_TIM_GetCounter(&htim2);
		TIM2->CCER &= ~0x02;
		state_tim2 =2;
	}
	else if(state_tim2==2)
	{
		cnt2_tim2 = __HAL_TIM_GetCounter(&htim2);
		state_tim2 =0;
		freq_PA1_last = freq_PA1;
		freq_PA1_r = 1e6/cnt2_tim2;
		duty_PA1_R = cnt1_tim2*100.0f/cnt2_tim2;
		
		if(++i<60)
			freq+=freq_PA1_r;
		else if(i==60)
		{
			i=0;
			freq_PA1 = freq/(60-1);
			freq=0;
		}
		
		if(++j<100)
			duty+=duty_PA1_R;
		else if(j==100)
		{
			j=0;
			duty_PA1 = duty/(100-1);
			duty=0;
		}
		
		if(freq_PA1>FH_set&&freq_PA1_last<=FH_set)
	  	FN++;
	}
	HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);
}

//3.Temp
__IO u16 temp_tick;
void Temp_Process()
{
	temp_last =temp;
	temp = ds18b20_read();
	if(temp>TH_set&&temp_last<TH_set)
		TN++;
}

//4.LCD

void LCD_Process()
{
	u8 lcd_buff[20];
	if(interface==0)
	{
		sprintf((char *)lcd_buff,"        DATA        ");
		LCD_DisplayStringLine(Line1, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     F=%d        ",freq_PA1);
		LCD_DisplayStringLine(Line3, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     D=%d%%        ",duty_PA1);
		LCD_DisplayStringLine(Line4, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     A=%3.1f       ",volt_r37);
		LCD_DisplayStringLine(Line5, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     T=%3.1f        ",temp);
		LCD_DisplayStringLine(Line6, (unsigned char *)lcd_buff);
	}
	else if(interface==1)
	{
		sprintf((char *)lcd_buff,"        PARA        ");
		LCD_DisplayStringLine(Line1, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     FH=%d        ",FH);
		LCD_DisplayStringLine(Line3, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     AH=%3.1f       ",AH);
		LCD_DisplayStringLine(Line4, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     TH=%d          ",TH);
		LCD_DisplayStringLine(Line5, (unsigned char *)lcd_buff);
		LCD_DisplayStringLine(Line6, (unsigned char *)"                    ");
	}
	else if(interface==2)
	{
		sprintf((char *)lcd_buff,"        RECD        ");
		LCD_DisplayStringLine(Line1, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     FN=%d        ",FN);
		LCD_DisplayStringLine(Line3, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     AN=%d        ",AN);
		LCD_DisplayStringLine(Line4, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     TN=%d          ",TN);
		LCD_DisplayStringLine(Line5, (unsigned char *)lcd_buff);
		LCD_DisplayStringLine(Line6, (unsigned char *)"                    ");
	}
	else if(interface==3)
	{
		sprintf((char *)lcd_buff,"        FSET        ");
		LCD_DisplayStringLine(Line1, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     FP=%d        ",FP);
		LCD_DisplayStringLine(Line3, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     VP=%-3.1f        ",VP);
		LCD_DisplayStringLine(Line4, (unsigned char *)lcd_buff);
		sprintf((char *)lcd_buff,"     TT=%d          ",TT);
		LCD_DisplayStringLine(Line5, (unsigned char *)lcd_buff);
		LCD_DisplayStringLine(Line6, (unsigned char *)"                    ");
	}
}

//record
u16 freq_r[101];
u8 duty_r[101];
u8 duty_Adc[101];
_Bool flag_Record;
u16 cnt_Record;
u8 cnt_index;

u16 cnt_KB34;
_Bool flag_K34;
_Bool flag_pwm;
_Bool flag_adc;
_Bool flag_jilu;

u8 led;
u8 led_cnt;
/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
	if(flag_K34)
	{
		if(++cnt_KB34>2000)
		{
			cnt_KB34=0;
			key_lock=1;
			flag_K34=0;
			
			interface=0;
			FH_set=FH=2000;
			AH_set=AH=3.0f;
			TH_set=TH=30;
			FP_set=FP=1;
			VP_set=VP=0.9f;
			TT_set=TT=6;
			FN=AN=TN=0;
		}
	}

	if(++temp_tick>750)
	{
		temp_tick = 0;
		Temp_Process();
	}
	
	if(flag_Record)
	{
		if(++cnt_Record>1000*TT_set)
		{
			cnt_Record=0;
			flag_Record=0;
			cnt_index=0;
			flag_jilu=1;
		}
		if(cnt_Record%100==0)//0.1s
		{
			freq_r[cnt_index]=freq_PA1;
			duty_r[cnt_index]=duty_PA1;
			if(volt_r37>=VP_set)
				duty_Adc[cnt_index]=90.0f/(3.3f-VP_set)*(volt_r37-3.3f)+100.0f;
			else
				duty_Adc[cnt_index]=10;
			cnt_index++;
		}
		if(++led_cnt==100)
		{
			led^=0x01;
			led_cnt=0;
		}
	}
	else
		led&=~0x01;
	
	if(flag_pwm)
	{
		if(++cnt_Record>1000*TT_set)
		{
			cnt_Record=0;
			flag_pwm=0;
			cnt_index=0;
		}
		if(cnt_Record%100==0)//0.1s
		{
			TIM17->ARR=1e6/freq_r[cnt_index]*FP_set-1;
			TIM17->CCR1=duty_r[cnt_index]*(1e6/freq_r[cnt_index]*FP_set)/100.0f;
			cnt_index++;
		}
		if(cnt_Record==0)
		{
			TIM17->CCR1=0;
		}
		if(++led_cnt==100)
		{
			led_cnt=0;
			led^=0x02;
		}
	}
	else
		led&=~0x02;
	
	if(flag_adc)
	{
		if(++cnt_Record>1000*TT_set)
		{
			cnt_Record=0;
			flag_adc=0;
			cnt_index=0;
		}
		if(cnt_Record%100==0)//0.1s
		{
			TIM17->ARR=999;
			TIM17->CCR1=duty_Adc[cnt_index]*10.0f;
			cnt_index++;
		}
		if(cnt_Record==0)
		{
			TIM17->CCR1=0;
		}
		if(++led_cnt==100)
		{
			led_cnt=0;
			led^=0x04;
		}
	}
	else
		led&=~0x04;
  /* USER CODE END SysTick_IRQn 1 */
}

//4.Key
u8 flag_interface1,flag_interface3;
__IO u32 key_tick;

void Key_Process()
{
	if(uwTick - key_tick<10)	return;
		key_tick = uwTick;
	Scan_Key();
	if(flag_Record) return;
	if(!Cnt)
	{
		key_lock =0;
		cnt_KB34=0;
		flag_K34=0;
	}
	if(Cnt&0x0c)
	{
		flag_K34=1;
	}
	
	if(Trg&0x01)
	{
		if(++interface==4)
			interface=0;
		if(interface==2)
		{
			FH_set = FH;
			AH_set = AH;
			TH_set = TH;
		}
		else if(interface==0)
		{
			FP_set = FP;
			VP_set = VP;
			TT_set = TT;
		}
		else if(interface==1)
		{
			flag_interface1=0;
		}
		else if(interface==3)
		{
			flag_interface3=0;
		}
	}
	else if(Trg&0x02)
	{
		if(interface==0)//Record
		{
			flag_Record=1;
			led_cnt=0;
		}
		else if(interface==1)
		{
			if(++flag_interface1==3)
				flag_interface1=0;
		}
		else if(interface==2)
		{
			FN=AN=TN=0;
		}
		else if(interface==3)
		{
			if(++flag_interface3==3)
				flag_interface3=0;
		}
	}
	else if(Trg&0x04)
	{
		if(interface==1)
		{
			if(flag_interface1==0)
			{
				if(FH<10000)
					FH+=1000;
			}
			else if(flag_interface1==1)
			{
				if(AH<3.2f)
					AH+=0.3f;
			}
			else if(flag_interface1==2)
			{
				if(TH<80)
					TH+=1;
			}
		}
		else if(interface==3)
		{
			if(flag_interface3==0)
			{
				if(FP<10)
					FP+=1;
			}
			else if(flag_interface3==1)
			{
				if(VP<3.2f)
					VP+=0.3f;
			}
			else if(flag_interface3==2)
			{
				if(TT<10)
					TT+=2;
			}
		}
		else if(interface==0)
		{
			if(!flag_pwm&&flag_jilu)
			{
				flag_adc=1;
				led_cnt=0;
			}
		}
	}
	else if(Trg&0x08)
	{
		if(interface==1)
		{
			if(flag_interface1==0)
			{
				if(FH>1000)
					FH-=1000;
			}
			else if(flag_interface1==1)
			{
				if(AH>0.2f)
					AH-=0.3f;
			}
			else if(flag_interface1==2)
			{
				if(TH>0)
					TH-=1;
			}
		}
		else if(interface==3)
		{
			if(flag_interface3==0)
			{
				if(FP>1)
					FP-=1;
			}
			else if(flag_interface3==1)
			{
				if(VP>0.5f)
					VP-=0.3f;
				else 
					VP=0;
			}
			else if(flag_interface3==2)
			{
				if(TT>2)
					TT-=2;
			}
		}
		else if(interface==0)
		{
			if(!flag_adc&&flag_jilu)
			{
				flag_pwm=1;
				led_cnt=0;
			}
		}
	}
}

//5.LED
void LED_Process()
{
	LED_Contr(led);
	if(freq_PA1>FH_set)
		led|=0x08;
	else
		led&=~0x08;
	
	if(volt_r37>AH_set)
		led|=0x10;
	else
		led&=~0x10;
	
	if(temp>TH_set)
		led|=0x20;
	else 
		led&=~0x20;
}

/* 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();
  /* USER CODE BEGIN 2 */

    LCD_Init();
		HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);
		ds18b20_init_x();
		HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
		TIM17->CCR1 = 0;//high 0
  /* USER CODE END 2 */

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

    LCD_Clear(Black);
    LCD_SetBackColor(Black);
    LCD_SetTextColor(White);
		while((u8)ds18b20_read()==85)
		{
		}
		temp = ds18b20_read();

    while (1)
    {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
			ADC_Process();
			LCD_Process();
			Key_Process();
			LED_Process();
    }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
  RCC_OscInitStruct.PLL.PLLN = 20;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the peripherals clocks
  */
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12;
  PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
    /* User can add his own implementation to report the file name and line number,
       tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

代码细节解释

1. 双按键长按
使用上升沿触发,三行按键写法如下:

#include "key.h"

#define KB1 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)
#define KB2 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)
#define KB3 HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)
#define KB4 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)

#define Key_Port (KB1)|(KB2<<1)|(KB3<<2)|(KB4<<3)|0xf0

u8 Trg;
u8 Cnt;
_Bool key_lock;

void Scan_Key(void)
{
	u8 Read_Dat = (Key_Port)^0xff;
	if(key_lock==0)
		Trg = Cnt&(Read_Dat^Cnt);
	Cnt = Read_Dat;
}

由于是KB3+KB4一起长按1s,需要判断两位0000 1100 即0x0c(通过仿真调试也可以验证)。
在这里插入图片描述

2. PWM和ADC数据记录
第一眼拿到赛题对信号记录的感觉是懵的,后来转念一想,这不就是按照同样时间频率进行打点计数嘛,于是我采用了数组计数,没有对动态内存作优化,直接定义100个字长的数组!每0.1s进行一次计数。
具体实现在main.h里面的systemtick回调函数里面(所有时间要求准操作的我都放在这里面了),实现思路就是定义变量自加取模。
3. 信号发生
直接操作寄存器,简洁了当。

TIM17->ARR;
TIM17->CCR1

这个过程其实和上个过程是反的,只需要倒过来赋值就可以了。
下面是我systemtick回调函数里的内容:

/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
	if(flag_K34)
	{
		if(++cnt_KB34>2000)
		{
			cnt_KB34=0;
			key_lock=1;
			flag_K34=0;
			
			interface=0;
			FH_set=FH=2000;
			AH_set=AH=3.0f;
			TH_set=TH=30;
			FP_set=FP=1;
			VP_set=VP=0.9f;
			TT_set=TT=6;
			FN=AN=TN=0;
		}
	}

	if(++temp_tick>750)
	{
		temp_tick = 0;
		Temp_Process();
	}
	
	if(flag_Record)
	{
		if(++cnt_Record>1000*TT_set)
		{
			cnt_Record=0;
			flag_Record=0;
			cnt_index=0;
			flag_jilu=1;
		}
		if(cnt_Record%100==0)//0.1s
		{
			freq_r[cnt_index]=freq_PA1;
			duty_r[cnt_index]=duty_PA1;
			if(volt_r37>=VP_set)
				duty_Adc[cnt_index]=90.0f/(3.3f-VP_set)*(volt_r37-3.3f)+100.0f;
			else
				duty_Adc[cnt_index]=10;
			cnt_index++;
		}
		if(++led_cnt==100)
		{
			led^=0x01;
			led_cnt=0;
		}
	}
	else
		led&=~0x01;
	
	if(flag_pwm)
	{
		if(++cnt_Record>1000*TT_set)
		{
			cnt_Record=0;
			flag_pwm=0;
			cnt_index=0;
		}
		if(cnt_Record%100==0)//0.1s
		{
			TIM17->ARR=1e6/freq_r[cnt_index]*FP_set-1;
			TIM17->CCR1=duty_r[cnt_index]*(1e6/freq_r[cnt_index]*FP_set)/100.0f;
			cnt_index++;
		}
		if(cnt_Record==0)
		{
			TIM17->CCR1=0;
		}
		if(++led_cnt==100)
		{
			led_cnt=0;
			led^=0x02;
		}
	}
	else
		led&=~0x02;
	
	if(flag_adc)
	{
		if(++cnt_Record>1000*TT_set)
		{
			cnt_Record=0;
			flag_adc=0;
			cnt_index=0;
		}
		if(cnt_Record%100==0)//0.1s
		{
			TIM17->ARR=999;
			TIM17->CCR1=duty_Adc[cnt_index]*10.0f;
			cnt_index++;
		}
		if(cnt_Record==0)
		{
			TIM17->CCR1=0;
		}
		if(++led_cnt==100)
		{
			led_cnt=0;
			led^=0x04;
		}
	}
	else
		led&=~0x04;
  /* USER CODE END SysTick_IRQn 1 */
}

实现了长按处理,温度采集,信号采集,信号播放功能。
4.PWM频率和占空比采集
简单在状态机里面写了个滤波,防止报警值不稳定。

else if(state_tim2==2)
	{
		cnt2_tim2 = __HAL_TIM_GetCounter(&htim2);
		state_tim2 =0;
		freq_PA1_last = freq_PA1;
		freq_PA1_r = 1e6/cnt2_tim2;
		duty_PA1_R = cnt1_tim2*100.0f/cnt2_tim2;
		
		if(++i<60)
			freq+=freq_PA1_r;
		else if(i==60)
		{
			i=0;
			freq_PA1 = freq/(60-1);
			freq=0;
		}
		
		if(++j<100)
			duty+=duty_PA1_R;
		else if(j==100)
		{
			j=0;
			duty_PA1 = duty/(100-1);
			duty=0;
		}
		
		if(freq_PA1>FH_set&&freq_PA1_last<=FH_set)
	  	FN++;
	}

5.其他一些注意的逻辑

  • 切换界面参数才生效,我设置了两对变量
  • 只要采集了才能生成PWM,用一个标志位处理
  • ds18b20温度采集放在while(1)里面容易跑飞,我放在中断
  • 数组处理好别越界

hex文件

如代码包所示,工程文件可以私信楼主获取,有任何问题欢迎友友们指出评论!!!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐