stm32使用PWM波中断的方式精确的控制波的个数

发布者:innovator8最新更新时间:2018-12-25 来源: eefocus关键字:stm32  PWM波  中断 手机看文章 扫描二维码
随时随地手机看文章

1,假如想要得到如下的波形:



每一个波的周期为25us,一组波的频率为10HZ


实现思路:


实现的时候使用TIM1的CH1和TIM2的CH1,使用TIM15的中断,每100个ms来一次中断,在中断服务函数中以中断的方式打开PWM波的输出,在输出一个PWM波之后会进入PWM的中断服务函数,在中断服务函数中计数PWM波的个数,当达到8个的时候关闭PWM波的中断输出。


中断优先级的安排:


TIM15   1    0


TIM1     2    0


TIM2     3    0


2,在CUBE中的配置


TIM15的配置:






TIM1的配置:



TIM2的配置:



3,代码实现


/**

  ******************************************************************************

  * File Name          : main.c

  * Description        : Main program body

  ******************************************************************************

  *

  * COPYRIGHT(c) 2017 STMicroelectronics

  *

  * Redistribution and use in source and binary forms, with or without modification,

  * are permitted provided that the following conditions are met:

  *   1. Redistributions of source code must retain the above copyright notice,

  *      this list of conditions and the following disclaimer.

  *   2. Redistributions in binary form must reproduce the above copyright notice,

  *      this list of conditions and the following disclaimer in the documentation

  *      and/or other materials provided with the distribution.

  *   3. Neither the name of STMicroelectronics nor the names of its contributors

  *      may be used to endorse or promote products derived from this software

  *      without specific prior written permission.

  *

  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE

  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE

  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR

  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER

  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,

  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE

  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

  *

  ******************************************************************************

  */

/* Includes ------------------------------------------------------------------*/

#include "main.h"

#include "stm32f0xx_hal.h"

 

/* USER CODE BEGIN Includes */

 

/* USER CODE END Includes */

 

/* Private variables ---------------------------------------------------------*/

TIM_HandleTypeDef htim1;

TIM_HandleTypeDef htim2;

TIM_HandleTypeDef htim15;

 

/* USER CODE BEGIN PV */

/* Private variables ---------------------------------------------------------*/

 

/* USER CODE END PV */

 

/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

void Error_Handler(void);

static void MX_GPIO_Init(void);

static void MX_TIM1_Init(void);

static void MX_TIM2_Init(void);

static void MX_TIM15_Init(void);                                    

void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);

                                

                                

 

/* USER CODE BEGIN PFP */

/* Private function prototypes -----------------------------------------------*/

 

/* USER CODE END PFP */

 

/* USER CODE BEGIN 0 */

 

/* USER CODE END 0 */

 

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();

 

  /* Configure the system clock */

  SystemClock_Config();

 

  /* Initialize all configured peripherals */

  MX_GPIO_Init();

  MX_TIM1_Init();

  MX_TIM2_Init();

  MX_TIM15_Init();

 

  /* USER CODE BEGIN 2 */

 

  /* USER CODE END 2 */

 

  /* Infinite loop */

  /* USER CODE BEGIN WHILE */

  while (1)

  {

  /* USER CODE END WHILE */

 

  /* USER CODE BEGIN 3 */

 

  }

  /* USER CODE END 3 */

 

}

 

/** System Clock Configuration

*/

void SystemClock_Config(void)

{

 

  RCC_OscInitTypeDef RCC_OscInitStruct;

  RCC_ClkInitTypeDef RCC_ClkInitStruct;

 

    /**Initializes the CPU, AHB and APB busses clocks 

    */

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

  RCC_OscInitStruct.HSIState = RCC_HSI_ON;

  RCC_OscInitStruct.HSICalibrationValue = 16;

  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;

  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;

  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

  {

    Error_Handler();

  }

 

    /**Initializes the CPU, AHB and APB busses clocks 

    */

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

                              |RCC_CLOCKTYPE_PCLK1;

  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

 

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)

  {

    Error_Handler();

  }

 

    /**Configure the Systick interrupt time 

    */

  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

 

    /**Configure the Systick 

    */

  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

 

  /* SysTick_IRQn interrupt configuration */

  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}

 

/* TIM1 init function */

static void MX_TIM1_Init(void)

{

 

  TIM_MasterConfigTypeDef sMasterConfig;

  TIM_OC_InitTypeDef sConfigOC;

  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;

 

  htim1.Instance = TIM1;

  htim1.Init.Prescaler = 48-1;

  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;

  htim1.Init.Period = 25-1;

  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  htim1.Init.RepetitionCounter = 0;

  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)

  {

    Error_Handler();

  }

 

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;

  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

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

  {

    Error_Handler();

  }

 

  sConfigOC.OCMode = TIM_OCMODE_PWM1;

  sConfigOC.Pulse = 12;

  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_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_1) != 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();

  }

 

  HAL_TIM_MspPostInit(&htim1);


