找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1046|回复: 5
打印 上一主题 下一主题
收起左侧

求助STM32F103 Timer3 CH2 PWM输出问题

[复制链接]
跳转到指定楼层
楼主
ID:916650 发表于 2022-12-8 10:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

我用IAR写的PWM输出程序,正常应该看到PB5的小灯亮灭交替,结果一直是常亮状态,搜了一圈没搞明白怎么回事
基本定时功能和中断倒是正常,PWM输出无作用


  1. //Main.c
  2. /* Includes ------------------------------------------------------------------*/
  3. #include "main.h"

  4. void SystemClock_Config(void);
  5. void LED_Init(void);

  6. #define     LED1_ON         HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5, GPIO_PIN_RESET)
  7. #define     LED1_OFF        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5, GPIO_PIN_SET)
  8. #define     LED1_Toggle     HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5)

  9. #define     LED2_ON          HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5, GPIO_PIN_RESET)
  10. #define     LED2_OFF        HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5, GPIO_PIN_SET)
  11. #define     LED2_Toggle     HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5)

  12. void Tim3_Init(void);
  13. void Tim3B_Init(void);

  14. TIM_HandleTypeDef         TIM3_Handler;              //定时器句柄
  15. TIM_OC_InitTypeDef         TIM3_CH2Handler;        //定时器3通道2句柄

  16. uint ret;
  17. int compare=0;

  18. int main(void)
  19. {

  20.   HAL_Init();

  21.   SystemClock_Config();
  22.    
  23. // LED_Init();
  24. // LED1_OFF;
  25. // LED2_OFF;
  26.   
  27.   //Tim3B_Init();
  28.      
  29.   Tim3_Init();
  30.   


  31.   while (1)
  32.   {
  33.    
  34.   }
  35. }

  36. /**
  37.   * @brief  System Clock Configuration
  38.   *         The system Clock is configured as follow :
  39.   *            System Clock source            = PLL (HSE)
  40.   *            SYSCLK(Hz)                     = 72000000
  41.   *            HCLK(Hz)                       = 72000000
  42.   *            AHB Prescaler                  = 1
  43.   *            APB1 Prescaler                 = 2
  44.   *            APB2 Prescaler                 = 1
  45.   *            HSE Frequency(Hz)              = 8000000
  46.   *            HSE PREDIV1                    = 1
  47.   *            PLLMUL                         = 9
  48.   *            Flash Latency(WS)              = 2
  49.   * @param  None
  50.   * @retval None
  51.   */
  52. void SystemClock_Config(void)
  53. {
  54.   RCC_ClkInitTypeDef clkinitstruct = {0};
  55.   RCC_OscInitTypeDef oscinitstruct = {0};
  56.   
  57.   /* Enable HSE Oscillator and activate PLL with HSE as source */
  58.   oscinitstruct.OscillatorType  = RCC_OSCILLATORTYPE_HSE;
  59.   oscinitstruct.HSEState        = RCC_HSE_ON;
  60.   oscinitstruct.HSEPredivValue  = RCC_HSE_PREDIV_DIV1;
  61.   oscinitstruct.PLL.PLLState    = RCC_PLL_ON;
  62.   oscinitstruct.PLL.PLLSource   = RCC_PLLSOURCE_HSE;
  63.   oscinitstruct.PLL.PLLMUL      = RCC_PLL_MUL9;
  64.   if (HAL_RCC_OscConfig(&oscinitstruct)!= HAL_OK)
  65.   {
  66.     /* Initialization Error */
  67.     while(1);
  68.   }

  69.   /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
  70.      clocks dividers */
  71.   clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  72.   clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  73.   clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  74.   clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1;
  75.   clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2;  
  76.   if (HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2)!= HAL_OK)
  77.   {
  78.     /* Initialization Error */
  79.     while(1);
  80.   }
  81. }

  82. void LED_Init(void)
  83. {
  84.   __HAL_RCC_GPIOB_CLK_ENABLE();
  85.   __HAL_RCC_GPIOE_CLK_ENABLE();
  86.   
  87.   GPIO_InitTypeDef GPIO_Init_Struct;
  88.   
  89.   GPIO_Init_Struct.Pin=GPIO_PIN_5;
  90.   GPIO_Init_Struct.Mode=GPIO_MODE_OUTPUT_PP;
  91.   GPIO_Init_Struct.Pull=GPIO_PULLUP;
  92.   GPIO_Init_Struct.Speed=GPIO_SPEED_FREQ_HIGH;
  93.   
  94.   HAL_GPIO_Init(GPIOB, &GPIO_Init_Struct);
  95.        
  96.   HAL_GPIO_Init(GPIOE, &GPIO_Init_Struct);
  97. }


  98. void Tim3_Init(void)
  99. {

  100.     TIM3_Handler.Instance=TIM3;                  //定时器3
  101.     TIM3_Handler.Init.Prescaler=(72-1);       //定时器分频
  102.     TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//向上计数模式
  103.     TIM3_Handler.Init.Period=(50000-1);          //自动重装载值
  104.     TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
  105.       TIM3_Handler.Init.RepetitionCounter = 0;
  106.   TIM3_Handler.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  107.   
  108.     HAL_TIM_PWM_Init(&TIM3_Handler);       //初始化PWM
  109.    
  110.     TIM3_CH2Handler.OCMode=TIM_OCMODE_PWM1; //模式选择PWM1
  111.     TIM3_CH2Handler.Pulse=(50000-1)/2;            //设置比较值,此值用来确定占空比,默认比较值为自动重装载值的一半,即占空比为50%
  112.     TIM3_CH2Handler.OCPolarity=TIM_OCPOLARITY_LOW; //输出比较极性为低
  113.       TIM3_CH2Handler.OCFastMode   = TIM_OCFAST_DISABLE;
  114.   TIM3_CH2Handler.OCNPolarity  = TIM_OCNPOLARITY_HIGH;
  115.   TIM3_CH2Handler.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  116.   
  117.     HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH2Handler,TIM_CHANNEL_2);//配置TIM3通道2
  118.        
  119.    HAL_TIM_PWM_Start(&TIM3_Handler,TIM_CHANNEL_2);//开启PWM通道2
  120. }

  121. void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
  122. {
  123.         GPIO_InitTypeDef GPIO_Initure;
  124.        
  125.     if(htim->Instance==TIM3)
  126.     {   

  127.             __HAL_RCC_TIM3_CLK_ENABLE();                        //使能定时器3
  128.             __HAL_RCC_GPIOB_CLK_ENABLE();                        //开启GPIOB时钟
  129.             __HAL_AFIO_REMAP_TIM3_PARTIAL();                //TIM3通道引脚部分重映射使能
  130.             
  131.             GPIO_Initure.Pin=GPIO_PIN_5;                   //PB5
  132.             GPIO_Initure.Mode=GPIO_MODE_AF_PP;          //复用推挽输出
  133.             //GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
  134.             GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
  135.             HAL_GPIO_Init(GPIOB,&GPIO_Initure);        
  136.     }
  137. }

  138. void Tim3B_Init(void)
  139. {

  140.     TIM3_Handler.Instance=TIM3;                  //定时器3
  141.     TIM3_Handler.Init.Prescaler=(72-1)*100;       //定时器分频
  142.     TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//向上计数模式
  143.     TIM3_Handler.Init.Period=(50000-1);          //自动重装载值
  144.     TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
  145.     HAL_TIM_Base_Init(&TIM3_Handler);       //初始化PWM
  146.        
  147.       HAL_TIM_Base_Start_IT(&TIM3_Handler); //使能定时器3和定时器3更新中断:TIM_IT_UPDATE   
  148. }

  149. void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
  150. {
  151.     if(htim->Instance==TIM3)
  152.         {
  153.                 __HAL_RCC_TIM3_CLK_ENABLE();            //使能TIM3时钟
  154.                 HAL_NVIC_SetPriority(TIM3_IRQn,1,3);    //设置中断优先级,抢占优先级1,子优先级3
  155.                 HAL_NVIC_EnableIRQ(TIM3_IRQn);          //开启ITM3中断   
  156.         }
  157. }

  158. //定时器3中断服务函数
  159. void TIM3_IRQHandler(void)
  160. {
  161.     HAL_TIM_IRQHandler(&TIM3_Handler);
  162. }

  163. //回调函数,定时器中断服务函数调用
  164. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  165. {
  166.     if(htim==(&TIM3_Handler))
  167.     {
  168.         LED1_Toggle;        //LED1反转
  169.     }
  170. }
