OpenEdv-开源电子网

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

SPWM波形问题

[复制链接]

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2012-2-26
在线时间
0 小时
发表于 2013-8-8 17:04:27 | 显示全部楼层 |阅读模式
    原子哥和各位高手,我最近打算用M3的定时器搞一下SPWM波形。通过仿真发现,当占空比接近90%左右的时候,会突然之间会有一个脉冲出现
  。如下图红色箭头所示。而低于这个占空比的时候就输出正常。



我怀疑是中断引起的。但是我们在中断服务程序中只有只有一句代码,就是修改CCR的值,没有其他了。请问,我该如何修改程序呢?谢谢~

工程.rar

1.34 MB, 下载次数: 517

他山之石,可以攻玉.
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
发表于 2013-8-9 10:14:19 | 显示全部楼层
回复【5楼】内有元基:
---------------------------------
哥们你走错路了,SPWM是输出PWM,但用的不是定时器的PWM功能,也就是说和占空比毫无关系。你应该使用的是输出比较,定时器计数产生三角波,你想要输出波形的值直接写入对应的寄存器即可!
回复 支持 1 反对 0

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-8-8 17:24:39 | 显示全部楼层
你别在中断中修改CCR值呢,还有这个脉冲么?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
发表于 2013-8-8 17:46:13 | 显示全部楼层
SPWM ?电力电子的?SPWM还是建议用DSP吧,FPGA也灰常棒!
回复 支持 反对

使用道具 举报

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2012-2-26
在线时间
0 小时
 楼主| 发表于 2013-8-9 08:14:52 | 显示全部楼层
回复【3楼】tian123chi:
---------------------------------
恩恩,是用M3来做SPWM波形,是做一个简单的逆变器,DSP和FPGA还没有学~谢谢
他山之石,可以攻玉.
回复 支持 反对

使用道具 举报

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2012-2-26
在线时间
0 小时
 楼主| 发表于 2013-8-9 08:17:36 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
原子哥,这个是使能了PWM模式的时间更新中断,如果没有进入中断的话就没有这个脉冲产生了。但是同样使能了中断,
为什么在90%以下的占空比就不会出现这个脉冲,反而是接近100%的时候就会出现了这个脉冲~~
他山之石,可以攻玉.
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-8-9 10:27:24 | 显示全部楼层
得分析代码了,我也不确定是哪里的问题.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2012-2-26
在线时间
0 小时
 楼主| 发表于 2013-8-9 22:31:21 | 显示全部楼层
回复【6楼】tian123chi:
---------------------------------
 恩恩,我的程序是通过定时器的PWM模式,将正弦波的幅值写到占空比的值去,输出就是SPWM方波,然后通过H桥,最后滤波之后就得到逆变出来的正弦波。这个方法做的逆变电源应该没问题吧?
他山之石,可以攻玉.
回复 支持 反对

使用道具 举报

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2012-2-26
在线时间
0 小时
 楼主| 发表于 2013-8-9 22:39:01 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
  嗯,原子哥,除了这种PWM中断修改占空比的方法,还有什么方法是可以产生占空比变化的方波呢?
他山之石,可以攻玉.
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-8-10 00:06:12 | 显示全部楼层
你改变CCRx就可以改变占空比了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2013-8-10 00:43:00 | 显示全部楼层
开启预加载功能即可.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
发表于 2013-8-10 08:13:22 | 显示全部楼层
回复【8楼】内有元基:
---------------------------------
有问题,哪有SPWM直接修改占空比的呢,说过了定时器计数,再写入幅值对比!并不是PWM模式的修改占空比
回复 支持 反对

使用道具 举报

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2012-2-26
在线时间
0 小时
 楼主| 发表于 2013-8-10 08:55:44 | 显示全部楼层
回复【11楼】shihantu:
---------------------------------
 TIM_ARRPreloadConfig(TIM3, ENABLE);  // 使能TIM3重载寄存器ARR

 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
  /* TIM3 enable counter */
  TIM_Cmd(TIM3, ENABLE);   

我这个也是使能了预加载,把波形输出到电路上去,通过示波器检测的确得到逆变的正弦波出来,但波形顶峰
会有比较大一点的谐波。但是如果我程序上面把占空比限定在98%以下,输出就比较好的正弦波的波形出来。所以我们
就觉得是程序上面有问题,仿真的时候也发现是在占空比接近98%~100%的时候就会出现一楼所示的脉冲出现了。
他山之石,可以攻玉.
回复 支持 反对

