OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2536|回复: 4

请教如何将F1输出的PWM快速关断

[复制链接]

1

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2016-10-19
在线时间
24 小时
发表于 2019-11-29 10:28:42 | 显示全部楼层 |阅读模式
10金钱
目的是想做三相PWM输出,利用PWM的定时器TIM4产生20us定时中断,每路PWM间隔两个周期再打开,在间隔周期内将PWM脉宽设为0(TIM4->CCR1=0;)


但在打开的周期内,PWM会出现两个高电平,下图只以一路PWM来测试得到的波形

微信图片_20191129102050.jpg
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2016-10-19
在线时间
24 小时
 楼主| 发表于 2019-11-29 10:31:47 | 显示全部楼层
可以确定是在同一周期内出现的两个高电平,因为我用其它引脚在定时中断里面翻转,刚好是在第一次出现高电平时该引脚翻转了。
当间隔周期内不加TIM4->CCR1=0;则输出波形正常,同一周期不会出现两个高电平。
回复

使用道具 举报

1

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2016-10-19
在线时间
24 小时
 楼主| 发表于 2019-11-29 10:32:43 | 显示全部楼层
定时器配置如下
  1. void TIM4_GPIO_Config(void)
  2. {
  3.   GPIO_InitTypeDef GPIO_InitStructure;

  4.         /* TIM2 clock enable */
  5.         //PCLK1经过2倍频后作为TIM3的时钟源等于72MHz
  6.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
  7.   /* GPIOA and GPIOB clock enable */
  8.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);

  9.   /*GPIOA Configuration: TIM2 channel 1 and 2 as alternate function push-pull */
  10.   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
  11.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                    // 复用推挽输出
  12.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  13.   GPIO_Init(GPIOB, &GPIO_InitStructure);
  14. }

  15. void TIM4_Mode_Config(void)
  16. {
  17.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  18.   TIM_OCInitTypeDef  TIM_OCInitStructure;
  19.         NVIC_InitTypeDef NVIC_InitStructure;
  20.         
  21.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
  22.         
  23.         TIM_DeInit(TIM4);//Use TIM_DeInit () function to set Timer as the default value;
  24.   TIM_TimeBaseStructure.TIM_Prescaler = 1-1;//预分频 To set the prescaler coefficient
  25.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//
  26.   TIM_TimeBaseStructure.TIM_Period = Fcount;//
  27.   TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//
  28.   TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;//
  29.   TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);//
  30.         
  31.         TIM_ARRPreloadConfig(TIM4,ENABLE);                          
  32.   
  33.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  34.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  35.   TIM_OCInitStructure.TIM_OutputNState = TIM_OutputState_Disable;
  36.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//不反相输出
  37.   TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
  38.   TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  39.   TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
  40.                
  41. ////////////////////////////////////////////////////////////////////////////////////
  42.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  43.   TIM_OCInitStructure.TIM_Pulse = 0;
  44.   TIM_OC1Init(TIM4,&TIM_OCInitStructure);
  45.   TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Disable);
  46.         
  47.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  48.   TIM_OCInitStructure.TIM_Pulse = 0;
  49.   TIM_OC2Init(TIM4,&TIM_OCInitStructure);
  50.   TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Disable);

  51.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  52.   TIM_OCInitStructure.TIM_Pulse = 0;
  53.   TIM_OC3Init(TIM4,&TIM_OCInitStructure);
  54.   TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Disable);

  55.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  56.   TIM_OCInitStructure.TIM_Pulse = 0;        //设置通道4的电平跳变值,输出另外一个占空比的PWM
  57.   TIM_OC4Init(TIM4, &TIM_OCInitStructure);        //使能通道4
  58.   TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Disable);

  59.         TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断,允许更新中断
  60.         //中断优先级NVIC设置
  61.         NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断
  62.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级0级
  63.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级3级
  64.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  65.         NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

  66.   TIM_Cmd(TIM4,ENABLE);
  67. }
复制代码
回复

使用道具 举报

1

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2016-10-19
在线时间
24 小时
 楼主| 发表于 2019-11-29 10:34:30 | 显示全部楼层
定时器中断函数为(PWM与定时中断同为TIM4)
  1. void TIM4_IRQHandler(void)   //20us中断一次
  2. {
  3. static u8 ThreePhase=0;        
  4.         if(TIM4->SR&0X0001)//溢出中断
  5.         {
  6.                 TIM4->SR&=~(1<<0);//清除中断标志位
  7.                 switch(ThreePhase)
  8.                 {
  9.                     case 0:
  10.                     TIM4->CCR1=500;
  11.                     ThreePhase=1;
  12.                     break;
  13.                     case 1:
  14.                     TIM4->CCR1=0;
  15.                     ThreePhase=2;
  16.                     break;
  17.                     case 2:
  18.                     TIM4->CCR1=0;
  19.                     ThreePhase=0;
  20.                     break;
  21.               }
  22.        }
  23. }
复制代码
回复

使用道具 举报

1

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2016-10-19
在线时间
24 小时
 楼主| 发表于 2019-11-29 11:04:35 | 显示全部楼层
本帖最后由 玖零壹捌 于 2019-11-29 11:07 编辑

利用这两句可以实现
关闭
TIM_SelectOCxM(TIM4,TIM_Channel_1,TIM_ForcedAction_InActive);
打开
TIM_SelectOCxM(TIM4, TIM_Channel_1, TIM_OCMode_PWM1);
TIM_CCxCmd(TIM4, TIM_Channel_1, TIM_CCx_Enable);
参看自FLYTito的回答见
http://www.openedv.com/posts/list/45711.htm
不明白为什么TIM4->CCR1=0;这种方式不行


回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-24 19:31

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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