kanhailiu 发表于 2020-6-17 20:54

我从网上下的风力摆系统的代码,然后改了改,下到开发板上电机不转,芯片型号一样。

<p>而且电机部分单独拿出来可以转,连线也没问题,大佬能给看看代码吗?</p>

<pre>
<code>#include "stm32f10x.h"
#include "mpu_usart.h"
#include "motor_pwm.h"
#include "motor_control.h"
#include "delay.h"
#include "timer.h"
#include "usart.h"
#include "oled.h"
#include "indkey.h"
#include "mpu6050.h"
#include "inv_mpu.h"

extern M1TypeDef M1;
extern M2TypeDef M2;

extern float pitch,roll,yaw;                 //欧拉角

extern float set_y;
extern float set_x;

extern int CurMode;
extern int Q1_Start;
extern int Q2_Start;
extern int Q3_Start;
extern int Q4_Start;
extern int Q5_Start;
extern int Q6_Start;
extern int LEDcnt;
void Init(void)
{
       NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
       PWM_Init();
       
   Key_IO_Init();

               
        delay_init();                 //延时函数初始化          
        uart_init(500000);               //串口初始化为9600
       
        MPU_Init();                                        //初始化MPU6050
       
        while(mpu_dmp_init());
       OLED_Init();

//       TIM1_Config(999,8);//0.125ms
       TIM2_Config(10000-1,71);//10ms
}
int main(void)
{              
Init();
       
        while (1)
        {
//   OLED_ShowString(0,0,"A");
                if(LEDcnt==20)
                        {               
                                                                                LEDcnt=0;                                       
                                                                                KeyScan();
                        }
                if(LEDcnt&gt;=20)
                                LEDcnt=0;
                get_date();
                if(1)mpu6050_send_data(pitch,roll,M1.PWM,M2.PWM,set_x,set_y);//用自定义帧发送加速度和陀螺仪原始数据       

               
                       

        }       
       
}

/*-------------------------------------------------------------------------------------------
                                                 风力摆控制系统(2015-8-12)

硬件平台:
                        主控器: STM32F103VET6 64K RAM 512K ROM
                        驱动器: LMD18200T
                  电源:   DC +12V

软件平台:
                        开发环境: RealView MDK-ARM uVision4.10
                        C编译器 : ARMCC
                        ASM编译器:ARMASM
                        连接器:   ARMLINK
                        底层驱动: 各个外设驱动程序      

时间: 2015年8月12日      

作者: BoX
-------------------------------------------------------------------------------------------*/
#include "motor_control.h"
#include "motor_pwm.h"
#include "motor_pid.h"
#include "stdlib.h"
#include "stdio.h"
#include "delay.h"
#include "math.h"
#include "motor_pwm.h"
#include "mpu6050.h"
#include "mpu_usart.h"
#include "sys.h"

/*------------------------------------------
//                                 全局变量                               
//------------------------------------------*/
M1TypeDef M1;
M2TypeDef M2;


extern float pitch,roll,yaw;                 //欧拉角
float set_x = 0.0;
float set_y = 0.0;


extern PIDTypdDef M1PID;
extern PIDTypdDef M2PID;

//extern MPU6050_AxisTypeDef    Axis;//MPU6050数据结构体
//extern AHRS_EulerAngleTypeDef EulerAngle;
float R = 30.0;                                        //半径设置(cm)
float angle = 120.0;                                       //摆动角度设置(°)
uint8_t RoundDir=0;                                //正反转控制画圆

