蓝桥杯嵌入式(G431)备赛笔记——ADC+LCD

目录

题目要求(真题):

cubeMX配置:

小试牛刀:

 Keil代码:

效果演示:


题目要求(真题):

使用第十一届第二场真题,练习ADC波部分的代码

cubeMX配置:

配置PB12,PB15为ADC输入通道

PB12对应R38,配置为ADC1的通道11

PB15对应R37,配置为ADC2的通道15

 最好将采样时间拉到最高,防止出错。

小试牛刀:

 Keil代码:

user.c

#include "user.h" // 包含用户自定义头文件 user.h

u32 adc_tick=0; // 定义 ADC 计时变量 adc_tick
u32 r37_value=0; // 定义变量存储 ADC1 读取的数值 r37_value
u32 r38_value=0; // 定义变量存储 ADC2 读取的数值 r38_value
float r37_volt=0; // 定义变量存储 ADC1 转换后的电压值 r37_volt
float r38_volt=0; // 定义变量存储 ADC2 转换后的电压值 r38_volt

void ADC_proc() // 定义 ADC 处理函数 ADC_proc
{
	if(uwTick-adc_tick<100) // 如果当前时间与上次 ADC 触发的时间间隔小于100ms
		return; // 直接返回,不进行 ADC 采样
	adc_tick = uwTick; // 更新 ADC 触发时间为当前时间
	HAL_ADC_Start(&hadc1); // 启动 ADC1 转换
	r38_value = HAL_ADC_GetValue(&hadc1); // 获取 ADC1 转换后的数值
	r38_volt = r38_value*3.3/4096; // 计算 ADC1 转换后的电压值
	HAL_ADC_Start(&hadc2); // 启动 ADC2 转换
	r37_value = HAL_ADC_GetValue(&hadc2); // 获取 ADC2 转换后的数值
	r37_volt = r37_value*3.3/4096; // 计算 ADC2 转换后的电压值
}

u8 ui=1; // 定义变量存储用户界面状态 ui
u8 pa6_duty=10; // 定义变量存储 PA6 的占空比 pa6_duty
u8 pa7_duty=10; // 定义变量存储 PA7 的占空比 pa7_duty

void KEY_proc() // 定义按键处理函数 KEY_proc
{
    // 对四个按键进行单击、长按、双击的处理
    if(single_key_flag[0]==1) // 如果按键1单次按下
    {
      ui+=1; // 切换 LCD 显示模式
			if(ui>=3) ui=1; // 如果超过最大模式数,回到第一个模式
      single_key_flag[0]=0; // 清除按键标志
    }
		
		if(single_key_flag[1]==1) // 如果按键2单次按下
    {
      pa6_duty+=10; // 增加 PA6 的占空比
			if(pa6_duty>=100) pa6_duty=10; // 如果占空比超过100%,重置为10%
			__HAL_TIM_SetCompare(&htim16, TIM_CHANNEL_1, pa6_duty); // 设置 PWM 输出的占空比
      single_key_flag[1]=0; // 清除按键标志
    }
		
		if(single_key_flag[2]==1) // 如果按键3单次按下
    {
      pa7_duty+=10; // 增加 PA7 的占空比
			if(pa7_duty>=100) pa7_duty=10; // 如果占空比超过100%,重置为10%
			__HAL_TIM_SetCompare(&htim17, TIM_CHANNEL_1, pa7_duty); // 设置 PWM 输出的占空比
      single_key_flag[2]=0; // 清除按键标志
    }
}

u32 lcd_tick=0; // 定义 LCD 刷新计时变量 lcd_tick

void Disp_proc () // 定义显示处理函数 Disp_proc
{
	if(uwTick-lcd_tick<100) // 如果当前时间与上次 LCD 刷新的时间间隔小于100ms
		return; // 直接返回,不进行 LCD 刷新
	lcd_tick=uwTick; // 更新 LCD 刷新时间为当前时间
	
	if(ui==1) // 如果当前界面为模式1
	{
		u8 text[50]; // 定义字符数组用于存储显示的文本信息
		sprintf(text, "      DATE        "); // 格式化字符串,显示日期
		LCD_DisplayStringLine(Line1, (unsigned char *)text); // 在第1行显示文本信息
		sprintf(text, "    V:%.2f V      ", r37_volt); // 格式化字符串,显示 ADC1 电压值
		LCD_DisplayStringLine(Line3, (unsigned char *)text); // 在第3行显示文本信息
		sprintf(text, "    Mode:         "); // 格式化字符串,显示模式
		LCD_DisplayStringLine(Line5, (unsigned char *)text); // 在第5行显示文本信息
		sprintf(text, "    V:%.2f V      ", r38_volt); // 格式化字符串,显示 ADC2 电压值
		LCD_DisplayStringLine(Line4, (unsigned char *)text); // 在第4行显示文本信息
	}
	
	if(ui==2) // 如果当前界面为模式2
	{
		u8 text[50]; // 定义字符数组用于存储显示的文本信息
		sprintf(text, "      Para        "); // 格式化字符串,显示参数
		LCD_DisplayStringLine(Line1, (unsigned char *)text); // 在第1行显示文本信息
		sprintf(text, "    PA6:%d        ", pa6_duty); // 格式化字符串,显示 PA6 占空比
		LCD_DisplayStringLine(Line3, (unsigned char *)text); // 在第3行显示文本信息
		sprintf(text, "    PA7:%d        ", pa7_duty); // 格式化字符串,显示 PA7 占空比
		LCD_DisplayStringLine(Line5, (unsigned char *)text); // 在第5行显示文本信息
	}
}

