蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛

之前准备省赛的时候用的是旧版的STM32F103,从准备国赛开始就用新版STM32G431平台了,主要是想经过新版的准备学习一下HAL库以及CubeMX的使用。用了几天的新版,感觉新版的还是比较香,单纯从配置各个模块来说,比旧版的省太多时间了,而且速度也比较块,单纯从比赛来说,还是推荐新版,因为配置方便,调试器兼容KEIL5,KEI5比KEIL4好用太多了,也有自动补全,在写代码的时候速度也会比较快一些。不过旧版的资料确实比较多,选择也看大家。所以之后的国赛赛题都是用的新版,当前除了模块的配置外,其他的代码其实都是一样的,没多大区别,所以旧版也是可以参考我的代码。

目录

  • 蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛
    • 一、赛题分析
    • 二、CubeMX模块配置
    • 三、部分程序分析
    • 五、main.c程序
    • 六、完整代码下载

一、赛题分析

刚刚比赛完,前两天刚出成绩。感觉这一届的难度还是挺大的,比前面的几届都要难一些。赛题更加着重逻辑考察,也考察了字符串的处理和一些小的算法。

  • 在逻辑方面体现在有一些参数并不是直接告诉的,而是需要我们进行一些简单的推导,如本届的吊绳和吊臂之间的角度,这里很多人看似简单,实际还要分情况进行讨论的,再比如说角度占空比的换算,赛题是给了一个角度和占空比关系的折线图,具体换算关系则需要我们自己进行推导。
  • 字符串的处理在这一次并没有多大的难度,使用strcmp即可,但是在省赛的时候,字符串的解析还是比较难的,相信有很多的人都是被搞自闭了的。
  • 小的算法在这一次的赛题体现在串口方面,要求我们按照采集时间先后顺序排列输出,相当于队列的先进先出。还有就是要求我们能够实现按照从小到大的顺序排列输出。这里就涉及到排序的知识了,数据量不大,使用冒泡排序或者选择排序都是可以的。
    要说赛题的难度有多大,其实也没有多大,发现都是一些基础的知识,比如说排序,这个在我们大一的C语言肯定是学过的吧。其他的比如说推导一些换算的关系,这个就是麻烦了一点,都是很简单的推导。 这些都是一些基础的知识,但是难的就是把这些知识全部集中到赛题上面,很容易出现错误,就要求我们要细致细致再细致,也有一些人,说自己功能全部都实现完了,但是最后的结果不令人满意,很大可能就是出现在细节的错误上面, 存在很多的BUG导致的。

在硬件的模块部分考察了LCD、LED、串口的不定长数据接收和发送,按键,定时器对方波频率的捕获,定时器捕获双通道的PWM的占空比,ADC等,其实老老实实准备了省赛,这些配置都是没有什么问题的。







二、CubeMX模块配置

  1. LED和按键的GPIO配置
    由于直接使用的考场提供的实例程序,里面的LCD以及LED的GPIO都是配置好了的,我们只需要额外再配置一下LED的使能端口,也就是PD2。与开发板按键相对应的是PB0,PB1,PB2,PA0等。

  2. 时钟配置
    这里我使用的外部晶振,将系统时钟配置成170MHz,也可以使用HSI,其他频率也是可以的。

  3. 定时器TIM4配置
    定时器在这里的作用就是产生1ms的中断,用于定时,用来扫描按键进行消抖,以及其他需要用到定时的模块。

    还要记得打开定时器的中断,

  4. 定时器TIM2,TIM3捕获的配置
    通过PA1捕获扩展板上的方波PULS1,对应的是TIM2的CH2,通过PA6和PA7来捕获扩展板上的PWM波,对应的是TIM3的CH1和CH2。


    最后不要完了打开定时器的全局中断

  5. ADC的配置
    通过ADC来获取光敏电阻的值的大小,使用到的是PA4,对应ADC2_IN17。

  6. 串口的配置
    基本设置,注意波特率为9600,这是试题指定的波特率。

    我使用的是串口的IDLE+DMA来接收不定长数据,这样比较方便,当然也可以有其他的方法,可以看我之前写的博客,所以这里还需要开启一个DMA用于串口的接收。

    然后还要记得要打开串口的总中断,由于我们在这里用不到DMA的中断,所以直接关闭DM的中断即可。