///*------------------------------------------
// 函数功能:控制器软件复位
// 函数说明:强制复位                       
//------------------------------------------
//void MCU_Reset(void)
//{
//        __set_FAULTMASK(1);   // 关闭所有中断
//         NVIC_SystemReset();   // 复位
//}
/*------------------------------------------
函数功能:初始化M1结构体参数
函数说明:                       
------------------------------------------*/
void M1TypeDef_Init(void)
{
        M1.CurPos    = 0.0;
        M1.PrevPos   = 0.0;
        M1.CurAcc    = 0.0;
        M1.PrevSpeed = 0.0;
        M1.Offset    = 0.1;   //允许偏差量
        M1.CurSpeed= 0.0;//当前速度矢量
        M1.PWM = 0;                 //PWM
}
/*------------------------------------------
函数功能:初始化M2结构体参数
函数说明:                       
------------------------------------------*/
void M2TypeDef_Init(void)
{
        M2.CurPos    = 0.0;
        M2.PrevPos   = 0.0;
        M2.CurAcc    = 0.0;
        M2.PrevSpeed = 0.0;
        M2.Offset    = 0.1;   //允许偏差量
        M2.CurSpeed= 0.0;//当前速度矢量
        M2.PWM = 0;                 //PWM               
}
/*------------------------------------------
函数功能:
------------------------------------------*/
//void Mode_0(void)
//{
//       
//               
//}
///*------------------------------------------
// 函数功能:第1问PID计算
// 函数说明:
//------------------------------------------*/
void Mode_1(void)
{
        const float priod = 760.0;//单摆周期(毫秒)
        static uint32_t MoveTimeCnt = 0;

        float A = 0.0;
        float Normalization = 0.0;
        float Omega = 0.0;
                               
        MoveTimeCnt += 5;                                                       //每5ms运算1次
        Normalization = (float)MoveTimeCnt / priod;       //对单摆周期归一化
        Omega = 2.0*3.14159*Normalization;                       //对2π进行归一化处理
        A = atan((R/80.0f))*57.2958f;                               //根据摆幅求出角度A,88为摆杆距离地面长度cm
        set_y = A*sin(Omega);                        //计算出当前摆角        
               
        PID_M1_SetPoint(0);        //X方向PID跟踪目标值sin
        PID_M1_SetKp(13);       
        PID_M1_SetKi(0.2);       
        PID_M1_SetKd(4100);

        PID_M2_SetPoint(set_y);        //Y方向PID跟踪目标值cos
        PID_M2_SetKp(17);   
        PID_M2_SetKi(0.4);               
        PID_M2_SetKd(4300);        
       
        M1.PWM = PID_M1_PosLocCalc(M1.CurPos)         ;        //roll
        M2.PWM = PID_M2_PosLocCalc(M2.CurPos)         ; //pitch
       
        if(M1.PWM &gt; POWER_MAX)M1.PWM =POWER_MAX;
        if(M1.PWM &lt; -POWER_MAX) M1.PWM = -POWER_MAX;       
       
        if(M2.PWM &gt; POWER_MAX)M2.PWM = POWER_MAX;
        if(M2.PWM &lt; -POWER_MAX) M2.PWM = -POWER_MAX;               
       
        MotorMove(M1.PWM,M2.PWM);
}
/*------------------------------------------
函数功能:第2问PID计算
函数说明:
------------------------------------------*/
void Mode_2(void)
{
        const float priod = 760.0;//单摆周期(毫秒)
        static uint32_t MoveTimeCnt = 0;

        float A = 0.0;
        float Normalization = 0.0;
        float Omega = 0.0;
                               
        MoveTimeCnt += 5;                                                       //每5ms运算1次
        Normalization = (float)MoveTimeCnt / priod;       //对单摆周期归一化
        Omega = 2.0*3.14159*Normalization;                       //对2π进行归一化处理
        A = atan((R/80.0f))*57.2958f;                               //根据摆幅求出角度A,88为摆杆距离地面长度cm
        set_y = A*sin(Omega);                        //计算出当前摆角        
               
        PID_M1_SetPoint(0);        //X方向PID跟踪目标值sin
        PID_M1_SetKp(13);       
        PID_M1_SetKi(0.2);       
        PID_M1_SetKd(4100);

        PID_M2_SetPoint(set_y);        //Y方向PID跟踪目标值cos
        PID_M2_SetKp(17);   
        PID_M2_SetKi(0.4);               
        PID_M2_SetKd(4300);        
       
        M1.PWM = PID_M1_PosLocCalc(M1.CurPos)         ;        //roll
        M2.PWM = PID_M2_PosLocCalc(M2.CurPos)         ; //pitch
       
        if(M1.PWM &gt; POWER_MAX)M1.PWM =POWER_MAX;
        if(M1.PWM &lt; -POWER_MAX) M1.PWM = -POWER_MAX;       
       
        if(M2.PWM &gt; POWER_MAX)M2.PWM = POWER_MAX;
        if(M2.PWM &lt; -POWER_MAX) M2.PWM = -POWER_MAX;               
       
        MotorMove(M1.PWM,M2.PWM);
}
/*------------------------------------------
函数功能:第3问PID计算
函数说明:
------------------------------------------*/
void Mode_3(void)
{
        const float priod = 760.0;//单摆周期(毫秒)
                   //相位补偿 0, 10   20   30   40   50   60   70   80   90   100110120130140150160170 180
        const float Phase= {0,-0.1,-0.0,0.0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.05,0.05,0.05,0.07,0};
        static uint32_t MoveTimeCnt = 0;
       
        float Ax = 0.0;
        float Ay = 0.0;
        float A = 0.0;
        uint32_t pOffset = 0;
        float Normalization = 0.0;
        float Omega = 0.0;
       
        pOffset = (uint32_t)(angle/10.0f);                       //相位补偿数组下标
        MoveTimeCnt += 5;                                                       //每5ms运算1次
        Normalization = (float)MoveTimeCnt / priod;       //对单摆周期归一化
        Omega = 2.0*3.14159*Normalization;                       //对2π进行归一化处理
        A = atan((R/83.0f))*57.2958f;//根据摆幅求出角度A,88为摆杆离地高度                                                                  
        Ax = A*cos(angle*0.017453);       //计算出X方向摆幅分量0.017453为弧度转换
        Ay = A*sin(angle*0.017453);       //计算出Y方向摆幅分量
        set_x = Ax*sin(Omega);                //计算出X方向当前摆角
        set_y = Ay*sin(Omega+Phase); //计算出Y方向当前摆角
               
        PID_M1_SetPoint(set_x);        //X方向PID跟踪目标值sin
        PID_M1_SetKp(13);       
        PID_M1_SetKi(0.2);       
        PID_M1_SetKd(4100);

        PID_M2_SetPoint(set_y);        //Y方向PID跟踪目标值cos
        PID_M2_SetKp(17);   
        PID_M2_SetKi(0.4);               
        PID_M2_SetKd(4300);        
       
        M1.PWM = PID_M1_PosLocCalc(M1.CurPos);        //Pitch
        M2.PWM = PID_M2_PosLocCalc(M2.CurPos);//Roll
       
        if(M1.PWM &gt; POWER_MAX)M1.PWM =POWER_MAX;
        if(M1.PWM &lt; -POWER_MAX) M1.PWM = -POWER_MAX;
                              
        if(M2.PWM &gt; POWER_MAX)M2.PWM =POWER_MAX;
        if(M2.PWM &lt; -POWER_MAX) M2.PWM = -POWER_MAX;               

        MotorMove(M1.PWM,M2.PWM);       
}
/*------------------------------------------
函数功能:第4问PID计算
函数说明:
------------------------------------------*/
void Mode_4(void)
{       
        if(abs(M1.CurPos)&lt;45.0 &amp;&amp; abs(M2.CurPos)&lt;45.0)        //小于45度才进行制动
        {               
                PID_M1_SetPoint(0);          //X方向PID定位目标值0
                PID_M1_SetKp(0);                
                PID_M1_SetKi(0);   
                PID_M1_SetKd(50000);

                PID_M2_SetPoint(0);          //Y方向PID定位目标值0
                PID_M2_SetKp(0);               
                PID_M2_SetKi(0);   
                PID_M2_SetKd(50000);
                       
                M1.PWM = PID_M1_PosLocCalc(M1.CurPos); //Pitch
                M2.PWM = PID_M2_PosLocCalc(M2.CurPos); //Roll
               
                if(M1.PWM &gt; POWER_MAX)M1.PWM =POWER_MAX;
                if(M1.PWM &lt; -POWER_MAX) M1.PWM = -POWER_MAX;

                if(M2.PWM &gt; POWER_MAX)M2.PWM =POWER_MAX;
                if(M2.PWM &lt; -POWER_MAX) M2.PWM = -POWER_MAX;
        }
        else       
        {
               M1.PWM = 0;
                M2.PWM = 0;       
        }
       
        MotorMove(M1.PWM,M2.PWM);
}
/*------------------------------------------
函数功能:第5问PID计算
函数说明:
------------------------------------------*/
void Mode_5(void)
{
        const float priod = 760.0;//单摆周期(毫秒)
        static uint32_t MoveTimeCnt = 0;
        float A = 0.0;
        float phase = 0.0;
        float Normalization = 0.0;
        float Omega = 0.0;
       
        MoveTimeCnt += 5;                                                       //每5ms运算1次
        Normalization = (float)MoveTimeCnt / priod;       //对单摆周期归一化
        Omega = 2.0*3.14159*Normalization;                       //对2π进行归一化处理                               
        A = atan((R/80.0f))*57.2958f;    //根据半径求出对应的振幅A
       
        if(RoundDir == 0)                 
                phase = 3.141592/2.0;               //逆时针旋转相位差90°
        else if(RoundDir == 1)
                phase = (3.0*3.141592)/2.0;       //顺时针旋转相位差270°
       
        set_x = A*sin(Omega);                       //计算出X方向当前摆角
        set_y = A*sin(Omega+phase);        //计算出Y方向当前摆角
       
        PID_M1_SetPoint(set_x);        //X方向PID跟踪目标值sin
        PID_M1_SetKp(13);       
        PID_M1_SetKi(0.2);       
        PID_M1_SetKd(4100);

        PID_M2_SetPoint(set_y);        //Y方向PID跟踪目标值cos
        PID_M2_SetKp(12);   
        PID_M2_SetKi(0);               
        PID_M2_SetKd(10000);        
       
        M1.PWM = PID_M1_PosLocCalc(M1.CurPos); //Pitch
        M2.PWM = PID_M2_PosLocCalc(M2.CurPos); //Roll
       
        if(M1.PWM &gt; POWER_MAX)M1.PWM =POWER_MAX;
        if(M1.PWM &lt; -POWER_MAX) M1.PWM = -POWER_MAX;
                              
        if(M2.PWM &gt; POWER_MAX)M2.PWM =POWER_MAX;
        if(M2.PWM &lt; -POWER_MAX) M2.PWM = -POWER_MAX;               

        MotorMove(M1.PWM,M2.PWM);
       
}
///*------------------------------------------
// 函数功能:第6问PID计算
// 函数说明:
//------------------------------------------*/
void Mode_6(void)
{
        const float priod = 760.0;//单摆周期(毫秒)
//        const float priody= 380.0;
        static uint32_t MoveTimeCnt = 0;
       
        float A = 0.0;
        float B = 0.0;
        //float phase = 0.0;
        float Normalization = 0.0;
//        float Normalizationy = 0.0;
        float Omega = 0.0;
//        float Omegay = 0.0;

        MoveTimeCnt += 5;                                                       //每5ms运算1次
        Normalization = (float)MoveTimeCnt / priod;       //对单摆周期归一化
//        Normalizationy = (float)MoveTimeCnt / priody;       //对单摆周期归一化
        Omega = 2.0*3.14159*Normalization;                       //对2π进行归一化处理       
//        Omegay = 2.0*3.14159*Normalizationy;                       //对2π进行归一化处理       
        A = atan((R/80.0f))*57.2958f;    //根据半径求出对应的振幅A          
B = A * 2.5;
        set_x = A*sin(Omega);                       //计算出X方向当前摆角
        set_y = B*sin(Omega/2);        //计算出Y方向当前摆角
       
               
        PID_M1_SetPoint(set_x);        //X方向PID跟踪目标值sin
        PID_M1_SetKp(13);       
        PID_M1_SetKi(0.2);       
        PID_M1_SetKd(4100);

        PID_M2_SetPoint(set_y);        //Y方向PID跟踪目标值cos
        PID_M2_SetKp(40);   
        PID_M2_SetKi(0);               
        PID_M2_SetKd(5000);        
               
       
        M1.PWM = PID_M1_PosLocCalc(M1.CurPos); //Pitch
        M2.PWM = PID_M2_PosLocCalc(M2.CurPos); //Roll
       
        if(M1.PWM &gt; POWER_MAX)M1.PWM =POWER_MAX;
        if(M1.PWM &lt; -POWER_MAX) M1.PWM = -POWER_MAX;
                              
        if(M2.PWM &gt; POWER_MAX)M2.PWM =POWER_MAX;
        if(M2.PWM &lt; -POWER_MAX) M2.PWM = -POWER_MAX;               

        MotorMove(M1.PWM,M2.PWM);
       

}
/*------------------------------------------
函数功能:电机底层驱动函数x   pitch23
函数说明:               yroll   41
------------------------------------------*/
void MotorMove(int pwm1,int pwm2)
{
        if(pwm1 &gt; 0)
        {   
               PWM_M3_Backward(pwm1);

                PWM_M2_Forward(pwm1);

        }
        else if(pwm1 &lt; 0)
        {
               PWM_M2_Backward(abs(pwm1));

                PWM_M3_Forward(abs(pwm1));       

        }


        if(pwm2 &gt; 0)
        {
               PWM_M1_Backward(pwm2);

                PWM_M4_Forward(pwm2);


        }
        else if(pwm2 &lt; 0)
        {
               PWM_M4_Backward(abs(pwm2));

                PWM_M1_Forward(abs(pwm2));
               
        }
       


}