ADC_proc 函数用于采样两个模拟输入通道的电压值并计算,KEY_proc 函数处理按键操作并控制相关功能,Disp_proc 函数根据当前界面状态和采样到的数据更新 LCD 显示。

user.h

#ifndef __USER_H // 如果未定义过 __USER_H 宏
#define __USER_H // 定义 __USER_H 宏,防止头文件重复包含

#include "main.h" // 包含主头文件 main.h
#include "lcd.h" // 包含 LCD 相关头文件 lcd.h
#include "key.h" // 包含按键相关头文件 key.h
#include "led.h" // 包含 LED 相关头文件 led.h
#include "tim.h" // 包含定时器相关头文件 tim.h

void ADC_proc(void); // 声明按键处理函数 ADC_proc
void KEY_proc(void); // 声明按键处理函数 KEY_proc
void Disp_proc(void); // 声明显示处理函数 Disp_proc

#endif // 结束条件编译指令

main.c

int main(void)
{
  /* USER CODE BEGIN 1 */ // 在这里插入用户自定义的代码段1

  /* USER CODE END 1 */ // 用户自定义的代码段1结束

  /* MCU Configuration--------------------------------------------------------*/ // MCU 配置

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ // 复位所有外设,初始化 Flash 接口和 SysTick 定时器
  HAL_Init(); // HAL 库初始化

  /* USER CODE BEGIN Init */ // 用户自定义的代码段2开始

  /* USER CODE END Init */ // 用户自定义的代码段2结束

  /* Configure the system clock */ // 配置系统时钟
  SystemClock_Config(); // 调用系统时钟配置函数

  /* USER CODE BEGIN SysInit */ // 用户自定义的代码段3开始

  /* USER CODE END SysInit */ // 用户自定义的代码段3结束

  /* Initialize all configured peripherals */ // 初始化所有配置的外设
  MX_GPIO_Init(); // 初始化 GPIO 外设
  MX_TIM3_Init(); // 初始化定时器 TIM3
  MX_TIM16_Init(); // 初始化定时器 TIM16
  MX_TIM17_Init(); // 初始化定时器 TIM17

  /* USER CODE BEGIN 2 */ // 用户自定义的代码段4开始
  LED_disp (0); // 调用 LED 显示函数,将 LED 初始状态设置为关闭
  HAL_TIM_Base_Start_IT(&htim3); // 启动 TIM3 定时器的基本定时器模式并启用定时器中断
  LCD_Init(); // LCD 初始化
  HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1); // 启动 TIM16 定时器的 PWM 模式,并启用通道1
  HAL_TIM_PWM_Start(&htim17, TIM_CHANNEL_1); // 启动 TIM17 定时器的 PWM 模式,并启用通道1

  /* USER CODE END 2 */ // 用户自定义的代码段4结束

  /* Infinite loop */ // 无限循环
  /* USER CODE BEGIN WHILE */ // 用户自定义的代码段5开始
  LCD_Clear(Black); // 清屏,将背景色设置为黑色
  LCD_SetBackColor(Black); // 设置背景色为黑色
  LCD_SetTextColor(White); // 设置文本颜色为白色

  while (1) // 进入无限循环
  {
    /* USER CODE END WHILE */ // 用户自定义的代码段5结束

    /* USER CODE BEGIN 3 */ // 用户自定义的代码段6开始
    ADC_proc(); // ADC处理函数
    KEY_proc(); // 处理按键事件
    Disp_proc (); // 控制 LCD 显示内容

  }
  /* USER CODE END 3 */ // 用户自定义的代码段6结束
}

关键函数:

HAL_ADC_Start(&hadc2);  //开启ADC

HAL_ADC_GetValue(&hadc2); //获取ADC的值

效果演示:

蓝桥杯嵌入式ADC效果演示

上一篇:电脑硬盘分区表的两种格式:MBR 和 GPT


下一篇:lua学习笔记18(面相对象之多态)