找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1900|回复: 2
打印 上一主题 下一主题
收起左侧

stm32 PID 脉宽调制程序

[复制链接]
跳转到指定楼层
楼主
ID:222531 发表于 2018-10-4 16:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
通过检测电流电压的大小,改变斩波电路的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)



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2018-10-6 22:17 | 只看该作者
补全原理图或者详细说明一下电路连接即可获得100+黑币
回复

使用道具 举报

板凳
ID:185611 发表于 2019-7-21 15:12 | 只看该作者
实际中这个程序工作正常吗
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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