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

目录

题目要求(真题):

cubeMX配置:

小试牛刀:

 Keil代码:

效果演示:


题目要求(真题):

使用第十一届第二场真题,练习PWM波部分的代码,实现可以通过按键进行页面切换,加减PWM波占空比,并显示在LCD屏幕上

 

cubeMX配置:

配置pa6,pa7为pwm输出引脚

启用定时器为pwm输出,占空比可以先随便设置一下,这里为20

 

配置pwm频率,计算公式为:

根据题目,PA6输出100hz,PA7输出200hz:

PA6:

PA7:

 

小试牛刀:

 Keil代码:

注意:首先要开启PWM输出通道

HAL_TIM_PWM_Start(&htim16, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim17, TIM_CHANNEL_1);

 user.c

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

u8 ui=1; // 定义全局变量 ui,用于控制 LCD 显示
u8 pa6_duty=10; // 定义全局变量 pa6_duty,用于控制 PA6 引脚的 PWM 占空比
u8 pa7_duty=10; // 定义全局变量 pa7_duty,用于控制 PA7 引脚的 PWM 占空比

void KEY_proc() // 定义按键处理函数 KEY_proc
{
    // 对四个按键进行单击、长按、双击的处理
    if(single_key_flag[0]==1) // 如果按键1单次按下
    {
      ui+=1; // 控制 LCD 显示界面切换
			if(ui>=3) ui=1; // 如果 ui 大于等于3,重置为1
      single_key_flag[0]=0; // 用完标记清零
    }
		
		if(single_key_flag[1]==1) // 如果按键2单次按下
    {
      pa6_duty+=10; // 增加 PA6 引脚的 PWM 占空比
			if(pa6_duty>=100) pa6_duty=10; // 如果占空比大于等于100,重置为10
			__HAL_TIM_SetCompare(&htim16, TIM_CHANNEL_1, pa6_duty); // 设置 TIM16 的通道1 PWM 占空比
      single_key_flag[1]=0; // 用完标记清零
    }
		
		if(single_key_flag[2]==1) // 如果按键3单次按下
    {
      pa7_duty+=10; // 增加 PA7 引脚的 PWM 占空比
			if(pa7_duty>=100) pa7_duty=10; // 如果占空比大于等于100,重置为10
			__HAL_TIM_SetCompare(&htim17, TIM_CHANNEL_1, pa7_duty); // 设置 TIM17 的通道1 PWM 占空比
      single_key_flag[2]=0; // 用完标记清零
    }
}

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

void Disp_proc () // 定义 LCD 显示处理函数 Disp_proc
{
	if(uwTick-lcd_tick<100) // 如果当前时间与上次刷新时间间隔小于100ms,返回
		return;
	lcd_tick=uwTick; // 更新 LCD 刷新时间

	if(ui==1) // 如果显示界面为1
	{
		u8 text[50]; // 定义存放文本的数组 text
		sprintf(text, "      DATE        "); // 设置第一行显示文本为 "      DATE        "
		LCD_DisplayStringLine(Line1, (unsigned char *)text); // 在第一行显示文本
		sprintf(text, "    V:            "); // 设置第三行显示文本为 "    V:            "
		LCD_DisplayStringLine(Line3, (unsigned char *)text); // 在第三行显示文本
		sprintf(text, "    Mode:         "); // 设置第五行显示文本为 "    Mode:         "
		LCD_DisplayStringLine(Line5, (unsigned char *)text); // 在第五行显示文本
	}
	
	if(ui==2) // 如果显示界面为2
	{
		u8 text[50]; // 定义存放文本的数组 text
		sprintf(text, "      Para        "); // 设置第一行显示文本为 "      Para        "
		LCD_DisplayStringLine(Line1, (unsigned char *)text); // 在第一行显示文本
		sprintf(text, "    PA6:%d        ",pa6_duty); // 根据 PA6 占空比设置第三行显示文本
		LCD_DisplayStringLine(Line3, (unsigned char *)text); // 在第三行显示文本
		sprintf(text, "    PA7:%d        ",pa7_duty); // 根据 PA7 占空比设置第五行显示文本
		LCD_DisplayStringLine(Line5, (unsigned char *)text); // 在第五行显示文本
	}
}

在 KEY_proc 中,根据按键的单击事件更新全局变量 ui(控制 LCD 显示界面切换)和两个 PWM 占空比参数 pa6_duty 和 pa7_duty;在 Disp_proc 中,根据 ui 的值选择显示不同的界面,其中界面1显示固定文本,界面2显示带有动态参数的文本。

注意:

__HAL_TIM_SetCompare(&htim16, TIM_CHANNEL_1, pa6_duty); // 设置 TIM16 的通道1 

一定要有这句代码,是它将pa6_duty这个参数的值更新到了PWM的输出中。

 

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 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开始
    KEY_proc(); // 处理按键事件
    Disp_proc (); // 控制 LCD 显示内容

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

效果演示:

 

蓝桥杯嵌入式PWM输出效果演示

  • 15
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玄奕子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值