如何计算产生SPWM所需要的占空比

[cpp]  view plain  copy
  1. /** @author Mei Jilin 
  2.     @date   2013/9/2 
  3.     @brief  加入生成SPWM部分 
  4. **/  
  5. #include "timer.h"  
  6. #include "led.h"  
  7. static uint16_t CCR3_Val = 1800;  
  8. static uint16_t PrescalerValue = 0;  
  9.   
  10. /*PWM输出配置说明,*/  
  11. /* - Prescaler = (TIM3CLK / TIM3 counter clock) - 1 选择TIMER工作在36MHZ 
  12.  
  13.     The TIM3 is running at 36 MHz: TIM3 Frequency = TIM3 counter clock/(ARR + 1) 
  14.                                                   = 36 MHz / 3600 = 10 KHz 
  15.     TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 */  
  16.     /*转换周期10K*/  
  17. void PWM_Init(void)  
  18. {  
  19.     TIM_TimeBaseInitTypeDef     TIM_TimeBaseStructure;  
  20.     TIM_OCInitTypeDef           TIM_OCInitStructure;  
  21.     GPIO_InitTypeDef            GPIO_InitStructure;  
  22.     NVIC_InitTypeDef NVIC_InitStructure;      
  23.         /* TIM3 clock enable */  
  24.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);  
  25.   
  26.     /* GPIOA and GPIOB clock enable */  
  27.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|  
  28.                              RCC_APB2Periph_AFIO, ENABLE);  
  29.     /* GPIOA Configuration:TIM3 Channel1, 2, 3 and 4 as alternate function push-pull */  
  30.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;  
  31.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
  32.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  33.     GPIO_Init(GPIOA, &GPIO_InitStructure);  
  34.       
  35.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;      //TIM1_CH1N  
  36.     GPIO_Init(GPIOB, &GPIO_InitStructure);  
  37.       
  38.      /* Compute the prescaler value */  
  39.     PrescalerValue = (uint16_t) (SystemCoreClock / 36000000) - 1; //TIMER2 - 36MHZ  
  40.     /* Time base configuration */  
  41.     TIM_TimeBaseStructure.TIM_Period = 3600;                    /*TIM3_ARR = 2879,12.5Khz*/  
  42.     TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;  
  43.     TIM_TimeBaseStructure.TIM_ClockDivision = 0;  
  44.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
  45.     TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;  
  46.     TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);  
  47.   
  48.     /* Channel 1, 2,3 and 4 Configuration in PWM mode */  
  49.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  
  50.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  
  51.     TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //关闭互补输出  
  52.     TIM_OCInitStructure.TIM_Pulse = CCR3_Val;  
  53.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  
  54.     TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;  
  55.     TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;  
  56.     TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Set;  
  57.     TIM_OC1Init(TIM1, &TIM_OCInitStructure);  
  58.       
  59.     TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //这句的功能是让改变CCR2之后马上有效      
  60.     TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);  
  61.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  
  62.     NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;  
  63.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
  64.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 6;  
  65.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  66.     NVIC_Init(&NVIC_InitStructure);      
  67.           
  68.     TIM_Cmd(TIM1, ENABLE);    
  69.     /* TIM1 Main Output Enable */  
  70.     TIM_CtrlPWMOutputs(TIM1, ENABLE);   //TIM1需要加上这句,貌似低级定时器不需要  
  71. }  
  72. uint16_t Duty[] = {1800,1856,1912,1968,2023,2078,2131,2183,2233,2282,2329,2373,2416,2456,2493,  
  73.     2528,2559,2588,2614,2636,2655,2671,2684,2692,2698,2699,2698,2692,2684,2671,2655,2636,2614,  
  74.     2588,2559,2528,2493,2456,2416,2373,2329,2282,2233,2183,2131,2078,2023,1968,1912,1856,1800,  
  75.     1743,1687,1631,1576,1521,1468,1416,1366,1317,1270,1226,1183,1143,1106,1071,1040,1011,985,  
  76.     963,944,928,915,907,901,900,901,907,915,928,944,963,985,1011,1040,1071,1106,1143,1183,1226,  
  77.     1270,1317,1366,1416,1468,1521,1576,1631,1687,1743,1799,1799};  
  78. uint16_t count = 0;  
  79. uint16_t num = sizeof(Duty)/(sizeof(Duty[0]));  
  80. void TIM1_CC_IRQHandler(void)  
  81. {  
  82.   if (TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET)  
  83.   {  
  84.     TIM1->SR = (uint16_t)~TIM_IT_CC1;  
  85.     TIM1->CCR1 = Duty[count];  
  86.     count++;  
  87.     if(count==num)  
  88.     {  
  89.         count=0;  
  90.     }  
  91.   }  
  92. }  



在上一篇文章里粘贴了STM32产生SPWM的代码,我在编写这些代码时最大的问题就是如何得到占空比,就是代码中的数组 Duty[]。他的思想就是对正弦波采样,在采样点出用PWM的占空比来代替正弦波在该点的数值。最容易想到就是用定时器的ARR值乘以sin(2*pi*f*t),就可以得到对应的寄存器CCR值。但是CCR值不能为负,所以要把sin(2*pi*f*t)变为

A*sin(2*pi*f*t)+B的形式,取A=B=0.5;那么计算公式为ARR*(0.5*sin(2*pi*f*t)+0.5),上传一个C++写的exe文件,可以帮助产生Duty[]数组.

http://download.csdn.NET/detail/mjlsuccess/6205567

软件使用vs2010编写的可能在有些电脑上无法运行,如果你装有VS2010,我可以把原工程发给你

转载于http://blog.csdn.net/mjlsuccess/article/details/11019805

自己思考:10KZ为载波(锯齿波)的频率,最终输入给电机为100HZ正弦波,则载波比为100,也就是100个数据,同时ccr不能为负值,故进行抬升,原本应该为0-1800,进行抬升1800的0.5倍

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值