基于HAL库的STM32呼吸灯实验

发布时间:
来源: 电子工程世界

先决条件:装有编译和集成的开发环境,比如:Keil uVision5。

板子硬件要求:设计了LED在定时器的接口上

呼吸灯是一种常见的电子制作实验项目,其通过控制 LED 灯的亮度变化,实现了一种模拟人类呼吸的效果。 作为一种常见的数字调光技术,呼吸灯广泛应用于工业控制、智能家居等领域。 而在此过程中,使用微控制器如 STM32 ,则可以更加便捷、灵活地实现呼吸灯的控制。 因此,本文将介绍基于 STM32 的呼吸灯实验,通过代码编写、编译下载和调试运行,实现了一个简单的呼吸灯控制系统。

实验目的

本实验旨在通过 STM32 的呼吸灯实验,掌握 STM32 的编程方法和调试技巧,并深入理解呼吸灯的原理、调光技术和周期控制等知识点。 在本实验过程中,我们将涉及 STM32 的 GPIO 端口配置、定时器和 PWM 的使用、时钟配置和中断处理等技术

PWM介绍

PWM(Pulse Width Modulation)即脉冲宽度调制技术,是一种通过调节脉冲信号的占空比来实现模拟信号的调节的技术。 在PWM控制中,周期性的方波称为PWM波,其占空比是指高电平时间与周期的比值。 PWM波信号可以通过控制电路的输出电平来实现对外设的控制,如对LED的亮度、电机的转速等。 通常使用定时器模块来生成PWM波,定时器在每个周期内发出固定的时间间隔中断,根据设定的占空比,每个周期内的高电平时间和低电平时间不同,从而实现对PWM波的控制。

基础工程

使用STM32CubeMX配置stm32的基本配置。 基本的配置如下:开启swd调试,开启外部时钟,配置相应的定时器。

图片

  • 呼吸灯连接的硬件定时器配置

图片

  • 时钟界面选项卡:

图片

  • 工程选项卡:

图片

点击右上角的的生成代码:

图片

使用keil打开工程,编译工程,一切都是ok

图片

主要代码

其中我定时器配置了200hz的频率,肉眼观察明显一些,主函数中改变占空比。

/* TIM1 init function */

void MX_TIM1_Init(void)

{



  /* USER CODE BEGIN TIM1_Init 0 */



  /* USER CODE END TIM1_Init 0 */



  TIM_ClockConfigTypeDef sClockSourceConfig = {0};

  TIM_MasterConfigTypeDef sMasterConfig = {0};

  TIM_OC_InitTypeDef sConfigOC = {0};

  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};



  /* USER CODE BEGIN TIM1_Init 1 */



  /* USER CODE END TIM1_Init 1 */

  htim1.Instance = TIM1;

  htim1.Init.Prescaler = 720-1;     // 分频720  100khz  10us计一数

  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;

  htim1.Init.Period = 500-1;        // 计数500次 500*10 = 5000us = 5ms = 200hz

  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  htim1.Init.RepetitionCounter = 0;

  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)

  {

    Error_Handler();

  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)

  {

    Error_Handler();

  }

  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)

  {

    Error_Handler();

  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)

  {

    Error_Handler();

  }

  sConfigOC.OCMode = TIM_OCMODE_PWM1;

  sConfigOC.Pulse = 0;   

  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)

  {

    Error_Handler();

  }

  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;

  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;

  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;

  sBreakDeadTimeConfig.DeadTime = 0;

  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;

  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;

  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)

  {

    Error_Handler();

  }

  /* USER CODE BEGIN TIM1_Init 2 */



  /* USER CODE END TIM1_Init 2 */

  HAL_TIM_MspPostInit(&htim1);



}

main函数


int main(void)

{

  /* USER CODE BEGIN 1 */

  //定义一个变量用来存储比较值

  uint16_t pulse = 0;

  //定义一个变量用来存储方向,0表示递增,1表示递减

  uint8_t dir = 0;

  /* 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_USART1_UART_Init();

  MX_TIM2_Init();

  MX_TIM1_Init();

  /* USER CODE BEGIN 2 */



  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);

  /* USER CODE END 2 */



  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

  while (1)

  {

    /* USER CODE END WHILE */



    /* USER CODE BEGIN 3 */

   //根据方向判断是递增还是递减

  if (dir == 0)

  {

    //延时10毫秒

    HAL_Delay(10);

    //比较值加一

    pulse++;

    //设置比较值

    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_4, pulse);

    //如果比较值达到最大值499,就改变方向为递减

    if (pulse == 499)

    {

      dir = 1;

    }

  }

  else if (dir == 1)

  {

    //延时10毫秒

    HAL_Delay(10);

    //比较值减一

    pulse--;

    //设置比较值

    __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_4, pulse);

    //如果比较值达到最小值0,就改变方向为递增

    if (pulse == 0)

    {

      dir = 0;

    }

  }

  }

  /* USER CODE END 3 */

}

实验现象


能在我的硬件上实现呼吸灯的效果。


文章来源于: 电子工程世界 原文链接

本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。