#include <hidef.h> /* common defines and macros */
#include <MC9S12XS128.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12xs128"
//定义全局变量
//函数声明
void system_init(void);
void set_parameter(void);
void clock_init(void) ;
void AD_Init(void);
void PWM_init(void);
void read(void);
void calculate(void);
void PACBInit(void);
void MDCInit(void);
void direct_ctl(void);
void steer_ctl(void);
void speed_ctl(void) ;
void motor_ctl(void);
void slow1(void);
void slow2(void);
void slow3(void);
void slow4(void);
void slow5(void);
void acc1(void);
void acc2(void);
void acc3(void);
int blackline;
int qian[10];int gear,d1,d2;
int counter_a;static int lock,lock_o; //前后两排在黑线阀值上的灯数
int one,two,three;int one_o,two_o; //前排灯在黑线上的灯编号
int biga,bigb,bigc; //前排最大的三个电压值he后排的最大值
int tan_n,tan_o,tan_n1,tan_n2,tan_n3,tan_n4,tan_n5,tan_n6;//黑线位置
int differa,differa_6,differa_5,differa_4,differa_3,differa_2,differa_1,differa_o; //轨迹参数
int differb;
int pianxin[10]={-100,-75,-50,-30,-10,10,30,50,75,100};int start,once;
int w,x,y,s,k; //延时计数
static unsigned int f=0;//刹车延时
int zhuan;//舵机偏移占空比
int speed,out;//脉冲数(0.02秒20至70)
int go=0;//赛程标志时间改变
int state,state_o,sure; //0 直道
//速度参数
int test;
int test;
void PACBInit()
{
TSCR1_TFFCA=1; //快速清除flag:PAOVF PAIF
/* DATASHEET P472
* To operate the 16-bit pulse accumulator independently of input capture or output compare 7 and 0
* respectively the user must set the corresponding bits IOSx = 1, OMx = 0 and OLx = 0. OC7M7 in the
* OC7M register must also be cleared.
*/
TIOS_IOS7=1; //单独使用16位脉冲累加器
OC7M_OC7M7=0;; //注意此时必须令IOS7=1,OC7M7=0,OM7=0,OL7=0
TCTL1_OM7=0;
TCTL1_OL7=0;
PACTL_PAMOD=0; //事件计数方式
PACTL_PEDGE=1; //PT7引脚上的出现上升沿时脉冲累加器计数器加1
PACTL_PAOVI=0; //允许脉冲累加器产生溢出时引发中断
PACTL_PAI=0; //允许PT7引脚上出现上升沿时引发中断
PACTL_PAEN=1; //启动脉冲累加器A
PACNT = 0x0000;
}
void MDCInit(void)
{
PITCFLMT=0x00;
PITCE=0x01;
PITMTLD0=249;
PITLD0=159;
PITINTE=0x01;
PITCFLMT=0x80;
PITMUX=0X00;
}
//-----系统初始化-----------------------
void system_init(void) //system initiat
{
set_parameter();
clock_init(); //clock initiat
PWM_init(); //pwm initiat
AD_Init(); //ATD initiat
}
void set_parameter(void)
{
tan_n=0;tan_o=0;
one=4;one_o=4;two=5;two_o=5;lock=0;lock_o=0;
blackline=700;zhuan=0;speed=0;
gear=0;
once=0;
start=0;
differa_6=0;differa=0;differb=0;
f=0;
}
void clock_init(void) //时钟初始化
{
CLKSEL=0X00; // not select PLL to system
PLLCTL_PLLON=1; // turn on PLL
SYNR=0x04;
REFDV=0x01; // busclock=osc*(1+SYNR)/(1+REFDV)
POSTDIV=0x00;
_asm(nop); // SYNR=0x04;REFDV=0x01;BUS CLOCK=40M
_asm(nop); // SYNR=0x05;REFDV=0x01;BUS CLOCK=48M
while(!(CRGFLG_LOCK==1)); //when pll is steady ,then use it;
CLKSEL_PLLSEL =1; //select PLL to system;
}
void AD_Init(void)
{
ATD0CTL0 = 0x0f;
ATD0CTL1 = 0x20; //10位转换
ATD0CTL2 = 0x40; // 0100_0000 AD模块上电, 快速清零, 无等待模式, 禁止外部触发, 中断禁止
ATD0CTL3 = 0x80; //1000_0100 转换长度为一
ATD0CTL4 = 0x01; // prs =9 9us fATDCLK=fBUS/[2 × (PRS + 1)]
DDRA=0x00;
DDRB=0xff;
PORTB=0xff; // prs =6 6.0us
// prs =5 5.1us
// prs =4 4.25us ok*40/11
// prs =3 3.3us
// prs =2 2.64 使用中
// prs =1 1.8
// prs =0 1us
ATD0CTL5 = 0b00110000; //第0通道转换
ATD0DIEN = 0x00;
}
void PWM_init(void)
{
PWME =0x00; //关闭
PWMPOL=0xff; //先高电平
PWMCAE=0x00; //左对齐
PWMCLK=0xcc; //选择0,1,4,5通道时钟源头A 2,3通道时钟源头SB, 6,7 通道时钟源头B
PWMPRCLK=0x33; //时钟预分频clockA为8, clockB为8
//set servo
PWMCTL_CON45=1; //使得通道0,1成为16位pwm
PWMPER4 =0x75;
PWMPER5 =0x30; //舵机的频率是: 50Hz 24M/8/30000=100Hz,T=10ms
PWMDTY45=4700; // 对应为4590/30000的占空比 6000left 6900 7800right
//set motor
PWMSCLB =60; // 24MHZ/8/2/15=100K
PWMPER6 =100; //电机的频率是: 24M/8/2/75/100=200Hz,T=5ms
PWMDTY6 =0; //用于测试电机
PWMPER7 =100; //电机的频率是: 24M/8/2/15/500=200Hz,T=5ms
PWMDTY7 =0; //用于测试电机
//set motor
PWMSCLB =60; //10kHz 24MHZ/8/2/50=30K
//PWM2为正转
PWMPER2 =100; // 频率是:100Hz 24M/8/2/50/100=300Hz,T=3.33ms
PWMDTY2 =30; // 用于测试电机
//PWM3为反转
PWMPER3 =100; //
PWMDTY3 =0; // 用于测试电机
DDRP =0xff; //控制输出
PWME =0xff; //开放通道
}
//----------红外检测---------
void read(void)
{
while(!ATD0STAT2_CCF0);
qian[0]=ATD0DR0;
while(!ATD0STAT2_CCF1);
qian[1]=ATD0DR1;
while(!ATD0STAT2_CCF2);
qian[2]=ATD0DR2;
while(!ATD0STAT2_CCF3);
qian[3]=ATD0DR3;
while(!ATD0STAT2_CCF4);
qian[4]=ATD0DR4;
while(!ATD0STAT2_CCF5);
qian[5]=ATD0DR5;
while(!ATD0STAT2_CCF6);
qian[6]=ATD0DR6;
while(!ATD0STAT2_CCF7);
qian[7]=ATD0DR7;
while(!ATD0STAT2_CCF8);
qian[8]=ATD0DR8;
while(!ATD0STAT2_CCF9);
qian[9]= ATD0DR9;
d1=PORTA_PA0;
d2=PORTA_PA1;
} //read
//计算
void find(void)
{ int n;
biga=0;
for(n=0;n<10;n++) //寻找最大值
{if(biga<qian[n]){biga=qian[n];one=n;}}
bigb=0;
for(n=0;n<10;n++) //寻找第二大值
{if((bigb<qian[n])&&n!=one){bigb=qian[n];two=n;}}
bigc=0;
for(n=0;n<10;n++) //寻找第三大值
{if((bigc<qian[n])&&n!=one&&n!=two){bigc=qian[n];three=n;}}}
//数据处理
void calculate(void)
{
int n;
gear=0;
if(d1==0&&d2==0) gear=1; // 统计档位数目
if(d1==1&&d2==0) gear=2;
if(d1==0&&d2==1) gear=3;
if(d1==1&&d2==1) gear=4;
counter_a=0; //数黑线上的灯
for(n=0;n<=9;n++)
{
if(qian[n]>blackline)
counter_a++;
}
find();
/******滤波*****/
if((qian[1]>blackline&&(qian[4]>blackline||qian[5]>blackline)&&qian[8]>blackline&&
(qian[9]>blackline||qian[0]>blackline)
&&qian[3]<blackline&&qian[6]<blackline)
)
{start++;counter_a=12;one=4;two=5;lock=0;}
if(counter_a!=12&&start<20)start=0;
if(start>19&&counter_a<3)
{
if(go!=3){start=0;once=0;}
if(go==3){once++;start=0;}
}
//起始线次数
if(counter_a==0) {
if(tan_o<-90) {tan_n=-105;one=0;two=1;lock=1;}
if(tan_o>90) {tan_n=105;one=9;two=8;lock=2;}
if(tan_n<91&&tan_n>-91)
{ tan_n=tan_o;one=one_o;two=two_o;counter_a=0;lock=0;}
}
switch(lock) {
case 1: { tan_n=-102;lock=1;
if(counter_a==1&&one==0) {
tan_n=-100;lock=0;
} one=0;two=1;
break;}
case 2: {tan_n=102;lock=2;
if(counter_a==1&&one==9){ tan_n=100;lock=0;
}one=9;two=8;