OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2259|回复: 15

小白对电机程序有点疑惑,求大神

[复制链接]

11

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2018-4-7
在线时间
29 小时
发表于 2018-5-14 11:00:40 | 显示全部楼层 |阅读模式
5金钱
[mw_shl_code=c,true]void PWM_init()
{         
        TMOD=0x02;  
        TH0=0xb8;     
        TL0=0xb8;  
        TR0=1;     
        CMOD=0x04;     
        CL=0x00;   
        CH=0x00;      
        CCAPM0=0x42;      
        CCAPM1=0x42;
        CCAP0H = 0xfc;
  CCAP1H = 0xfc;
        CR=1;      
}

//对电机调速        SP:0~13        CCAPxH:0xe6(2ms)~0xf3(1ms)

void Moto_SPEED(unsigned char Sp1,unsigned char Sp2)

{
        CCAP0H = 0xfc - Sp1;
        CCAP1H = 0xfc - Sp2;

}[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

为什么是500,按说应该是512才对的。应该是达不到512才用的500的上限(你用512也可以)。 这里的512从哪里来的。我的理解是GetData函数得到的数据范围就是0---512。 参与PID计算的变量范围就是PID输出数据的变化范围。也就是说Vspeed的范围也是0---512. 我猜测这是一个自动平衡车的代码吧。两个电机一个负责正转,一个负责反转。输出两路PWM. CCAP0H 和 CCAP1H分别调整两个PWM的输出。这就出现大于0去调整一个PWM输出,小于0去 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

571

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2922
金钱
2922
注册时间
2016-5-13
在线时间
185 小时
发表于 2018-5-14 11:00:41 | 显示全部楼层
为什么是500,按说应该是512才对的。应该是达不到512才用的500的上限(你用512也可以)。
这里的512从哪里来的。我的理解是GetData函数得到的数据范围就是0---512。
参与PID计算的变量范围就是PID输出数据的变化范围。也就是说Vspeed的范围也是0---512.
我猜测这是一个自动平衡车的代码吧。两个电机一个负责正转,一个负责反转。输出两路PWM.
CCAP0H 和 CCAP1H分别调整两个PWM的输出。这就出现大于0去调整一个PWM输出,小于0去调整另一个输出。
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

11

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2018-4-7
在线时间
29 小时
 楼主| 发表于 2018-5-14 11:01:08 | 显示全部楼层
这里不太明白这个PWM是怎么计算的,52的程序。。
回复

使用道具 举报

11

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2018-4-7
在线时间
29 小时
 楼主| 发表于 2018-5-14 11:02:14 | 显示全部楼层
        if(Vspeed>0)
         {
         if(Vspeed>500)                   //
                 Vspeed=500;
         Moto_SPEED(7,Vspeed/500*16+10);                           
        }
        if(Vspeed<0)
        {         
         Vspeed=fabs(Vspeed);                   //求绝对值
         Moto_SPEED(Vspeed/500*16+10,7);
        }
         DisplayBitData(Vspeed,2,1);                    //显示
          SendData('\n');                        
        delay(40);

        }
回复

使用道具 举报

11

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2018-4-7
在线时间
29 小时
 楼主| 发表于 2018-5-14 11:04:29 | 显示全部楼层
还有这里也不太明白为什么Vspeed要除以500再乘16,Vspeed是PID运算后返回的占空比。
回复

使用道具 举报

11

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2018-4-7
在线时间
29 小时
 楼主| 发表于 2018-5-14 13:50:25 | 显示全部楼层
求大佬看看
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165538
金钱
165538
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-5-15 01:50:40 | 显示全部楼层
帮顶
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165538
金钱
165538
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-5-15 01:50:40 | 显示全部楼层
帮顶
回复

使用道具 举报

20

主题

200

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
462
金钱
462
注册时间
2015-11-28
在线时间
89 小时
发表于 2018-5-15 11:36:09 | 显示全部楼层
可能是我菜,可能是程序不全。我也看不懂。帮顶。
回复

