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

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

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

目录

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

一、赛题分析

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

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

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

蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第1张图片
蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第2张图片
蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第3张图片
蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第4张图片
蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第5张图片
蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第6张图片
蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第7张图片

二、CubeMX模块配置

  1. LED和按键的GPIO配置
    由于直接使用的考场提供的实例程序,里面的LCD以及LED的GPIO都是配置好了的,我们只需要额外再配置一下LED的使能端口,也就是PD2。与开发板按键相对应的是PB0,PB1,PB2,PA0等。
    蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第8张图片

  2. 时钟配置
    这里我使用的外部晶振,将系统时钟配置成170MHz,也可以使用HSI,其他频率也是可以的。
    蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第9张图片蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第10张图片

  3. 定时器TIM4配置
    定时器在这里的作用就是产生1ms的中断,用于定时,用来扫描按键进行消抖,以及其他需要用到定时的模块。
    蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第11张图片
    还要记得打开定时器的中断,蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第12张图片

  4. 定时器TIM2,TIM3捕获的配置
    通过PA1捕获扩展板上的方波PULS1,对应的是TIM2的CH2,通过PA6和PA7来捕获扩展板上的PWM波,对应的是TIM3的CH1和CH2。
    蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第13张图片
    蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第14张图片
    最后不要完了打开定时器的全局中断
    蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第15张图片

  5. ADC的配置
    通过ADC来获取光敏电阻的值的大小,使用到的是PA4,对应ADC2_IN17。
    蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第16张图片

  6. 串口的配置
    基本设置,注意波特率为9600,这是试题指定的波特率。
    蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第17张图片
    我使用的是串口的IDLE+DMA来接收不定长数据,这样比较方便,当然也可以有其他的方法,可以看我之前写的博客,所以这里还需要开启一个DMA用于串口的接收。
    蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第18张图片
    然后还要记得要打开串口的总中断,由于我们在这里用不到DMA的中断,所以直接关闭DM的中断即可。
    蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第19张图片

三、部分程序分析

  1. 角度与占空比转换计算
    使用PWM1和PWM2模拟旋转角度传感器输出信号,输出信号占空比值与角度关系如下图所示:
    蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第20张图片
    根据关系图可以解得:
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,所以要以吊臂的竖直为边界进行讨论。具体分析请看下图:
    蓝桥杯嵌入式——第十二届蓝桥杯嵌入式国赛_第21张图片
    所以根据上面的推导,有以下的代码:
#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]);
        else
            printf("%.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;
    else
        upper_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]);
        else
            printf("%.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
  *
  * 

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * 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; else angle_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; else angle_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; else ax = angle_a - angle_a_pre; if(angle_b_pre > angle_b) bx = angle_b_pre - angle_b; else bx = 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]); else printf("%.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; else upper_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]); else printf("%.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'; else mode = '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); else TIM2_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; else TIM3_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; else TIM3_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; else TIM3_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; else TIM3_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****/

六、完整代码下载

代码使用说明,一定要看

完整代码下载点我

你可能感兴趣的:(蓝桥杯,嵌入式,stm32)