m_delay_motor(int t,int f1,int f2)语句else if(read_a[2]|read_a[3]|read_a[4]|read_a[5])存在问题,需要完成的步骤是在八路巡线中,中间四路只要有一个寻到了就立即执行限时巡线的操作(flag_r1 == 8)。修改代码#include "ti_msp_dl_config.h"
#include "headfile.h"
void usart0_send_bytes(unsigned char *buf, int len);
void usart1_send_bytes(unsigned char *buf, int len);
void usart2_send_bytes(unsigned char *buf, int len);
void usart3_send_bytes(unsigned char *buf, int len);
void sent_num(UART_Regs *port,int num,int len);
#define M1_0 DL_GPIO_clearPins(PORTB_PORT, DL_GPIO_PIN_6)
#define M1_1 DL_GPIO_setPins(PORTB_PORT, DL_GPIO_PIN_6)
#define M2_0 DL_GPIO_clearPins(PORTB_PORT, DL_GPIO_PIN_7)
#define M2_1 DL_GPIO_setPins(PORTB_PORT, DL_GPIO_PIN_7)
#define M3_0 DL_GPIO_clearPins(PORTB_PORT, DL_GPIO_PIN_8)
#define M3_1 DL_GPIO_setPins(PORTB_PORT, DL_GPIO_PIN_8)
#define M4_0 DL_GPIO_clearPins(PORTB_PORT, DL_GPIO_PIN_9)
#define M4_1 DL_GPIO_setPins(PORTB_PORT, DL_GPIO_PIN_9)
#define BEEP_0 DL_GPIO_clearPins(PORTB_PORT, DL_GPIO_PIN_11)
#define BEEP_1 DL_GPIO_setPins(PORTB_PORT, DL_GPIO_PIN_11)
#define BEEP_OFF DL_GPIO_clearPins(PORTB_PORT, DL_GPIO_PIN_12)
#define BEEP_ON DL_GPIO_setPins(PORTB_PORT, DL_GPIO_PIN_12)
#define LED_OFF DL_GPIO_clearPins(PORTB_PORT, DL_GPIO_PIN_13)
#define LED_ON DL_GPIO_setPins(PORTB_PORT, DL_GPIO_PIN_13)
int speed_s=300,speed_q=0, angle_t=100;;
int suA=0,suB=0,duo=0,su_TA=0,su_TB=100;
int pid_pwm1=0,pid_l=0,pid_r=0;
volatile uint32_t gpioA,gpioB;
volatile int32_t gEncoderCount = 0,gEncoderCountB = 0;
volatile int flag_delay_motor = 500; // 专用于电机延时(直行)
volatile int flag_delay_angle = 0; // 专用于电机延时(转向)
float speed = 0;
float Kp=0.05,Ki=0,Kd=0;
float Kp_1=0.06,Ki_1=0.00005,Kd_1=0.8;
float Kp_2=0.1,Ki_2=0.00006,Kd_2=0.8;
//float Kp_1=0.05,Ki_1=0,Kd_1=0;
//float Kp_2=0.025,Ki_2=0.00004,Kd_2=0;//float Kp_2=0.05,Ki_2=0.0001,Kd_2=-0.03; // Kp_2=0.05,Ki_2=0.0001,Kd_2=0;
float Kp_3=0.0005,Ki_3=0,Kd_3=0;//Kp_3=0.0005,Ki_3=0,Kd_3=0;
int pwm_1,pwm_2,num_L=0,target_speed=200;int su_jA=0,su_jB=0;
int flag_r1=0,flag_r2=0,flag_r3=0,flag_r4=0;
int suK=10,suJ=100,suJ2=100;
int read_a[12];
uint32_t read_all = 0;
int angle_mpu=0;
int str_angle(int angle);
int flag_delay=0;
int counter = 1;
int delay_active = 0;
void read(void);
void maple_duty_200hz(void);
void beep_led(void);
void left_1(void);
void jichu_1(void);
void jichu_2(void);
void jichu_3(void);
void jichu_4(void);
void pailei(void);
int beep_led_new(int t);
int m_delay(int t);
int m_delay_motor(int t,int f1,int f2);
int m_delay_angle(int t,int a1,int a2);
int str_angle_0(int angle);
int turn_angle(int angle);
int pid_js_l=300,pid_js_r=300,dj_dj=800,dj_1=0;
int go=0;
int main(void)
{
usart_irq_config(); //串口中断配置
SYSCFG_DL_init(); //系统资源配置初始化
rgb_init(); //RGB灯初始化
timer_irq_config();
NVIC_EnableIRQ(PORTB_INT_IRQN);
PWM_Output(500,500,500,500);
M1_1,M2_0,M3_1,M4_0; //0101后转
LED_OFF,BEEP_1,BEEP_OFF;
// Reserved_PWM6_Output(dj_dj);
// Reserved_PWM7_Output(dj_dj);
// Reserved_PWM8_Output(dj_dj);
while(1)
{
if(flag_r1==1)HMI_SendNum(UART_1_INST,"n5.val=",7,1,5),flag_r1=1;
if(flag_r1==2)HMI_SendNum(UART_1_INST,"n5.val=",7,2,5),flag_r1=2;
if(flag_r1==3)HMI_SendNum(UART_1_INST,"n5.val=",7,3,5),flag_r1=3;
if(flag_r1==4)HMI_SendNum(UART_1_INST,"n5.val=",7,4,5),flag_r1=4;
// if(flag_r1==4)HMI_SendNum(UART_1_INST,"n5.val=",7,4,5),dj_dj=1300,flag_r1=0; //舵机
// if(flag_r1==5)HMI_SendNum(UART_1_INST,"n5.val=",7,5,5),dj_dj=1900,flag_r1=0;
// if(flag_r1==6)HMI_SendNum(UART_1_INST,"n5.val=",7,6,5),dj_dj=2600,flag_r1=0;
if(flag_r1==7)HMI_SendNum(UART_1_INST,"n5.val=",7,7,5),flag_r1=7;
if(flag_r1==8)HMI_SendNum(UART_1_INST,"n5.val=",7,8,5),flag_r1=8;
HMI_SendNum(UART_1_INST,"n1.val=",7,suA,3);
HMI_SendNum(UART_1_INST,"n7.val=",7,suB,3);
HMI_SendNum(UART_1_INST,"n0.val=",7,su_jA,6);
Reserved_PWM5_Output(dj_dj);
}
}
void GROUP1_IRQHandler(void)
{
gpioA = DL_GPIO_getEnabledInterruptStatus(GPIOB, PORTB_PIN_11_PIN );
gpioB = DL_GPIO_getEnabledInterruptStatus(GPIOB, PORTB_PIN_9_PIN );
if(gpioA>0) gEncoderCount++;
if(gpioB>0) gEncoderCountB++;
DL_GPIO_clearInterruptStatus(GPIOB, PORTB_PIN_11_PIN);
DL_GPIO_clearInterruptStatus(GPIOB, PORTB_PIN_9_PIN);
}
int i;
int suA_P,suB_P;
void maple_duty_200hz(void)
{
static int motor_state = 1;
static int delay_active = 0; // 新增:延时激活标志
static int saved_f1 = 0, saved_f2 = 0; // 保存PID输出值
i++;
if(i==5)
{
suA = gEncoderCount;
su_jA=su_jA+suA;
gEncoderCount = 0;
suB = gEncoderCountB;
su_jB=su_jB+suB;
gEncoderCountB = 0;
read();
i=0;
}
read();
if(flag_r1 == 0) // 停止模式
{
PWM_Output(0, 0, 0, 0);
}
// 模式选择
if(flag_r1 == 1) { // 直行模式
suA_P = contorl_PID(suA, 10);
suB_P = contorl_PID2(suB, 10);
PWM_Output(0, 0, 100, 100);
}
else if(flag_r1 == 2) { // 巡线模式
read(); // 更新传感器数据
PWM_Output(0, 0, su_TA, su_TB);
}
else if(flag_r1 == 3) { // 直行+巡线模式
if (!delay_active) { // 首次进入:计算并保存PID值
suA_P = pid_r;
suB_P = pid_l;
saved_f1 = 100;
saved_f2 = suA_P;
delay_active = 1; // 激活延时
flag_delay_motor = 0; // 重置专用计数器
}
// 执行延时控制
if (m_delay_motor(2000, 100, 100)) {
delay_active = 0; // 延时完成
flag_r1 = 8; // 进入巡线状态
}
}
else if(flag_r1 == 4) { // 旋转模式
int target_angle = 9000; // 目标角度90度
int error_threshold = 50; // 允许误差0.5度
str_angle(target_angle); // 实时计算PID
//动态设置电机方向(根据PID输出正负)
if (pid_pwm1 > 0) {
M1_0,M2_1,M3_1,M4_0; // 正旋
} else {
M1_1,M2_0,M3_0,M4_1; // 反旋
}
PWM_Output(0, 0, abs(pid_l), abs(pid_r)); // 输出PID计算值
int current_error = target_angle - angle_mpu; // 检查是否到达目标角度
if (abs(current_error) < error_threshold) {
PWM_Output(0, 0, 0, 0); // 停止电机
flag_r1 = 7; // 进入停止状态
}
// if (!delay_active) {
// str_angle(9000); // 首次进入:计算并保存PID值
// saved_f1 = pid_r;
// saved_f2 = pid_l;
// delay_active = 1; // 激活延时
// flag_delay_motor = 0; // 重置专用计数器
// }
// // 执行延时控制
// if (m_delay_angle(20, saved_f2, saved_f1)) {
// delay_active = 0; // 延时完成
// flag_r1 = 7; // 进入停止状态
// }
}
else if(flag_r1 == 7)
{
PWM_Output(0, 0, 0, 0); // 停止模式
}
else if(flag_r1 == 8) { // 巡线延时模式
if (!delay_active) {
// 首次进入:计算并保存PID值
read();
delay_active = 1; // 激活延时
flag_delay_motor = 0; // 重置专用计数器
}
// 执行延时控制
if (m_delay_motor(500*4, su_TA, su_TB)) {
delay_active = 0; // 延时完成
flag_r1 = 7; // 进入停止状态
}
}
// suA_P = contorl_PID(suA, 10);
// if( counter >=0 )
// {
// counter = m_delay_motor(50, 100, suA_P); // 只有运行状态下才调用延时函数
// }
// suA_P=contorl_PID(suA,10); //PID计算函数
// suB_P=contorl_PID2(suB,10); //PID计算函数
// PWM_Output(0,0,100,suA_P); //PID运算后输出
//PWM_Output(0,0,su_TA,su_TB); //PID运算后输出
}
void read(void)
{
if (DL_GPIO_readPins(PORTB_PORT, XUN_XUN_1_PIN) > 0) read_a[0]=1;else read_a[0]=0;
if (DL_GPIO_readPins(PORTB_PORT, XUN_XUN_2_PIN) > 0) read_a[1]=1;else read_a[1]=0;
if (DL_GPIO_readPins(PORTB_PORT, XUN_XUN_3_PIN) > 0) read_a[2]=1;else read_a[2]=0;
if (DL_GPIO_readPins(PORTB_PORT, XUN_XUN_4_PIN) > 0) read_a[3]=1;else read_a[3]=0;
if (DL_GPIO_readPins(PORTB_PORT, XUN_XUN_5_PIN) > 0) read_a[4]=1;else read_a[4]=0;
if (DL_GPIO_readPins(PORTB_PORT, XUN_XUN_6_PIN) > 0) read_a[5]=1;else read_a[5]=0;
if (DL_GPIO_readPins(PORTA_PORT, XUN_XUN_10_PIN) > 0) read_a[6]=1;else read_a[6]=0;
if (DL_GPIO_readPins(PORTA_PORT, XUN_XUN_8_PIN) > 0) read_a[7]=1;else read_a[7]=0;
read_all= read_a[0]*10000000+read_a[1]*1000000+read_a[2]*100000+read_a[3]*10000+read_a[4]*1000+read_a[5]*100+read_a[6]*10+read_a[7];//+read_a[8]*10;//+read_a[9];
HMI_SendNum(UART_1_INST,"n2.val=",7,read_all,8);
switch (read_all)
{
case 0: su_TA=suJ, su_TB=suJ2;flag_r2=2;break;
case 1: su_TA=suJ-suK*7, su_TB=suJ2+suK*7; flag_r2=2;break;
case 11: su_TA=suJ-suK*6, su_TB=suJ2+suK*6; flag_r2=2;break;
case 10: su_TA=suJ-suK*5, su_TB=suJ2+suK*5; flag_r2=2;break;
case 110: su_TA=suJ-suK*4, su_TB=suJ2+suK*4; flag_r2=2;break;
case 100: su_TA=suJ-suK*3, su_TB=suJ2+suK*3; flag_r2=2;break;
case 1100: su_TA=suJ-suK*2, su_TB=suJ2+suK*2; flag_r2=2;break;
case 1000: su_TA=suJ-suK*1, su_TB=suJ2+suK*1; flag_r2=2;break;
case 11000: su_TA=suJ, su_TB=suJ2; flag_r2=2;break;
case 10000: su_TA=suJ+suK*1, su_TB=suJ2-suK*1; flag_r2=2;break;
case 110000: su_TA=suJ+suK*2, su_TB=suJ2-suK*2; flag_r2=2;break;
case 100000: su_TA=suJ+suK*3, su_TB=suJ2-suK*3; flag_r2=2;break;
case 1100000: su_TA=suJ+suK*4, su_TB=suJ2-suK*4; flag_r2=2;break;
case 1000000: su_TA=suJ+suK*5, su_TB=suJ2-suK*5; flag_r2=2;break;
case 11000000: su_TA=suJ+suK*6, su_TB=suJ2-suK*6; flag_r2=2;break;
case 10000000: su_TA=suJ+suK*7, su_TB=suJ2-suK*7; flag_r2=2;break;
default:break;
}
}
void beep_led(void)
{
for(i=0;i<10;i++)
{
BEEP_ON;LED_ON;HMI_SendNum(UART_3_INST,"n0.val=",7,111,5);
}
BEEP_OFF;LED_OFF;
}
void left_1(void)
{
for(i=0;i<10;i++)
{
PWM_Output(0,0,50,100),
M1_1,M2_0,M3_1,M4_0;HMI_SendNum(UART_3_INST,"n0.val=",7,111,5);
}
for(i=0;i<10;i++)
{
PWM_Output(0,0,0,0),
M1_1,M2_0,M3_1,M4_0;HMI_SendNum(UART_3_INST,"n0.val=",7,111,5);
}
}
int turn_angle(int angle)
{
if(0<angle)
{
pwm_1=contorl_PID(suB,50),
pwm_2=contorl_PID2(suA,50),
PWM_Output(0,0,pwm_1,pwm_2),
M1_0,M2_1,M3_1,M4_0;
}
else
{
PWM_Output(0,0,0,0);
flag_r1=0;
beep_led();
M1_1,M2_0,M3_1,M4_0;
}
if(0>angle) return 1 ;
}
int str_angle(int angle)
{
if(angle==36000)
{
if(angle_mpu<18000) angle_mpu=angle_mpu+36000;
}
pid_pwm1= contorl_PID3(angle_mpu,angle);
if((pid_js_l-pid_pwm1)<0)
pid_l=-(pid_js_l-pid_pwm1),M1_1,M2_0;
else pid_l=(pid_js_l-pid_pwm1),M1_0,M2_1;
if((pid_js_r-pid_pwm1)<0)
pid_r=-(pid_js_r+pid_pwm1),M1_1,M2_0;
else pid_r=(pid_js_r+pid_pwm1),M1_0,M2_1;
//PWM_Output(0,0,pid_l,pid_r);
}
int str_angle_0(int angle)
{
pid_pwm1= contorl_PID4(angle_mpu,angle);
if((pid_js_l-pid_pwm1)<0)
pid_l=-(pid_js_l-pid_pwm1),M1_1,M2_0;
else pid_l=(pid_js_l-pid_pwm1),M1_0,M2_1;
if((pid_js_r-pid_pwm1)<0)
pid_r=-(pid_js_r+pid_pwm1),M1_1,M2_0;
else pid_r=(pid_js_r+pid_pwm1),M1_0,M2_1;
PWM_Output(0,0,pid_l,pid_r);
}
int m_delay(int t)
{ flag_delay++;
if(flag_delay<t)
{
PWM_Output(0,0,0,0);
return 2;
}
if(flag_delay>=t)
{
flag_delay=0;
return 2;
}
}
int m_delay_motor(int t,int f1,int f2)
{
if (flag_delay_motor < t) {
read();
PWM_Output(0, 0, f1, f2); // 持续输出PWM
flag_delay_motor++;
return 0; // 延时未完成
} else if(read_a[2]|read_a[3]|read_a[4]|read_a[5])//else if((read_a[2]|read_a[3]|read_a[4]|read_a[5])&&(t>500))
{
PWM_Output(0, 0, 0, 0); // 停止输出
flag_delay_motor = 0;
return 1; // 延时完成
}
}
int m_delay_angle(int t,int a1,int a2)
{
if (flag_delay_angle < t) {
M1_0,M2_1,M3_1,M4_0;
PWM_Output(0,0,a1,a2);
flag_delay_angle++;
return 0; // 延时未完成
} else {
M1_1,M2_0,M3_1,M4_0;
PWM_Output(0, 0, 0, 0); // 停止输出
flag_delay_angle = 0;
return 1; // 延时完成
}
}
// flag_delay++;
// if(flag_delay<t) PWM_Output(0,0,f1,f2);
//
// if(flag_delay>=t)
// {
// flag_delay=0;PWM_Output(0,0,0,0);
// return 2;
// }
int beep_led_new(int t)
{
BEEP_ON;LED_ON;
flag_delay++;
if(flag_delay<t) BEEP_OFF,LED_OFF;
if(flag_delay>=t)
{
flag_delay=0;
return 2;
}
}
/****************************************************************************************
MSPM0G3507电赛小车开源方案资源分配表--MSPM0学习中心交流群828746221
功能 单片机端口 外设端口
无名创新地面站通讯
PA10-->UART0-TXD USB转TTL-RXD
PA11-->UART0-RXD USB转TTL-TXD
机器视觉OPENMV4 MINI
PA8-UART1-TXD UART3-RXD
PA9-->UART1-RXD UART3-TXD·
手机蓝牙APP地面站
PA21-UART2-TXD 蓝牙串口模块RXD
PA22-->UART2-RXD 蓝牙串口模块TXD
US100超声波模块
PB2-UART3-TXD US100-TX/TRIG
PB3-->UART3-RXD US100-RX/ECHO
12路灰度传感器FPC
PA31-->P1
PA28-->P2
PA1-->P3
PA0-->P4
PA25-->P5
PA24-->P6
PB24-->P7
PB23-->P8
PB19-->P9
PB18-->P10
PA16-->P11
PB13-->P12
电机控制MPWM
PA4-A0-PWM-CH3 右边电机调速INA1
PA7-->A0-PWM-CH2 右边电机调速INA2
PA3-->A0-PWM-CH1 左边电机调速INB1
PB14-->A0-PWM-CH0 左边电机调速INB2
舵机控制SPWM
PA15-A1-PWM-CH0 预留1
PB1-->A1-PWM-CH1 预留2
PA23-->G7-PWM-CH0 预留3
PA2-->G7-PWM-CH1 前轮舵机转向控制PWM
编码器测速ENC
PB4-RIGHT-PULSE 右边电机脉冲倍频输出P1
PB5-->LEFT-PULSE 左边电机脉冲倍频输出P2
PB6-->RIGHT-DIR 右边电机脉冲鉴相输出D1
PB7-->LEFT-DIR 左边电机脉冲鉴相输出D2
外置IMU接口IMU
PA29-I2C-SCL MPU6050-SCL
PA30-->I2C-SDA MPU6050-SDA
PB0-->HEATER 温控IO可选
电池电压采集
PA26-ADC-VBAT· 需要外部分压后才允许接入
****************************************************************************************/