找回密码
 立即注册

QQ登录

只需一步,快速开始

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

stm32平衡车源码

[复制链接]
跳转到指定楼层
楼主
ID:402452 发表于 2018-11-25 20:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机源程序如下:
  1. #include "sys.h"

  2. /**************************************************************************************************

  3. 程序作者:CUIT 3+1 Taocr


  4. ***************************************************************************************************/


  5. extern u16 Gyro_y, Gyro_z;
  6. u8 time_20ms, timer_5_flag, timer_10_flag;

  7. u8 Turn_Off(float angle)
  8. {
  9.             u8 temp;
  10.                         if(angle<-40||angle>40)
  11.                         {                                                         //===倾角大于40度关闭电机
  12.       temp=1;                                            //===Flag_Stop置1关闭电机
  13.                         PWMA2 = 0;
  14.                         PWMB2 = 0;
  15.                         PWMA1 = 0;
  16.                         PWMB1 = 0;
  17.       }
  18.                         else
  19.       temp=0;
  20.       return temp;                       
  21. }

  22. int velocity(int encoder_left,int encoder_right)
  23. {  
  24.     static float Velocity,Encoder_Least,Encoder,Movement;
  25.           static float Encoder_Integral;
  26.           float kp=300,ki=1.5;
  27.           //=============遥控前进后退部分=======================//
  28. //                if(1==Flag_Qian)        Movement=90/Flag_sudu;                     //===如果前进标志位置1 位移为负
  29. //                else if(1==Flag_Hou)          Movement=-90/Flag_sudu;        //===如果后退标志位置1 位移为正
  30. //          else  
  31.         Movement=0;       
  32.    //=============速度PI控制器=======================//       
  33.                 Encoder_Least =(encoder_left+encoder_right)-0;  //===获取最新速度偏差==测量速度(左右编码器之和)-目标速度(此处为零)
  34.                 Encoder *= 0.8;                                         //===一阶低通滤波器      
  35.                 Encoder += Encoder_Least*0.2;                     //===一阶低通滤波器   
  36.                 Encoder_Integral +=Encoder;                                  //===积分出位移 积分时间:10ms
  37.                 Encoder_Integral=Encoder_Integral-Movement;                  //===接收遥控器数据,控制前进后退
  38.                 if(Encoder_Integral>10000)          Encoder_Integral=10000;         //===积分限幅
  39.                 if(Encoder_Integral<-10000)        Encoder_Integral=-10000;         //===积分限幅       
  40.                 Velocity=Encoder*kp+Encoder_Integral*ki; //===速度控制       
  41.                 if(Turn_Off(Pitch)==1)   Encoder_Integral=0;    //===电机关闭后清除积分
  42.           return Velocity;
  43. }

  44. int turn(int encoder_left,int encoder_right,float gyro)//转向控制
  45. {
  46.           static float Turn_Target,Turn,Encoder_temp,Turn_Convert=0.9,Turn_Count;
  47.           float Turn_Amplitude=88/2,Kp=42,Kd=0;     
  48.           //=============遥控左右旋转部分=======================//
  49. //          if(1==Flag_Left||1==Flag_Right)                      //这一部分主要是根据旋转前的速度调整速度的起始速度,增加小车的适应性
  50. //                {
  51. //                        if(++Turn_Count==1)
  52. //                        Encoder_temp=myabs(encoder_left+encoder_right);
  53. //                        Turn_Convert=50/Encoder_temp;
  54. //                        if(Turn_Convert<0.6)Turn_Convert=0.6;
  55. //                        if(Turn_Convert>3)Turn_Convert=3;
  56. //                }       
  57. //          else
  58. //                {
  59.                         Turn_Convert=0.9;
  60.                         Turn_Count=0;
  61.                         Encoder_temp=0;
  62. //                }                       
  63. //                if(1==Flag_Left)                   Turn_Target-=Turn_Convert;
  64. //                else if(1==Flag_Right)             Turn_Target+=Turn_Convert;
  65. //                else
  66.                         Turn_Target=0;
  67.        
  68.     if(Turn_Target>Turn_Amplitude)  Turn_Target=Turn_Amplitude;    //===转向速度限幅
  69.           if(Turn_Target<-Turn_Amplitude) Turn_Target=-Turn_Amplitude;
  70. //                if(Flag_Qian==1||Flag_Hou==1)  Kd=1;        
  71. //                else
  72.                         Kd=0;   //转向的时候取消陀螺仪的纠正 有点模糊PID的思想
  73.           //=============转向PD控制器=======================//
  74.                   Turn=-Turn_Target*Kp -gyro*Kd;                 //===结合Z轴陀螺仪进行PD控制
  75.           return Turn;
  76. }


  77. int main(void)
  78. {       
  79.         int Speed_R, Speed_L;       
  80.          int Motol_PWM, Moto2_PWM;
  81.          int flag = 0;
  82.          u8 Right_Flag = 0;

  83.         delay_init();                                                                     //延时初始化
  84.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
  85.         LED_Init();
  86.   LCD_init();//OLED初始化
  87.         LCD_clear();//显示屏清屏       
  88.         PWM_Init(7199,0);
  89.         Encoder_Init_TIM3();
  90.         Encoder_Init_TIM2();
  91.         uart_init(115200);                           //初始化串口1
  92.         IIC_Init();                     //模拟IIC初始化
  93.   MPU6050_initialize();           //=====MPU6050初始化       
  94.         DMP_Init();                     //初始化DMP
  95. //        NRF24L01_Init();            //初始化NRF24L01           
  96.          

  97. //while(NRF24L01_Check())        //检查NRF24L01是否在位.       
  98. //        {
  99. //                delay_ms(200);
  100. //                 delay_ms(200);
  101. //        }
  102. printf("NRF24L01Ready!");
  103.   Timer1_Init(29,7199);
  104.         while(1)
  105.         {               
  106.                 if(time_20ms == 10)
  107.                 {
  108.                         time_20ms = 0;
  109.                 printf("X轴倾角%f  Y轴倾角%d   转向角%d  \r\n",Pitch,Speed_R,Speed_L);//向上位机发送数据
  110.                         show_size8float4_2f(0,0,Roll);
  111.                         show_size8float4_2f(0,4,Right_Flag);
  112.                         time_20ms = 0;}
  113.                 if(timer_5_flag == 1)
  114.                 {
  115.                         timer_5_flag = 0;
  116.                         timer_10_flag = !timer_10_flag;
  117. //                        if(timer_10_flag == 0)
  118. //                        {
  119.                                 Read_DMP();
  120. //                        }
  121.                         Speed_R = Read_Encoder(2);
  122.                         Speed_L = Read_Encoder(3);
  123.                        
  124.                         Motol_PWM = 650*(Roll-5)+0.5*gyro[0]-velocity(Speed_L,Speed_R);//+turn(Speed_L,Speed_R,gyro[2]);
  125.                         Moto2_PWM = 200*(Pitch)+1.5*gyro[1];//-velocity(Speed_L,Speed_R);//-turn(Speed_L,Speed_R,gyro[2]);
  126.                         if(Roll>15&&flag<10000){Motol_PWM = 5000;flag++;}
  127.                         if(Roll<-15&&flag<10000){Motol_PWM = -5000;flag++;}
  128.                         if(Motol_PWM>=0)
  129.                         {
  130.                                 if(Right_Flag == 0)
  131.                                 Right_Flag = 1;
  132.                                 PWMA1 = Motol_PWM;
  133.                                 PWMB1 = Motol_PWM;
  134.                                 PWMA2 = 1;
  135.                                 PWMB2 = 1;
  136.                         }
  137.                         else
  138.                         {
  139.                                 if(Right_Flag == 0)
  140.                                 Right_Flag = 2;
  141.                                 PWMA2 = -Motol_PWM;
  142.                                 PWMB2 = -Motol_PWM;
  143.                                 PWMA1 = 1;
  144.                                 PWMB1 = 1;
  145.                         }
  146.                 }
  147.                 if(Turn_Off(Pitch)==1){}
  148.                                
  149.         }          
  150. }

  151. int TIM1_UP_IRQHandler(void)  
  152. {   
  153.         if(TIM1->SR&0X0001)//5ms定时中断
  154.         {   
  155.                   TIM1->SR&=~(1<<0);                                       //===清除定时器1中断标志位       
  156.                         time_20ms++;       
  157.                         timer_5_flag = 1;               
  158.         }
  159.         return 0;
  160. }
复制代码

所有资料51hei提供下载:
平衡车源码.rar (393.04 KB, 下载次数: 25)


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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