【核心代码】
/*******************************************************************************/
//
//
//
//
oo——NXP2018_PRO——oo
PART1:初始化区段
/*******************************************************************************/
/************************包含的头文件****************************/
#include "common.h"
#include "include.h"
#include "OLED.h"
#include "SEEKFREE_18TFT.h"
/***********************参数定义&设置****************************/
//---------------------------------------------------------------
//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//---------------------------------------------------------------
/***********************系统运行参数*****************************/
uint8 code_Time_flag=0;
//程序运行时间
/**************************舵机*********************************/
uint8 KP_A=6,KP_B=27,KD=150;
//MAIN 舵机 PID
uint32 DJ_midpoint=7330;
uint32 DJ_PWM;
//舵机中值
//输出 PWM
/************************速度控制*******************************/
uint8 speed_need=20;
uint8 speed_need_Boost=30;
uint8 speed_need_normal=30;
uint8 speed_need_L=30;
//目标速度
//目标高速
//目标速度
//目标弯道
uint8 speed_SW_flag=1;
//速度选择标志
/*************************电机控制******************************/
float Speed_P=4,Speed_I=0.15,Speed_D=1; //MAIN 电机 PID
uint8 Block_motor_time_flag=0;
//堵转计时标志
uint8 Block_motor_duty_flag=0;
//堵转事件标志
uint8 Block_motor_delay_flag=0;
//堵转弛懈标志
/**************************编码器********************************/
float feed_fix=10.6;
//编码器修正系数
uint32 Feed_flag=0;
//编码器采集计数
uint32 Feed_speed=0;
//编码器采集速度
/***********************摄像头有关参数***************************/
/*调控参量*/
uint8 img_y_max=50;
//扫描纵坐标最近值
uint8 img_y_min=10;
//扫描纵坐标最远值
uint8 img_y_control=30;
//扫描纵坐标控制值
/*传递参量*/
uint8 imgbuff[CAMERA_SIZE];
//定义存储接收图像的数组
uint8 img[CAMERA_W*CAMERA_H];
//摄像头解压数组
uint8 img_x=40;
uint8 img_y=30;
//扫描横坐标
//扫描纵坐标
uint8 start_point=40;
//扫描起始点
uint8 mid_point[60];
//提取的中线
uint8 mid_point_His[10];
//历史的中线
uint8 left_point[60];
//左边界
int right_point[60];
//右边界
uint8 init_len[60];
//初始化赛道宽度
uint8 point_len[60];
//实时赛道宽度
uint8 street_len=0;
//直道长度
uint8 len_His[10];
//直道长度历史数组
/*圆环补线*/
float L_Cur_K=0;
float R_Cur_K=0;
//左圆环补线斜率
//由圆环补线斜率
/******************识别与判断标志***************************/
/*丢线标志*/
uint8 all_lost=0;
//全丢标志
uint8 lost_left[60];
//左丢线标志
uint8 lost_right[60];
//右丢线标志
/*起停*/
uint8 KEY_start_flag=0;
//一键启动标志
uint16 KEY_start_time_flag=0;
//启动时间标志
/*十字*/
uint8 lost_flag=0;
//全丢线初始识别标志
uint8 lost_delay_flag=0;
//十字弛懈标志
uint16 lost_car_time_flag=0;
//十字计时变量
uint8 lost_duty_flag=0;
//全丢线准确识别标志(十字)
/*圆环预判断*/
uint8 cur_L_ready_flag=0;
//左圆环预判断初始识别标志
uint8 cur_L_ready_delay_flag=0;
//左圆环预判断弛懈标志
uint16 cur_L_ready_time_flag=0;
//左圆环预判断计时变量
uint8 cur_L_ready_rest_flag=0;
//左圆环预判断复位变量
uint8 cur_R_ready_flag=0;
//右圆环预判断初始识别标志
uint8 cur_R_ready_delay_flag=0;
//右圆环预判断弛懈标志
uint16 cur_R_ready_time_flag=0;
//右圆环预判断计时变量
uint8 cur_R_ready_rest_flag=0;
//右圆环预判断复位变量
/*圆环准确识别*/
uint8 cur_L_real_flag=0;
//左圆环准确判断识别标志
uint8 cur_L_real_delay_flag=0;
//左圆环准确弛懈识别标志
uint8 cur_L_real_rest_flag=0;
//左圆环准确复位识别标志
uint16 cur_L_real_time_flag=0;
//左圆环准确弛懈识别标志
uint16 cur_L_real_time_flag1=0;
//左圆环准确弛懈识别标志 1
uint8 cur_R_real_flag=0;
//右圆环准确判断识别标志
uint8 cur_R_real_delay_flag=0;
//右圆环准确弛懈识别标志
uint8 cur_R_real_rest_flag=0;
//右圆环准确复位识别标志
uint16 cur_R_real_time_flag=0;
//右圆环准确弛懈识别标志
uint16 cur_R_real_time_flag1=0;
//右圆环准确弛懈识别标志 1
/***************************END**********************************/
//---------------------------------------------------------------
//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//---------------------------------------------------------------
/*************************函数声明*******************************/
/*初始化部分*/
void IO_init(void);
/*调试界面部分*/
//车辆端口初始化
void speed_SW(void);
//速度档位选择
void Board_led_duty(void);
//板载 LED 闪烁函数
void BEEP_duty(void);
//蜂鸣器控制函数
uint8 Button_Duty(uint8 Button_val);
//按键设置函数
void GUI_Duty(void);
//调试界面函数
/*图像处理部分*/
void img_ext(uint8 *dst,uint8 *src,uint32 srclen);//数组解压函数
void len_init(void);
//赛道宽度初始化
void street_duty(void);
//赛道直道长度测量
uint8 PointL_DUTY(uint8 L_Start,uint8 L_y);//边线扫描函数
uint8 PointR_DUTY(uint8 R_Start,uint8 R_y);//边线扫描函数
void mid_Point_DUTY(uint8 Mid_len,uint8 Mid_y);//补线算法
void IMG_DUTY(void);
//主图像处理函数
/*事件管理部分*/
void EVENT_Duty(void);
//事件管理函数
/*车辆控制部分*/
void DJ_PID(unsigned char midpoint_in);//舵机 PD
void FEED_COUNT(void);
//编码器计数结算
void speed_PID(unsigned char speed_in);//转速 PID 控制函数
void CAR_Drive_duty(void);
//执行机构综合控制函数
/*中断函数部分*/
void PORTC_IRQHandler();
//PORTC 中断服务函数
void DMA0_IRQHandler();
//DMA 中断服务函数
void PIT0_IRQHandler();
//PIT0 中断服务函数
void PORTD_IRQHandler();
//PORTD 中断服务函数
/**********************车辆端口初始化****************************/
void IO_init(void)
{
/*****蜂鸣器输出端口******/
gpio_init (PTE28 ,GPO,0);
/******板载 LED 端口*******/
gpio_init (PTA17,GPO,1);
gpio_init (PTC0, GPO,1);
gpio_init (PTD15,GPO,1);
gpio_init (PTE26,GPO,1);
/*****播码开关接口*******/
gpio_init (PTE4, GPI,0);
gpio_init (PTE6, GPI,0);
gpio_init (PTE8, GPI,0);
gpio_init (PTE10,GPI,0);
/*******五轴按键接口*****/
gpio_init (PTE7,GPI,0); //左
gpio_init (PTE5,GPI,0); //下
gpio_init (PTE12,GPI,0); //右
gpio_init (PTE11,GPI,0); //中
gpio_init (PTE9,GPI,0); //上
/*******编码器接口*******/
gpio_init (PTD0,GPI,0);
gpio_init (PTD1,GPI,0);
port_init (PTD0,ALT1|IRQ_EITHER|PULLUP );
/******电机 PWM 接口*******/
ftm_pwm_init(FTM0, FTM_CH0,1000,0);
ftm_pwm_init(FTM0, FTM_CH1,1000,0);
/******舵机 PWM 接口*******/
ftm_pwm_init(FTM2, FTM_CH0,50,7200);
}
/*******************************************************************************/
//
//
//
上一部分:初始化区段
下一部分:调试界面部分
/*******************************************************************************/
/********************速度档位选择************************/
void speed_SW(void)
{
if(speed_SW_flag==1)
//速度档位 1
{
}
speed_need_Boost=30;
//目标高速 30
speed_need_normal=25;
//目标速度 25
speed_need_L=26;
//目标弯道
KP_A=10,KP_B=27,KD=150; //6
else if(speed_SW_flag==2)
//速度档位 2
{
speed_need_Boost=32;
//目标高速
speed_need_normal=26;
//目标速度
speed_need_L=27;
//目标弯道
KP_A=20,KP_B=27,KD=180;
}
else if(speed_SW_flag==3)
//速度档位 3
{
}
speed_need_Boost=33;
//目标高速
speed_need_normal=27;
//目标速度
speed_need_L=28;
//目标弯道
KP_A=20,KP_B=27,KD=180;
else if(speed_SW_flag==4)
//速度档位 4
{
speed_need_Boost=34;
//目标高速
speed_need_normal=27;
//目标速度
speed_need_L=28;
//目标弯道
KP_A=25,KP_B=27,KD=180;
}
else;
}
/********************板载 LED 闪烁函数************************/
void Board_led_duty(void)
{
}
gpio_turn (PTD15);
gpio_turn (PTE26);
gpio_turn (PTA17);
gpio_turn (PTC0);
/********************蜂鸣器控制函数************************/
void BEEP_duty(void)
{
}
//if(!gpio_get(PTE11)||lost_flag)
//工作条件
if(!gpio_get(PTE11)||cur_L_real_delay_flag||cur_R_real_delay_flag)
gpio_set (PTE28,0);
else gpio_set (PTE28,1);
/********************按键设置函数****************************/
uint8 Button_Duty(uint8 Button_val)
//按键计数函数
{
if(!gpio_get(PTE9))
//按键加
{
DELAY_MS(10);
if(!gpio_get(PTE9))
//二次判断
Button_val ;
if(Button_val>250)
//限幅
Button_val=250;
while(!gpio_get(PTE9));
{
}
}
if(!gpio_get(PTE5))
//按键减
{
DELAY_MS(10);
if(!gpio_get(PTE5))
//二次判断
Button_val--;
if(Button_val<2)
//限幅
Button_val=1;
while(!gpio_get(PTE5));
{
}
}
return Button_val;
}
/*******************调试界面函数**************************/
void GUI_Duty(void)
{
/*********系统设置***********/
unsigned char static GUI_flag=0;
//调试界面变量
unsigned char static display_y=25;
//调试行数变量
if(!gpio_get(PTE12))
//改变界面
{
DELAY_MS(10);
if(!gpio_get(PTE12))
//二次确认
LCD_Fill(0x00);
GUI_flag ;
if(GUI_flag>2)
GUI_flag=0;
while(!gpio_get(PTE12));
//清屏
//设置界面页数
{
}
}
/*********板载 LED 指示********/
Board_led_duty();
/*********蜂鸣器控制********/
BEEP_duty();
/*********调试界面#0***********/
if(GUI_flag==0)
{
}
LED_PrintImage(img,60,80);
//OLED 显示图像
display_y=Button_Duty(display_y);
//按键设置行数
Display_uint8(display_y,85,0);
//OLED 显示行数
Display_uint8(mid_point[display_y],85,2);
//OLED 显示中线
Display_uint8(street_len,85,4);
//赛道直道长度测量
//Display_uint8(code_Time_flag,85,6);
//显示程序运行时间
Display_uint8(point_len[display_y],85,6);
//OLED 显示赛道宽度
/*********调试界面#1***********/
else if(GUI_flag==1)
{
}
LCD_P8x16Str(1,0,"DJ_PWM");
//OLED 显示舵机 PWM
Display(DJ_PWM,1,2);
LCD_P8x16Str(1,4,"Speed_SET");
//OLED 显示设定速度
/***速度档位选择***/
Display(speed_SW_flag,1,6);
//显示速度选择标志
speed_SW_flag=Button_Duty(speed_SW_flag);
//速度档位选择
if(speed_SW_flag>4)speed_SW_flag=1;
speed_SW();
//速度档位选择函数
else if(GUI_flag==2)
{
LCD_P8x16Str(10,2,"START ENGINE!");
//一键启动
if(!gpio_get(PTE11))
{KEY_start_flag=1;Block_motor_delay_flag=0;}//启动标志值置 1 电机堵转保护复位
else;
if(Block_motor_duty_flag)
LCD_P8x16Str(10,5,"Block_motor!");
//电机堵转
else if(!KEY_start_flag)
LCD_P8x16Str(10,5,"
Loop
");
//停车
else if(KEY_start_flag && KEY_start_time_flag<100)
LCD_P8x16Str(10,5,"
READY
");
//准备
//else if(KEY_start_time_flag>100 && !stop_motors_flag)
else if(KEY_start_time_flag>100)
LCD_P8x16Str(10,5,"
Voom!
");
//启动!
else
LCD_P8x16Str(10,5,"
STOP
");
//停车
}
else;
/************END**************/
}
/*******************************************************************************/
//
上一部分:调试界面部分
//
//
下一部分:图像处理部分
/*******************************************************************************/
/********************摄像头数组解压*************************/
void img_ext(uint8 *dst, uint8 *src, uint32 srclen)
{
uint8 colour[2] = {255, 0}; //0 和 1 分别对应的颜色
//注:山外的摄像头 0 表示 白色,1 表示 黑色
uint8 tmpsrc;
while(srclen --)
{
tmpsrc = *src ;
*dst
= colour[ (tmpsrc >> 7 ) & 0x01 ];
*dst
= colour[ (tmpsrc >> 6 ) & 0x01 ];
*dst
= colour[ (tmpsrc >> 5 ) & 0x01 ];
*dst
= colour[ (tmpsrc >> 4 ) & 0x01 ];
*dst
= colour[ (tmpsrc >> 3 ) & 0x01 ];
*dst
= colour[ (tmpsrc >> 2 ) & 0x01 ];
*dst
= colour[ (tmpsrc >> 1 ) & 0x01 ];
*dst
= colour[ (tmpsrc >> 0 ) & 0x01 ];
}
}
/*********************赛道宽度初始化************************/
void len_init(void)
//赛道宽度初始化
{
}
for(img_y=img_y_min;img_y<=img_y_max;img_y )
{
}
init_len[img_y]=img_y 30;
/********************赛道直道长度测量**********************/
void street_duty(void)
//赛道直道长度测量
{
/*中线直道长度测量*/
for(img_y=55;img_y>=1;img_y--)
{
}
if(img[40 img_y*80]==0)
break;
else;
street_len=59-img_y;
/*右圆环切入点测量*/
for(img_y=55;img_y>=1;img_y--)
{