蓝桥杯嵌入式第十五届模拟考试二

题目

蓝桥杯嵌入式第十五届模拟考试二_第1张图片

这套题也是有点麻烦,之前一直做不到稳定满分(相同代码测评分数有差异),问题应该是定时问题,这套题有5秒熄灭,3秒led点亮,之前的写法不好,这几天看了几个新的写法修改了一下,也是稳定满分了。

CubeMX配置

引脚配置

蓝桥杯嵌入式第十五届模拟考试二_第2张图片

ADC配置

这题使用的还是R37,和之前一样的配置PB15,这里就不多说了

定时器配置

这里我使用了TIM2,TIM4,TIM6,TIM8,和之前一样TIM2_CH2用于PA1的PWM脉冲输出,TIM4用于按键中断,TIM6和TIM8用于计时,代码中只用了TIM6来计时数据界面5秒息屏,LD3的3秒点亮这里我们使用滴答定时器比较简单。

串口配置

串口配置没什么难的地方,注意的是一定要根据题目要求修改波特率和开启NVIC

蓝桥杯嵌入式第十五届模拟考试二_第3张图片

代码实现

中断回调函数

我们每次的中断回调函数都是差不多的,所以每次做题目可以优先写interrupt部分

//中断回调函数
#include "interrupt.h"
#include "usart.h"

struct keys key[4]={0,0,0,0};
int time1=0,time2=0,time1_flag=0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
    if(htim->Instance == TIM4){
        key[0].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
        key[1].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
        key[2].key_sta = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
        key[3].key_sta = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
        for(int i=0;i<4;i++){
            switch(key[i].judge_sta){
                case 0:{
                    if(key[i].key_sta==0){
                        key[i].judge_sta=1;
                    }
                }
                break;
                case 1:{
                    if(key[i].key_sta==0){
                        key[i].judge_sta=2;
                        key[i].single_flag=1;
                    }
                    else
                        key[i].judge_sta=0;
                }
                break;
                case 2:{
                    if(key[i].key_sta==1){
                        key[i].judge_sta=0;
                    }
                }
                break;
            }
        }
    }
    if(htim->Instance==TIM6){
        time1++;
    }
    if(htim->Instance==TIM8){
        time2++;
    }
}



char rxdata[30];
int rx_pointer;
uint8_t rxda;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
    rxdata[rx_pointer++]=rxda;
    HAL_UART_Receive_IT(&huart1,&rxda,1);
}

主函数

代码里面我都写了注释,写的不清楚的可以在下面评论