/*-------------------------------------------------------------------------------------------
                                                 风力摆控制系统(2015-8-12)

硬件平台:
                        主控器: STM32F103VET6 64K RAM 512K ROM
                        驱动器: LMD18200T
                  电源:   DC +12V

软件平台:
                        开发环境: RealView MDK-ARM uVision4.10
                        C编译器 : ARMCC
                        ASM编译器:ARMASM
                        连接器:   ARMLINK
                        底层驱动: 各个外设驱动程序      

时间: 2015年8月12日      

作者: BoX
-------------------------------------------------------------------------------------------*/
#include "motor_control.h"
#include "motor_pwm.h"
#include "motor_pid.h"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
/*------------------------------------------
                                声明变量                               
------------------------------------------*/
extern M1TypeDefM1;
extern M2TypeDefM2;

PIDTypdDef M1PID;
PIDTypdDef M2PID;
/*------------------------------------------
函数功能:初始化M1PID结构体参数
函数说明:                       
------------------------------------------*/
void PID_M1_Init(void)
{
    M1PID.LastError= 0;                        //Error[-1]
    M1PID.PrevError= 0;                        //Error[-2]
        M1PID.Proportion = 0;                        //比例常数 Proportional Const
    M1PID.Integral   = 0;                        //积分常数 Integral Const
    M1PID.Derivative = 0;                        //微分常数 Derivative Const
    M1PID.SetPoint   = 0;
        M1PID.SumError   = 0;
}
/*------------------------------------------
函数功能:初始化M2PID结构体参数
函数说明:                       
------------------------------------------*/
void PID_M2_Init(void)
{
    M2PID.LastError= 0;                        //Error[-1]
    M2PID.PrevError= 0;                        //Error[-2]
        M2PID.Proportion = 0;                        //比例常数 Proportional Const
    M2PID.Integral   = 0;                        //积分常数 Integral Const
    M2PID.Derivative = 0;                        //微分常数 Derivative Const
    M2PID.SetPoint   = 0;
        M2PID.SumError   = 0;
}
/*------------------------------------------
函数功能:设置M1PID期望值
函数说明:                       
------------------------------------------*/
void PID_M1_SetPoint(float setpoint)
{       
        M1PID.SetPoint = setpoint;       
}
/*------------------------------------------
函数功能:设置M2期望值
函数说明:                       
------------------------------------------*/
void PID_M2_SetPoint(float setpoint)
{       
        M2PID.SetPoint = setpoint;       
}
/*------------------------------------------
函数功能:设置M1PID比例系数
函数说明:浮点型                       
------------------------------------------*/
void PID_M1_SetKp(float dKpp)
{       
        M1PID.Proportion = dKpp;       
}
/*------------------------------------------
函数功能:设置M2比例系数
函数说明:浮点型                       
------------------------------------------*/
void PID_M2_SetKp(float dKpp)
{       
        M2PID.Proportion = dKpp;       
}
/*------------------------------------------
函数功能:设置M1PID积分系数
函数说明:浮点型                       
------------------------------------------*/
void PID_M1_SetKi(float dKii)
{       
        M1PID.Integral = dKii;       
}
/*------------------------------------------
函数功能:设置M2积分系数
函数说明:浮点型                       
------------------------------------------*/
void PID_M2_SetKi(float dKii)
{       
        M2PID.Integral = dKii;       
}
/*------------------------------------------
函数功能:设置M1PID微分系数
函数说明:浮点型                       
------------------------------------------*/
void PID_M1_SetKd(float dKdd)
{       
        M1PID.Derivative = dKdd;
}
/*------------------------------------------
函数功能:设置M2微分系数
函数说明:浮点型                       
------------------------------------------*/
void PID_M2_SetKd(float dKdd)
{       
        M2PID.Derivative = dKdd;
}
/*------------------------------------------
函数功能:电机1位置式PID计算
函数说明:               
------------------------------------------*/
int32_t PID_M1_PosLocCalc(float NextPoint)
{
    register float iError,dError;

        iError = M1PID.SetPoint - NextPoint;      // 偏差
        M1PID.SumError += iError;                                  // 积分
        if(M1PID.SumError &gt; 2300.0)                                        //积分限幅2300
                M1PID.SumError = 2300.0;
        else if(M1PID.SumError &lt; -2300.0)
                M1PID.SumError = -2300.0;       
        dError = iError - M1PID.LastError;                         // 当前微分
        M1PID.LastError = iError;
       
        return(int32_t)(M1PID.Proportion * iError                 // 比例项
                            + M1PID.Integral   * M1PID.SumError                 // 积分项
                            + M1PID.Derivative * dError);
}