使用道具 举报

8

主题

571

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2922
金钱
2922
注册时间
2016-5-13
在线时间
185 小时
发表于 2018-5-15 18:30:30 | 显示全部楼层
本帖最后由 电脑小白 于 2018-5-15 18:32 编辑

我对PID还算比较熟悉,仔细分析了下。因为你没有把所有程序贴上来,所以以下都是猜测:(仅供参考)
Vspeed的范围应该是-100到100(猜测)。假设A=Vspeed/500*16+10  那么A的范围就是10±3.2=6.8---13.2
其实应该是达不到500的 那就是A的范围是7---13.
CCAP0H 和CCAP1H是分高低位的,这两个是相差16倍。
可以这样理解其实调节的是:CCAP=(0xfc - Sp2)*16+(0xfc - Sp1)
这样就可以得到结论:Vspeed=0到100变化的时候PWM变化比较大,Vspeed=0到-100变化的时候PWM变化比较小。
因为不知道PID具体调节的是什么,所以无法得出具体的调节效果。
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

11

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2018-4-7
在线时间
29 小时
 楼主| 发表于 2018-5-15 19:32:41 | 显示全部楼层

//****************************************
// 定义MPU6050内部地址  
//****************************************
#define SMPLRT_DIV  0x19 //陀螺仪采样率,典型值:0x07(125Hz)
#define CONFIG   0x1A //低通滤波频率,典型值:0x06(5Hz)
#define GYRO_CONFIG  0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)  
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H  0x41
#define TEMP_OUT_L  0x42
#define GYRO_XOUT_H  0x43
#define GYRO_XOUT_L  0x44
#define GYRO_YOUT_H  0x45
#define GYRO_YOUT_L  0x46
#define GYRO_ZOUT_H  0x47
#define GYRO_ZOUT_L  0x48
#define PWR_MGMT_1  0x6B                //电源管理,典型值:0x00(正常启用)
#define WHO_AM_I   0x75                 //IIC地址寄存器(默认数值0x68,只读)
#define SlaveAddress 0xD0               //IIC写入时的地址字节数据,+1为读取

//****************************************
/////////////////////////////////////////////////////////////////定义类型及变量  (全局变量)////////////////////////////////////////////////////////////////////////
//****************************************
uchar dis[4];                            //显示数字(-511至512)的字符数组
uchar ReceiveData[11];          //串口接收数据
//uchar SendVSpeed[4];          //串口发送占空比(输入)
bit flag=0;                     //定义一个位操作变量,赋值为0
//****************************************
//函数声明  
//****************************************
void  delay(unsigned int k);             //延时

//LCD相关函数
void  InitLcd();                         //初始化lcd1602  
void  lcd_printf(uchar *s,int temp_data);
void  WriteDataLCM(uchar dataW);         //LCD数据
void  WriteCommandLCM(uchar CMD,uchar Attribc);    //LCD指令
void  DisplayOneChar(uchar X,uchar Y,uchar DData);   //显示一个字符
void  DisplayListChar(uchar X,uchar Y,uchar *DData,L); //显示字符串

//MPU6050操作函数
void  InitMPU6050();             //初始化MPU6050  
void  Delay5us();
void  I2C_Start();
void  I2C_Stop();  
void  I2C_SendACK(bit ack);
bit   I2C_RecvACK();  
void  I2C_SendByte(uchar dat);
uchar I2C_RecvByte();
void  I2C_ReadPage();
void  I2C_WritePage();
void  display_ACCEL_x();
void  display_ACCEL_y();
void  display_ACCEL_z();  
uchar Single_ReadI2C(uchar REG_Address);      //读取I2C数据
void  Single_WriteI2C(uchar REG_Address,uchar REG_data); //向I2C写入数据

//串口相关函数
void UartInit();
void SendData(uchar dat);
void SendString(char *s);



