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

题目

8a2bd993d273f79a77874783766229dc.png

这套模拟题和十四届模拟一很相似,主要是按键控制频率和占空比,串口切换界面,十四届模拟一是按键控制频率,串口控制占空比,都是差不多写法

CubeMX配置

首先,查看题目

b03e562da4f9d3d9f6353a73ac5e8a18.png

这个图可以让我们知道大概有那些功能,有LCD、LED、KEY、PWM、USART,根据比赛给出的产品手册去配置相应的引脚和参数就行。

引脚配置

7f0f1fe355d8832a0f0cb8a14202b154.png

前面我的文章里也有CubeMX的配置,大家不知道怎么配置的可以去看一下,这里就不多说了,我们这里直接看一下代码实现

代码实现

我一般习惯将按键、输入捕获和串口放在一个interrupt.c中,led、pwm这些放在主函数中。

中断回调函数

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

extern int pa1_frq,pa7_frq;
struct keys key[4]={0,0,0,0};
int time1,time2;
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;
                        key[i].key_time=0;
                    }
                }
                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用于ld1闪烁
    {
        if(pa1_frq>pa7_frq)
            time1++;
        else
            time1=0;
    }
    if(htim->Instance==TIM8)    //time2用于ld2闪烁
    {
        if(pa1_frq<pa7_frq)
            time2++;
        else
            time2=0;
    }
}

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
  *
  * <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 "tim.h"
#include "usart.h"
#include "gpio.h"

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

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
extern char rxdata[30];
extern int rx_pointer;
extern uint8_t rxda;
extern struct keys key[4];
extern int time1,time2;

int view=0; //界面
char text[20];
int pa1_duty=10,pa7_duty=10;
int pa1_frq=1000,pa7_frq=1000;
int num1=1,num2=1,num3=1,num4=1;
int control_flag=0;
unsigned char led=0x00;
/* 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)
{
    HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOC,dsled<<8,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
void lcd_pro(void)
{
    if(view==0)
    {
        LCD_DisplayStringLine(Line3,(u8 *)"        PA1   ");
        sprintf(text,"      F:%dHz  ",pa1_frq);
        LCD_DisplayStringLine(Line4,(u8 *)text);
        sprintf(text,"      D:%d%%  ",pa1_duty);
        LCD_DisplayStringLine(Line5,(u8 *)text);
    }
    if(view==1)
    {
        LCD_DisplayStringLine(Line3,(u8 *)"        PA7   ");
        sprintf(text,"      F:%dHz  ",pa7_frq);
        LCD_DisplayStringLine(Line4,(u8 *)text);
        sprintf(text,"      D:%d%%  ",pa7_duty);
        LCD_DisplayStringLine(Line5,(u8 *)text);
    }
}
void key_pro(void)
{
    //B1增加PA1频率
    if(view==0)
    {
        if(key[0].single_flag==1)
        {
            num1+=1;
            if(num1>10)
                num1=1;
            pa1_frq=1000*num1;
            TIM2->ARR = 1000000/(1000*num1)-1;
            __HAL_TIM_SetCounter(&htim2,0);
            TIM2->CCR2 = (0.1*num3) * TIM2->ARR;
            key[0].single_flag=0;
        }
    }
    //B1增加PA7频率
    if(view==1)
    {
        if(key[0].single_flag==1)
        {
            num2+=1;
            if(num2>10)
                num2=1;
            pa7_frq=1000*num2;
            TIM3->ARR = 1000000/(1000*num2)-1;
            __HAL_TIM_SetCounter(&htim3,0);
            TIM3->CCR2 = (0.1*num4) * TIM3->ARR;
            key[0].single_flag=0;
        }
    }
    //B2增加PA1占空比
    if(view==0)
    {
        if(key[1].single_flag==1)
        {
            num3+=1;
            if(num3>9)
                num3=1;
            pa1_duty=10*num3;
            TIM2->CCR2 = (0.1*num3) * TIM2->ARR;
            key[1].single_flag=0;
        }
    }
    //B2增加PA7占空比
    if(view==1)
    {
        if(key[1].single_flag==1)
        {
            num4+=1;
            if(num4>9)
                num4=1;
            pa7_duty=10*num4;
            TIM3->CCR2 = (0.1*num4) * TIM3->ARR;
            key[1].single_flag=0;
        }
    }
    //按键控制模式下按下B3可切换
    if(key[2].single_flag==1&&control_flag==0)
    {
        view^=1;
        LCD_Clear(Black);
        key[2].single_flag=0;
    }
    //B4切换控制模式 0:按键     1:串口
    if(key[3].single_flag==1)
    {
        control_flag^=1;
        key[3].single_flag=0;
    }
}
void rx_pro(void)
{
    if(rx_pointer>0)
    {
        if(rx_pointer==1&&control_flag==1)
        {
            if(rxda=='@')
            {
                view=0;
            }
            if(rxda=='#')
            {
                view=1;
            }
            else
            {
                sprintf(text,"ERROR");
                HAL_UART_Transmit(&huart1,(unsigned char *)text,strlen(text),10);
            }
        }
        if(rx_pointer>=2&&control_flag==1)
        {
            sprintf(text,"ERROR");
            HAL_UART_Transmit(&huart1,(unsigned char *)text,strlen(text),12);
        }
        if(control_flag==0)
        {
            sprintf(text,"KEY CONTROL");
            HAL_UART_Transmit(&huart1,(unsigned char *)text,strlen(text),12);
        }
    }
    rx_pointer=0;
    memset(rxdata,0,strlen(rxdata));
}
void led_pro(void)
{
    if(view==0&&pa1_frq<=pa7_frq)
        led |= 0x01;
    else
        led &= ~0x01;
    if(view==1&&pa1_frq>=pa7_frq)
        led |= 0x02;
    else
        led &= ~0x02;
    if(control_flag==0)
        led |= 0x04;
    else
        led &= ~0x04;
    if(time1%2==0&&pa1_frq>pa7_frq)
        led |= 0x01;
    if(time1%2==1&&pa1_frq>pa7_frq)
        led &= ~0x01;
    if(time2%2==0&&pa1_frq<pa7_frq)
        led |= 0x02;
    if(time2%2==1&&pa1_frq<pa7_frq)
        led &= ~0x02;
    led_disp(led);
}
void pwm_start(void)
{
    TIM2->ARR = 1000000/1000-1;
    TIM2->CCR2 = 0.1*TIM2->ARR; 
    TIM3->ARR = 1000000/1000-1;
    TIM3->CCR2 = 0.1*TIM2->ARR;
}
/* 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_TIM2_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
  MX_USART1_UART_Init();
  MX_TIM6_Init();
  MX_TIM8_Init();
  /* USER CODE BEGIN 2 */

    LCD_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
    led_disp(led);
    LCD_Clear(Black);
    LCD_SetBackColor(Black);
    LCD_SetTextColor(White);
    HAL_UART_Receive_IT(&huart1,&rxda,1);
    pwm_start();
    HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
    HAL_TIM_Base_Start_IT(&htim4);
    HAL_TIM_Base_Start_IT(&htim6);
    HAL_TIM_Base_Start_IT(&htim8);
    while (1)
    {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
        lcd_pro();
        key_pro();
        rx_pro();
        led_pro();
    }
  /* USER CODE END 3 */
}

这套模拟题比较简单,看不懂的地方可以发在评论区,需要源码的可以私

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值