/*------------------------------------------
函数功能:电机2位置式PID计算
函数说明:                       
------------------------------------------*/
int32_t PID_M2_PosLocCalc(float NextPoint)
{
        register float iError,dError;

        iError = M2PID.SetPoint - NextPoint;      // 偏差
    M2PID.SumError += iError;                        //累加误差 即误差积分       
        if(M2PID.SumError &gt; 2300.0)                                        //积分限幅
                M2PID.SumError = 2300.0;
        else if(M2PID.SumError &lt; -2300.0)
                M2PID.SumError = -2300.0;
       
        dError = iError - M2PID.LastError;                         // 当前微分
        M2PID.LastError = iError;
       
        return(int32_t)(M2PID.Proportion * iError                 // 比例项
                            + M2PID.Integral   * M2PID.SumError        // 积分项
                            + M2PID.Derivative * dError);
}
/*-------------------------------------------------------------------------------------------
                                                 风力摆控制系统(2015-8-12)

硬件平台:
                        主控器: STM32F103VET6 64K RAM 512K ROM
                        驱动器: LMD18200T
                  电源:   DC +12V

软件平台:
                        开发环境: RealView MDK-ARM uVision4.10
                        C编译器 : ARMCC
                        ASM编译器:ARMASM
                        连接器:   ARMLINK
                        底层驱动: 各个外设驱动程序      

时间: 2015年8月12日      

作者: BoX
-------------------------------------------------------------------------------------------*/
#include "motor_pwm.h"
#include "motor_control.h"
#include "stdio.h"
#include "sys.h"
/*------------------------------------------
                                全局变量                               
------------------------------------------*/
//extern M1TypeDef M1;
//extern M2TypeDef M2;
/*------------------------------------------
函数功能:配置TIM2复用输出PWM时用到的I/O
函数说明:PA0 - TIM2_CH1 - M4_PWM
                     PA1 - TIM2_CH2 - M1_PWM
                     PA2 - TIM2_CH3 - M2_PWM
                  PA3 - TIM2_CH4 - M3_PWM
                  
                  - M1_DIR-&gt; PD14
                  - M1_STOP -&gt; PD12

                  - M2_DIR-&gt; PD15
                  - M2_STOP -&gt; PD13
                  
                  - M3_DIR-&gt; PD10
                  - M3_STOP -&gt; PD11x
                  
                  - M4_DIR-&gt; PD8
                  - M4_STOP -&gt; PD9                               
------------------------------------------*/                                                                  
void PWM_GPIO_Config(void)           
{
       GPIO_InitTypeDef GPIO_InitStructure;                  
       
//       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);        
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
                                      //   M1          M2         M3         M4
       GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6 | GPIO_Pin_7;                           
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出          
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(GPIOA, &amp;GPIO_InitStructure);
             
       
       GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1;
       GPIO_Init(GPIOB, &amp;GPIO_InitStructure);
       
       
       
}
/*------------------------------------------
函数功能:配置TIM2输出的PWM信号的模式
函数说明:- TIM2通道4输出PWM
                  - PWM模式1
                  - 极性低电平
                  - PWM频率 = 24kHz                               
------------------------------------------*/
void PWM_Mode_Config(void)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        TIM_OCInitTypeDef TIM_OCInitStructure;       
                  
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);        

        TIM_TimeBaseStructure.TIM_Prescaler =0;                                 //时钟预分频
        TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up;//向上计数
        TIM_TimeBaseStructure.TIM_Period = 3000;                                  //自动重装值
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;          //时钟分频1
        TIM_TimeBaseInit(TIM3,&amp;TIM_TimeBaseStructure);

        TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_PWM2;         
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
        TIM_OCInitStructure.TIM_Pulse = 0;   
        TIM_OC1Init(TIM3,&amp;TIM_OCInitStructure);
       
        TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_PWM2;         
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
        TIM_OCInitStructure.TIM_Pulse = 0;   
        TIM_OC2Init(TIM3,&amp;TIM_OCInitStructure);                                        
       
        TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_PWM2;         
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
        TIM_OCInitStructure.TIM_Pulse = 0;   
        TIM_OC3Init(TIM3,&amp;TIM_OCInitStructure);       
       
        TIM_OCInitStructure.TIM_OCMode =TIM_OCMode_PWM2;         
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
        TIM_OCInitStructure.TIM_Pulse = 0;   
        TIM_OC4Init(TIM3,&amp;TIM_OCInitStructure);                                
       
        TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable); //使能TIM1在CCR2上的预装载寄存器
        TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable); //使能TIM1在CCR2上的预装载寄存器
        TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable); //使能TIM1在CCR3上的预装载寄存器
        TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable); //使能TIM1在CCR4上的预装载寄存器