//****************************************
////////////////////////////////////////////////////////////////////////////////延时 /////////////////////////////////////////////////////////
//****************************************
void delay(unsigned int k)
{  
    unsigned int i,j;  
    for(i=0;i<k;i++)
     {   for(j=0;j<121;j++);  
      }
}

//****************************************
//、、、、、、、、、、、、、、、、、////////////////////////////////////////整数转字符串  ////////////////////////////////////////////////////////////////
//****************************************
void lcd_printf(uchar *s,int temp_data)
{  
     if(temp_data<0)  
         {   temp_data=-temp_data;   
             *s='-';  
          }  
     else *s=' ';
//                 *++s =temp_data/10000+0x30;
//           temp_data=temp_data%100;     //取余运算                 
//                 *++s =temp_data/1000+0x30;
//           temp_data=temp_data%100;     //取余运算                         
     *++s =temp_data/100+0x30;
           temp_data=temp_data%100;     //取余运算  
     *++s =temp_data/10+0x30;  
     temp_data=temp_data%10;      //取余运算  
     *++s =temp_data+0x30;
}


/////////////////////////////////////////////////////////////////////////////////1602//////////////////////////////////////////////////////////////////////////////////////////////////////////

//**************************************
//延时5微秒(STC90C52RC@12M)
//不同的工作环境,需要调整此函数  
//当改用1T的MCU时,请调整此延时函数
//**************************************
void Delay5us()
{  
        _nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();
}

/////////////////////////////////////////////////////////////////////////////////I2C//////////////////////////////////////////////////////////////////////////////////////////////////////////

//**************************************
//I2C起始信号  
//**************************************
void I2C_Start()
{      
        SDA = 1;                    //拉高数据线     
        SCL = 1;                    //拉高时钟线     
        Delay5us();                 //延时      
        SDA = 0;                    //产生下降沿     
        Delay5us();                 //延时      
        SCL = 0;                    //拉低时钟线
}  
//**************************************
//I2C停止信号
//**************************************
void I2C_Stop()
{      
        SDA = 0;                    //拉低数据线     
        SCL = 1;                    //拉高时钟线     
        Delay5us();                 //延时      
        SDA = 1;                    //产生上升沿     
        Delay5us();                 //延时
}  
//**************************************
//I2C发送应答信号  
//入口参数:ack (0:ACK 1:NAK)  
//**************************************
void I2C_SendACK(bit ack)
{      
        SDA = ack;                  //写应答信号     
        SCL = 1;                    //拉高时钟线     
        Delay5us();                 //延时      
        SCL = 0;                    //拉低时钟线     
        Delay5us();                 //延时
}  
//**************************************
//I2C接收应答信号  
//**************************************
bit I2C_RecvACK()
{      
        SCL = 1;                    //拉高时钟线     
        Delay5us();                 //延时      
        CY = SDA;                   //读应答信号
    SCL = 0;                    //拉低时钟线     
        Delay5us();                 //延时     
        return CY;
}  
//**************************************
//向I2C总线发送一个字节数据  
//**************************************
void I2C_SendByte(uchar dat)
{      
        uchar i;      
        for (i=0; i<8; i++)         //8位计数器     
        {         
                dat <<= 1;              //移出数据的最高位         
                SDA = CY;               //送数据口        
                SCL = 1;                //拉高时钟线        
                Delay5us();             //延时         
                SCL = 0;                //拉低时钟线         
                Delay5us();             //延时     
        }      
        I2C_RecvACK();
}  
//**************************************
//从I2C总线接收一个字节数据  
//**************************************
uchar I2C_RecvByte()
{     
         uchar i;      
         uchar dat = 0;      
         SDA = 1;                    //使能内部上拉,准备读取数据,     
         for (i=0; i<8; i++)         //8位计数器     
         {         
                 dat <<= 1;         
                SCL = 1;                //拉高时钟线        
                Delay5us();             //延时         
                dat |= SDA;             //读数据         
                SCL = 0;                //拉低时钟线         
                Delay5us();             //延时   
         }      
        return dat;
}  
//**************************************
//向I2C设备写入一个字节数据  
//**************************************  
void Single_WriteI2C(uchar REG_Address,uchar REG_data)
{      
        I2C_Start();                  //起始信号      
        I2C_SendByte(SlaveAddress);   //发送设备地址+写信号     
        I2C_SendByte(REG_Address);    //内部寄存器地址,     
        I2C_SendByte(REG_data);       //内部寄存器数据,   
        I2C_Stop();                   //发送停止信号
}  
//**************************************
//从I2C设备读取一个字节数据  
//**************************************
uchar Single_ReadI2C(uchar REG_Address)
{  
        uchar REG_data;  
        I2C_Start();                   //起始信号  
        I2C_SendByte(SlaveAddress);    //发送设备地址+写信号  
        I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始  
        I2C_Start();                   //起始信号  
        I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号
        REG_data=I2C_RecvByte();       //读出寄存器数据  
        I2C_SendACK(1);                //接收应答信号  
        I2C_Stop();                    //停止信号  
        return REG_data;
}
////////////////////////////////////////////////////////////////////////////////I2C//////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////MPU6050//////////////////////////////////////////////////////////////////////////////////////////////////////////

