8271 views|1 replies

2

Posts

0

Resources
The OP
 

I downloaded the code of the wind pendulum system from the Internet, then modified it. When I downloaded it to the development board, the motor did not rotate, and the chip model was the same. [Copy link]

Moreover, the motor part can be rotated separately, and there is no problem with the wiring. Can you show me the 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>=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 > POWER_MAX)  M1.PWM =  POWER_MAX;
	if(M1.PWM < -POWER_MAX) M1.PWM = -POWER_MAX;	
	
	if(M2.PWM > POWER_MAX)  M2.PWM = POWER_MAX;
	if(M2.PWM < -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 > POWER_MAX)  M1.PWM =  POWER_MAX;
	if(M1.PWM < -POWER_MAX) M1.PWM = -POWER_MAX;	
	
	if(M2.PWM > POWER_MAX)  M2.PWM = POWER_MAX;
	if(M2.PWM < -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   100  110  120  130  140  150  160  170 180
	const float Phase[19]= {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[pOffset]); //计算出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 > POWER_MAX)  M1.PWM =  POWER_MAX;
	if(M1.PWM < -POWER_MAX) M1.PWM = -POWER_MAX;
			 	
	if(M2.PWM > POWER_MAX)  M2.PWM =  POWER_MAX;
	if(M2.PWM < -POWER_MAX) M2.PWM = -POWER_MAX;		

	MotorMove(M1.PWM,M2.PWM);	
}
/*------------------------------------------
 函数功能:第4问PID计算
 函数说明:
------------------------------------------*/ 
void Mode_4(void)
{	
	if(abs(M1.CurPos)<45.0 && abs(M2.CurPos)<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 > POWER_MAX)  M1.PWM =  POWER_MAX;
		if(M1.PWM < -POWER_MAX) M1.PWM = -POWER_MAX;

		if(M2.PWM > POWER_MAX)  M2.PWM =  POWER_MAX;
		if(M2.PWM < -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 > POWER_MAX)  M1.PWM =  POWER_MAX;
	if(M1.PWM < -POWER_MAX) M1.PWM = -POWER_MAX;
			 	
	if(M2.PWM > POWER_MAX)  M2.PWM =  POWER_MAX;
	if(M2.PWM < -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 > POWER_MAX)  M1.PWM =  POWER_MAX;
	if(M1.PWM < -POWER_MAX) M1.PWM = -POWER_MAX;
			 	
	if(M2.PWM > POWER_MAX)  M2.PWM =  POWER_MAX;
	if(M2.PWM < -POWER_MAX) M2.PWM = -POWER_MAX;		

	MotorMove(M1.PWM,M2.PWM);
	

}
/*------------------------------------------
 函数功能:电机底层驱动函数  x   pitch  2  3
 函数说明:                 y  roll   4  1
------------------------------------------*/
void MotorMove(int pwm1,int pwm2)
{
	if(pwm1 > 0)
	{   
	 	PWM_M3_Backward(pwm1);

		PWM_M2_Forward(pwm1);

	}
	else if(pwm1 < 0)
	{
	 	PWM_M2_Backward(abs(pwm1));

		PWM_M3_Forward(abs(pwm1));	

	}


	if(pwm2 > 0)
	{
	 	PWM_M1_Backward(pwm2);

		PWM_M4_Forward(pwm2);


	}
	else if(pwm2 < 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 M1TypeDef  M1;
extern M2TypeDef  M2;

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 > 2300.0)					//积分限幅2300
		M1PID.SumError = 2300.0;
	else if(M1PID.SumError < -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 > 2300.0)					//积分限幅
		M2PID.SumError = 2300.0;
	else if(M2PID.SumError < -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  -> PD14
 		  - M1_STOP -> PD12

		  - M2_DIR  -> PD15
 		  - M2_STOP -> PD13
		  
		  - M3_DIR  -> PD10
 		  - M3_STOP -> PD11x
		  
		  - M4_DIR  -> PD8
 		  - M4_STOP -> 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, &GPIO_InitStructure);
	      
	
	 GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1;
	 GPIO_Init(GPIOB, &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,&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,&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,&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,&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,&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  -> PC0
 		  - M1_STOP ->PC1

		  - M2_DIR  -> PC2
 		  - M2_STOP -> PC3
		  
		  - M3_DIR  -> PC4
 		  - M3_STOP -> PC5
		  
		  - M4_DIR  -> PC6
 		  - M4_STOP -> 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, &GPIO_InitStructure);
	GPIOC->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->BSRR = GPIO_Pin_0;
	GPIOC->BRR = GPIO_Pin_1;
}
void M2_Forward(void){	
 	GPIOC->BSRR = GPIO_Pin_2;
	GPIOC->BRR = GPIO_Pin_3;
}
void M3_Forward(void){	
 	GPIOC->BSRR = GPIO_Pin_4;
	GPIOC->BRR = GPIO_Pin_5;
}
void M4_Forward(void){	
 	GPIOC->BSRR = GPIO_Pin_6;
	GPIOC->BRR = GPIO_Pin_7;
}
void M1_Backward(void){	
 	GPIOC->BSRR = GPIO_Pin_1;
	GPIOC->BRR = GPIO_Pin_0;
}
void M2_Backward(void){	
 	GPIOC->BSRR = GPIO_Pin_3;
	GPIOC->BRR = GPIO_Pin_2;
}
void M3_Backward(void){	
 	GPIOC->BSRR = GPIO_Pin_5;
	GPIOC->BRR = GPIO_Pin_4;
}
void M4_Backward(void){	
 	GPIOC->BSRR = GPIO_Pin_7;
	GPIOC->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, &IO_Init);
	IO_Init.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_5;		    
  IO_Init.GPIO_Mode = GPIO_Mode_IPU;	
  GPIO_Init(GPIOC, &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)&&(key_up==1)) //K1
	{	
		switch(Item)
		{
			case 2:R+=5.0;
				   if(R >= 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 >= 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 >= 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 >= 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)&&(key_up==1)) //K2
	{
		switch(Item)
		{
			case 2:R-=5.0;
				   if(R <= 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 <= 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 <= 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 <= 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)&&(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)&&(key_up==1))  //K4
	{
		Item++;
		if(Item>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)&&(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15) == KEY_UNPRESS)&&(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == KEY_UNPRESS)&&(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5) == KEY_UNPRESS)&&(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_8) == KEY_UNPRESS))
	{
	   key_up =1;
	}
}

This post is from Electronics Design Contest

Latest reply

Debug it yourself   Details Published on 2020-9-16 15:09
 
 

310

Posts

5

Resources
2
 

Debug it yourself

This post is from Electronics Design Contest
 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list