TIM_CtrlPWMOutputs(TIM3,ENABLE);
TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器
        TIM_Cmd(TIM3,ENABLE);        //使能TIM1
        GPIO_SetBits(GPIOC,GPIO_Pin_0);
        GPIO_ResetBits(GPIOC,GPIO_Pin_1);
        GPIO_SetBits(GPIOC,GPIO_Pin_2);
        GPIO_ResetBits(GPIOC,GPIO_Pin_3);
        GPIO_SetBits(GPIOC,GPIO_Pin_4);
        GPIO_ResetBits(GPIOC,GPIO_Pin_5);
        GPIO_SetBits(GPIOC,GPIO_Pin_6);
        GPIO_ResetBits(GPIOC,GPIO_Pin_7);
//        TIM_SetCompare1(TIM3,1500);
//        TIM_SetCompare2(TIM3,1500);
//        TIM_SetCompare3(TIM3,1500);
//        TIM_SetCompare4(TIM3,1500);
//   TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器
//        TIM_Cmd(TIM1,ENABLE);        //使能TIM1
}
/*------------------------------------------
函数功能:电机运动方向管脚配置
函数说明:- M1_DIR-&gt; PC0
                  - M1_STOP -&gt;PC1

                  - M2_DIR-&gt; PC2
                  - M2_STOP -&gt; PC3
                  
                  - M3_DIR-&gt; PC4
                  - M3_STOP -&gt; PC5
                  
                  - M4_DIR-&gt; PC6
                  - M4_STOP -&gt; PC7                               
------------------------------------------*/
void MOTOR_DIR_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE);
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3| GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   // 推挽输出   
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOC, &amp;GPIO_InitStructure);
        GPIOC-&gt;BRR =GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3| GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;       
