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;
}
}
|