//**************************************
//初始化MPU6050  
//**************************************
void InitMPU6050()
{  
        Single_WriteI2C(PWR_MGMT_1, 0x00); //解除休眠状态  
        Single_WriteI2C(SMPLRT_DIV, 0x07);  //采样速率
        Single_WriteI2C(CONFIG, 0x06);  
        Single_WriteI2C(GYRO_CONFIG, 0x18);  
        Single_WriteI2C(ACCEL_CONFIG, 0x01);
}  
//**************************************
//合成数据  
//**************************************
int GetData(uchar REG_Address)
{  
        char H,L;  
        H=Single_ReadI2C(REG_Address);  
        L=Single_ReadI2C(REG_Address+1);  
        return (H<<8)+L;   //合成数据      高八位和低八位
}

//**************************************
//在1602上显示数据  
//**************************************
void DisplayBitData(int value,uchar x,uchar y)
{  
       

        lcd_printf(dis, value);   //转换数据显示
  DisplayListChar(x,y,dis,4); //启始列,行,显示数组,显示长度
}

/////////////////////////////////////////////////////////////////////////////////MPU6050//////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////  PWM   //////////////////////////////////////////////////////////////////////////////////////////////////////////

//*********************************************************
//STC12C5A60S2内部PWM初始化程序
//*********************************************************
void PWM_init()
{         
        TMOD=0x02;  
        TH0=0xb8;     
        TL0=0xb8;  
        TR0=1;     
        CMOD=0x04;     
        CL=0x00;   
        CH=0x00;      
        CCAPM0=0x42;      
        CCAPM1=0x42;
        CCAP0H = 0xfc;
  CCAP1H = 0xfc;
        CR=1;      
}

//对电机调速        SP:0~13        CCAPxH:0xe6(2ms)~0xf3(1ms)

void Moto_SPEED(unsigned char Sp1,unsigned char Sp2)

{
        CCAP0H = 0xfc - Sp1;
        CCAP1H = 0xfc - Sp2;

}

/////////////////////////////////////////////////////////////////////////////////PWM//////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////PID//////////////////////////////////////////////////////////////////////////////////////////////////////////

//*********************************************************
//PID算法
//定义PID结构体
//*********************************************************
struct _pid
{      
        float SetAngle;            //定义给定值 本程序为角度
        float ActualAngle;         //定义实际测量角度值   
        float err;                 //偏差值  
        float err_last;            //上一时刻偏差值     
        float Kp,Ki,Kd;            //比例、积分、微分系数
        float vSpeed;              //计算占空比值     
        float integral;            //定义积分值
}pid;

//*********************************************************
//PID算法
//PID参数初始化
//*********************************************************
void PID_init()
{      
            
        pid.SetAngle=0.0;     
        pid.ActualAngle=0.0;   
        pid.err=0.0;      
        pid.err_last=0.0;     
  pid.vSpeed=0.0;     
  pid.integral=0.0;     
  pid.Kp=1.3;     
  pid.Ki=0.002222;     
  pid.Kd=0;  
}       