//        M1_Forward();          // roll -
//        M2_Forward();          //pitch +
//        M3_Forward();          //pitch-
//        M4_Forward();          //roll+
//       
//M1_Backward();
//        M2_Backward();
//        M3_Backward();
//        M4_Backward();
}
/*------------------------------------------
函数功能:PWM输出初始化                               
------------------------------------------*/

void PWM_Init(void)
{
        PWM_GPIO_Config();
        PWM_Mode_Config();
        MOTOR_DIR_GPIO_Config();               
}

void M1_Forward(void)
{       
        GPIOC-&gt;BSRR = GPIO_Pin_0;
        GPIOC-&gt;BRR = GPIO_Pin_1;
}
void M2_Forward(void){       
        GPIOC-&gt;BSRR = GPIO_Pin_2;
        GPIOC-&gt;BRR = GPIO_Pin_3;
}
void M3_Forward(void){       
        GPIOC-&gt;BSRR = GPIO_Pin_4;
        GPIOC-&gt;BRR = GPIO_Pin_5;
}
void M4_Forward(void){       
        GPIOC-&gt;BSRR = GPIO_Pin_6;
        GPIOC-&gt;BRR = GPIO_Pin_7;
}
void M1_Backward(void){       
        GPIOC-&gt;BSRR = GPIO_Pin_1;
        GPIOC-&gt;BRR = GPIO_Pin_0;
}
void M2_Backward(void){       
        GPIOC-&gt;BSRR = GPIO_Pin_3;
        GPIOC-&gt;BRR = GPIO_Pin_2;
}
void M3_Backward(void){       
        GPIOC-&gt;BSRR = GPIO_Pin_5;
        GPIOC-&gt;BRR = GPIO_Pin_4;
}
void M4_Backward(void){       
        GPIOC-&gt;BSRR = GPIO_Pin_7;
        GPIOC-&gt;BRR = GPIO_Pin_6;
}