复制代码




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:916650 发表于 2022-12-8 12:56 | 只看该作者
更新一下,我好像发现问题所在了
问题出在缺少语句__HAL_RCC_AFIO_CLK_ENABLE();
而且这个语句必须在PWM输出引脚重映射语句前执行,否则就不会执行PWM输出引脚重映射,PWM不会从PB5输出。

现在在我的程序中单独执行PWM输出,PB5就可以正常亮灭了

  1. //Main.c
  2. /* Includes ------------------------------------------------------------------*/
  3. #include "main.h"

  4. void SystemClock_Config(void);
  5. void LED_Init(void);

  6. #define     LED1_ON         HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5, GPIO_PIN_RESET)
  7. #define     LED1_OFF        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5, GPIO_PIN_SET)
  8. #define     LED1_Toggle     HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5)

  9. #define     LED2_ON          HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5, GPIO_PIN_RESET)
  10. #define     LED2_OFF        HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5, GPIO_PIN_SET)
  11. #define     LED2_Toggle     HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5)

  12. void Tim3_Init(void);
  13. void Tim3B_Init(void);

  14. TIM_HandleTypeDef         TIM3_Handler;              //定时器句柄
  15. TIM_OC_InitTypeDef         TIM3_CH2Handler;        //定时器3通道2句柄

  16. uint ret;
  17. int compare=0;

  18. int main(void)
  19. {

  20.   HAL_Init();

  21.   SystemClock_Config();
  22.    
  23. // LED_Init();
  24. // LED1_OFF;
  25. // LED2_OFF;
  26.   
  27.   //Tim3B_Init();
  28.   
  29.   Tim3_Init();
  30.   


  31.   while (1)
  32.   {
  33.    
  34.   }
  35. }

  36. /**
  37.   * @brief  System Clock Configuration
  38.   *         The system Clock is configured as follow :
  39.   *            System Clock source            = PLL (HSE)
  40.   *            SYSCLK(Hz)                     = 72000000
  41.   *            HCLK(Hz)                       = 72000000
  42.   *            AHB Prescaler                  = 1
  43.   *            APB1 Prescaler                 = 2
  44.   *            APB2 Prescaler                 = 1
  45.   *            HSE Frequency(Hz)              = 8000000
  46.   *            HSE PREDIV1                    = 1
  47.   *            PLLMUL                         = 9
  48.   *            Flash Latency(WS)              = 2
  49.   * @param  None
  50.   * @retval None
  51.   */
  52. void SystemClock_Config(void)
  53. {
  54.   RCC_ClkInitTypeDef clkinitstruct = {0};
  55.   RCC_OscInitTypeDef oscinitstruct = {0};
  56.   
  57.   /* Enable HSE Oscillator and activate PLL with HSE as source */
  58.   oscinitstruct.OscillatorType  = RCC_OSCILLATORTYPE_HSE;
  59.   oscinitstruct.HSEState        = RCC_HSE_ON;
  60.   oscinitstruct.HSEPredivValue  = RCC_HSE_PREDIV_DIV1;
  61.   oscinitstruct.PLL.PLLState    = RCC_PLL_ON;
  62.   oscinitstruct.PLL.PLLSource   = RCC_PLLSOURCE_HSE;
  63.   oscinitstruct.PLL.PLLMUL      = RCC_PLL_MUL9;
  64.   if (HAL_RCC_OscConfig(&oscinitstruct)!= HAL_OK)
  65.   {
  66.     /* Initialization Error */
  67.     while(1);
  68.   }

  69.   /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
  70.      clocks dividers */
  71.   clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  72.   clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  73.   clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  74.   clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1;
  75.   clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2;  
  76.   if (HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2)!= HAL_OK)
  77.   {
  78.     /* Initialization Error */
  79.     while(1);
  80.   }
  81. }

  82. void LED_Init(void)
  83. {
  84.   __HAL_RCC_GPIOB_CLK_ENABLE();
  85.   __HAL_RCC_GPIOE_CLK_ENABLE();
  86.   
  87.   GPIO_InitTypeDef GPIO_Init_Struct;
  88.   
  89.   GPIO_Init_Struct.Pin=GPIO_PIN_5;
  90.   GPIO_Init_Struct.Mode=GPIO_MODE_OUTPUT_PP;
  91.   GPIO_Init_Struct.Pull=GPIO_PULLUP;
  92.   GPIO_Init_Struct.Speed=GPIO_SPEED_FREQ_HIGH;
  93.   
  94.   HAL_GPIO_Init(GPIOB, &GPIO_Init_Struct);
  95.        
  96.   HAL_GPIO_Init(GPIOE, &GPIO_Init_Struct);
  97. }


  98. void Tim3_Init(void)
  99. {

  100.     TIM3_Handler.Instance=TIM3;                  //定时器3
  101.     TIM3_Handler.Init.Prescaler=(7200-1);       //定时器分频
  102.     TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//向上计数模式
  103.     TIM3_Handler.Init.Period=(50000-1);          //自动重装载值
  104.     TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
  105.     HAL_TIM_PWM_Init(&TIM3_Handler);       //初始化PWM
  106.    
  107.     TIM3_CH2Handler.OCMode=TIM_OCMODE_PWM1; //模式选择PWM1
  108.     TIM3_CH2Handler.Pulse=(50000-1)/2;            //设置比较值,此值用来确定占空比,默认比较值为自动重装载值的一半,即占空比为50%
  109.     TIM3_CH2Handler.OCPolarity=TIM_OCPOLARITY_LOW; //输出比较极性为低
  110.   
  111.     HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH2Handler,TIM_CHANNEL_2);//配置TIM3通道2
  112.        
  113.    HAL_TIM_PWM_Start(&TIM3_Handler,TIM_CHANNEL_2);//开启PWM通道2
  114. }

  115. void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
  116. {
  117.         GPIO_InitTypeDef GPIO_Initure;
  118.        
  119.     if(htim->Instance==TIM3)
  120.     {   
  121.       __HAL_RCC_TIM3_CLK_ENABLE();                        //使能定时器3
  122.       __HAL_RCC_AFIO_CLK_ENABLE();
  123.       __HAL_AFIO_REMAP_TIM3_PARTIAL();                //TIM3通道引脚部分重映射使能
  124.       __HAL_RCC_GPIOB_CLK_ENABLE();                        //开启GPIOB时钟
  125.       
  126.             
  127.             GPIO_Initure.Pin=GPIO_PIN_5;                   //PB5
  128.             GPIO_Initure.Mode=GPIO_MODE_AF_PP;          //复用推挽输出
  129.             //GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
  130.             GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
  131.             HAL_GPIO_Init(GPIOB,&GPIO_Initure);        
  132.     }
  133. }

  134. void Tim3B_Init(void)
  135. {

  136.     TIM3_Handler.Instance=TIM3;                  //定时器3
  137.     TIM3_Handler.Init.Prescaler=(72-1);       //定时器分频
  138.     TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//向上计数模式
  139.     TIM3_Handler.Init.Period=(50000-1);          //自动重装载值
  140.     TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
  141.     HAL_TIM_Base_Init(&TIM3_Handler);       //初始化PWM
  142.        
  143.       HAL_TIM_Base_Start_IT(&TIM3_Handler); //使能定时器3和定时器3更新中断:TIM_IT_UPDATE   
  144. }

  145. void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
  146. {
  147.     if(htim->Instance==TIM3)
  148.         {
  149.                 __HAL_RCC_TIM3_CLK_ENABLE();            //使能TIM3时钟
  150.                 HAL_NVIC_SetPriority(TIM3_IRQn,1,3);    //设置中断优先级,抢占优先级1,子优先级3
  151.                 HAL_NVIC_EnableIRQ(TIM3_IRQn);          //开启ITM3中断   
  152.         }
  153. }

  154. //定时器3中断服务函数
  155. void TIM3_IRQHandler(void)
  156. {
  157.     HAL_TIM_IRQHandler(&TIM3_Handler);
  158. }

  159. //回调函数,定时器中断服务函数调用
  160. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  161. {
  162.     if(htim==(&TIM3_Handler))
  163.     {
  164.         LED1_Toggle;        //LED1反转
  165.     }
  166. }