三、部分程序分析

  1. 角度与占空比转换计算
    使用PWM1和PWM2模拟旋转角度传感器输出信号,输出信号占空比值与角度关系如下图所示:

    根据关系图可以解得:
angle_a = TIM3_IC1_Duty * 100.0 * 2.25 - 22.5;
angle_b = TIM3_IC2_Duty * 100.0 * 1.125 - 11.5;
  1. 模式B,通过光敏电阻来触发角度数据更新
    经过的的测试如果手没有遮挡,大概读到的ADC的值为2000,如果手挡住光敏电阻大概读到的值是3000,所以这里可以取一个中间的值,当ADC的值大于2500表示有东西遮挡传感器。这个值会收到环境的影响,根据自己的测试修改即可。
    还需要注意的是,不要一直让ADC进行刷新,我推荐500ms刷新一次,其实就相当于按键消抖。
  2. 吊绳与吊臂之间的夹角
    这里其实应该分两种情况进行讨论,因为角度a的范围是0~180,所以要以吊臂的竖直为边界进行讨论。具体分析请看下图:

    所以根据上面的推导,有以下的代码:
#define LED5_STATE           (angle_a < 90 + angle_b) && 90 - angle_a + angle_b < 10 || (angle_a > 90 + angle_b) && angle_a - 90 - angle_b < 10
led_ctrl(LD5,LED5_STATE);
  1. 串口部分

void sendAngleOderByTime(float* sendBuffer)
{uint8_t index = 0,i,upper_limit = angle_cnt;if(angle_cnt_overflow){index = angle_cnt;upper_limit = 5;}for(i = 0; i < upper_limit; i++){if(i != upper_limit - 1)printf("%.1f-",sendBuffer[index]);elseprintf("%.1f",sendBuffer[index]);index = (index + 1) % 5;}printf("\r\n");
}void sendAngleBySort(float *array1)
{float sendBuffer[20];uint8_t i = 0,j,upper_limit;for(i = 0; i < 5; i++)sendBuffer[i] = array1[i];if(angle_cnt_overflow)upper_limit = 5;elseupper_limit = angle_cnt;for(i = upper_limit - 1; i > 0 && upper_limit; i--){for(j = 0; j < i; j++){if(sendBuffer[j] > sendBuffer[j + 1]){float temp;temp = sendBuffer[j];sendBuffer[j] = sendBuffer[j + 1];sendBuffer[j + 1] = temp;}}}for(i = 0; i < upper_limit; i++){if(i != upper_limit - 1)printf("%.1f-",sendBuffer[i]);elseprintf("%.1f",sendBuffer[i]);}printf("\r\n");
}void uart_proc(void)
{static _Bool firstRx = 1;if(RxFlag && firstRx){firstRx = 0;RxFlag = 0;memset(RxBuffer,0, sizeof(RxBuffer));HAL_UART_DMAStop(&huart1);HAL_UART_Receive_DMA(&huart1,RxBuffer,100);return;}if(RxFlag){RxFlag = 0;if(strcmp((const char *)RxBuffer,"a?") == 0){printf("a:%.1f\r\n",angle_a);}else if(strcmp((const char *)RxBuffer,"b?") == 0){printf("b:%.1f\r\n",angle_b);}else if(strcmp((const char *)RxBuffer,"aa?") == 0){printf("aa:");sendAngleOderByTime(angle_a_buffer);}else if(strcmp((const char *)RxBuffer,"bb?") == 0){printf("bb:");sendAngleOderByTime(angle_b_buffer);}else if(strcmp((const char *)RxBuffer,"qa?") == 0){printf("qa:");sendAngleBySort(angle_a_buffer);}else if(strcmp((const char *)RxBuffer,"qb?") == 0){printf("qb:");sendAngleBySort(angle_b_buffer);}else{printf("error\r\n");}memset(RxBuffer,0, sizeof(RxBuffer));HAL_UART_DMAStop(&huart1);HAL_UART_Receive_DMA(&huart1,RxBuffer,100);}
}