使用道具 举报

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
发表于 2013-8-10 09:09:22 | 显示全部楼层
回复【12楼】tian123chi:
---------------------------------
用FPGA怎么写啊?寄存器累加查表比较输出??有木有其他方便点的方法??
坚持到底就是胜利!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-8-10 10:25:37 | 显示全部楼层
回复【13楼】内有元基:
---------------------------------
你上传下工程,我仿真看看.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
发表于 2013-8-10 11:22:12 | 显示全部楼层
回复【14楼】VictorScarlet:
---------------------------------
FPGA,逆变器可以直接定时查表(电平表)输出即可,变频器与APF使用计数值与输出值对比。
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2013-8-10 11:32:23 | 显示全部楼层
回复【13楼】内有元基:
---------------------------------
你的注释里也写了嘛,只是使能了ARR的预加载.

还需要预加载CCR.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
发表于 2013-8-10 11:33:05 | 显示全部楼层
回复【13楼】内有元基:
---------------------------------
我是做APF的,当中也有逆变器的过程,芯片为DSP的28335,首先跟占空比没关系,第二你所说占空比大后波形顶峰会有谐波?你应该好好看看谐波的定义了!还有你死区是如何设置的?
回复 支持 反对

使用道具 举报

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2012-2-26
在线时间
0 小时
 楼主| 发表于 2013-8-12 13:40:43 | 显示全部楼层
回复【10楼】正点原子:
---------------------------------
原子哥,我在1楼上传了工程了,麻烦你帮我仿真一下,无限感激~~
他山之石,可以攻玉.
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-8-12 21:45:52 | 显示全部楼层
问题就出在spwm 函数.
修改为如下,问题解决:
void spwm (void)

  WM3plus+=1; //每次查表递增加1
  if(PWM3plus==320)
   PWM3plus=0;
//if(PWM3plus==0)
//  PWM3plus=255;
  WMch1=PWM3plus;
//   WMch2=PWM3plus;
//   TIM1->CCR3=PWMdata[PWM3plus];
//   TIM1->CCR2=PWMdata[PWMch2];
//   TIM1->CCR1=PWMdata[PWMch1];
TIM3->CCR2 =  WMdata[PWMch1];  //将查表得到的值写到TIM_Pluse
  //TIM_OCInitStructure.TIM_Pulse = WMdata[PWMch1];  //将查表得到的值写到TIM_Pluse
//TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //使能通道1
//  TIM_OCInitStructure.TIM_Pulse = WMdata[PWMch2];
//  TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //使能通道2
// TIM_OCInitStructure.TIM_Pulse = WMdata[PWM3plus];
// TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //使能通道3

}

这是因为PWM改变一个CCR2的值而已,你调用TIM_OC2Init(TIM3, &TIM_OCInitStructure);  受影响的寄存器太多,修改过程中,可能就导致出这么个畸形脉冲了.
所以,某些淘宝卖家,说什么要他用寄存器还不如回家耕田,遇到这种问题,楼主要是信了这些卖家所言,死抱着库函数,以为是万金油,放哪里都适用的话,估计真要回家耕田了....
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

10

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2013-8-5
在线时间
0 小时
发表于 2013-8-13 08:45:21 | 显示全部楼层
回复【9楼】内有元基:
---------------------------------
我试过直接运用定时器基本功能,在中断里能过修改TIMx_CNT的值,来达到修改占空比的目的。可以用普通的IO口通过翻转电平,产生SPWM波。最好用的还是运用高级定时器的PWM互补输出模式,还带有死区。
不疯魔,不成活。
回复 支持 反对

使用道具 举报

0

主题

