找回密码
 立即注册

QQ登录

只需一步,快速开始

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

stm32f407进行直流电机pid调速源程序

  [复制链接]
跳转到指定楼层
#
stm32f407驱动电机进行pid调速。

单片机源程序如下:
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "lcd.h"
  6. #include "adc.h"
  7. #include "key.h"
  8. #include "encoder.h"
  9. #include "moter.h"
  10. #include "pwm.h"
  11. #include "tim.h"

  12. #define BYTE0(dwTemp)       ( *( (char *)(&dwTemp)          ) )
  13. #define BYTE1(dwTemp)       ( *( (char *)(&dwTemp) + 1) )
  14. #define BYTE2(dwTemp)       ( *( (char *)(&dwTemp) + 2) )
  15. #define BYTE3(dwTemp)       ( *( (char *)(&dwTemp) + 3) )
  16.    
  17. u8 testdatatosend[50];
  18. void Test_Send_User(uint16_t data1, uint16_t data2, uint16_t data3,uint16_t data4,uint16_t data5,uint16_t data6,uint16_t data7,uint16_t data8,uint16_t data9,uint16_t data10)        ;
  19. void UART1_Send_Str(unsigned char *s);
  20. u8 temp[50];
  21. char i=0;
  22. int now;
  23. int aim=50000;
  24. int error,last_error;
  25. int error_sum;
  26. int pwm=200;
  27. float KP=3.0
  28.        ,KI=0.32 //0.34
  29.         ,KD=50.0; //55.0
  30.   
  31. int main(void)
  32. {

  33.         u8 key;
  34.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
  35.         delay_init(168);    //初始化延时函数
  36.         uart_init(115200);        //初始化串口波特率为115200
  37.         LED_Init();                                        //初始化LED
  38.          LCD_Init();                                        //LCD初始化KEY_Init();                                 //按键初始化
  39.     TIM3_ENC_Init();
  40.     KEY_Init();
  41.     MOTER_Init();
  42.     LED_Init();
  43.     PWM_TIM4_Init(1000-1,84-1); //1000HZ
  44.     setPWM(pwm);
  45.     POINT_COLOR=RED;
  46.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        
  47.         LCD_ShowString(30,70,200,16,16,"---PID---");        
  48.         LCD_ShowString(30,90,200,16,16,"MOTER:");
  49.         LCD_ShowString(30,110,200,16,16,"2014/5/6");         
  50.     TIM6_Int_Init(499,1679);
  51.                
  52.         while(1)
  53.         {
  54.         key=KEY_Scan(0);        
  55.         switch(key){
  56.             case 1: aim+=500;break;
  57.             case 2: aim-=500;break;
  58.         }
  59.         sprintf((char*)temp,"pwm:=%d    ",pwm);
  60.                 LCD_ShowString(30,130,200,16,16,temp);
  61.         sprintf((char*)temp,"encoder:=%d    ",read_TIM3_position());
  62.                 LCD_ShowString(30,150,200,16,16,temp);
  63.         sprintf((char*)temp,"aim:=%d    ",aim);
  64.                 LCD_ShowString(30,170,200,16,16,temp);
  65.         sprintf((char*)temp,"error:=%d    ",error);
  66.                 LCD_ShowString(30,190,200,16,16,temp);
  67.         Test_Send_User(now,aim,0,0,0,0,0,0,0,0);
  68.       
  69.                
  70.             
  71.                
  72.         }
  73. }
  74. void TIM6_DAC_IRQHandler(void)  //100HZ 中断函数
  75. {

  76.     if(TIM_GetITStatus(TIM6,TIM_IT_Update)==SET)
  77.     {
  78.         if(++i==5)
  79.         {
  80.             i=0;
  81.             GPIO_ToggleBits(GPIOF,GPIO_Pin_9 );    //闪灯代表正在工作
  82.         }
  83.       
  84.         now=read_TIM3_position();   //get现在位置
  85.         error=now-aim;               //获取误差
  86.         if(error>=0)                 //如果error大于0 正转动
  87.            { MOTER_CW();
  88.                LCD_ShowString(30,90,200,16,16,"++++++++++++++++");  //表示正转动
  89.            }
  90.         else
  91.            { MOTER_CCW();
  92.                LCD_ShowString(30,90,200,16,16,"----------------");//表示反转动
  93.            }            //如果error大于0 正转动
  94.         error_sum+=error;      //误差累计和
  95.        if(error_sum>1000)error_sum=1000;  //积分限幅
  96.        if(error_sum<-1000)error_sum=-1000;
  97.         pwm=error*KP+error_sum*KI+(error-last_error)*KD;  //pwm= 当前误差*比例项 + 误差累计*积分项 + 两次误差之差*微分项
  98.         last_error=error;           //误差冲洗赋值
  99.         setPWM(pwm);         //设定PWM
  100.         
  101.             
  102.     }

  103.         
  104.         
  105.   TIM_ClearITPendingBit(TIM6,TIM_IT_Update);

  106. }


  107. void Test_Send_User(uint16_t data1, uint16_t data2, uint16_t data3,uint16_t data4,uint16_t data5,uint16_t data6,uint16_t data7,uint16_t data8,uint16_t data9,uint16_t data10)        
  108. {
  109.         u8 _cnt=0;
  110.     u8 i;
  111.     u8 sum = 0;
  112.         
  113.         testdatatosend[_cnt++]=0xAA;
  114.         testdatatosend[_cnt++]=0x05;
  115.         testdatatosend[_cnt++]=0xAF;
  116.         testdatatosend[_cnt++]=0xF1;
  117.         testdatatosend[_cnt++]=0;

  118.         testdatatosend[_cnt++]=BYTE1(data1);
  119.         testdatatosend[_cnt++]=BYTE0(data1);
  120.         
  121.         testdatatosend[_cnt++]=BYTE1(data2);
  122.         testdatatosend[_cnt++]=BYTE0(data2);
  123.         
  124.         testdatatosend[_cnt++]=BYTE1(data3);
  125.         testdatatosend[_cnt++]=BYTE0(data3);
  126.         
  127.         testdatatosend[_cnt++]=BYTE1(data4);
  128.         testdatatosend[_cnt++]=BYTE0(data4);
  129.         
  130.         testdatatosend[_cnt++]=BYTE1(data5);
  131.         testdatatosend[_cnt++]=BYTE0(data5);
  132.         
  133.         testdatatosend[_cnt++]=BYTE1(data6);
  134.         testdatatosend[_cnt++]=BYTE0(data6);
  135.         
  136.         testdatatosend[_cnt++]=BYTE1(data7);
  137.         testdatatosend[_cnt++]=BYTE0(data7);
  138.         
  139.         testdatatosend[_cnt++]=BYTE1(data8);
  140.         testdatatosend[_cnt++]=BYTE0(data8);
  141.         
  142.         testdatatosend[_cnt++]=BYTE1(data9);
  143.         testdatatosend[_cnt++]=BYTE0(data9);
  144.         
  145.         testdatatosend[_cnt++]=BYTE1(data10);
  146.         testdatatosend[_cnt++]=BYTE0(data10);
  147.         
  148.         

  149.         testdatatosend[4] = _cnt-5;
  150.         
  151.                
  152.         for( i=0;i<_cnt;i++)
  153.                 sum += testdatatosend[i];
  154.         
  155.         testdatatosend[_cnt++]=sum;        

  156.         UART1_Send_Str(testdatatosend);
  157. }

  158. void UART1_Send_Str(unsigned char *s)//发送字符串 函数   应用指针 方法
  159. {
  160.         unsigned char i=0;  //定义一个局部变量  用来 发送字符串 ++运算

  161.         while(s[i]!=' ')  // 每个字符串结尾 都是以   结尾的
  162.         {
  163.                 USART_SendData(USART1,s[i]);        //通过库函数  发送数据
  164.                 while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);  
  165.                 //等待发送完成。   检测 USART_FLAG_TC 是否置1;    //见库函数 P359 介绍

  166.                 i++;                 //i++一次
  167.         }

  168. }
复制代码

所有资料51hei提供下载:
PID教程视频对应代码.7z (343.65 KB, 下载次数: 123)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:1089424 发表于 2023-7-27 21:31 | 只看该作者
我的好哥哥,视频在哪里呀
回复

使用道具 举报

楼主
ID:1080782 发表于 2023-7-13 19:22 | 只看该作者
视频在哪里
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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