五、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 "dma.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define     DATA       0
#define     PARA       1
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
__IO _Bool TRUE = 1;uint32_t TIM2_IC2_Value1,TIM2_IC2_Value2;
uint32_t TIM2_IC2_Fre;
uint8_t TIM2_IC2_Number;uint16_t TIM3_IC1_Value1,TIM3_IC1_Value2;
uint16_t TIM3_IC1_High,TIM3_IC1_Low;
float TIM3_IC1_Duty;
uint8_t TIM3_IC1_Number;uint16_t TIM3_IC2_Value1,TIM3_IC2_Value2;
uint16_t TIM3_IC2_High,TIM3_IC2_Low;
float TIM3_IC2_Duty;
uint8_t TIM3_IC2_Number;uint16_t adc_value = 0;
uint16_t adc_tick = 0;
_Bool adc_flag = 0;uint8_t RxBuffer[100];
_Bool RxFlag = 0;_Bool interface = DATA;float angle_a = 0.0;
float  angle_b = 0.0;
uint8_t ax = 0;
uint8_t bx = 0;
uint8_t mode = 'A';uint16_t Pf = 1000;
uint8_t Pax = 20;
uint8_t Pbx = 20;uint16_t Pf_temp = 1000;
uint8_t Pax_temp = 20;
uint8_t Pbx_temp = 20;_Bool angle_flag = 0;float angle_a_buffer[5];
float angle_b_buffer[5];
uint8_t angle_cnt = 0;
_Bool angle_cnt_overflow = 0;
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void key_proc(void);
void led_proc(void);
void adc_proc(void);
void lcd_proc(void);
void uart_proc(void);
void angle_proc(void);
void sendAngleBySort(float *array1);
void USER_UART_IdleCallback(UART_HandleTypeDef *huart);
void sendAngleOderByTime(float* sendBuffer);
/* 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_DMA_Init();MX_TIM4_Init();MX_USART1_UART_Init();MX_ADC2_Init();MX_TIM2_Init();MX_TIM3_Init();/* USER CODE BEGIN 2 */LCD_Init();led_init();HAL_TIM_Base_Start_IT(&htim4);HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_2);HAL_ADCEx_Calibration_Start(&hadc2,ADC_SINGLE_ENDED);HAL_ADC_Start(&hadc2);HAL_UART_Receive_DMA(&huart1,RxBuffer,100);__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);__HAL_UART_CLEAR_IDLEFLAG(&huart1);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */LCD_Clear(Black);LCD_SetBackColor(Black);LCD_SetTextColor(White);printf("error\r\n");printf("error\r\n");printf("error\r\n");while (TRUE){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */adc_proc();led_proc();lcd_proc();uart_proc();angle_proc();}/* 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_BOOST);/** Initializes the CPU, AHB and APB busses clocks*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV6;RCC_OscInitStruct.PLL.PLLN = 85;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 busses 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_8) != HAL_OK){Error_Handler();}/** Initializes the peripherals clocks*/PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_ADC12;PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 */
void angle_proc(void)
{static float angle_a_pre = 0.0;static float angle_b_pre = 0.0;if(angle_flag){angle_flag = 0;if(TIM3_IC1_Duty < 0.1)angle_a = 0.0;else if(TIM3_IC1_Duty > 0.9)angle_a = 180.0;elseangle_a = TIM3_IC1_Duty * 100.0 * 2.25 - 22.5;if(TIM3_IC2_Duty < 0.1)angle_b = 0.0;else if(TIM3_IC2_Duty > 0.9)angle_b = 90.0;elseangle_b = TIM3_IC2_Duty * 100.0 * 1.125 - 11.5;angle_a_buffer[angle_cnt] = angle_a;angle_b_buffer[angle_cnt] = angle_b;if(angle_cnt_overflow == 0 && angle_cnt == 4){angle_cnt_overflow = 1;}angle_cnt = (angle_cnt + 1) % 5;if(angle_a_pre > angle_a)ax = angle_a_pre - angle_a;elseax = angle_a - angle_a_pre;if(angle_b_pre > angle_b)bx = angle_b_pre - angle_b;elsebx = angle_b - angle_b_pre;angle_a_pre = angle_a;angle_b_pre = angle_b;}
}void sendAngleOderByTime(float* sendBuffer)
{uint8_t index = 0,i,upper_limit = angle_cnt;if(angle_cnt_overflow){index = angle_cnt;upper_limit = 5;}for(i = 0; i < upper_limit; i++){if(i != upper_limit - 1)printf("%.1f-",sendBuffer[index]);elseprintf("%.1f",sendBuffer[index]);index = (index + 1) % 5;}printf("\r\n");
}void sendAngleBySort(float *array1)
{float sendBuffer[20];uint8_t i = 0,j,upper_limit;for(i = 0; i < 5; i++)sendBuffer[i] = array1[i];if(angle_cnt_overflow)upper_limit = 5;elseupper_limit = angle_cnt;for(i = upper_limit - 1; i > 0 && upper_limit; i--){for(j = 0; j < i; j++){if(sendBuffer[j] > sendBuffer[j + 1]){float temp;temp = sendBuffer[j];sendBuffer[j] = sendBuffer[j + 1];sendBuffer[j + 1] = temp;}}}for(i = 0; i < upper_limit; i++){if(i != upper_limit - 1)printf("%.1f-",sendBuffer[i]);elseprintf("%.1f",sendBuffer[i]);}printf("\r\n");
}void uart_proc(void)
{static _Bool firstRx = 1;if(RxFlag && firstRx){firstRx = 0;RxFlag = 0;memset(RxBuffer,0, sizeof(RxBuffer));HAL_UART_DMAStop(&huart1);HAL_UART_Receive_DMA(&huart1,RxBuffer,100);return;}if(RxFlag){RxFlag = 0;if(strcmp((const char *)RxBuffer,"a?") == 0){printf("a:%.1f\r\n",angle_a);}else if(strcmp((const char *)RxBuffer,"b?") == 0){printf("b:%.1f\r\n",angle_b);}else if(strcmp((const char *)RxBuffer,"aa?") == 0){printf("aa:");sendAngleOderByTime(angle_a_buffer);}else if(strcmp((const char *)RxBuffer,"bb?") == 0){printf("bb:");sendAngleOderByTime(angle_b_buffer);}else if(strcmp((const char *)RxBuffer,"qa?") == 0){printf("qa:");sendAngleBySort(angle_a_buffer);}else if(strcmp((const char *)RxBuffer,"qb?") == 0){printf("qb:");sendAngleBySort(angle_b_buffer);}else{printf("error\r\n");}memset(RxBuffer,0, sizeof(RxBuffer));HAL_UART_DMAStop(&huart1);HAL_UART_Receive_DMA(&huart1,RxBuffer,100);}
}#define LED5_STATE (angle_a < 90 + angle_b) && 90 - angle_a + angle_b < 10 || (angle_a > 90 + angle_b) && angle_a - 90 - angle_b < 10
void led_proc(void)
{led_ctrl(LD1,(ax > Pax));led_ctrl(LD2,(bx > Pbx));led_ctrl(LD3,(TIM2_IC2_Fre > Pf));led_ctrl(LD4,(mode == 'A'));led_ctrl(LD5,LED5_STATE);
}void adc_proc(void)
{if(adc_flag && mode == 'B' && interface == DATA){adc_flag = 0;HAL_ADC_Start(&hadc2);while(HAL_ADC_PollForConversion(&hadc2,0xFF) != HAL_OK);adc_value = HAL_ADC_GetValue(&hadc2);HAL_ADC_Stop(&hadc2);HAL_ADC_Start(&hadc2);HAL_ADC_PollForConversion(&hadc2,0xFF);if(adc_value > 2500)angle_flag = 1;}
}void lcd_proc(void)
{uint8_t lcd_str[20];if(interface == DATA){snprintf((char*)lcd_str,20,"        DATA        ");LCD_DisplayStringLine(Line1, lcd_str);snprintf((char*)lcd_str,20,"   a:%.1f           ",angle_a);LCD_DisplayStringLine(Line2, lcd_str);snprintf((char*)lcd_str,20,"   b:%.1f           ",angle_b);LCD_DisplayStringLine(Line3, lcd_str);snprintf((char*)lcd_str,20,"   f:%dHz          ",TIM2_IC2_Fre);LCD_DisplayStringLine(Line4, lcd_str);snprintf((char*)lcd_str,20,"   ax:%d            ",ax);LCD_DisplayStringLine(Line6, lcd_str);snprintf((char*)lcd_str,20,"   bx:%d            ",bx);LCD_DisplayStringLine(Line7, lcd_str);snprintf((char*)lcd_str,20,"   mode:%c          ",mode);LCD_DisplayStringLine(Line8, lcd_str);}else{snprintf((char*)lcd_str,20,"        PARA        ");LCD_DisplayStringLine(Line1, lcd_str);snprintf((char*)lcd_str,20,"   Pax:%d           ",Pax_temp);LCD_DisplayStringLine(Line2, lcd_str);snprintf((char*)lcd_str,20,"   Pbx:%d           ",Pbx_temp);LCD_DisplayStringLine(Line3, lcd_str);snprintf((char*)lcd_str,20,"   f:%d             ", Pf_temp );LCD_DisplayStringLine(Line4, lcd_str);snprintf((char*)lcd_str,20,"                    ");LCD_DisplayStringLine(Line6, lcd_str);snprintf((char*)lcd_str,20,"                    ");LCD_DisplayStringLine(Line7, lcd_str);snprintf((char*)lcd_str,20,"                    ");LCD_DisplayStringLine(Line8, lcd_str);}}void key_proc(void)
{key_refresh();if(key_falling == B1){if(interface == DATA){interface = PARA;} else{Pax = Pax_temp;Pbx = Pbx_temp;Pf = Pf_temp;interface = DATA;}}else if (key_falling == B2 && interface == PARA){Pax_temp = Pax_temp % 60 + 10;Pbx_temp = Pbx_temp % 60 + 10;}else if (key_falling == B3){if(interface == PARA)Pf_temp = Pf_temp % 10000 + 1000;else{if(mode == 'A')mode = 'B';elsemode = 'A';}}else if (key_falling == B4 && interface == DATA && mode == 'A'){angle_flag = 1;}
}void USER_UART_IdleCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == USART1){if(__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE)){RxFlag = 1;__HAL_UART_CLEAR_IDLEFLAG(huart);}}
}void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM2){if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2){if(TIM2_IC2_Number == 0){TIM2_IC2_Value1 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_2);TIM2_IC2_Number = 1;}else if(TIM2_IC2_Number == 1){TIM2_IC2_Value2 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_2);if(TIM2_IC2_Value1 > TIM2_IC2_Value2)TIM2_IC2_Fre = 1000000 / ((0xFFFFFFFF - TIM2_IC2_Value1) + TIM2_IC2_Value2);elseTIM2_IC2_Fre = 1000000 / (TIM2_IC2_Value2 - TIM2_IC2_Value1);TIM2_IC2_Number = 0;}}}if(htim->Instance == TIM3){if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){if(TIM3_IC1_Number == 0){TIM3_IC1_Value1 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1);__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING);TIM3_IC1_Number = 1;}else if(TIM3_IC1_Number == 1){TIM3_IC1_Value2 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1);__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);if(TIM3_IC1_Value1 > TIM3_IC1_Value2)TIM3_IC1_High = (0xFFFF - TIM3_IC1_Value1) + TIM3_IC1_Value2;elseTIM3_IC1_High = TIM3_IC1_Value2 - TIM3_IC1_Value1;TIM3_IC1_Value1 = TIM3_IC1_Value2;TIM3_IC1_Number = 2;}else if(TIM3_IC1_Number == 2){TIM3_IC1_Value2 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1);if(TIM3_IC1_Value1 > TIM3_IC1_Value2)TIM3_IC1_Low = (0xFFFF - TIM3_IC1_Value1) + TIM3_IC1_Value2;elseTIM3_IC1_Low = TIM3_IC1_Value2 - TIM3_IC1_Value1;TIM3_IC1_Duty = TIM3_IC1_High * 1.0 / (TIM3_IC1_High + TIM3_IC1_Low);TIM3_IC1_Number = 0;}}if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2){if(TIM3_IC2_Number == 0){TIM3_IC2_Value1 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_2);__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_2,TIM_INPUTCHANNELPOLARITY_FALLING);TIM3_IC2_Number = 1;}else if(TIM3_IC2_Number == 1){TIM3_IC2_Value2 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_2);__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_2,TIM_INPUTCHANNELPOLARITY_RISING);if(TIM3_IC2_Value1 > TIM3_IC2_Value2)TIM3_IC2_High = (0xFFFF - TIM3_IC2_Value1) + TIM3_IC2_Value2;elseTIM3_IC2_High = TIM3_IC2_Value2 - TIM3_IC2_Value1;TIM3_IC2_Value1 = TIM3_IC2_Value2;TIM3_IC2_Number = 2;}else if(TIM3_IC2_Number == 2){TIM3_IC2_Value2 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_2);if(TIM3_IC2_Value1 > TIM3_IC2_Value2)TIM3_IC2_Low = (0xFFFF - TIM3_IC2_Value1) + TIM3_IC2_Value2;elseTIM3_IC2_Low = TIM3_IC2_Value2 - TIM3_IC2_Value1;TIM3_IC2_Duty = TIM3_IC2_High * 1.0 / (TIM3_IC2_High + TIM3_IC2_Low);TIM3_IC2_Number = 0;}}}
}void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{static  uint16_t key_tick = 0;if(htim->Instance == TIM4){if(++key_tick == 10){key_tick = 0;key_proc();}if(++adc_tick == 500){adc_tick = 0;adc_flag = 1;}}
}int fputc(int ch,FILE* f)
{HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xFF);return ch;
}
/* 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. 蓝桥杯单片机——第十二届蓝桥杯单片机第一场省赛

    蓝桥杯单片机--第十二届蓝桥杯单片机第一场省赛 目录 蓝桥杯单片机--第十二届蓝桥杯单片机第一场省赛 一.赛题分析 二.问题总结 三.代码 一.赛题分析 前两天实验室的学妹把开发板还给我了,刚好今天没 ...

  2. 2021 第十二届 蓝桥杯 国赛决赛 Java B组 真题 详细解析

    文章目录 2021 第十二届 Java B组 国赛 真题答案 详细解析 试题A: 整数范围 答案:255 分析: Code: 试题B: 纯质数 答案:1903 分析: Code: 试题C: 完全日期 ...

  3. 第十二届蓝桥杯电子类嵌入式设计与开发省、国赛经验分享

    文章目录 前言 一.嵌入式省赛 二.嵌入式国赛 1.前期准备 2.国赛考试 总结 前言 已经考完差不多两周时间了,自己也一直想找个时间写一篇关于蓝桥杯的总结,所以今天就来啦,希望可以帮到后面想参加蓝桥 ...

  4. 蓝桥杯嵌入式第十二届省赛真题

    第十二届蓝桥杯嵌入式-停车计费 文章目录 第十二届蓝桥杯嵌入式-停车计费 1.题目分析 2.项目结构 2.1停车部分整体流程 2.2串口数据解析流程 2.3细节部分 3.代码结构 3.1停车部分 3. ...

  5. 报!!第十二届蓝桥杯大赛报名启动!!

    蓝桥杯全国软件和信息技术专业人才大赛是由工业和信息化部人才交流中心举办的全国性IT学科赛事.共有北京大学.清华大学.上海交通大学等全国1200余所高校参赛,累计参赛人数超过40万人. 2020年,蓝桥 ...

  6. 十二届蓝桥杯省赛B组C++解析(填空题部分)

    十二届蓝桥杯省赛B组C++解析(填空题部分) 目录 十二届蓝桥杯省赛B组C++解析(填空题部分) A:空间 B:卡片 C:直线 D:货物摆放 E:路径 A:空间 该题是一道计算机基础原理题,这里需要了 ...

  7. 2021年第十二届蓝桥杯 - 省赛 - C/C++大学A组 - D.路径

    2021年第十二届蓝桥杯 - 省赛 - C/C++大学A组 - D.路径 Ideas 算法:最短路径 数据结构:图 思路:根据规则构图,单源最短路径Dijkstra算法. 首先构图其实很简单,就是按照 ...

  8. 2021年第十二届蓝桥杯 - 省赛 - C/C++大学B组 - I.双向排序

    2021年第十二届蓝桥杯 - 省赛 - C/C++大学B组 - I.双向排序 Ideas 题目中给出了两种操作: 当 pi = 0 时,表示将 a1, a2, · · · , aqi 降序排列: 当 ...

  9. 第十二届蓝桥杯青少年组国赛C++中级组 第1题 -- 第3题(python3实现)

    12届蓝桥杯青少年组国赛C++中级组编程题 12届蓝桥杯青少年组国赛C++中级组编程题_lybc2019的博客-CSDN博客 蓝桥杯算法学习路线 | 全程制作过程公开 蓝桥杯算法学习路线 | 全程制作 ...

最新文章

  1. java Spring 生命周期
  2. 从0到1,网上搜不到的企业信息安全搭建全过程,这本书讲透了!
  3. curl学习(实例不断总结)
  4. lsnrctl 与 tnsnames.ora 的联系
  5. laravel 同数据表字段比较查询和状态不正规排序
  6. 牛客题霸 NC19 子数组的最大累加和问题
  7. 14_Android中Service的使用,关于广播接收者的说明
  8. AbstractListView源码分析4
  9. 全球最伟大50名商业领袖,任正非和马云未入选,中国只有一人上榜
  10. drupal php filter,Drupal A-Z and number filter
  11. stderr和stdout详细解说
  12. 高效Redis Client多线程操作的并发吞吐设计
  13. php5.2、5.3和5.4,Apache多虚拟主机多版本PHP(5.2+5.3+5.4)共存运行配置
  14. linux查找大文件或目录
  15. python 写入文件 wb_python读写文件
  16. Git 技术篇 - github镜像推荐,无需翻墙实现飞速访问github官网
  17. 与六年测试工程师促膝长谈,他分享的这些让我对软件测试工作有了全新的认知~
  18. 极客日报:苹果或推出粉色款iPhone 13;拼多多再超阿里
  19. strcmp, strncmp和memcmp的区别
  20. linux搭建raid5命令,命令行操作RAID5

热门文章

  1. java设置语言编码_Java多语言编码问题解析
  2. 20175316 盛茂淞 2018-2019-2 《Java程序设计》实验三《敏捷开发与XP实践》 实验报告...
  3. 基于图像的数据增强方法发展现状综述
  4. [6 函数子类及函数] 42. 确保less<T>与operator<具有相同的语义(POLA)
  5. 没有一只蟹能活着爬出上海
  6. Matter Project 入门 – 构建和运行照明应用程序示例
  7. Rewired.GG进行欧洲迄今规模最大的电竞团队投资
  8. 迷你计算机工作站,这到底是什么 迄今最mini的工作站即将发售
  9. dev c++怎么设置断点_斑马进度计划软件可以检查计划中是否存在逻辑断点和错误逻辑关系...
  10. 轻松解决网络广播风暴