stm32f051产生可调占空比的pwm波

[复制链接]
7454|6
 楼主| wago2008 发表于 2013-5-21 09:44 | 显示全部楼层 |阅读模式
产生pwm波是比较容易的,调占空比也比较容易,老大提要求要用Tim1产生pwm波的同时还要产生中断,在中断中对pwm波的占空比进行改变,然后说很多单片机都可以实现,是小弟愚昧还是老大说的不对,请各位老师帮忙讨论下。
s_f_tan 发表于 2013-5-21 10:56 | 显示全部楼层
在T1 的update 中断时修改pwm值不就行了
cqmiao 发表于 2013-5-21 11:48 来自手机 | 显示全部楼层
貌似是这样
捡漏王子 发表于 2013-5-21 12:00 | 显示全部楼层
最近正在弄PWM
 楼主| wago2008 发表于 2013-5-22 10:07 | 显示全部楼层
原来是没有给tim1加中断优先级配置,但是随后问题又出来了,如果要产生互补的pwm波,不改变占空比前是正常互补的,在中断中改变了通道1的占空比后,互补通道没有输出了?


  1. /**********************************
  2. * [url=home.php?mod=space&uid=247401]@brief[/url] TIM_PWM_Config
  3. * @param None
  4. * @retval 配置pwm 参数
  5. **********************************/
  6. void TIM1_PWM_Config(void)
  7. {
  8. NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel=TIM1_CC_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  9. NVIC_Init(&NVIC_InitStructure);

  10. //预定标的值TIM1_Period = (time定时器频率 / pwm的频率) - 1
  11. TimerPeriod = (SystemCoreClock / 50000 ) - 1;
  12. //Channel1Pulse的值可以按照下面的公式进行计算:
  13. //ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100
  14. //DutyCycle/100为占空比的值

  15. //计算CCR1 跳转值 在占空比为50%时
  16. /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */
  17. Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10);
  18. /* TIM1 clock enable */
  19. RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE);

  20. //Time 定时基础设置
  21. TIM_TimeBaseStructure.TIM_Prescaler = 0;
  22. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//Time 定时设置为上升沿计算模式
  23. TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
  24. TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  25. TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  26. TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
  27. TIM_UpdateRequestConfig(TIM1,TIM_UpdateSource_Regular);
  28. //频道1的PWM 模式设置
  29. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;//TIM_OCMode_Toggle;
  30. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//选择输出比较状态
  31. TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//选择互补输出比较状态
  32. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//设置输出极性
  33. TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//设置互补输出极性
  34. TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  35. TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
  36. //装载比较寄存器,判断什么时候发生PWM翻转
  37. TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;//使能频道1配置
  38. TIM_OC1Init(TIM1, &TIM_OCInitStructure);
  39. //使能TIM1 CCR2寄存器上的 载入
  40. TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable);
  41. TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);

  42. //装载比较寄存器,判断什么时候发生PWM翻转
  43. TIM_OCInitStructure.TIM_Pulse = Channel2Pulse;//使能频道2配置
  44. TIM_OC2Init(TIM1, &TIM_OCInitStructure);
  45. //使能TIM1 CCR2寄存器上的 载入
  46. TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Disable);
  47. TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);
  48. //使能ARR寄存器 加载
  49. TIM_ARRPreloadConfig(TIM1,ENABLE);
  50. //死区设置
  51. TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; //运行模式下输出
  52. TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; //空闲模式下输出选择
  53. TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; //锁定设置,锁定级别1
  54. TIM_BDTRInitStructure.TIM_DeadTime = 0x0F; //死区时间
  55. TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; //刹车功能使能
  56. TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low; //刹车输入极性,即刹车控制引脚接GND时,PWM停止
  57. TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; //自动输出使能

  58. TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
  59. TIM_Cmd(TIM1, ENABLE);
  60. TIM_ITConfig(TIM1,TIM_IT_Update ,ENABLE);
  61. TIM_ITConfig(TIM1,TIM_IT_CC1,ENABLE);
  62. //TIM1 主输出使能
  63. TIM_CtrlPWMOutputs(TIM1, ENABLE);
  64. }

  65. 中断部分


  66. void TIM1_CC_IRQHandler(void)

  67. {
  68. TIM_OCInitTypeDef TIM_OCInitStructure;
  69. if (TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET)
  70. {
  71. TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
  72. if(Num_tim1==500000)
  73. {
  74. Num_tim1=0;
  75. if(PWM_num==5)
  76. {
  77. PWM_num=1;
  78. SETPwmPulse(PWM_num);
  79. //TIM_SetCompare1();
  80. }
  81. else
  82. {
  83. SETPwmPulse(PWM_num);
  84. PWM_num++;
  85. }
  86. }
  87. else
  88. {
  89. Num_tim1++;
  90. }
  91. }
  92. else if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
  93. {
  94. TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
  95. }
  96. }



 楼主| wago2008 发表于 2013-5-22 10:08 | 显示全部楼层
  1. /*******************************************************
  2.   * [url=home.php?mod=space&uid=95362]@func[/url] SETPwmPulse()
  3.   * @brief
  4.   * @param
  5.   * @

  6. ********************************************************/
  7. void SETPwmPulse(char num)
  8. {
  9.         switch(num)
  10.                 {
  11.                         case 1:
  12.                                 //50%
  13.                                 Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10);
  14.                                 Channel2Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10);
  15.                                 break;
  16.                         case 2:
  17.                                 //37.5%
  18.                                 Channel1Pulse = (uint16_t) (((uint32_t) 375 * (TimerPeriod - 1)) / 1000);
  19.                                 Channel2Pulse = (uint16_t) (((uint32_t) 375 * (TimerPeriod - 1)) / 1000);
  20.                                 break;
  21.                         case 3:
  22.                                 //25%
  23.                                 Channel1Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100);
  24.                                 Channel2Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100);
  25.                                 break;
  26.                         case 4:
  27.                                 //12.5%
  28.                                 Channel1Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000);
  29.                                 Channel2Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000);
  30.                                 break;
  31.                         default:
  32.                                 //77.5%
  33.                                 Channel1Pulse = (uint16_t) (((uint32_t) 775 * (TimerPeriod - 1)) / 1000);
  34.                                 Channel2Pulse = (uint16_t) (((uint32_t) 775 * (TimerPeriod - 1)) / 1000);
  35.         }
  36.        
  37.          TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;//使能频道1配置
  38.           TIM_OC1Init(TIM1, &TIM_OCInitStructure);
  39.           //TIM_OCInitStructure.TIM_Pulse = Channel2Pulse;//使能频道1配置
  40.           //TIM_OC2Init(TIM1, &TIM_OCInitStructure);
  41. }
我是老罗 发表于 2015-11-10 13:40 | 显示全部楼层
你好,我最近再做pwm输出脉冲,请问怎样设置占空比可调?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

81

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部