HAL_NVIC_SetPriority(TIM1_CC_IRQn, 2, 0);

  HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);

 

}

 

/* TIM2 init function */

static void MX_TIM2_Init(void)

{

 

  TIM_MasterConfigTypeDef sMasterConfig;

  TIM_OC_InitTypeDef sConfigOC;

 

  htim2.Instance = TIM2;

  htim2.Init.Prescaler = 48-1;

  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

  htim2.Init.Period = 25-1;

  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

  if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)

  {

    Error_Handler();

  }

 

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;

  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

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

  {

    Error_Handler();

  }

 

  sConfigOC.OCMode = TIM_OCMODE_PWM1;

  sConfigOC.Pulse = 12;

  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

  if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)

  {

    Error_Handler();

  }

 

  HAL_TIM_MspPostInit(&htim2);


HAL_NVIC_SetPriority(TIM2_IRQn , 3, 0);

  HAL_NVIC_EnableIRQ(TIM2_IRQn );

}

 

/* TIM15 init function */

static void MX_TIM15_Init(void)

{

 

  TIM_ClockConfigTypeDef sClockSourceConfig;

  TIM_MasterConfigTypeDef sMasterConfig;

 

  htim15.Instance = TIM15;

  htim15.Init.Prescaler = 480-1;

  htim15.Init.CounterMode = TIM_COUNTERMODE_UP;

  htim15.Init.Period = 10000;//100ms

  htim15.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  htim15.Init.RepetitionCounter = 0;

  htim15.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

  if (HAL_TIM_Base_Init(&htim15) != HAL_OK)

  {

    Error_Handler();

  }

 

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

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

  {

    Error_Handler();

  }

 

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;

  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

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

  {

    Error_Handler();

  }


HAL_NVIC_SetPriority(TIM15_IRQn, 1, 0);

  HAL_NVIC_EnableIRQ(TIM15_IRQn);

  /*##-2- Start the TIM Base generation in interrupt mode ####################*/

  /* Start Channel1 */

  if (HAL_TIM_Base_Start_IT(&htim15) != HAL_OK)

  {

    /* Starting Error */

    Error_Handler();

  }

}

static uint8_t count1 = 0,count2 = 0;

void delay(uint16_t j)

{

while(j--);

}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_1);

delay(12);//12us

HAL_TIM_PWM_Start_IT(&htim1, TIM_CHANNEL_1);

while(count1 && count2);

}

 

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)

{

if(htim == &htim1)

{

if(count1 < 8)

{

count1++;

}

else

{

HAL_TIM_PWM_Stop_IT(&htim1, TIM_CHANNEL_1);

count1 = 0;

}

}

if(htim == &htim2)

{

if(count2 < 8)

{

count2++;

}

else

{

HAL_TIM_PWM_Stop_IT(&htim2, TIM_CHANNEL_1);

count2 = 0;

}

}

}

/** Configure pins as 

        * Analog 

        * Input 

        * Output

        * EVENT_OUT

        * EXTI

*/

static void MX_GPIO_Init(void)