10

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2013-8-5
在线时间
0 小时
发表于 2013-8-13 08:58:45 | 显示全部楼层
回复【20楼】正点原子:
---------------------------------
确实如原子哥所说,有时候修改寄存器是要方便许多。还是得多翻翻数据手册~!
另外附上
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
{
  uint16_t tmpccmrx = 0, tmpccer = 0, tmpcr2 = 0;
   
  /* Check the parameters */
  assert_param(IS_TIM_123458_PERIPH(TIMx)); 
  assert_param(IS_TIM_OC_MODE(TIM_OCInitStruct->TIM_OCMode));
  assert_param(IS_TIM_OUTPUT_STATE(TIM_OCInitStruct->TIM_OutputState));
  assert_param(IS_TIM_OC_POLARITY(TIM_OCInitStruct->TIM_OCPolarity));   
  /* Disable the Channel 2: Reset the CC2E Bit */
  TIMx->CCER &= CCER_CC2E_Reset;
  
  /* Get the TIMx CCER register value */  
  tmpccer = TIMx->CCER;
  /* Get the TIMx CR2 register value */
  tmpcr2 =  TIMx->CR2;
  
  /* Get the TIMx CCMR1 register value */
  tmpccmrx = TIMx->CCMR1;
    
  /* Reset the Output Compare Mode Bits */
  tmpccmrx &= CCMR_OC24M_Mask;
  
  /* Select the Output Compare Mode */
  tmpccmrx |= (uint16_t)(TIM_OCInitStruct->TIM_OCMode << 8);
  
  /* Reset the Output olarity level */
  tmpccer &= CCER_CC2P_Reset;
  /* Set the Output Compare olarity */
  tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCPolarity << 4);
  
  /* Set the Output State */
  tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputState << 4);
  
  /* Set the Capture Compare Register value */
  TIMx->CCR2 = TIM_OCInitStruct->TIM_Pulse;
  
  if((*(uint32_t*)&TIMx == TIM1_BASE) || (*(uint32_t*)&TIMx == TIM8_BASE))
  {
    assert_param(IS_TIM_OUTPUTN_STATE(TIM_OCInitStruct->TIM_OutputNState));
    assert_param(IS_TIM_OCN_POLARITY(TIM_OCInitStruct->TIM_OCNPolarity));
    assert_param(IS_TIM_OCNIDLE_STATE(TIM_OCInitStruct->TIM_OCNIdleState));
    assert_param(IS_TIM_OCIDLE_STATE(TIM_OCInitStruct->TIM_OCIdleState));
    
    /* Reset the Output N olarity level */
    tmpccer &= CCER_CC2NP_Reset;
    /* Set the Output N olarity */
    tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OCNPolarity << 4);
    /* Reset the Output N State */
    tmpccer &= CCER_CC2NE_Reset;
    
    /* Set the Output N State */
    tmpccer |= (uint16_t)(TIM_OCInitStruct->TIM_OutputNState << 4);
    /* Reset the Ouput Compare and Output Compare N IDLE State */
    tmpcr2 &= CR2_OIS2_Reset;
    tmpcr2 &= CR2_OIS2N_Reset;
    /* Set the Output Idle state */
    tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCIdleState << 2);
    /* Set the Output N Idle state */
    tmpcr2 |= (uint16_t)(TIM_OCInitStruct->TIM_OCNIdleState << 2);
  }
  /* Write to TIMx CR2 */
  TIMx->CR2 = tmpcr2;
  
  /* Write to TIMx CCMR1 */
  TIMx->CCMR1 = tmpccmrx;
  
  /* Write to TIMx CCER */
  TIMx->CCER = tmpccer;
}
楼主只是要修改一个TIMx->CCR2的值,却重新初始化了这么寄存器。。在其他占空比时能正常已是奇迹!
如果要用库函数写,也不该用这句。
换成库函数里的
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2)
{
  /* Check the parameters */
  assert_param(IS_TIM_123458_PERIPH(TIMx));
  /* Set the Capture Compare2 Register value */
  TIMx->CCR2 = Compare2;
}
这句倒还可以。
不过类似这种操作,还是提倡直接操作寄存器来得方便些!
不疯魔,不成活。
回复 支持 反对

使用道具 举报

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2012-2-26
在线时间
0 小时
 楼主| 发表于 2013-8-13 16:11:37 | 显示全部楼层
回复【20楼】正点原子:
---------------------------------
嗯,非常感谢原子哥,问题解决了。我以前都买了本例说回来,也是搞过大半个学期的寄存器,明白了M3里面很多东西。继续支持~~
他山之石,可以攻玉.
回复 支持 反对

使用道具 举报

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
74
金钱
74
注册时间
2012-2-26
在线时间
0 小时
 楼主| 发表于 2013-8-13 16:13:43 | 显示全部楼层
回复【22楼】loue:
---------------------------------
多谢loue,问题解决了。看来自己对库的使用还是不熟练,多谢~
他山之石,可以攻玉.
回复 支持 反对

使用道具 举报

13

主题

206

帖子

1

精华

高级会员

Rank: 4

积分
613
金钱
613
注册时间
2014-10-26
在线时间
32 小时
发表于 2015-7-23 21:20:43 | 显示全部楼层
你程序里面的  WMdata[320]  320是 采样个数?
还有 SPWM 波形该怎么检测呢,好像一般的示波器 看不出来~
学习!
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-19 23:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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