标题: stm32 PID 脉宽调制程序 [打印本页]

作者: 812881784    时间: 2018-10-4 16:30
标题: stm32 PID 脉宽调制程序
通过检测电流电压的大小,改变斩波电路的PWM信号的脉宽,以实现稳压目的。


单片机源程序如下:
  1. #include "PID.h"

  2. u8 m=0;
  3. u16 adn=0;
  4. char b[20];

  5. typedef struct PID
  6. {
  7. int SetPoint;
  8. float Kp;
  9. float Ki;
  10. float Kd;
  11. int NowError;  //当前误差
  12. int LastError; //上次误差
  13. int PrevError; //上上次误差
  14. double OUT;
  15. }PID;

  16. static PID sPID;
  17. static PID *sptr = &sPID;

  18. void PID_Init(void)
  19. {
  20.         sptr->NowError = 0;
  21.   sptr->LastError = 0;
  22.   sptr->PrevError = 0;
  23.   sptr->Kp = 2;
  24.   sptr->Ki= 0;
  25.   sptr->Kd = 0;
  26.   sptr->SetPoint = 1241;   //1241/4096*3.3=1V
  27.         sptr->OUT = 0;
  28. }

  29. int        PIDCal(u16 actually)
  30. {
  31.         register int ep,ei,ed,zout;
  32.   sptr->NowError = sptr->SetPoint - actually;   //设定值-实际值
  33.         ep = sptr->NowError - sptr->LastError;
  34.         ei = sptr->NowError;
  35.         ed = sptr->NowError - 2*sptr->LastError + sptr->PrevError;
  36.   zout = sptr->Kp * ep + sptr->Ki * ei + sptr->Kd * ed;
  37.         sptr->OUT+=zout;
  38.   sptr->PrevError = sptr->LastError;
  39.   sptr->LastError = sptr->NowError;
  40.         if(sptr->OUT<360) sptr->OUT=360;
  41.         if(sptr->OUT>3240) sptr->OUT=3240;
  42.   return(sptr->OUT);
  43. }

  44. void TIM2_init()
  45. {
  46.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStruct;
  47.   NVIC_InitTypeDef  NVIC_InitStruct;
  48.        
  49.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
  50.        
  51.         TIM_TimeBaseInitStruct.TIM_Period = 4999;
  52.         TIM_TimeBaseInitStruct.TIM_Prescaler = 71;
  53.         TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
  54.         TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
  55.         TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
  56.        
  57.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  58.         NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
  59.         NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  60.         NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
  61.         NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
  62.         NVIC_Init(&NVIC_InitStruct);
  63.        
  64.         TIM_ClearFlag(TIM2,TIM_FLAG_Update);
  65.         TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
  66.        
  67.         TIM_Cmd(TIM2,ENABLE);
  68. }

  69. void TIM2_IRQHandler()
  70. {
  71.         u16 adv;
  72.         if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
  73.         {
  74.                 TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
  75.                 if(m<3)
  76.                 {
  77.                         adn+=AD_read();
  78.                         m++;
  79.                 }
  80.                 else
  81.                 {
  82.                         adv=adn/4;
  83.                         TIM3->CCR1 = PIDCal(adv);
  84.                         adn=0;m=0;
  85.                 }
  86.         }
  87. }
复制代码
  1. #include "PWM.h"

  2. void PWM_init(u16 a,u16 b)
  3. {
  4.         GPIO_InitTypeDef  GPIO_InitStruct;
  5.         TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
  6.         TIM_OCInitTypeDef  TIM_OCInitStructure;
  7.        
  8.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
  9.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
  10.        
  11.         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
  12.         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP ;
  13.         GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  14.         GPIO_Init(GPIOA,&GPIO_InitStruct);
  15.        
  16.         TIM_TimeBaseInitStruct.TIM_Period = a;
  17.         TIM_TimeBaseInitStruct.TIM_Prescaler = b;
  18.         TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
  19.         TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
  20.         TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
  21.        
  22.         TIM_OCInitStructure.TIM_Pulse = 1799;
  23.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
  24.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
  25.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
  26.         TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2

  27.         TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
  28.        
  29.         TIM_Cmd(TIM3,ENABLE);
  30. }
复制代码

所有资料51hei提供下载:
STM32PWM.rar (389.88 KB, 下载次数: 53)




作者: admin    时间: 2018-10-6 22:17
补全原理图或者详细说明一下电路连接即可获得100+黑币
作者: kinto    时间: 2019-7-21 15:12
实际中这个程序工作正常吗




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1