float PID_realize(float SAngle,float AAngle)
{             
        pid.SetAngle=SAngle;
  pid.ActualAngle=AAngle;       
        pid.err=pid.ActualAngle-pid.SetAngle;     
        pid.integral+=pid.err;                //a+=b相当于a=a+b 积分=偏差的累加     
        pid.vSpeed=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);      
  pid.err_last=pid.err;
  return pid.vSpeed;
}

/////////////////////////////////////////////////////////////////////////////////PID//////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////串口//////////////////////////////////////////////////////////////////////////////////////////////////////////


/********************************************************************************************                        
串口初始化函数                                                                                                        
/**********************************************************************************************/                     
void UartInit()                //9600bps@11.0592MHz                                                                             
{                                                                                                               
                PCON &= 0x7F;                 //?????    最高位清零                                                                                      
                SCON = 0x50;                 //         模式1,8-bit 使能接收                                                                        
                AUXR |= 0x04;                 //         独立波特率发生器时钟为Fosc,即1T                                                                           
                BRT = 0xDC;                   //         设定独立波特率发生器重装值                                                                                 
                AUXR |= 0x01;                 //         串口1选择独立波特率发生器为波特率发生器                                                                          
                AUXR |= 0x10;                 //         启动独立波特率发生器                                                                                    
                ES=1;            //         打开串口中断                                                                                                
                EA=1;            //         打开总中断                                                                                             
}                                                                                                                  
/*********************************************************************************************                     
UART串口发送函数                                                                                                      
/**********************************************************************************************/                     
void SendData(uchar UART_data)                                                                                       
{                                                                                                                     
    SBUF = UART_data;        //把UART_data数据发送出去                                                                                 
          while(TI == 0);                //表示等待发送结束                                                                                   
          TI = 0;                              //TI发送标志位置0,等待新的发送                                                                                    
}                                                                                                                    
/**********************************************************************************************/                     
/*********************************************************************************************                        
UART串口发送字符串函数
/**********************************************************************************************/
void SendString(char *str)
{
    while(*str != '\0')
                        {
                                SendData(*str);
                                *str=*str++;                       
                        }
                *str = 0;
}
void UART_1Interrupt(void) interrupt 4 using 1  //第一组寄存器中断
{
  int i;
        if(RI==1)  //接收标志位
    {
      Moto_SPEED(7,7);
                        RI=0;
                        pid.SetAngle=0.0;     
                        pid.ActualAngle=0.0;   
                        pid.err=0.0;      
                        pid.err_last=0.0;     
                        pid.vSpeed=0.0;     
                        pid.integral=0.0;
    }
}

/*********************************************************************************串口*********************************************************************************************************/
//*********************************************************
//主程序  
//*********************************************************
void main()
{  
        float Ax=0,temp1=0,temp2=0,temp3,Vspeed;
        int i;
        InitLcd();            //液晶初始化  
        InitMPU6050();        //初始化MPU6050
        UartInit();
        delay(150);
        PWM_init();
        PID_init();
        Led=1;
        DisplayBitData(0,2,0);                    //显示
        SendData(0x2c);                           //括号里为DData[ListLength]?
        DisplayBitData(0,2,1);                    //显示
  SendData('\n');
        Moto_SPEED(23,23);      //电机启动过程,油门开最大保持,再拉低保持
        delay(20000);
        Moto_SPEED(7,7);
        delay(20000);
        while(1)  
        {  
                 for(i=0;i<50;i++)
                  {
                                temp1=GetData(ACCEL_XOUT_H);
        temp3=temp1;
                               
                                if(temp1<3)
                                temp1=temp3;
                               
                                temp3=temp1;
        temp2=temp1+temp2;
                        }
                        temp2=temp2/50/64;
      Ax=temp2*0.2577-2.4497;          //计算x轴夹角( 反余弦函数用不对 暂时用加速度的值模拟拟合公式 )
                        DisplayBitData(Ax,2,0);                    //显示
                        SendData(0x2c);
                        DisplayBitData(30,2,0);                    //显示
                        SendData(0x2c);
      Vspeed=PID_realize(30,Ax);          //设定角度30度
                       
                        if(Vspeed>0)
                         {
                                 if(Vspeed>500)                   // 最高为500?500是从哪来的?
                                         Vspeed=500;
                                 Moto_SPEED(7,Vspeed/500*16+10);
                                 
                         }
                        if(Vspeed<0)
                        {         
                                 Vspeed=fabs(Vspeed);                   //求绝对值
                                 Moto_SPEED(Vspeed/500*16+10,7);
                        }
      DisplayBitData(Vspeed,2,1);                    //显示
                  SendData('\n');                       
                        delay(40);

        }
}[/mw_shl_code]
回复