{

  /* GPIO Ports Clock Enable */

  __HAL_RCC_GPIOF_CLK_ENABLE();

  __HAL_RCC_GPIOA_CLK_ENABLE();

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**

  * @brief  This function is executed in case of error occurrence.

  * @param  None

  * @retval None

  */

void Error_Handler(void)

{

  /* USER CODE BEGIN Error_Handler */

  /* User can add his own implementation to report the HAL error return state */

  while(1) 

  {

  }

  /* USER CODE END Error_Handler */ 

}

#ifdef USE_FULL_ASSERT

/**

   * @brief Reports the name of the source file and the source line number

   * where the assert_param error has occurred.

   * @param file: pointer to the source file name

   * @param line: assert_param error line source number

   * @retval None

   */

void assert_failed(uint8_t* file, uint32_t line)

{

  /* USER CODE BEGIN 6 */

  /* User can add his own implementation to report the file name and line number,

    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* USER CODE END 6 */

}

#endif

/**

  * @}

  */ 

/**

  * @}

*/ 

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


关键字:stm32  PWM波  中断 引用地址:stm32使用PWM波中断的方式精确的控制波的个数

上一篇:stm32f103 学习笔记 —— 05 使用SysTick实现硬件延时
下一篇:配置STM32的PWM输出时没有波形输出的问题

推荐阅读最新更新时间:2024-03-16 16:21

51单片机中断的响应及撤销
中断响应 中断响应就是单 片机CPU对中断源提出的中断请求的接受。中断请求被响应后,再经过一系列的操作,而后转向中断 服务程序,完成中断所要求的处理任务。下面简要说明80c51的中断响应过程: 1.外中断采样和内中断置位 1.1外中断采样 要想知道外中断是否有请求发生,需要对外中断进行采样。 当通过软件将寄存器TCON的IT0(或IT1)位设置为0时,/INT0(或/INT1)为电平触发方式,CPU在每个机器周期的S5P2(第五个状态第2拍节)期间对/INT0(或/INT1)采样,一旦在P3.2(或P3.3)上检测到低电平时,则认为有外部中断申请,随即由硬件使TCON的IE0(或IE1)位置1,向CPU申请中断。在中断响应完成
[单片机]
51单片机<font color='red'>中断</font>的响应及撤销
MSP430x149x之---外部中断
外部中断 IO口中断 MSP430x149x的6组IO口中,只有P0、P1才具有外部中断功能。 设置IO口中断,并书写中断服务函数 设置步骤: 1. 设置相应IO口的方向为输入,即 在PXDIR 中的相应位置0。 2. 设置相应IO口为普通引脚,即PXSEL 中相应位置0。 3. 开启相应的IO口中断,即PXIE中的相应位置1。 4. 设置中断触发方式,即PxIES中, 0为上升沿,1为下降沿。 5. 开启外部总中断,即_EINT();。 6. 书写中断服务程序。 中断服务子程序的格式: #pragma vector = PORTx_VECTOR _interrupt void IRQ_PORT
[单片机]
STM32串口通信数据乱码的相关问题
STM32串口通信以及温度采集搞定,其中主要遇到STM32系列单片机时钟树的问题,串口通信遇到串口调试助手能够接收到数据但出现乱码现象,开始一直以为是串口配置和程序代码问题,因为是第一次上电在线调试STM32板子,后面主要查串口波特率配置和收发函数程序段,如下图: 波特率设置成115200没问题,试着降低波特率改成9600和4800但问题依旧没有解决,紧接着如下处理: 将重定向函数注释,单独写串口发送字节和字符串函数,依旧失败。最后锁定到系统时钟配置上,由于手上的STM32开发板改用了12M的晶振,根据单片机时钟树的理解和解读,一般采用外部时钟HSE,系统时钟配置成72M,8*9=72,,12*6=72,对于 SYSCLK
[单片机]
<font color='red'>STM32</font>串口通信数据乱码的相关问题
嵌入式stm32学习:SPI-读写串行FLASH
bsp_spi_flash.h #ifndef __SPI_FLASH_H #define __SPI_FLASH_H #include stm32f4xx.h #include stdio.h /* Private typedef -----------------------------------------------------------*/ //#define sFLASH_ID 0xEF3015 //W25X16 //#define sFLASH_ID 0xEF4015 //W25Q16 //#define sFLASH_ID
[单片机]
基于STM32的printf串口数据输出
该方法适用于STM32,实现了使用printf等标准C流函数输出数据的办法,极大的减少了输出串口数据时所需要做的数据处理。 实现原理 在C库中,printf()等输出流函数都是通过fputc()这个函数实现的,所以我们通过重映射的方式,修改这个函数的定义使它输出在STM32的寄存器中,便可以实现使用printf()函数在STM32串口上输出数据的功能。 Keil环境 重映射 在STM32的Keil开发环境中,C的库函数有两种实现方式 使用标准的C函数库 就是我们平常在PC Window平台上用的C库函数,此库的的优点在于实现的功能全面。但是由于这个库基本上是专为PC设计的,故而如果在嵌入式芯片中调用时将会使得工程文件变
[单片机]
基于<font color='red'>STM32</font>的printf串口数据输出
STM32串口使用方法
串口接收函数
[单片机]
<font color='red'>STM32</font>串口使用方法
STM32学习之串口
第一步:把串口用的引脚设置。接收的为 GPIO_Mode_IN_FLOATING; //浮空输入 发送的为GPIO_Mode_AF_PP; // 复用推挽输出 第二部设置 void NVIC_Configuration(void) NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel ; // 全局中断、、 NVIC_InitStructure.NVIC_IRQChannelPreemptio
[单片机]
ARM 之六 Cortex-M 内核中断/异常系统、中断优先级/嵌套 详解
问题 最近在使用STM32F3芯片的时候,遇到这样一个问题:如果外部中断来的频率足够快,上一个中断没有处理完成,新来的中断如何处理? 在调试时,发现有中断有 挂起、激活、失能等状态,考虑这些状态都是干啥用的呢!他们是Cortex-M核所共有的,因此这里不针对与具体用的STM32 MCU,直接上升到 Cortex-M内核来了解一下! 简介 中断(也称为“异常”)是微控制器一个很常见的特性。中断一般是由硬件(例如外设、外部引脚)产生,当中断产生以后 CPU 就会中断当前的程序执行流程转而去处理中断服务中指定的操作。 所有的Cortex-M 内核都会系统一个用于中断处理的组件:NVIC(Nested Vectored Inte
[单片机]
ARM 之六 Cortex-M 内核<font color='red'>中断</font>/异常系统、<font color='red'>中断</font>优先级/嵌套 详解
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved