当前位置: 首页 > article >正文

【蓝桥杯——物联网设计与开发】基础模块9 - PWM

目录

一、PWM

(1)资源介绍

(2)STM32CubeMX 软件配置

(3)代码编写

(4)实验现象

二、PWM接口函数封装

三、踩坑日记

(1)PWM输出测量不准

(2)PWM模式

(3)实训平台PWM测量困难


一、PWM

(1)资源介绍

        PWM(Pulse Width Modulation)​脉冲宽度调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。

图1        PWM周期与脉宽

        其中,脉宽时间即高电平时间;

        单片机的 IO 口输出的是数字信号,其仅能输出高电平和低电平这两种状态,假设高电平为 5V,低电平为 0V。当我们需要输出不同的模拟电压时,就会用到 PWM 技术。其原理是通过改变 IO 口输出方波的占空比,以此来获取由数字信号模拟而成的模拟电压信号。

图2        有效电压
  • PWM是在合适的信号频率下,通过一个周期里改变占空比的方式来改变输出的有效电压;
  • PWM频率越高,响应越快;

以上资料来源于:

PWM原理 PWM频率与占空比详解-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/as480133937/article/details/103439546        在蓝桥杯物联网竞赛实训平台中,提供了两个电机接口 P1 P2,由达林顿管 ULN2803 驱动。因为达林顿管是反向驱动,所以在调节占空比时,需要注意取值。

图3        板极资源

(2)STM32CubeMX 软件配置


🔅“工程建立、时钟树配置、Debug 串行线配置、代码生成配置” 在下文中有讲解,这里不再赘述❗️

【蓝桥杯——物联网设计与开发】基础模块1- GPIO输出icon-default.png?t=O83Ahttps://blog.csdn.net/m0_63116406/article/details/135604705?spm=1001.2014.3001.5502

1️⃣配置引脚 PA0 TIM2_CH1,引脚 PA1 TIM2_CH2;(此时引脚呈黄色状态

     点击 "Timers" → 点击"TIM2"→将"Clock Source"配置为 "Internal Clock" → 将"Channel1" "Channel2"分别配置为 "PWM Generation CH1" 和 "PWM Generation CH2";(此时引脚呈绿色状态);

     修改参数:

  • Counter Settings - Prescaler:3132分频,使定时器时钟为1MHz);
  • Counter Settings - Counter Period:9999(计数值10000,即PWM频率为100kHz);



2️⃣配置OLED;

3️⃣生成代码即可;

(3)代码编写

🟢️main 函数

/* USER CODE BEGIN PV */
uint8_t cnt_key;	
uint8_t cnt_oled;		
uint8_t puc_oled[17];	// oled显示缓存区
uint8_t pwm_duty;		// pwm占空比
/* USER CODE END PV */

/**
  * @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_I2C3_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
	OLED_Init();
	/* PWM启动 */
	HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		Task_Key();
		Task_OLED();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

void Task_Key(void)
{
	uint8_t key_temp, key_down;
	static uint8_t key_old = 0;
	if(cnt_key < 10)	return;
	cnt_key = 0;
	key_temp = Key_Read();
	key_down = key_temp & (key_temp ^ key_old);
	key_old = key_temp;
	if(key_down)
	{
		/* 按键按下,占空比+5 */
		pwm_duty += 5;
		if(pwm_duty > 100)
			pwm_duty = 0;
		__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pwm_duty * 100);
		__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, pwm_duty * 100);
	}
}

void Task_OLED(void)
{
	if(cnt_oled < 200)	return;
	cnt_oled = 0;
	sprintf((char*)puc_oled, "PWM_DUTY:%d  ", pwm_duty);
	OLED_ShowString(0, puc_oled);
}

(4)实验现象

        按键按下后,测得 PA0 PA1 引脚输出有变动;


二、PWM接口函数封装

🟡️修改自动重载值和比较值函数

/* 设置TIM2自动重装值 */
void TIM2_SetReload(uint16_t usData)
{
  __HAL_TIM_SET_AUTORELOAD(&htim2, usData);
}
/* 设置TIM2比较值1 */
void TIM2_SetCompare1(uint16_t usData)
{
  __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, usData);
}
/* 设置TIM2比较值2 */
void TIM2_SetCompare2(uint16_t usData)
{
  __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, usData);
}

三、踩坑日记

(1)PWM输出测量不准

        🔅这个可能与达林顿管有一定关系,在单片机设计与开发赛道中,同样会有这个问题;

(2)PWM模式

        🔅PWM有两个模式:

  • 模式1:TIMX_CNT<TIMX_CCRX,输出有效电平;
  • 模式2:TIMX_CNT>TIMX_CCRX,输出有效电平;

        可以通过调节PWM模式和有效电平极性输出不同的PWM波,适应不同电路;

(3)实训平台PWM测量困难

        🔅一般检验PWM波,需要使用示波器,一根接地线,一根接PWM波线;

        在实训平台上,PWM产生引脚处,旁边是5V电压,而地线需要从拓展接口引出,操作较为麻烦;后续新的实训平台解决了这一问题;


http://www.kler.cn/a/461548.html

相关文章:

  • 在 pandas.Grouper() 中,freq 参数用于指定时间频率,它定义了如何对时间序列数据进行分组。freq 的值可以是多种时间单位
  • 多层设计模式:可否设计各层之间公用的数据定义模块?
  • MT8788安卓核心板_MTK8788核心板参数_联发科模块定制开发
  • 【数据结构】树链刨分
  • 4.Web安全——JavaScript基础
  • Unity3D ILRuntime开发原则与接口绑定详解
  • Android Notification 问题:Invalid notification (no valid small icon)
  • 读书网(文章内容的抓取)
  • 【Redis知识】Redis进阶-redis还有哪些高级特性?
  • private static final Logger log = LoggerFactory.getLogger()和@Slf4j的区别
  • wpf 基于Behavior库 的行为模块
  • 网络安全 | 物联网安全:从设备到网络的全方位防护
  • day 29 进程exec函数族 ,进程实现无人机模块,exec实现minishell
  • Ribbon和Eureka的集成
  • 黑神话悟空游戏鼠标光标使用教程与下载
  • 探秘Kafka源码:关键内容解析
  • 【Leetcode 热题 100】22. 括号生成
  • 设计模式-创建型模式-工厂模式
  • 【Git_bugs】remote error GH013 Repository rule violations found for.md
  • 【网络】什么是路由协议(Routing Protocols)?常见的路由协议包括RIP、OSPF、EIGRP和BGP
  • ESP8266+STM32+阿里云保姆级教程(AT指令+MQTT)
  • 随笔 | 写在2024的最后一天
  • 线程锁和协程锁的区别
  • Redis Stream:实时数据处理的高效解决方案
  • 2分钟知晓Vscode 插件发布流程
  • 【Rust自学】8.6. HashMap Pt.2:更新HashMap