使用道具 举报

11

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2018-4-7
在线时间
29 小时
 楼主| 发表于 2018-5-15 19:33:46 | 显示全部楼层
电脑小白 发表于 2018-5-15 18:30
我对PID还算比较熟悉,仔细分析了下。因为你没有把所有程序贴上来,所以以下都是猜测:(仅供参考)
Vspee ...

大神 下面基本是全部程序,字数限制删除了一些没啥用的,您再帮忙看一下下 万分感谢!
回复

使用道具 举报

11

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2018-4-7
在线时间
29 小时
 楼主| 发表于 2018-5-16 10:19:05 | 显示全部楼层
之前是两个电机的代码,一个电机的时候是下面这样最后。
[mw_shl_code=c,true]while(1)  
        {  
                 temp=GetData(ACCEL_XOUT_H);
                 Ax=temp/258/64*100*0.6791-3.1116;          //计算x轴夹角( 反余弦函数用不对 暂时用加速度的值模拟拟合公式 y=0.6791x-3.1116)

                 DisplayBitData(Ax,2,1);                    //显示
               
           delay(40);
     Vspeed=PID_realize(30,Ax);
                 if(Vspeed>999)                   //
                         Vspeed=999;
                 if(Vspeed<0)
                         Vspeed=0;
                 Moto_SPEED(Vspeed/1000*16+7);
                 delay(40);

        }[/mw_shl_code]
回复

使用道具 举报

8

主题

571

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2922
金钱
2922
注册时间
2016-5-13
在线时间
185 小时
发表于 2018-5-16 15:57:35 | 显示全部楼层
最后再说为什么是16.
我认为这个16是凑出来的。
假设A=Vspeed/500*16+10  那么A的范围就是10±3.2=6.8---13.2
其实应该是达不到500的,那就是A的范围是7---13.
为了满足A的范围是7--13. A=Vspeed/500*X+Y 。 令Y=10,算出来的X就=16了。也可以令Y=7.那么X就=13了。
虽然不明白你们在说什么,但感觉很厉害的样子。
回复

使用道具 举报

11

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2018-4-7
在线时间
29 小时
 楼主| 发表于 2018-5-16 20:23:12 | 显示全部楼层
电脑小白 发表于 2018-5-16 15:46
为什么是500,按说应该是512才对的。应该是达不到512才用的500的上限(你用512也可以)。
这里的512从哪里 ...

是一个平衡装置。两个是无刷电机,谢谢大佬。
回复

使用道具 举报

11

主题

49

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2018-4-7
在线时间
29 小时
 楼主| 发表于 2018-5-17 09:00:35 | 显示全部楼层
电脑小白 发表于 2018-5-16 15:57
最后再说为什么是16.
我认为这个16是凑出来的。
假设A=Vspeed/500*16+10  那么A的范围就是10±3.2=6.8--- ...

大神 我还想请教一下。现在我把这个改成STM32的程序了。转速最低1000,最高2000,但是我不知道PID返回值需要通过什么样的逻辑公式来转化成一个合适的占空比。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-15 15:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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