/*------------------------------------------
函数功能:电机1正方向运动
函数参数:CCR2_VAL占空比计数值
函数说明:CCR2_VAL越大转速越快                                
------------------------------------------*/
void PWM_M1_Forward(uint16_t val)
{          
        M1_Forward();
//        M3_Backward();
        TIM_SetCompare1(TIM3,val);   //值越大转速越快
}
/*------------------------------------------
函数功能:电机1反方向运动
函数参数:CCR2_VAL占空比计数值
函数说明:CCR2_VAL越大转速越快                                
------------------------------------------*/
void PWM_M1_Backward(uint16_t val)
{          
//        M3_Forward();
        M1_Backward();
        TIM_SetCompare1(TIM3,val);   //值越大转速越快
}
/*------------------------------------------
函数功能:电机2正方向运动
函数参数:CCR3_VAL占空比计数值
函数说明:CCR3_VAL越大转速越快                                
------------------------------------------*/
void PWM_M2_Forward(uint16_t val)
{   
        M2_Forward();
//        M4_Backward();
        TIM_SetCompare2(TIM3,val);   //值越大转速越快
}
/*------------------------------------------
函数功能:电机2反方向运动
函数参数:CCR3_VAL占空比计数值
函数说明:CCR3_VAL越大转速越快                                
------------------------------------------*/
void PWM_M2_Backward(uint16_t val)
{          
//        M4_Forward();
        M2_Backward();
        TIM_SetCompare2(TIM3,val);   //值越大转速越快
}
/*------------------------------------------
函数功能:电机3正方向运动
函数参数:CCR4_VAL占空比计数值
函数说明:CCR4_VAL越大转速越快                                
------------------------------------------*/
void PWM_M3_Forward(uint16_t val)
{          
        M3_Forward();
//        M1_Backward();
        TIM_SetCompare3(TIM3,val);   //值越大转速越快
}
/*------------------------------------------
函数功能:电机3反方向运动
函数参数:CCR4_VAL占空比计数值
函数说明:CCR4_VAL越大转速越快                                
------------------------------------------*/
void PWM_M3_Backward(uint16_t val)
{   
//        M1_Forward();
        M3_Backward();
        TIM_SetCompare3(TIM3,val);   //值越大转速越快
}
/*------------------------------------------
函数功能:电机4正方向运动
函数参数:CCR1_VAL占空比计数值
函数说明:CCR1_VAL越大转速越快                                
------------------------------------------*/
void PWM_M4_Forward(uint16_t val)
{   
        M4_Forward();
//        M2_Backward();
        TIM_SetCompare4(TIM3,val);   //值越大转速越快
}
/*------------------------------------------
函数功能:电机4反方向运动
函数参数:CCR1_VAL占空比计数值
函数说明:CCR1_VAL越大转速越快                                
------------------------------------------*/
void PWM_M4_Backward(uint16_t val)
{          
//        M2_Forward();
        M4_Backward();
        TIM_SetCompare4(TIM3,val);   //值越大转速越快
}


/*-----------------------------------------------
                独立按键端口配置及检测程序
        说明:        已经将端口配置和按键扫描程序封装成型
                根据程序实际需要更改相应的参数即可。
        时间:        2013年7月22日 BoX编写
------------------------------------------------*/
#include "indkey.h"
#include "stm32f10x.h"
#include "delay.h"
#include "stdio.h"
#include "mpu6050.h"
#include "stm32f10x_tim.h"
#include "oled.h"
/*-----------------------------------------
                                全局变量
------------------------------------------*/
uint8_t Item = 0;
uint8_t Q1_Start = 0;
uint8_t Q2_Start = 0;
uint8_t Q3_Start = 0;
uint8_t Q4_Start = 0;
uint8_t Q5_Start = 0;
uint8_t Q6_Start = 0;
uint8_t Q7_Start = 0;



extern float R;
extern float angle;
extern uint8_t RoundDir;
extern uint8_t CurMode;

/*-----------------------------------------
                                KEY IO配置
------------------------------------------*/
void Key_IO_Init(void)       //按键IO配置
{
GPIO_InitTypeDef IO_Init;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);       
IO_Init.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_15;                  
IO_Init.GPIO_Mode = GPIO_Mode_IPU;       
GPIO_Init(GPIOA, &amp;IO_Init);
        IO_Init.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_5;                  
