|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
/********************这是以前做比赛是写过的一些代码,分享出来,仅供参考而也******************/
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uint i,t;
long counter; //编码器脉冲数值
uchar finish=0;//停车标志
//--------传感器变量------------
sbit ri1=P0^0; //*左边传感器*//
sbit ri2=P0^1;
sbit ri3=P0^2;
sbit mid=P0^3;//*中间传感器*//
sbit le3=P0^4;
sbit le2=P0^5;
sbit le1=P0^6;//*右边传感器*//
sbit bz=P2^7;//蔽障管
//-------电机舵机控制变量-----------
sbit ENA=P1^0; //驱动电机pwm//
sbit moto1=P1^1; //电机控制//
sbit moto2=P1^2;
sbit PWM=P1^4; //舵机pwm//
//---------转角变量---------
uint angle;
uint absolute(int);
//--------速度变量----------
uint pro; //驱动电机调速
uint car_driver; //驱动力参数
uint pulse_speed; //电机当前速度
uint ideal_speed; //理想状态下的速度
int speed_error; //理想速度与当前速度的差值
int pre_error=0; //PID控制的速度差值
int pre_d_error=0; //PID控制的速度上一次的差值
int pk=0,error=0; //速度的PID值
int speedmax;
//----------表格值----------
uint code speed_table[]={50,40,40};
uint code angle_table[]={110,75,110};
#define kp 213
#define ki 7
#define kd 15
//-----------函数定义-------
void init();
void delay(uint);
void qctyp();
void duoji();
void carposition();
void speed();
void pid();
//=============主函数==========
void main()
{
init();
while(1)
{
qctyp();
carposition();
speed();
}
}
//===========子函数============
//-----------初始化-----------
void init()
{
TMOD=0x11;//设定双定时器
EA=1;
// EX0=1;//开外部中断0
// TCON=0x01;
TR0=1;
TR1=1;
TH0=(65536-20000)/256;
TL0=(65536-20000)%256;//设定定时初始值,可去下载个定时器计算软件,20ms
TH1=(65536-1000)/256;
TL1=(65536-1000)%256;
ET0=1;
ET1=1;
ENA=1;
pulse_speed=0;
speedmax=0;
}
//---------延时函数----------
void delay(uint n)
{
uchar a,b,c;
for(c=1;c>0;c--)
for(b=n;b>0;b--)
for(a=2;a>0;a--);
}
//-------光电管全无状态时(脱离轨道),读取前次状态---------
void qctyp()
{
ri1=P0^0;
ri2=P0^1;
ri3=P0^2;
mid=P0^3;
le3=P0^4;
le2=P0^5;
le1=P0^6;
}
//-------循迹函数,读取光电管状态------------
void carposition()
{
if(!le1&&!le2&&!le3&&mid&&!ri3&&!ri2&&!ri1)
{
angle=0;
}
else if(le3&&!mid&&!ri3&&!ri2&&!ri1)
{
angle=1;
}
else if(le2&&!mid&&!ri3&&!ri2&&!ri1)
{
angle=1;
}
else if(le1&&!mid&&!ri3&&!ri2&&!ri1)
{
angle=1;
}
else if(ri1&&!mid&&!le3&&!le2&&!le1)
{
angle=2;
}
else if(ri2&&!mid&&!le3&&!le2&&!le1)
{
angle=2;
}
else if(ri3&&!mid&&!le3&&!le2&&!le1)
{
angle=2;
}
}
//-----------舵机控制-------------
void duoji() //舵机控制
{
PWM=1;
delay(angle_table[angle]); //可改变舵机转向角度
PWM=0;
}
//-----------------计算车的速度-----------------
void speed()
{ /*
if(speedmax<=pulse_speed) speedmax=pulse_speed;
if(speedmax>=40)
speedmax=40;
pid();
pro=car_driver;//变量y是改变小车速度这里范围是0--39
*/
pro=speed_table[angle];
moto1=1;
moto2=0;
}
//------------PID控制----------------
/*
void pid()
{
signed int d_error, dd_error; //error=speed_error
ideal_speed=speed_table[angle];
error=ideal_speed-pulse_speed;
d_error=error-pre_error; //d_error 当前速度差与上一次速度差之差
dd_error=d_error-pre_d_error;
pre_error=error; //存储当前偏差
pre_d_error=d_error;
pk+=kp*d_error+ki*error+kd*dd_error;
if(pk<=0) pk=0;
else if(pk>=40) pk=40;
car_driver=pk;
}
//-----------中断---------------
void exter0() interrupt 0
{
counter++;
} */
void timer0() interrupt 1//产生pwm信号控制舵机,周期20ms
{
TH0=(65536-20000)/256; //1011 0001 即THO=(65536-20000)/256
TL0=(65536-20000)%256; //1110 0000 即TLO=(65536-20000)%256
duoji();
}
void timer1() interrupt 3//产生pwm信号控制驱动电机速度
{
TH1=(65536-1000)/256;
TL1=(65536-1000)%256;
i++;
if(i<=pro)
{
ENA=1;
}
else
{
ENA=0;
}
if(i==50)
{
ENA=~ENA;
i=0;
}
/* t++;
if(t==1000)
{
t=0;
pulse_speed=4*counter/500; //速度=编码器主动轮周长(M)*脉冲/分辨率
counter=0;
} */
} |
|