/* 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 "tim.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "interrupt.h" #include "string.h" #include "stdio.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ extern struct keys key[4]; extern int time1,time2; //定时器6和定时器8 extern double ccr1; extern int frq1; extern char rxdata[30]; extern int rx_pointer; extern uint8_t rxda;; double temp=0; //温度 int view=0; //界面 char text[20]; char mode[5]="Auto"; //模式(初始为自动) int gear=1; //挡位 int pa1_duty; //PA1的占空比 int rxled_time=0; //LD4计时 unsigned char led=0x00; int rx_flag=0; //串口接收标志 extern __IO uint32_t uwTick; /* 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 */ void led_disp(unsigned char dsled){ //LED HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOC,led<<8,GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET); } double getADC(ADC_HandleTypeDef *pin){ //ADC unsigned int adc; HAL_ADC_Start(pin); adc = HAL_ADC_GetValue(pin); return adc *3.3/4096; } void tem_mea(void){ //温度测量 if(getADC(&hadc2)>3) temp = 40; if(getADC(&hadc2)<1) temp = 0; if(getADC(&hadc2)>=1&&getADC(&hadc2)<=3) temp = getADC(&hadc2)*10+10; if(strcmp(mode,"Auto")==0){ //在自动模式中,挡位随温度切换 if(temp<25) gear=1; if(temp>30) gear=3; if(temp>=25&&temp<=30) gear=2; } } void lcd_pro(void){ //数据界面 if(view==0){ LCD_DisplayStringLine(Line1, (unsigned char *)" DATA"); sprintf(text," TEMP:%.1f",temp); LCD_DisplayStringLine(Line3, (unsigned char *)text); sprintf(text," MODE:%.5s",mode); LCD_DisplayStringLine(Line4, (unsigned char *)text); sprintf(text," GEAR:%d",gear); LCD_DisplayStringLine(Line5, (unsigned char *)text); } //睡眠界面 if(view==1){ LCD_DisplayStringLine(Line4, (unsigned char *)" SLEEPING"); sprintf(text," TEMP:%.1f",temp); LCD_DisplayStringLine(Line5, (unsigned char *)text); } } void key_pro(void){ if(view==0){//数据界面 //数据界面计时(无按键动作和串口接收5s后切换为睡眠界面) HAL_TIM_Base_Start_IT(&htim6); if(strcmp(mode,"Auto")==0) { if(key[0].single_flag==1){//切换手动模式 strcpy(mode, "Manu"); key[0].single_flag=0; } key[1].single_flag=0; key[2].single_flag=0; } if(strcmp(mode,"Manu")==0) { if(key[0].single_flag==1){//切换自动模式 strcpy(mode, "Auto"); key[0].single_flag=0; } if(key[1].single_flag==1){//B2手动加档 gear+=1; if(gear>3) gear=3; key[1].single_flag=0; } if(key[2].single_flag==1){//B3手动减档 gear-=1; if(gear<1) gear=1; key[2].single_flag=0; } } } if(view==1)//睡眠界面 { //任意按键唤醒 if(key[0].single_flag==1||key[1].single_flag==1||key[2].single_flag==1){ LCD_Clear(Black); view=0; key[0].single_flag=0; key[1].single_flag=0; key[2].single_flag=0; } } //无按键动作和串口接收5s后切换为睡眠界面 if(time1>=500) { if(view==0&&key[0].key_sta==1&&key[1].key_sta==1&&key[2].key_sta==1&&rx_flag==0) { LCD_Clear(Black); view=1; time1=0; HAL_TIM_Base_Stop_IT(&htim6); } } //在5s内按键和串口有动作停止计时 if(time1<500) { if(key[0].key_sta==0||key[1].key_sta==0||key[2].key_sta==0||rx_flag==1) { time1=0; HAL_TIM_Base_Stop_IT(&htim6); } } } void uart_rx(void){ if(rx_pointer>0) { rx_flag=1; //串口接收标志位 uwTick = rxled_time; if(rx_pointer==2) { if(view==0)//数据界面 { //接收B1 if(strcmp(rxdata,"B1")==0){ key[0].single_flag=1; } //B2 if(strcmp(rxdata,"B2")==0){ key[1].single_flag=1; } //B3 if(strcmp(rxdata,"B3")==0){ key[2].single_flag=1; } //如果不是B1、B2、B3 发送NULL else if(strcmp(rxdata,"B1")!=0&&strcmp(rxdata,"B2")!=0&&strcmp(rxdata,"B3")!=0) { sprintf(text,"NULL"); HAL_UART_Transmit(&huart1,(uint8_t *)text,strlen(text),50); } } if(view==1)//睡眠界面 { //B1、B2、B3唤醒 if(strcmp(rxdata,"B1")==0||strcmp(rxdata,"B2")==0||strcmp(rxdata,"B3")==0) { LCD_Clear(Black); view=0; } //如果不是B1、B2、B3 发送NULL else { sprintf(text,"NULL"); HAL_UART_Transmit(&huart1,(uint8_t *)text,strlen(text),50); } } } //如果不是rx_pointer不等于2发送NULL else { sprintf(text,"NULL"); HAL_UART_Transmit(&huart1,(uint8_t *)text,strlen(text),50); } } rx_pointer=0; memset(rxdata,0,30); } void pwm_pro(void){ if(gear==1){ pa1_duty = htim2.Init.Period; __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,pa1_duty*0.1); } if(gear==2){ pa1_duty = htim2.Init.Period; __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,pa1_duty*0.4); } if(gear==3){ pa1_duty = htim2.Init.Period; __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,pa1_duty*0.8); } } void led_pro(void){ if(gear==1) led |= 0x01; else led &= ~0x01; if(gear==2) led |= 0x02; else led &= ~0x02; if(gear==3) led |= 0x04; else led &= ~0x04; if(strcmp(mode,"Auto")==0) led |= 0x80; else led &= ~0x80; if(uwTick-rxled_time<3000) { led |= 0x08; rx_flag=0; } else led &= ~0x08; led_disp(led); } /* 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_USART1_UART_Init(); MX_TIM6_Init(); MX_TIM4_Init(); MX_TIM8_Init(); MX_TIM7_Init(); /* USER CODE BEGIN 2 */ LCD_Init(); led_disp(led); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ LCD_Clear(Black); LCD_SetBackColor(Black); LCD_SetTextColor(White); HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2); HAL_TIM_Base_Start_IT(&htim4); HAL_UART_Receive_IT(&huart1,&rxda,1); __HAL_TIM_SetCompare(&htim2,TIM_CHANNEL_2,pa1_duty); uwTick=3000; while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ uart_rx(); tem_mea(); key_pro(); lcd_pro(); led_pro(); pwm_pro(); } /* USER CODE END 3 */ }

你可能感兴趣的:(蓝桥杯嵌入式,蓝桥杯,c++,嵌入式硬件)