OpenEdv-开源电子网

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

定时器中断中修改PWM的占空比出现了问题

[复制链接]

2

主题

5

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2018-8-14
在线时间
3 小时
发表于 2018-10-2 23:02:34 | 显示全部楼层 |阅读模式
1金钱
void TIM14_PWM_Init(void)//PWM配置
{         
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);   //
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);  //

GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //GPIOF9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //
GPIO_Init(GPIOF,&GPIO_InitStructure);              //
   
TIM_TimeBaseStructure.TIM_Prescaler=83;  //
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //
TIM_TimeBaseStructure.TIM_Period=499;   //
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//

//
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //
TIM_OC1Init(TIM14, &TIM_OCInitStructure);  //
TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);  //
  TIM_ARRPreloadConfig(TIM14,ENABLE);//
TIM_Cmd(TIM14, ENABLE);  //
}  
void TIM3_Int_Init(void)//定时器配置
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  

  TIM_TimeBaseInitStructure.TIM_Period = 99;  //
TIM_TimeBaseInitStructure.TIM_Prescaler=8399;  //
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //
TIM_Cmd(TIM3,ENABLE); //

NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);

}

u16 led0pwmval=0;   
  u8 dir=1;
void TIM3_IRQHandler(void)//定时器中断
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //
{
    if(dir)led0pwmval++;//
  else led0pwmval--; //
   if(led0pwmval>499)dir=0;//
  if(led0pwmval==0)dir=1; //

  TIM_SetCompare1(TIM14,led0pwmval); //修改占空比的值,达到499重新从0开始计数
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //
}

问题在于对应的的LED灯亮了,但是始终亮度不变,改变led0pwmval的初值,灯的亮度就会变化,这是什么原因?

最佳答案

查看完整内容[请看2#楼]

更新一下,问题解决了,led0pwmval的值确实变化了,只是中断的频率可能比较高,况且中断里没有加延时,所以看不到现象,如果想看到LED灯的变化,只需把中断频率调低点,加个延时,就能看到现象了。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

5

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2018-8-14
在线时间
3 小时
 楼主| 发表于 2018-10-2 23:02:35 | 显示全部楼层
更新一下,问题解决了,led0pwmval的值确实变化了,只是中断的频率可能比较高,况且中断里没有加延时,所以看不到现象,如果想看到LED灯的变化,只需把中断频率调低点,加个延时,就能看到现象了。
回复

使用道具 举报

34

主题

331

帖子

0

精华

高级会员

Rank: 4

积分
857
金钱
857
注册时间
2018-9-16
在线时间
240 小时
发表于 2018-10-3 11:12:00 | 显示全部楼层
输出一个PWM,主要就是改变CCRx这个比较值,调节占空比,灯的亮度就会改变
回复

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2018-10-3
在线时间
2 小时
发表于 2018-10-3 15:44:27 | 显示全部楼层
输出一个PWM,主要就是改变CCRx这个比较值,调节占空比,灯的亮度就会改变
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //表示小于你设置的led0pwmval的值部分输出高电平,大于部分为高电平。 led0pwmval=0表示小于0的部分没得,所以输出为高电平,led不亮。
回复

使用道具 举报

2

主题

5

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2018-8-14
在线时间
3 小时
 楼主| 发表于 2018-10-3 16:24:53 | 显示全部楼层
everythingfalls 发表于 2018-10-3 15:44
输出一个PWM,主要就是改变CCRx这个比较值,调节占空比,灯的亮度就会改变
TIM_OCInitStructure.TIM_OCPol ...

但是我中断里是改变led0pwmval的值了,关键是这个值不变化
回复

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2018-10-3
在线时间
2 小时
发表于 2018-10-3 19:47:21 | 显示全部楼层
中断里面不是死循环,程序执行一次就出了,应该把if(dir)led0pwmval++;//   else led0pwmval--; //    if(led0pwmval>499)dir=0;//   if(led0pwmval==0)dir=1; //   TIM_SetCompare1(TIM14,led0pwmval); //修改占空比的值,达到499重新从0开始计数
回复

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2018-10-3
在线时间
2 小时
发表于 2018-10-3 19:48:20 | 显示全部楼层
放到主函数while(1){};里面
回复

使用道具 举报

2

主题

5

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2018-8-14
在线时间
3 小时
 楼主| 发表于 2018-10-3 21:11:41 | 显示全部楼层
everythingfalls 发表于 2018-10-3 19:47
中断里面不是死循环,程序执行一次就出了,应该把if(dir)led0pwmval++;//   else led0pwmval--; //    if(l ...

循环一次出来后下一次执行中断,led0pwmval的值不会再变化了么
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-8 07:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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