IO_Init.GPIO_Mode = GPIO_Mode_IPU;       
GPIO_Init(GPIOC, &amp;IO_Init);
}
/*-----------------------------------------------
        函数功能:        独立按键检测
        函数参数:        端口组名GPIOx,引脚名GPIO_Pin
        函数回值:        INT8U类型 按键值0,1
------------------------------------------------*/
void KeyScan(void)
{       
        static uint8_t key_up=1;
        if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == KEY_PRESSED)&amp;&amp;(key_up==1)) //K1
        {       
                switch(Item)
                {
                        case 2:R+=5.0;
                                   if(R &gt;= 35.0) R = 35.0;
//                                   sprintf(buf,"DS16(6,60,'设置长度:%.1f ',10)\r\n",R);
//                                   GpuSend(buf);
         OLED_ShowString(0,2,"length:");
                     OLED_ShowNum(70,2,R,4,12);                       
                             
                             break;//第2问按下S4增加距离

                        case 3:angle+=10.0;
                                   if(angle &gt;= 180.0)
                                             angle = 180.0;
//                                   sprintf(buf,"DS16(6,80,'设置角度:%.1f ',10)\r\n",angle);
//                                   GpuSend(buf);       
                                       OLED_ShowString(0,2,"angle:");
                     OLED_ShowNum(70,2,angle,4,12);
                             break;//第3问按下S4增加角度;
                       
                        case 5:R+=5.0;
                                   if(R &gt;= 35.0) R = 35.0;
//                                   sprintf(buf,"DS16(6,100,'设置半径:%.1f ',10)\r\n",R);
//                                   GpuSend(buf);
                                       OLED_ShowString(0,2,"radius:");
                     OLED_ShowNum(70,2,R,4,12);
                                   break;

                        case 6:R+=5.0;
                                   if(R &gt;= 35.0) R = 35.0;
//                                   sprintf(buf,"DS16(6,100,'设置半径:%.1f ',10)\r\n",R);
//                                   GpuSend(buf);
                                       OLED_ShowString(0,2,"radius:");
                     OLED_ShowNum(70,2,R,4,12);
                                   break;
                                  

                        default:break;
                }               
    key_up=0;               
        }

        if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15) == KEY_PRESSED)&amp;&amp;(key_up==1)) //K2
        {
                switch(Item)
                {
                        case 2:R-=5.0;
                                   if(R &lt;= 15.0) R = 15.0;
//                                   sprintf(buf,"DS16(6,60,'设置长度:%.1f ',10)\r\n",R);
//                                   GpuSend(buf);       
                             OLED_ShowString(0,2,"length:");
                     OLED_ShowNum(70,2,R,4,12);                       
                             break;//第2问按下S4增加距离

                        case 3:angle-=10.0;
                                   if(angle &lt;= 0.0)
                                             angle = 0.0;
//                                   sprintf(buf,"DS16(6,80,'设置角度:%.1f ',10)\r\n",angle);
//                                   GpuSend(buf);       
                                              OLED_ShowString(0,2,"angle:");
                         OLED_ShowNum(70,2,angle,4,12);
                             break;//第3问按下S4增加角度;
                       
                        case 5:R-=5.0;
                                   if(R &lt;= 15.0) R = 15.0;
//                                   sprintf(buf,"DS16(6,100,'设置半径:%.1f ',10)\r\n",R);
//                                   GpuSend(buf);
                                          OLED_ShowString(0,2,"radius:");
                     OLED_ShowNum(70,2,R,4,12);
                                   break;

                        case 6:R-=5.0;
                                   if(R &lt;= 15.0) R = 15.0;
//                                   sprintf(buf,"DS16(6,100,'设置半径:%.1f ',10)\r\n",R);
//                                   GpuSend(buf);
                                          OLED_ShowString(0,2,"radius:");
                     OLED_ShowNum(70,2,R,4,12);
                                   break;
                                  

                        default:break;
                }               
                key_up =0;
        }
       
        if((GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5) == KEY_PRESSED)&amp;&amp;(key_up==1)) //K3
        {
                  CurMode=Item;
//                switch(Item)
//                {
//                        case 1:
//                          OLED_ShowString(25,4,"Ready Go!");
//                                   break;

//                        case 2:
//                                       OLED_ShowString(25,4,"Ready Go!");
//                                   break;

//                        case 3:
//                                       OLED_ShowString(25,4,"Ready Go!");
//                                   break;

//                        case 4:
//                                       OLED_ShowString(25,4,"Ready Go!");
//                                       break;
//                                  
//                        case 5:
//                                   RoundDir = !RoundDir;
//                                       if(RoundDir == 1)
//                                                     OLED_ShowString(20,6,"Clockwise");
//                                   else
//                                                  OLED_ShowString(10,6,"contrarotate");
//                                       break;
//                                  
//                        case 6:
//                                          OLED_ShowString(25,4,"Ready Go!");
//                        default:break;
//               }
                key_up =0;
        }        

        if((GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_8) == KEY_PRESSED)&amp;&amp;(key_up==1))//K4
        {
                Item++;
                if(Item&gt;6)                //共有7问
                        Item = 0;
        //        sprintf(buf,"DS16(6,40,'第%d问',10)\r\n",Item);
        //        GpuSend(buf);
                OLED_ShowString(0,0,"mode:");
                OLED_ShowNum(70,0,Item,3,12);
                key_up =0;
        }
        if((key_up ==0)&amp;&amp;(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15) == KEY_UNPRESS)&amp;&amp;(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == KEY_UNPRESS)&amp;&amp;(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5) == KEY_UNPRESS)&amp;&amp;(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_8) == KEY_UNPRESS))
        {
           key_up =1;
        }
}

</code></pre>

<p>&nbsp;</p>

宋元浩 发表于 2020-9-16 15:09

<p>自己debug下吧</p>
页: [1]
查看完整版本: 我从网上下的风力摆系统的代码,然后改了改,下到开发板上电机不转,芯片型号一样。