复制代码

回复

使用道具 举报

板凳
ID:814525 发表于 2022-12-8 13:01 | 只看该作者
要能看到LED闪烁,PWM频率必须要十几赫兹一下。频率高了,是看不到的,必须用示波器观察。
回复

使用道具 举报

地板
ID:77589 发表于 2022-12-8 14:34 | 只看该作者
初步看了一下,你设置PWM的频率是20Hz, 人眼应该是感觉不到闪烁。
你先试试几Hz的情况。
回复

使用道具 举报

5#
ID:916650 发表于 2022-12-8 15:21 | 只看该作者
张天师 发表于 2022-12-8 13:01
要能看到LED闪烁,PWM频率必须要十几赫兹一下。频率高了,是看不到的,必须用示波器观察。

感谢回复,确实频率设的有些低了
问题后来解决了,发现是少了复用引脚时钟开启语句。
回复

使用道具 举报

6#
ID:916650 发表于 2022-12-8 15:21 | 只看该作者
Longan.Wang 发表于 2022-12-8 14:34
初步看了一下,你设置PWM的频率是20Hz, 人眼应该是感觉不到闪烁。
你先试试几Hz的情况。

感谢回复,确实频率设的有些低了
问题后来解决了,发现是少了复用引脚时钟开启语句。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表