2012飞思卡尔 哈尔滨工业大学智能车程序

合集下载

第五界飞思卡尔智能车大赛程序(光电组)

第五界飞思卡尔智能车大赛程序(光电组)
speed_expect=speed_set[0];
}
else if(turn_value==direction_turn[0])
{
turn_value=direction_turn[0];
speed_expect=speed_set[0];
}
break;
case 2:if(turn_value==direction_turn[0])
//The PIT module has no external pins.
//PIT 模式没有外部引脚
unsigned char light=0; //激光管检测标志
unsigned short turn_value=0; //转向的PWM数值
unsigned short direction_turn[7]={333,430,560,647,705,780,888}; //转向给定值初始化
{
turn_value=direction_turn[6];
speed_expect=speed_set[6];
}
else if(turn_value==direction_turn[6])
{
turn_value=direction_turn[6];
speed_expect=speed_set[6];
}
else if(turn_value==direction_turn[2])
{
turn_value=direction_turn[1];
speed_expect=speed_set[1];
}
break;
case 4:if(turn_value==direction_turn[1])

飞思卡尔智能车dg128单片机控制程序代码

飞思卡尔智能车dg128单片机控制程序代码
}
void AD_Init(void)
{
ATD0CTL2=0xC0; //AD模块上电, 快速清零, 无等待模式, 禁止外部触发, 中断禁止
ATD0CTL3=0x44; //每次转换8个序列, FIFO, Freeze模式下继续转
ATD0CTL4=0x02; //10位精度, 采样时间为2个AD时钟周期,ATDClock=4MHz
//设置舵机
PWMCTL_CON01=1; //使得通道0,1成为16位pwm
PWMPER0 =0x75;
PWMPER1 =0x30; //舵机的频率是: 24M/8/30000=100Hz,T=10ms
PWMDTY01=4500; // 对应为4500/30000的占空比,待调整
Infrared_detect();
data_handle();
motor_ctl();
steer_ctl();
}
}
void interrupt 26 MDC_ISR(void)
{
static unsigned int number_count=0; static unsigned int start=0; static
go=2;
if(begin>=150)
go=3;
}
}
}
//-----系统初始化-----------------------
void system_init(void) //system initiat
void speed_ctl(void); //速度控制
void motor_ctl(void); //电机控制
void PACBInit(void);

飞思卡尔智能车最终完整程序 具有很高的参考价值

飞思卡尔智能车最终完整程序 具有很高的参考价值

#include<hidef.h>/* common defines andmacros */#include<mc9s12dg128.h>/* derivativeinformation *///#include "PWM.h"//#include "AD.h"#include"control.h"#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"word AD_wData[9]; //全局变量存放AD0,AD1,AD2的结果word sum[9]; //初始化时为求平均值,全白中,各个灯的FF次的电压和word avrg0[9]; //全白时各个灯的平均电压word summ[9];//初始化时为求平均值,全黑中,各个灯的FF次的电压和word avrg1[9]; //全黑时各个灯的平均电压word ss[9]; //实际采集来的各个灯的电压word s[9]; // 实际采集来的各个灯的电压word sum2[8];//用于存放两两灯电压之和word k; //用于存放比较出的最大值uint h=1500;//转角大小int flag = 0;//标志中间灯是否第一次在黑道附近int flagg=0;//标志灯从哪边感应到黑道int flagg1=0;//标志灯从哪边感应到黑道int flagg0=0;//标志是左边还是右边出道int j=0;dword i;dword m;dword s0;dword s1;dword p11=0;//以下四个变量用于记录黑道处于同一侧的时间dword p12=0;dword p21=0;dword p22=0;word max0[9]=0;//初始化时采集来的黑道的值int g=0;//为过滤算法使用word cha[9];//用来存放黑白电压差int ffgg0=0;//标志是否用中间板采的数据int ffgg1=0;//标志是否用中间板采的数据word sum0=0; //初始化时采集来个灯的全白电压和//word sum1=0; //实际采集来的左个灯的电压和//word sum22=0; //实际采集来的右个灯的电压和int fla=0;//标志是出道还是入道void AD_Init();void PWM_Init();void PWM_Init1();//void PID();void AD_Init(void) //AD初始化{//控制寄存器:上电,标志位快速清零,开中断ATD0CTL2 =(ATD0CTL2_ADPU_MASK|ATD0CTL2_AFFC_MASK|ATD0CTL2_ASCIE_MASK) ;ATD1CTL2 =(ATD1CTL2_ADPU_MASK|ATD1CTL2_AFFC_MASK|ATD1CTL2_ASCIE_MASK) ;//控制寄存器:转换序列长度为ATD0CTL3 =0x78;//(ATD0CTL3_S2C_MASK|ATD0CTL3_S1C_MASK);ATD1CTL3 =0x78;//(ATD1CTL3_S2C_MASK|ATD1CTL3_S1C_MASK);//控制寄存器:ATD0CTL4 =(ATD0CTL4_SRES8_MASK|ATD0CTL4_PRS1_MASK|ATD0CTL4_PRS0_MASK) ;ATD1CTL4 =(ATD1CTL4_SRES8_MASK|ATD1CTL4_PRS1_MASK|ATD1CTL4_PRS0_MASK) ;//控制寄存器:ATD0CTL5 =(ATD0CTL5_DJM_MASK|ATD0CTL5_SCAN_MASK|ATD0CTL5_MULT_MASK);ATD1CTL5 =(ATD1CTL5_DJM_MASK|ATD1CTL5_SCAN_MASK|ATD1CTL5_MULT_MASK); ATD0DIEN=0x00; // 禁止数字输入缓冲ATD1DIEN=0x00; // 禁止数字输入缓冲}#pragma CODE_SEG NON_BANKED //中断服务程序#pragma TRAP_PROCvoid interrupt 22 Int_AD0(void){AD_wData[0] = ATD0DR0; //将结果寄存器中的值存放到数组中AD_wData[1] = ATD0DR1; //将结果寄存器中的值存放到数组中AD_wData[2] = ATD0DR2; //将结果寄存器中的值存放到数组中AD_wData[3] = ATD0DR3;AD_wData[4] = ATD0DR4;AD_wData[5] = ATD0DR5;AD_wData[6] = ATD0DR6;AD_wData[7] = ATD0DR7;AD_wData[8] = ATD1DR0;}#pragma CODE_SEG DEFAULTword max(word a,word b,word c,word d,word e,wordf,word r,word w) {word maxx=0;if(a>maxx)maxx=a;if(b>maxx)maxx=b;if(c>maxx)maxx=c;if(d>maxx)maxx=d;if(e>maxx)maxx=e;if(f>maxx)maxx=f;if(r>maxx)maxx=r;if(w>maxx)maxx=w;return maxx;}void delay0(){for(i=0;i<0xFFFF;i++)for(m=0;m<0x05;m++);}void delay1(){for(i=0;i<0xFFFF;i++);// for(i=0;i<0xFFFF;i++);}void main(void){AD_Init(); //AD 初始化DDRB = 0xFF;DDRA_BIT6=0; //A_BIT6口作为第二块板左边传感器的输入口DDRA_BIT7=0; //A_BIT7口作为第二块板右边传感器的输入口 PORTB = 0xFF;p=0;for(j=0;j<9;j++){AD_wData[j] = 0; //全局变量初始化sum[j]=0;avrg0[j]=0;avrg1[j]=0;summ[j]=0;}for(j=0;j<9;j++) {max0[j]=0;ss[j]=0;}for(j=0;j<8;j++)sum2[j]=0;EnableInterrupts; //开AD中断for(i=0;i<0xFFFF;i++);for(i=0;i<0xFF;i++) //只能是FF,防止下面sum溢出 {for(j=0;j<9;j++)//采集白道路信息{sum[j]=sum[j]+AD_wData[j];}}for(i=0;i<9;i++) {sum0=sum0+sum[i]/0xFF;avrg0[i]=sum[i]/0xFF;}PORTB=sum[0]/0xFF; //显示通道采集到的值 delay0();PORTB=0x00;//显示马上得进行黑道信息采集了 delay1();for(j=0;j<9;j++){for(m=0;m<0xFF;m++){summ[j]=summ[j]+AD_wData[j];}avrg1[j]=summ[j]/0xFF;PORTB=avrg1[j]; //显示采来的黑道信息cha[j]=avrg1[j]-avrg0[j];delay0();PORTB=0x00; //显示马上得进行下一次黑道信息采集了 delay1();}PORTB=0x00;//灯全亮,提示车马上就可以跑了delay1();PWM_Init() ;PWM_Init1(1500,1,200);for(i=0;i<0xFFF;i++);// delay1();for(;;){int f=0;u3=100;if(flagk1==1){p21=0;flagk2=0;p11++;if(p11==0xFFF)flagkk1=1;}else if(flagk2==1){p11=0;flagk1=0;p21++;if(p21==0xFFF)flagkk2=1;}for(f=0;f<9;f++){s[f]=AD_wData[f];ss[f]=s[f]-(avrg0[f]-0x50); //当前值减去初始白道值,以便比较}for(f=0;f<8;f++)sum2[f]=ss[f]+ss[f+1]; //两两灯电压之和//减去.6V防止溢出*******************if(AD_wData[0]<0xC0&& AD_wData[1]<0xC0&&AD_wData[2]<0xC0&&AD_wData[3]<0xC0&&AD_wData[4]<0xC0&&AD_wData[5]<0xC0&&AD_wData[6]<0xC0&&AD_wD ata[7]<0xC0&&AD_wData[8]<0xC0){if(sum2[0]<0xC0&&sum2[1]<0xC0&&sum2[2]<0xC0&&sum2[3]<0xC0&&sum2[4]<0xC0&&sum2[5]<0xC0&&sum2[6]<0xC0&&sum2[7]<0xD0){fla=1;if(flagg0==1){for(i=0;i<0xFF;i++);PWM_Init1(1140,u1,200);flagk1=1;flagkk2=0;for(;;){if(AD_wData[4]>0xB0||AD_wData[5]>0xB0||AD_wData[6]>0xB0|| AD_wData[7]>0xB0||AD_wData[8]>0xB0){flagg0=0;break;}}}else if(flagg0==2){for(i=0;i<0xFF;i++);PWM_Init1(1860,u1,200);flagk1=0;flagkk2=1;for(;;)if(AD_wData[0]>0xB0||AD_wData[1]>0xB0||AD_wData[2]>0xB0||AD_wData[3]>0xB0||AD_wData[4]>0xB0){flagg0=0;break;}}}else{}}else{if(s[0]-(avrg0[0]-0x13)<0x40 &&s[1]-(avrg0[1]-0x13)<0x40 &&s[2]-(avrg0[2]-0x13)<0x40 && s[3]-(avrg0[3]-0x13)<0x40 &&s[4]-(avrg0[4]-0x13)<0x40 && s[5]-(avrg0[5]-0x13)<0x40 &&s[6]-(avrg0[6]-0x13)<0x40 && s[7]-(avrg0[7]-0x13)<0x40&&s[8]-(avrg0[8]-0x13)<0x40)///////////注意调整该值***************{/* if(PORTA_BIT6!=0||PORTA_BIT7!=0){if(PORTA_BIT6!=0&&PORTA_BIT7==0)PWM_Init1(1900,200,1);else if(PORTA_BIT7!=0&&PORTA_BIT6==0)PWM_Init1(1100,200,1);}*/}else{k=max(sum2[0],sum2[1],sum2[2],sum2[3],sum2[4],sum2[5],sum2[ 6],sum2[7]);//谁两和最大,黑道就在谁两之间if(k==sum2[0]){p=0;flagg0=2;if(fla==1)control_11();else if(fla==0) control_1();}else{if(k==sum2[1]){p=0;p1=0;fla=0;control_2(s[1],s[2],ss[1],ss[2],cha[1],cha[2],avrg0[1],avrg 0[2]);}else{if(k==sum2[2]){p=0;p1=0;fla=0;control_3(s[2],s[3],ss[2],ss[3],cha[2],cha[3],avrg0[2],avrg 0[3]);}else{if(k==sum2[3]){p=0;p1=0;fla=0;control_4(s[3],s[4],ss[3],ss[4],cha[3],cha[4],avrg0[3],avrg 0[4]);}else{if(k==sum2[4]){fla=0;p1=0;control_5(s[4],s[5],ss[4],ss[5],cha[4],cha[5],avrg0[4],avrg 0[5]);}else{if(k==sum2[5]){fla=0;p1=0;control_6(s[5],s[6],ss[5],ss[6],cha[5],cha[6],avrg0[5],avrg 0[6]);}else{if(k==sum2[6]){p=0;p1=0;fla=0;control_7(s[6],s[7],ss[6],ss[7],cha[6],cha[7],avrg0[6],avrg 0[7]);}else{if(k==sum2[7]){p=0;flagg0=1;if(fla==0) control_8();elseif(fla==1)control_88(); } else{}}}}}}}}}}}}。

飞思卡尔智能车完整程序

飞思卡尔智能车完整程序

#include <hidef.h> /* common defines and macros */#include <mc9s12dg128.h> /* derivative information */ #include "lib.c"#include "funtion.h"#pragma LINK_INFO DERIV ATIVE "mc9s12dg128b"void s_ini(void) //系统初始化{uchar tmp;SYNR=3;REFDV=1;PLLCTL=0x50;delay(100);CLKSEL|=0x80; //超频到48M, 总线24M// INITRG = 0x00; /* lock registers block to 0x0000 */// INITRM = 0x39; /* lock Ram to end at 0x3FFF */// INITEE = 0x09; /* lock EEPROM block to end at 0x0fff */ delay(100);PORTB=0xff;DDRB=0xff;DDRA=0x00; //A口设置为输入PTH=0x00;DDRH=0x68; //PH1=inputPERH=0x97; //enable pullPPSH=0x80; //PH7,PH6,PH5 pull up, PH4 pull down PIEH=0x00; //使能遥控中断PH7PTP =0x00;DDRP=0x30; //PP4,PP5 outputDDRA=0x00;PUCR=0x01; //Port A enable pull upPTJ=0x00;DDRJ=0x00;PERJ=0x00; //diable pullPPSJ=0x80;PIEJ=0xc0; //enable PJ interruptPTT=0x00;DDRT=0x00; //PT7-PT4 =inputPERT=0x40; //enable pull for PT6// PACN3=0x00;// PACN2=0x00;// PACTL=0x40; //enable pulse couter B// DL YCT=0x00; //TIOS=0x80; //ch 7 compare modeOC7M=0x00;OC7D=0x00;// PACTL=0x74;TSCR2=0x0f; //when ch7 compare rst pre div =128 TC7=50000; //timer for 200mS //*/TSCR1=0x80; //enable timerTCTL1=0x00;TCTL2=0x00;TCTL3=0x20;TCTL4=0x00; //通道6下降沿输入捕捉TIE =0xC0; //中断使能ini_at45(); //初始化SPI0PWME=0xc3; //enable ch1, ch7PWMPOL=0xc3; //high level effectPWMDTY6=(uchar)(3000>>8);PWMDTY7=(uchar)(3000&0x00ff); //占空比PWMPER6=(uchar)(40000>>8); // 舵机PWMPER7=(uchar)(40000&0x00ff); //周期PWMDTY0=(uchar)(0>>8);PWMDTY1=(uchar)(0&0x00ff); //占空比// PWMPER0=(uchar)(2000>>8); //电机PWMPER1=(uchar)(2000&0x00ff); //周期PWMCLK=0x00;PWMPRCLK=0x40; //SB=Fck/1 SA=Fck/8PWMCTL=0x90; //4_16 bit PWM //*/SCI0BDH=0; //串口0初始化SCI0BDL=35; //set bandrate=57600bpsSCI0CR1=0x00;SCI0CR2=0x2c; //enable to sent and receivetmp=SCI0SR1;A TD0CTL2=0xc0; //enable ATD, interruptA TD0CTL3=0x08;A TD0CTL4=0x80; //8bit,A TD1CTL2=0xc0; //enable ATD, interruptA TD1CTL3=0x08;A TD1CTL4=0x80; //8bit,A TD0DIEN=0x00; //AD口数字输入使能,使能CCD输入A TD1DIEN=0x80; //CCD二元输入ECLKDIV=0x5C; //EEPROM时钟分频器INTCR=0xc0; //行同步中断, 下降沿触发,delay(10);SE_s; //舵机供电}interrupt 20 void sci0(void) //SCI0 interrupt{uchar sta,das;sta=SCI0SR1; //read the statedas=SCI0DRL;if(sta&0x40) //sent finish{}if(sta&0x20) //receve a data{speed(das*8);SCI0DRL=das;}}interrupt 15 void ch7(void) //ch7 interrupt 266mS {TFLG1=0x80; //clr flagif(m_en) //LED falshPORTB^=0xf0;}void choice(void) //choice a funtion{uchar kv;uchar pp=0;uchar tmp=0;V1: kv=0;wu(CN1[0],CN1[1],CN1[2],CN1[3]); //displayset(2);go(0,pp); //flashfor(;;) //loop{kv=key();if(kv==5&&pp) //lastpp--,go(0,pp);else if(kv==6&&pp<3) //nextpp++,go(0,pp);if(kv==8||kv==10) //enter{if(pp==0) //进入比赛{match();goto V1;}else if(pp==1) //传感受器测方式{text();goto V1;}else if(pp==2) //CCD 测试{t_ccd();goto V1;}else if(pp==3) //参数设定{setting();goto V1;}} //*/}}void main(void) {/* put your own code here */volatile uint t1=0;s_ini(); //系统初始化EnableInterrupts;get_s(); //获取设定参数choice(); //shoicefor(;;) {} /* wait forever *//* please make sure that you never leave this function */ }/****************************************************************************** FILE : datapage.cPURPOSE : paged data access runtime routinesMACHINE : Freescale 68HC12 (Target)LANGUAGE : ANSI-CHISTORY : 21.7.96 first version created******************************************************************************/#include "hidef.h"#include "non_bank.sgm"#include "runtime.sgm"#ifndef __HCS12X__ /* it's different for the HCS12X. See the text below at the #else // __HCS12X__ *//*According to the -Cp option of the compiler the__DPAGE__, __PPAGE__ and __EPAGE__ macros are defined.If none of them is given as argument, then no page accesses should occur andthis runtime routine should not be used !To be on the save side, the runtime routines are created anyway.If some of the -Cp options are given an adapted versions which only covers theneeded cases is produced.*//* if no compiler option -Cp is given, it is assumed that all possible are given : *//* Compile with option -DHCS12 to activate this code */#if defined(HCS12) || defined(_HCS12) || defined(__HCS12__) /* HCS12 family has PPAGE register only at 0x30 */#define PPAGE_ADDR (0x30+REGISTER_BASE)#ifndef __PPAGE__ /* may be set already by option -CPPPAGE */#define __PPAGE__#endif/* Compile with option -DDG128 to activate this code */#elif defined DG128 /* HC912DG128 derivative has PPAGE register only at 0xFF */#define PPAGE_ADDR (0xFF+REGISTER_BASE)#ifndef __PPAGE__ /* may be set already by option -CPPPAGE */#define __PPAGE__#endif#elif defined(HC812A4)/* all setting default to A4 already */#endif#if !defined(__EPAGE__) && !defined(__PPAGE__) && !defined(__DPAGE__)/* as default use all page registers */#define __DPAGE__#define __EPAGE__#define __PPAGE__#endif/* modify the following defines to your memory configuration */#define EPAGE_LOW_BOUND 0x400u#define EPAGE_HIGH_BOUND 0x7ffu#define DPAGE_LOW_BOUND 0x7000u#define DPAGE_HIGH_BOUND 0x7fffu#define PPAGE_LOW_BOUND (DPAGE_HIGH_BOUND+1)#define PPAGE_HIGH_BOUND 0xBFFFu#define REGISTER_BASE 0x0u#ifndef DPAGE_ADDR#define DPAGE_ADDR (0x34u+REGISTER_BASE)#endif#ifndef EPAGE_ADDR#define EPAGE_ADDR (0x36u+REGISTER_BASE)#endif#ifndef PPAGE_ADDR#define PPAGE_ADDR (0x35u+REGISTER_BASE)#endif/*The following parts about the defines are assumed in the code of _GET_PAGE_REG :- the memory region controlled by DPAGE is above the area controlled by the EPAGE andbelow the area controlled by the PPAGE.- the lower bound of the PPAGE area is equal to be the higher bound of the DPAGE area + 1*/#if EPAGE_LOW_BOUND >= EPAGE_HIGH_BOUND || EPAGE_HIGH_BOUND >= DPAGE_LOW_BOUND || DPAGE_LOW_BOUND >= DPAGE_HIGH_BOUND || DPAGE_HIGH_BOUND >= PPAGE_LOW_BOUND || PPAGE_LOW_BOUND >= PPAGE_HIGH_BOUND#error /* please adapt _GET_PAGE_REG for this non default page configuration */#endif#if DPAGE_HIGH_BOUND+1 != PPAGE_LOW_BOUND#error /* please adapt _GET_PAGE_REG for this non default page configuration */#endif/* this module does either control if any access is in the bounds of the specified page or *//* ,if only one page is specified, just use this page. *//* This behavior is controlled by the define USE_SEVERAL_PAGES. *//* If !USE_SEVERAL_PAGES does increase the performance significantly *//* NOTE : When !USE_SEVERAL_PAGES, the page is also set for accesses outside of the area controlled *//* by this single page. But this is should not cause problems because the page is restored to the old value before any other access could occur */#if !defined(__DPAGE__) && !defined(__EPAGE__) && !defined(__PPAGE__)/* no page at all is specified *//* only specifying the right pages will speed up these functions a lot */#define USE_SEVERAL_PAGES 1#elif defined(__DPAGE__) && defined(__EPAGE__) || defined(__DPAGE__) && defined(__PPAGE__) || defined(__EPAGE__) && defined(__PPAGE__)/* more than one page register is used */#define USE_SEVERAL_PAGES 1#else#define USE_SEVERAL_PAGES 0#if defined(__DPAGE__) /* check which pages are used */#define PAGE_ADDR PPAGE_ADDR#elif defined(__EPAGE__)#define PAGE_ADDR EPAGE_ADDR#elif defined(__PPAGE__)#define PAGE_ADDR PPAGE_ADDR#else /* we do not know which page, decide it at runtime */#error /* must not happen */#endif#endif#if USE_SEVERAL_PAGES /* only needed for several pages support *//*--------------------------- _GET_PAGE_REG --------------------------------Runtime routine to detect the right register depending on the 16 bit offset partof an address.This function is only used by the functions below.Depending on the compiler options -Cp different versions of _GET_PAGE_REG are produced.Arguments :- Y : offset part of an addressResult :if address Y is controlled by a page register :- X : address of page register if Y is controlled by an page register- Zero flag cleared- all other registers remain unchangedif address Y is not controlled by a page register :- Zero flag is set- all registers remain unchanged--------------------------- _GET_PAGE_REG ----------------------------------*/#if defined(__DPAGE__)#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEstatic void NEAR _GET_PAGE_REG(void) { /*lint -esym(528, _GET_PAGE_REG) used in asm code */__asm {L_DPAGE:CPY #DPAGE_LOW_BOUND ;// test of lower bound of DPAGE#if defined(__EPAGE__)BLO L_EPAGE ;// EPAGE accesses are possible#elseBLO L_NOPAGE ;// no paged memory below accesses#endifCPY #DPAGE_HIGH_BOUND ;// test of higher bound DPAGE/lower bound PPAGE#if defined(__PPAGE__)BHI L_PPAGE ;// EPAGE accesses are possible#elseBHI L_NOPAGE ;// no paged memory above accesses#endifFOUND_DPAGE:LDX #DPAGE_ADDR ;// load page register address and clear zero flagRTS#if defined(__PPAGE__)L_PPAGE:CPY #PPAGE_HIGH_BOUND ;// test of higher bound of PPAGEBHI L_NOPAGEFOUND_PPAGE:LDX #PPAGE_ADDR ;// load page register address and clear zero flagRTS#endif#if defined(__EPAGE__)L_EPAGE:CPY #EPAGE_LOW_BOUND ;// test of lower bound of EPAGEBLO L_NOPAGECPY #EPAGE_HIGH_BOUND ;// test of higher bound of EPAGEBHI L_NOPAGEFOUND_EPAGE:LDX #EPAGE_ADDR ;// load page register address and clear zero flagRTS#endifL_NOPAGE:ORCC #0x04 ;// sets zero flagRTS}}#else /* !defined(__DPAGE__) */#if defined( __PPAGE__ )#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEstatic void NEAR _GET_PAGE_REG(void) { /*lint -esym(528, _GET_PAGE_REG) used in asm code */__asm {L_PPAGE:CPY #PPAGE_LOW_BOUND ;// test of lower bound of PPAGE#if defined( __EPAGE__ )BLO L_EPAGE#elseBLO L_NOPAGE ;// no paged memory below#endifCPY #PPAGE_HIGH_BOUND ;// test of higher bound PPAGEBHI L_NOPAGEFOUND_PPAGE:LDX #PPAGE_ADDR ;// load page register address and clear zero flagRTS#if defined( __EPAGE__ )L_EPAGE:CPY #EPAGE_LOW_BOUND ;// test of lower bound of EPAGEBLO L_NOPAGECPY #EPAGE_HIGH_BOUND ;// test of higher bound of EPAGEBHI L_NOPAGEFOUND_EPAGE:LDX #EPAGE_ADDR ;// load page register address and clear zero flagRTS#endifL_NOPAGE: ;// not in any allowed page area;// its a far access to a non paged variableORCC #0x04 ;// sets zero flagRTS}}#else /* !defined(__DPAGE__ ) && !defined( __PPAGE__) */#if defined(__EPAGE__)#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEstatic void NEAR _GET_PAGE_REG(void) { /*lint -esym(528, _GET_PAGE_REG) used in asm code */__asm {L_EPAGE:CPY #EPAGE_LOW_BOUND ;// test of lower bound of EPAGEBLO L_NOPAGECPY #EPAGE_HIGH_BOUND ;// test of higher bound of EPAGEBHI L_NOPAGEFOUND_EPAGE:LDX #EPAGE_ADDR ;// load page register address and clear zero flagRTSL_NOPAGE: ;// not in any allowed page area;// its a far access to a non paged variableORCC #0x04 ;// sets zero flagRTS}}#endif /* defined(__EPAGE__) */#endif /* defined(__PPAGE__) */#endif /* defined(__DPAGE__) */#endif /* USE_SEVERAL_PAGES *//*--------------------------- _SET_PAGE --------------------------------Runtime routine to set the right page register. This routine is used if the compilerdoes not know the right page register, i.e. if the option -Cp is used for more thanone pageregister or if the runtime option is used for one of the -Cp options.Arguments :- offset part of an address in the Y register- page part of an address in the B registerResult :- page part written into the correct page register.- the old page register content is destroyed- all processor registers remains unchanged--------------------------- _SET_PAGE ----------------------------------*/#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEvoid NEAR _SET_PAGE(void) {#if USE_SEVERAL_PAGES__asm {PSHX ;// save X register__PIC_JSR(_GET_PAGE_REG)BEQ L_NOPAGESTAB 0,X ;// set page registerL_NOPAGE:PULX ;// restore X registerRTS}#else /* USE_SEVERAL_PAGES */__asm {STAB PAGE_ADDR ;// set page registerRTS}#endif /* USE_SEVERAL_PAGES */}/*--------------------------- _LOAD_FAR_8 --------------------------------This runtime routine is used to access paged memory via a runtime function.It may also be used if the compiler option -Cp is not used with the runtime argument.Arguments :- offset part of an address in the Y register- page part of an address in the B registerResult :- value to be read in the B register- all other registers remains unchanged- all page register still contain the same value--------------------------- _LOAD_FAR_8 ----------------------------------*/#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEvoid NEAR _LOAD_FAR_8(void) {#if USE_SEVERAL_PAGES__asm {PSHX ;// save X register__PIC_JSR(_GET_PAGE_REG)BEQ L_NOPAGEPSHA ;// save A registerLDAA 0,X ;// save page registerSTAB 0,X ;// set page registerLDAB 0,Y ;// actual load, overwrites pageSTAA 0,X ;// restore page registerPULA ;// restore A registerPULX ;// restore X registerRTSL_NOPAGE:LDAB 0,Y ;// actual load, overwrites pagePULX ;// restore X registerRTS}#else /* USE_SEVERAL_PAGES */__asm {PSHA ;// save A registerLDAA PAGE_ADDR ;// save page registerSTAB PAGE_ADDR ;// set page registerLDAB 0,Y ;// actual load, overwrites pageSTAA PAGE_ADDR ;// restore page registerPULA ;// restore A registerRTS}#endif /* USE_SEVERAL_PAGES */}/*--------------------------- _LOAD_FAR_16 --------------------------------This runtime routine is used to access paged memory via a runtime function.It may also be used if the compiler option -Cp is not used with the runtime argument.Arguments :- offset part of an address in the Y register- page part of an address in the B registerResult :- value to be read in the Y register- all other registers remains unchanged- all page register still contain the same value--------------------------- _LOAD_FAR_16 ----------------------------------*/#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEvoid NEAR _LOAD_FAR_16(void) {#if USE_SEVERAL_PAGES__asm {PSHX ;// save X register__PIC_JSR(_GET_PAGE_REG)BEQ L_NOPAGEPSHA ;// save A registerLDAA 0,X ;// save page registerSTAB 0,X ;// set page registerLDY 0,Y ;// actual load, overwrites addressSTAA 0,X ;// restore page registerPULA ;// restore A registerPULX ;// restore X registerRTSL_NOPAGE:LDY 0,Y ;// actual load, overwrites addressPULX ;// restore X registerRTS}#else /* USE_SEVERAL_PAGES */__asm {PSHA ;// save A registerLDAA PAGE_ADDR ;// save page registerSTAB PAGE_ADDR ;// set page registerLDY 0,Y ;// actual load, overwrites addressSTAA PAGE_ADDR ;// restore page registerPULA ;// restore A registerRTS}#endif /* USE_SEVERAL_PAGES */}/*--------------------------- _LOAD_FAR_24 --------------------------------This runtime routine is used to access paged memory via a runtime function.It may also be used if the compiler option -Cp is not used with the runtime argument. Arguments :- offset part of an address in the Y register- page part of an address in the B registerResult :- value to be read in the Y:B registers- all other registers remains unchanged- all page register still contain the same value--------------------------- _LOAD_FAR_24 ----------------------------------*/#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEvoid NEAR _LOAD_FAR_24(void) {#if USE_SEVERAL_PAGES__asm {PSHX ;// save X register__PIC_JSR(_GET_PAGE_REG)BEQ L_NOPAGEPSHA ;// save A registerLDAA 0,X ;// save page registerSTAB 0,X ;// set page registerLDAB 0,Y ;// actual load, overwrites page of addressLDY 1,Y ;// actual load, overwrites offset of addressSTAA 0,X ;// restore page registerPULA ;// restore A registerPULX ;// restore X registerRTSL_NOPAGE:LDAB 0,Y ;// actual load, overwrites page of addressLDY 1,Y ;// actual load, overwrites offset of addressPULX ;// restore X registerRTS}#else /* USE_SEVERAL_PAGES */__asm {PSHA ;// save A registerLDAA PAGE_ADDR ;// save page registerSTAB PAGE_ADDR ;// set page registerLDAB 0,Y ;// actual load, overwrites page of addressLDY 1,Y ;// actual load, overwrites offset of addressSTAA PAGE_ADDR ;// restore page registerPULA ;// restore A registerRTS}#endif /* USE_SEVERAL_PAGES */}/*--------------------------- _LOAD_FAR_32 --------------------------------This runtime routine is used to access paged memory via a runtime function.It may also be used if the compiler option -Cp is not used with the runtime argument.Arguments :- offset part of an address in the Y register- page part of an address in the B registerResult :- low 16 bit of value to be read in the D registers- high 16 bit of value to be read in the Y registers- all other registers remains unchanged- all page register still contain the same value--------------------------- _LOAD_FAR_32 ----------------------------------*/#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEvoid NEAR _LOAD_FAR_32(void) {#if USE_SEVERAL_PAGES__asm {PSHX ;// save X register__PIC_JSR(_GET_PAGE_REG)BEQ L_NOPAGELDAA 0,X ;// save page registerPSHA ;// put it onto the stackSTAB 0,X ;// set page registerLDD 2,Y ;// actual load, low wordLDY 0,Y ;// actual load, high wordMOVB 1,SP+,0,X ;// restore page registerPULX ;// restore X registerRTSL_NOPAGE:LDD 2,Y ;// actual load, low wordLDY 0,Y ;// actual load, high wordPULX ;// restore X registerRTS}#else /* USE_SEVERAL_PAGES */__asm {LDAA PAGE_ADDR ;// save page registerPSHA ;// put it onto the stackSTAB PAGE_ADDR ;// set page registerLDD 2,Y ;// actual load, low wordLDY 0,Y ;// actual load, high wordMOVB 1,SP+,PAGE_ADDR ;// restore page registerRTS}#endif /* USE_SEVERAL_PAGES */}/*--------------------------- _STORE_FAR_8 --------------------------------This runtime routine is used to access paged memory via a runtime function.It may also be used if the compiler option -Cp is not used with the runtime argument.Arguments :- offset part of an address in the Y register- page part of an address in the B register- value to be stored in the B registerResult :- value stored at the address- all registers remains unchanged- all page register still contain the same value--------------------------- _STORE_FAR_8 ----------------------------------*/#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEvoid NEAR _STORE_FAR_8(void) {#if USE_SEVERAL_PAGES__asm {PSHX ;// save X register__PIC_JSR(_GET_PAGE_REG)BEQ L_NOPAGEPSHB ;// save B registerLDAB 0,X ;// save page registerMOVB 0,SP, 0,X ;// set page registerSTAA 0,Y ;// store the value passed in ASTAB 0,X ;// restore page registerPULB ;// restore B registerPULX ;// restore X registerRTSL_NOPAGE:STAA 0,Y ;// store the value passed in APULX ;// restore X registerRTS}#else /* USE_SEVERAL_PAGES */__asm {PSHB ;// save A registerLDAB PAGE_ADDR ;// save page registerMOVB 0,SP,PAGE_ADDR ;// set page registerSTAA 0,Y ;// store the value passed in ASTAB PAGE_ADDR ;// restore page registerPULB ;// restore B registerRTS}#endif /* USE_SEVERAL_PAGES */}/*--------------------------- _STORE_FAR_16 --------------------------------This runtime routine is used to access paged memory via a runtime function.It may also be used if the compiler option -Cp is not used with the runtime argument.Arguments :- offset part of an address in the Y register- page part of an address in the B register- value to be stored in the X registerResult :- value stored at the address- all registers remains unchanged- all page register still contain the same value--------------------------- _STORE_FAR_16 ----------------------------------*/#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEvoid NEAR _STORE_FAR_16(void) {#if USE_SEVERAL_PAGES__asm {PSHX ;// save X register__PIC_JSR(_GET_PAGE_REG)BEQ L_NOPAGEPSHALDAA 0,X ;// save page registerSTAB 0,X ;// set page registerMOVW 1,SP,0,Y ;// store the value passed in XSTAA 0,X ;// restore page registerPULA ;// restore A registerPULX ;// restore X registerRTSL_NOPAGE:STX 0,Y ;// store the value passed in XPULX ;// restore X registerRTS}#else /* USE_SEVERAL_PAGES */__asm {PSHA ;// save A registerLDAA PAGE_ADDR ;// save page registerSTAB PAGE_ADDR ;// set page registerSTX 0,Y ;// store the value passed in XSTAA PAGE_ADDR ;// restore page registerPULA ;// restore A registerRTS}#endif /* USE_SEVERAL_PAGES */}/*--------------------------- _STORE_FAR_24 --------------------------------This runtime routine is used to access paged memory via a runtime function.It may also be used if the compiler option -Cp is not used with the runtime argument.Arguments :- offset part of an address in the Y register- page part of an address in the B register- value to be stored in the X:A registers (X : low 16 bit, A : high 8 bit)Result :- value stored at the address- all registers remains unchanged- all page register still contain the same value--------------------------- _STORE_FAR_24 ----------------------------------*/#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEvoid NEAR _STORE_FAR_24(void) {#if USE_SEVERAL_PAGES__asm {PSHX ;// save X register__PIC_JSR(_GET_PAGE_REG)BEQ L_NOPAGEPSHALDAA 0,X ;// save page registerSTAB 0,X ;// set page registerMOVW 1,SP, 1,Y ;// store the value passed in XMOVB 0,SP, 0,Y ;// store the value passed in ASTAA 0,X ;// restore page registerPULA ;// restore A registerPULX ;// restore X registerRTSL_NOPAGE:STX 1,Y ;// store the value passed in XSTAA 0,Y ;// store the value passed in XPULX ;// restore X registerRTS}#else /* USE_SEVERAL_PAGES */__asm {PSHA ;// save A registerLDAA PAGE_ADDR ;// save page registerSTAB PAGE_ADDR ;// set page registerMOVB 0,SP, 0,Y ;// store the value passed in ASTX 1,Y ;// store the value passed in XSTAA PAGE_ADDR ;// restore page registerPULA ;// restore A registerRTS}#endif /* USE_SEVERAL_PAGES */}/*--------------------------- _STORE_FAR_32 --------------------------------This runtime routine is used to access paged memory via a runtime function.It may also be used if the compiler option -Cp is not used with the runtime argument.Arguments :- offset part of an address in the Y register- page part of an address is on the stack at 3,SP (just below the return address)- value to be stored in the X:D registers (D : low 16 bit, X : high 16 bit)Result :- value stored at the address- all registers remains unchanged- the page part is removed from the stack- all page register still contain the same value--------------------------- _STORE_FAR_32 ----------------------------------*/#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEvoid NEAR _STORE_FAR_32(void) {#if USE_SEVERAL_PAGES__asm {PSHX ;// save X register__PIC_JSR(_GET_PAGE_REG)BEQ L_NOPAGEPSHDLDAA 0,X ;// save page registerMOVB 6,SP, 0,X ;// set page registerMOVW 2,SP, 0,Y ;// store the value passed in X (high word)MOVW 0,SP, 2,Y ;// store the value passed in D (low word)STAA 0,X ;// restore page registerPULD ;// restore A registerBRA doneL_NOPAGE:MOVW 0,SP, 0,Y ;// store the value passed in X (high word)STD 2,Y ;// store the value passed in D (low word) done:PULX ;// restore X registerMOVW 0,SP, 1,+SP ;// move return addressRTS}#else /* USE_SEVERAL_PAGES */__asm {PSHD ;// save D registerLDAA PAGE_ADDR ;// save page registerLDAB 4,SP ;// load page part of addressSTAB PAGE_ADDR ;// set page registerSTX 0,Y ;// store the value passed in XMOVW 0,SP, 2,Y ;// store the value passed in D (low word)STAA PAGE_ADDR ;// restore page registerPULD ;// restore D registerMOVW 0,SP, 1,+SP ;// move return addressRTS}#endif /* USE_SEVERAL_PAGES */}/*--------------------------- _FAR_COPY_RC --------------------------------This runtime routine is used to access paged memory via a runtime function.It may also be used if the compiler option -Cp is not used with the runtime argument.Arguments :- offset part of the source int the X register- page part of the source in the A register- offset part of the dest int the Y register- page part of the dest in the B register- number of bytes to be copied is defined by the next 2 bytes after the return address.Result :- memory area copied- no registers are saved, i.e. all registers may be destroyed- all page register still contain the same value as before the call- the function returns after the constant defining the number of bytes to be copiedstack-structure at the loop-label:0,SP : destination offset2,SP : source page3,SP : destination page4,SP : source offset6,SP : points to length to be copied. This function returns after the sizeA usual call to this function looks like:struct Huge src, dest;; ...LDX #srcLDAA #PAGE(src)LDY #destLDAB #PAGE(dest)JSR _FAR_COPY_RCDC.W sizeof(struct Huge); ...--------------------------- _FAR_COPY_RC ----------------------------------*/#ifdef __cplusplusextern "C"#endif#pragma NO_ENTRY#pragma NO_EXIT#pragma NO_FRAMEvoid NEAR _FAR_COPY_RC(void) {#if USE_SEVERAL_PAGES__asm {DEX ;// source addr-=1, because loop counter ends at 1PSHX ;// save source offsetPSHD ;// save both pagesDEY ;// destination addr-=1, because loop counter ends at 1PSHY ;// save destination offsetLDY 6,SP ;// Load Return addressLDX 2,Y+ ;// Load Size to copySTY 6,SP ;// Store adjusted return addressloop:LDD 4,SP ;// load source offset。

飞思卡尔智能车程序

飞思卡尔智能车程序

Main.c#include <hidef.h> /* common defines and macros */#include <mc9s12db128.h> /* derivative information */#pragma LINK_INFO DERIVATIVE "mc9s12db128b"#include "define.h"#include "init.h"// variable used in video processvolatile unsigned char image_data[ROW_MAX][LINE_MAX] ; // data array of picture unsigned char black_x[ROW_MAX] ; // 0ne-dimensional arrayunsigned char row ; // x-position of the arrayunsigned char line ; // y-position of the arrayunsigned int row_count ; // row counterunsigned char line_sample ; // used to counter in ADunsigned char row_image ;unsigned char line_temp ; // temperary variable used in data transferunsigned char sample_data[LINE_MAX] ; // used to save one-dimension array got in interruption// variables below are used in speed measureUnsigned char pulse[5] ; // used to save data in PA processUnsigned char counter; // temporary counter in Speed detectUnsigned char cur_speed; // current speedshort stand;short data;unsigned char curve ; // valve used to decide straight or turnshort Bounds(short data);short FuzzyLogic(short stand);/*----------------------------------------------------------------------------*\receive_sci\*----------------------------------------------------------------------------*/unsigned char receive_sci(void) // receive data through sci{ unsigned char sci_data;while(SCI0SR1_RDRF!=1);sci_data=SCI0DRL;return sci_data;}/*----------------------------------------------------------------------------*\transmit_sci\*----------------------------------------------------------------------------*/void transmit_sci(unsigned char transmit_data) // send data through sci{while(SCI0SR1_TC!=1);while(SCI0SR1_TDRE!=1);SCI0DRL=transmit_data;}/***************************************************************************** ***//*----------------------------------------------------------------------------*\abs_sub\*----------------------------------------------------------------------------*/ unsigned char abs_sub(unsigned char num1, unsigned char num2) { unsigned char difference;if(num1>=num2){difference=num1-num2;}else{difference=num2-num1;}return difference;}void pwm_set(unsigned int dutycycle){PWMDTY1=dutycycle&0x00FF;PWMDTY0=dutycycle>>8;}void get_black_wire(void) // used to extract black wire{ unsigned char i;for(row=0;row<ROW_MAX;row++){for(line=LINE_MIN;line<LINE_MAX-3;line++){if(image_data[row][line]>image_data[row][line+3]+VALVE){for(i=3;i<10;i++){if(image_data[row][line+i]+VALVE<image_data[row][line+i+3]){ black_x[row]=line+i/2+2;i=10;}}line=LINE_MAX;} else{//black_x[row]=(black_x[row]/45)*78;}}}}/*----------------------------------------------------------------------------*\speed_control\*----------------------------------------------------------------------------*/void speed_control(void){unsigned int sum,average;sum=0;for(row=0;row<FIRST_FIVE;row++){sum=sum+black_x[row];}average=sum/FIRST_FIVE;curve=0;for(row=0;row<FIRST_FIVE;row++){curve=curve+abs_sub(black_x[row],average);if(curve>CURVE_MAX){curve_flag=0;speed=low_speed;}else{curve_flag=1;speed=hign_speed;}}}/*----------------------------------------------------------------------------*\ steer_control\*----------------------------------------------------------------------------*/ void steer_control(void){ unsigned int dutycycle;unsigned char video_center;unsigned int coefficient;int E,U; //currentstatic int e=0;video_center=(LINE_MIN+LINE_MAX)/2;stand=abs_sub(black_x[1]+ black_x[9],2*black_x[5]);E=video_center-black_x[8];coefficient=30+1*FuzzyLogic(stand);U=coefficient*E;dutycycle=Bounds(center+U);pwm_set(dutycycle);}// make sure it is within boundsshort Bounds(short data){if(data>right_limit){data = right_limit;}if(data<left_limit){data = left_limit;}return data;}Void speed_get(void){Unsigned char temp;Counter++;Temp=PACN1;cur_speed=temp-pulse[counter-1];pulse[counter-1]=temp;if(counter==5){counter=0;}}Void set_speed(unsigned char desired_speed){If(desired_speed<cur_speed){PWMDTY2=low_speed;}Else{PWMDTY2=high_speed;}}/***************************************************************************** *\Main\***************************************************************************** */void main(void) {// main functiioninit_PORT() ;// port initializationinit_PLL() ;// setting of the PLLinit_ECT();init_PWM() ;// PWM INITIALIZATIONinit_SPEED() ;init_SCI() ;for(;;) {if(field_signal==0){ // even->oddwhile(field_signal==0);row_count=0;row_image=0;EnableInterrupts;while(row_count<ROW_END){get_black_wire();speed_control();steer_control();}DisableInterrupts;}else{ // odd->evenwhile(field_signal==1);row_count=0;row_image=0;EnableInterrupts;while(row_count<ROW_END){get_black_wire();speed_control();steer_control();}DisableInterrupts;}/* transmit_sci('x');for(row=0;row<ROW_MAX;row++){transmit_sci(black_x[row]);}transmit_sci(curve);*/}}interrupt 6 void IRQ_ISR(){row_count++;if((row_count>ROW_START)&&(row_count%INTERVAL==0)&&(row_image<ROW_MAX )){init_AD();for(line_sample=0;line_sample<LINE_MAX;line_sample++){while(!ATD0STAT1_CCF0); // WAIT FOR TRANSFORM TO ENDsample_data[line_sample]=signal_in; // A/D transfer}ATD0CTL2=0x00;row_image++;}if((row_count>ROW_START)&&(row_count%INTERVAL==2)&&(row_image<ROW_MAX +1)){for(line_temp=0;line_temp<LINE_MAX;line_temp++){image_data[row_image-1][line_temp]=sample_data[line_temp];}}}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // THE END///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Define.h // all macros are define in this header file/*----------------------------------------------------------------------------*\macro need to be used in video sample\*----------------------------------------------------------------------------*/////////////////////////////#define signal_in ATD0DR0L // signal from video: right aligned mode,// only use low 8-bit in ATD Conversion ResultRegisters#define field_signal PTT_PTT2 // field signal is sent into PortT_bit2#define LINE_MIN 12 // first effective pint in each row#define LINE_MAX 78 // number of points sampled in each row#define ROW_MAX 10 // number of rows needed to be sampled in eachpicture#define ROW_START 50 // begin to sample from line start#define ROW_END 300 // end flag of sampling#define INTERVAL 20 // interval between effective rows#define VALVE 24 // valve to decide black track or white track#define FIRST_FIVE 5/*----------------------------------------------------------------------------*\舵机控制变量\*----------------------------------------------------------------------------*/#define left_limit 7400 //#define center 6400 //#define right_limit 5400 ////#define coefficient 30 // (LEFT-RIGHT)/(LINE_MAX-LINE_MIN) /*----------------------------------------------------------------------------*\速度控制变量\*----------------------------------------------------------------------------*/#define curve_flag PORTE_BIT2 // indicate straight line or not #define speed PWMDTY2 // speed of the car#define CURVE_MAX 24 // valve to decide straight track or not #define hign_speed 120 // speed used on straight track#define low_speed 100 // speed used on the turn/*----------------------------------------------------------------------------*\ define jump wire; code switch; Led\*----------------------------------------------------------------------------*/#define JP4_1 PTT_PTT7 // JP4#define JP4_2 PTT_PTT6#define JP4_3 PTT_PTT5#define JP4_4 PTT_PTT4#define JP4_5 PTP_PTP4#define JP4_6 PTP_PTP5#define JP4_7 PTP_PTP6// define code switch#define RP1_1 PTM_PTM0#define RP1_2 PTM_PTM1#define RP1_3 PTM_PTM2#define RP1_4 PTM_PTM3#define RP1_5 PTM_PTM4#define RP1_6 PTM_PTM5#define RP1_7 PORTAD0_PTAD4#define RP1_8 PORTAD0_PTAD3// define Led#define Led1 PORTA_BIT4#define Led2 PORTA_BIT5#define Led3 PORTA_BIT6#define Led4 PORTA_BIT7Init.c // include initial function in this file#include <hidef.h> /* common defines and macros */#include <mc9s12db128.h> /* derivative information */#include "define.h" /* all macro included */#include "init.h" /* all init function included */#pragma LINK_INFO DERIVATIVE "mc9s12db128b"/*----------------------------------------------------------------------------*\init_PLL\*----------------------------------------------------------------------------*/ void init_PLL(void)// setting of the PLL{REFDV=3;SYNR=7; // bus period=16Mhz*(SYNR+1)/(REFDV+1) while(0==CRGFLG_LOCK); // wait for VCO to stablize CLKSEL=0x80;// open PLL}Void init_ECT(void);{TIOS_IOS3=0; // set PT3 as input captureTCTL4=0b11000000; // set pt3 as any edge triggered ICPAR_PA1EN=1; // PA1 enabled}/*----------------------------------------------------------------------------*\ init_PORT\*----------------------------------------------------------------------------*/ void init_PORT(void) // port initialization{DDRT_DDRT2=0;// Port M1 function as even-odd field signalinputDDRJ_DDRJ6=1;// Port J6 enable 33886 0 enable// Led portDDRA_BIT4 =1;DDRA_BIT5 =1;DDRA_BIT6 =1;DDRA_BIT7 =1;INTCR_IRQE =1; // IRQ Select Edge Sensitive Only INTCR_IRQEN=1; // External IRQ Enable//输出指示JP4_1 PTT_PTT0DDRT_DDRT7=1;DDRT_DDRT6=1;DDRT_DDRT5=1;DDRT_DDRT4=1;DDRP_DDRP4=1; //PTP_PTP0DDRP_DDRP5=1;DDRP_DDRP7=1;/*----------------------------------------------------------------------------*\init_AD\*----------------------------------------------------------------------------*/void init_AD(void)// initialize AD{ATD0CTL2=0xC0;// open AD, quick clear, no wait mode, inhibit outer awake, inhibit interruptATD0CTL3=0x08;// one transform in one sequence, No FIFO, contine to transform under freeze mode ATD0CTL4=0x81;// 8-bit precision, two clocks, ATDClock=[BusClock*0.5]/[PRS+1] ; PRS=1, divider=4 ; BusClock=8MHZATD0CTL5=0xA0; // right-algned unsigned,single channel,channel 0ATD0DIEN=0x00; // inhibit digital input}/*----------------------------------------------------------------------------*\init_PWM\*----------------------------------------------------------------------------*/void init_PWM(void)// PWM initialize{PTJ_PTJ6 = 0 ; // "0" enable 33886 motor, "1" disable itPWME = 0x00 ; // PWW is disabledPWMCTL_CON01 = 1 ; // combine PWM0,1PWMPRCLK = 0x33 ; // A=B=32M/8=4MPWMSCLA = 100 ; // SA=A/2/100=20kPWMSCLB = 1 ; // SB=B/2/1 =2000kPWMCLK = 0b00011100; // PWM0,1-A; PWM2,3-SB; PWM4-SAPWMPOL = 0xff ; // Duty=High TimePWMCAE = 0x00 ; // left-alignedPWMPER0 = 0x4e ;PWMPER1 = 0x20 ;// 20000 = 0x4e20; Frequency=A/20000=200HzPWMDTY0 = 0x18 ;PWMDTY1 = 0x6a ; // initialize PWMPWME_PWME1 = 1 ; // enable steerPWMDTY2 = 20 ; // Duty cyclePWMPER2 = 200 ; // Frequency=SB/200=10KPWME_PWME2 = 1 ; // enable motor/*----------------------------------------------------------------------------*\init_SPEED\*----------------------------------------------------------------------------*/void init_SPEED(void) {DDRM_DDRM0 =0 ; //code switch 1 on RP1DDRM_DDRM1 =0 ; //code switch 1 on RP1DDRM_DDRM2 =0 ; //code switch 1 on RP1DDRM_DDRM3 =0 ; //code switch 1 on RP1DDRM_DDRM4 =0 ; //code switch 1 on RP1DDRM_DDRM5 =0 ; //code switch 1 on RP1ATD0DIEN_IEN4 = 1; //code switch 1 on RP1,Enable Digital Input PAD4 ATD0DIEN_IEN3 = 1; //code switch 1 on RP1,Enable Digital Input PAD3 if(RP1_1==1) {speed= hign_speed+2*(RP1_2*10+RP1_3*5+RP1_4*2+RP1_5*2+RP1_6+RP1_7+RP1_8); }else{speed= hign_speed-2*(RP1_2*10+RP1_3*5+RP1_4*2+RP1_5*2+RP1_6+RP1_7+RP1_8); }}/********************************************************************************//*----------------------------------------------------------------------------*\init_SCI\*----------------------------------------------------------------------------*/void init_SCI(void) // initialize SCI{SCI0BD = 104 ; // bode rate=32M/(16*SCI0BD)=19200SCI0CR1=0x00 ; //SCI0CR2=0b00001100 ;}Init.hvoid init_PLL(void);void init_AD(void);void init_PWM(void);void init_SPEED(void);void init_SCI(void);void init_PORT(void);Void init_ECT(void);Fuzzy.asm // S12 fuzzy logic codeRAM: section; Fuzzy Membership sets; input membership variablesabsentry fuzvarfuzvar: ds.b 5 ; inputsZ: equ 0 ; indicate of straight lineVS: equ 1 ; turn slightlyS: equ 2 ; turn a littleBB: equ 3 ; a big turnVB: equ 4 ; a very big turn;output membership variablesabsentry fuzoutfuzout: ds.b 4 ; outputsremain: equ 5 ; no change on kplittle: equ 6 ; little change on kpbig: equ 7 ; big change on Kpvery_big: equ 8 ; very big change on kp EEPROM: section; fuzzifications_tab: dc.b 0,35,0,8 ; indicate of straight linedc.b 0,69,8,8 ; turn slightlydc.b 35,104,8,8 ; turn a littledc.b 69,138,8,8 ; a big turndc.b 104,255,8,0 ; a very big turnrules: ;constructing of ruledc.b Z, $FE,remain,$FEdc.b VS, $FE,little,$FEdc.b S, $FE,big,$FEdc.b BB, $FE,big,$FEdc.b VB, $FE,very_big,$FEdc.b $FF ;end of the ruleaddsingleton:dc.b 0,1,2,3 ; setting of the weightabsentry FuzzyLogicFuzzyLogic:pshxldx #s_tabldy #fuzvarmem ; number of mem indicates the number of input memmemmemmemldab #4 ; number of output fuzzy membership setscloop:clr 1,y+ ; clear output fuzzy variablesdbne b,cloopldx #rulesldy #fuzvarldaa #$FFrevldy #fuzoutldx #addsingletonldab #4wavediv ;tfr y,d ; return dpowerpulxrtsmemmemldab #4 ; number of output fuzzy membership setscloop:clr 1,y+ ; clear output fuzzy variablesdbne b,cloopldx #rulesldy #fuzvarldaa #$FFrevldy #fuzoutldx #addsingletonldab #4wavediv ;tfr y,d ; return dpowerpulxrts6。

基于“飞思卡尔”单片机的智能车

基于“飞思卡尔”单片机的智能车

哈尔滨工业大学华德应用技术学院毕业设计(论文)开题报告题目:基于“飞思卡尔”单片机的智能车(硬件部分设计)系(部)应用电子与通信技术系专业电子信息工程学生刘晓磊学号1089212211班号0892122指导教师赵建新开题报告日期2011-10-17哈工大华德学院说明一、开题报告应包括下列主要内容:1.通过学生对文献论述和方案论证,判断是否已充分理解毕业设计(论文)的内容和要求2.进度计划是否切实可行;3.是否具备毕业设计所要求的基础条件。

4.预计研究过程中可能遇到的困难和问题,以及解决的措施;5.主要参考文献。

二、如学生首次开题报告未通过,需在一周内再进行一次。

三、开题报告由指导教师填写意见、签字后,统一交所在系(部)保存,以备检查。

指导教师评语:指导教师签字:检查日期:一、课题背景车与我们的社会生活息息相关,然而当今车的智能化发展还不是很发达,特别是在安全性,智能化,车与路之间交互信息等方面。

当今的车辆技术与未来的智能车辆技术还存在着巨大的差距。

今天的汽车工程师面临着巨大的挑战,需要在新旧技术之间建立一座桥梁,通过应用先进的电子技术,信息技术,电子通信技术推动车辆技术的革新与进步。

本课题小组在履带车模的基础上,使用飞思卡尔公司的MC9S12XS128 单片机作为控制核心,自行设计并制作了相关电路以和检测到道路周围的黑线信号处理以及对舵机、电机的控制。

最终实现车模在赛道上通过自身控制以最短时间独立完成行驶和自动超车的功能。

二、目的意义智能小车的应用越来越广泛,几乎渗透到所有领域。

智能小车的发展体现了一个国家技术水平的高低,现代智能小车从其诞生到现在,已经发展到了第三代。

第一代智能小车是示教再现型智能小车。

它们装有记忆存储器,由人将作业的各种操作要求示范给智能小车,使之记住操作的程序和要领。

当它接到再现命令时,则自主地再现示教的动作。

第二代智能小车是装有简单计算机和简单传感器的离线编程的工业智能小车。

飞思卡尔智能车程序

飞思卡尔智能车程序

#include <hidef.h> /* common defines and macros */#include <MC9S12XS128.h> /* derivative-specific definitions */#pragma LINK_INFO DERIV ATIVE "MC9S12XS128.h"/////////////////////////////////////////////////////word AD_Value[16];//AD转换结int Done_cache[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//记忆int Angle_cache[20]={50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50};//记忆//////////////////////////////////////////////////////#define PAEN 6/////////////////////////////////////////////////////unsigned int i=0,Xmax=0,Ymax=0,Xmax2=0,Ymax2=0;unsigned int flag=0;unsigned int Snake_flag=0;unsigned int SenA=50;unsigned int Out_flag=0;unsigned int DuoJi_angle;unsigned int Turn_flag=0;unsigned int Keep_flag=0;unsigned int Run_Time_Count=0;///////////////////////////////////////////////////////////////////unsigned int Speed=0, Count=0;//count=2即4秒测一次速度unsigned int ii=0,tt=0;int Goal_speed=15;int E1=0;int E2=0;int DE=0;int B1=0;int B2=0;int OUT=0;//////////////////////////////////////////////////////#include "Initiate.h"#include "Basic.h"#include "5110.h"#include "Control.h"//////////////////////////////////////////////////////////////////////void main(void){SetBusCLK_64M();Dly_ms(600);DisableInterrupts;PWMINIT();initPIT(); //内部中断SciInit() ; //串口LCD_init(); //LCDADCInit(); //ADCInit_Event_Count(); //测速初始化PWMDTY0=0;PWMDTY1=0;PWMDTY23=1450;Dly_ms(100);DDRB=0x00;while(PORTB_PB6==1) ; //等待开始键按下PWMDTY1=0;PWMDTY0=0;DuoJi_angle=1450;PWMDTY23=DuoJi_angle;Dly_ms(600);EnableInterrupts;while(1);}//////////////////////////////////////////////////////////////////////////////// void Scan_A2(){Xmax=0;Ymax=0;Xmax2=0;Ymax2=0;for(i=0;i<8;i++){if(AD_Value[i]<=10) AD_Value[i]=0;}for(i=0;i<8;i++) ///////////max{if(AD_Value[i]>Ymax){Ymax=AD_Value[i];Xmax=i;}}for(i=0;i<8;i++) ///////////max2{if(AD_Value[i]>Ymax2 && AD_Value[i]<Ymax){Ymax2=AD_Value[i];Xmax2=i;}}if(Ymax!=0){if(Xmax>Xmax2) SenA=(90*(Xmax+Xmax2)+Ymax-Ymax2)/12; //SenA else if(Xmax<Xmax2){if((90*(Xmax+Xmax2))<(Ymax-Ymax2)) SenA=0;else SenA=(90*(Xmax+Xmax2)+Ymax2-Ymax)/12;}else SenA=(90*(Xmax+Xmax2))/12;if(SenA>100) SenA=100;if(Xmax<1 /*&& Xmax2==1 && Ymax2<40*/ ) //////Out_flag 0/1/2{Out_flag=1;}else if(Xmax>6 /*&& Xmax2==6 && Ymax2<40*/ ){Out_flag=2;}else Out_flag=0;}switch(Out_flag){case 1 : SenA=0;break;case 2 : SenA=100;break;}}///////////////////////////////////////////////////////////////////////////////////void Change_angle(){if(SenA>50) DuoJi_angle=(65*(SenA-50)+14500)/10;else DuoJi_angle=(14500-65*(50-SenA))/10;PWMDTY23=DuoJi_angle;}/////////////////////////////////////////////////////////////////////////////////////void Rem_angle() //记忆传感器角度20个{if(SenA<40) Done_cache[20]=1;else if(SenA>60) Done_cache[20]=2;else Done_cache[20]=0;Angle_cache[20]=SenA;for(ii=0;ii<20;ii++){Done_cache[ii]=Done_cache[ii+1];Angle_cache[ii]=Angle_cache[ii+1];}}///////////////////////////////////////////////////////////////////////////////////void Mod(){if(Done_cache[0]==0 && Done_cache[1]==0 && Done_cache[2]==0 && Done_cache[3]==0 && Done_cache[4]==0 && Done_cache[5]==0 && Done_cache[6]==0 && Done_cache[7]==0 && Done_cache[8]==0 && Done_cache[9]==0 && Done_cache[10]==0 && Done_cache[11]==0 && Done_cache[12]==0 && Done_cache[13]==0 && Done_cache[14]==0 && Done_cache[15]==0 && Done_cache[16]==0 && Done_cache[17]==1 && Done_cache[18]==1 && Done_cache[19]==1 && Done_cache[20]==1 && Angle_cache[19]<Angle_cache[18] && Angle_cache[18]<Angle_cache[17] ){Keep_flag=1;//直道左弯}else if(Done_cache[0]==0 && Done_cache[1]==0 && Done_cache[2]==0 && Done_cache[3]==0 && Done_cache[4]==0 && Done_cache[5]==0 && Done_cache[6]==0 && Done_cache[7]==0 && Done_cache[8]==0 && Done_cache[9]==0 && Done_cache[10]==0 && Done_cache[11]==0 && Done_cache[12]==0 && Done_cache[13]==0 && Done_cache[14]==0 && Done_cache[15]==0 && Done_cache[16]==0 && Done_cache[17]==2 &&Done_cache[18]==2 && Done_cache[19]==2 && Done_cache[20]==2 && Angle_cache[19]>Angle_cache[18] && Angle_cache[18]>Angle_cache[17] ){Keep_flag=2;//直道右弯}else if(Done_cache[0]==1 && Done_cache[1]==1 && Done_cache[2]==1 && Done_cache[3]==1 && Done_cache[4]==1 && Done_cache[5]==1 && Done_cache[6]==1 && Done_cache[7]==1 && Done_cache[8]==1 && Done_cache[9]==1 && Done_cache[10]==1 && Done_cache[11]==1 && Done_cache[12]==1 && Done_cache[13]==1 && Done_cache[14]==1 && Done_cache[15]==1 && Done_cache[16]==1 && Done_cache[17]==1 && Done_cache[18]==1 && Done_cache[19]==1 && Done_cache[20]==1 ){Keep_flag=3;//左弯}else if(Done_cache[0]==2 && Done_cache[1]==2 && Done_cache[2]==2 && Done_cache[3]==2 && Done_cache[4]==2 && Done_cache[5]==2 && Done_cache[6]==2 && Done_cache[7]==2 && Done_cache[8]==2 && Done_cache[9]==2 && Done_cache[10]==2 && Done_cache[11]==2 && Done_cache[12]==2 && Done_cache[13]==2 && Done_cache[14]==2 && Done_cache[15]==2 && Done_cache[16]==2 && Done_cache[17]==2 && Done_cache[18]==2 && Done_cache[19]==2 && Done_cache[20]==2 ){Keep_flag=4;//左弯}else Keep_flag=0;}///////////////////////////////////////////////////////////////////////////////////*误差----------E = 实际值-设定值误差变化------dE = 本次误差-上次误差中间变量1-----B1= E + dE中间变量2-----B2= E*E + dE*dE输出----------OUT= B2/B1一次修改后: IF E=0 AND dE=0 THAN OUT=0 ELSE OUT=B2/B1二次修改后: IF B1=0 THAN OUT=0 ELSE OUT=B2/B1*///////////////////////////////////////////////////////////void Speed_pid(){E2=Speed-Goal_speed;DE=E2-E1;B1=E2+DE;B2=E2*E2+DE*DE;E1=E2;if(B1==0) OUT=0;else OUT=B2/B1;PWMDTY1=OUT;}//////////////////////内部中断///////////////////////////////////////////////#pragma CODE_SEG __NEAR_SEG NON_BANKEDvoid interrupt 66 PIT0(void) //2ms{PITTF_PTF0=1;//清中断标志位if(Keep_flag==1 || Keep_flag==2 || Keep_flag==3 || Keep_flag==4){tt++;if(tt==160){Keep_flag=0;tt=0;}}while(ATD0STA T2_CCF0==0); // 等待转换结束while(A TDOSTAT2_CCF0==0) AD_GetValue();Count++;if(Count>1){Speed=PACNT;Scan_A2();Rem_angle();PACNT=0;Count=0;}if(Keep_flag==0){Mod();Goal_speed=17;}else if(Keep_flag==1){//SenA=0;Goal_speed=6;}else if(Keep_flag==2){//SenA=100;Goal_speed=6;}else if(Keep_flag==3 || Keep_flag==4){Goal_speed=15;}PID();Change_angle();}void interrupt 67 PIT1(void) //100ms {PITTF_PTF1=1;//清中断标志位Run_Time_Count++;//PWMDTY23=DuoJi_Middle;//DuoJi_Middle++;/*LCD_Show_Number(30,0,DuoJi_angle);LCD_Show_Number(0,0,SenA);LCD_Show_Number(0,1,Xmax);LCD_Show_Number(30,1,PWMDTY1);LCD_Show_Number(0,2,Ymax);LCD_Show_Number(30,2,Speed);LCD_Show_Number(0,3,Xmax2);LCD_Show_Number(0,4,Ymax2);LCD_Show_Number(0,5,Out_flag);LCD_Show_Number(30,5,flag);*/LCD_Show_Number(0,0,PWMDTY1);LCD_Show_Number(30,0,SenA);LCD_Show_Number(0,1,Speed);LCD_Show_Number(30,1,Goal_speed);LCD_Show_Number(0,2,Keep_flag);LCD_Show_Number(30,2,tt);LCD_Show_Number(0,3,Done_cache[0]);LCD_Show_Number(30,3,Done_cache[5]);LCD_Show_Number(0,4,Done_cache[10]);LCD_Show_Number(30,4,Done_cache[15]);LCD_Show_Number(0,5,Done_cache[19]);LCD_Show_Number(30,5,Done_cache[20]);if(Run_Time_Count>180) stop();}/***************************************************************************/ /*****常用操作**************************************************************/ /* enable global interrupts */#define GIE (SREG |= BIT(7))/* disable global interrupts */#define GID (SREG &= ~BIT(7))#define SLEEP() asm("sleep")/* enables an unsigned char to be used as a series of booleans */#define BIT(x) (1 << (x))#define SETBIT(x, y) (x |= y)#define CLEARBIT(x, y) (x &= ~y)#define CHECKBIT(x, y) (x & y)// ***** Define I/O pins *****#define BIT7 0x80#define BIT6 0x40#define BIT5 0x20#define BIT4 0x10#define BIT3 0x08#define BIT2 0x04#define BIT1 0x02#define BIT0 0x01#define true 1#define True 1#define false 0#define False 0#define SCLK BIT4#define SDIN BIT3#define LCD_DC BIT2#define LCD_CE BIT0#define LCD_RST BIT1#define LCD_PORT PTT#define LCD_DIR DDRT//#define LCD_IN aa/************************************************************************/void LCD_init(void);void LCD_clear(void);void delay_1us(void);void LCD_set_XY(unsigned char x,unsigned char y);void LCD_write_char(unsigned char c);void LCD_write_english_string(unsigned char X,unsigned char Y,char *s);void LCD_write_chinese_string(unsigned char X, unsigned char Y,unsigned char ch_with,unsigned char num,unsigned char line,unsigned char row);void LCD_draw_bmp_pixel(unsigned char X,unsigned char Y,unsigned char *map,unsigned char Pix_x,unsigned char Pix_y);void LCD_write_byte(unsigned char dat, unsigned char command);const tabpoint[9]={0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//***********************电机PID控制变量声明和初始化*******************************static unsigned int Kp=100;static unsigned int Kp2=100;static unsigned int Ki=3;static unsigned int Kd=30;unsigned short E = 5;unsigned char q = 1;int Mp = 0;int Mi = 0;int Md = 0;int Mp2 = 0;int MPWM=0;int L_u[3];/*************************电机PID调节***************************************************************************/ void PID(){L_u[2] = L_u[1];L_u[1] = L_u[0];L_u[0] = Goal_speed - Speed;//p_speed是根据传感器的检测情况在软件中给定的理论速度,search_PACN10就是PACN10表实际速度Mp = Kp * L_u[0];//偏差的放大倍数,KP值大可以加快调节,但会使稳定性下降Mi = Mi + Ki * L_u[0];//积分累加,可以消稳态误差,但是会使稳定下降,动态响应变慢Md = Kd * (L_u[0] - 2 * L_u[1] + L_u[2]);//改善动态性能,减少超调,太大会有干扰Mp2 = Kp2 * (L_u[0] - L_u[1]);if(((Ki * L_u[0]) > E)||((Ki * L_u[0]) < -E)) //初始化q=1,E=5 用这个if来决定是否需要用积分来调节,如果刚开始的积分已经很大了,就不需要用积分来调节了q = 0;else q = 1;MPWM = MPWM + Mp + q * Mi + Md +Mp2;// MPWM = MPWM + Mp+ Md +Mp2;if(MPWM > 1000) MPWM = 1000;//保证不溢出if(MPWM < 0) MPWM = 0;MPWM=MPWM/3;if(MPWM>100) MPWM=100;if(MPWM<0) MPWM=0;PWMDTY01=MPWM;Mp = 0;//调节一次后要把PID值清0Mi = 0;Md = 0;Mp2 = 0;}/////////////////////////////////////////////////////////////////////////////////////////////unsigned int Key_Scan2() // 返回1,2,4,8{unsigned int i=0;DDRB=0x00;i=PORTB&0x0f;return i;}////////////////////////////////////////////////////////////////////////////////////////////////// void AD_GetValue(){AD_Value[0]=A TD0DR0; //读取结果寄存器的值AD_Value[1]=A TD0DR1;AD_Value[2]=A TD0DR2;AD_Value[3]=A TD0DR3;AD_Value[4]=A TD0DR4;AD_Value[5]=A TD0DR5;AD_Value[6]=A TD0DR6;AD_Value[7]=A TD0DR7;AD_Value[8]=A TD0DR8; //读取结果寄存器的值AD_Value[9]=A TD0DR9;AD_Value[10]=A TD0DR10;AD_Value[11]=ATD0DR11;AD_Value[12]=A TD0DR12;AD_Value[13]=A TD0DR13;AD_Value[14]=A TD0DR14;AD_Value[15]=A TD0DR15;}////////////////////////////////////////////////////////////////////////////////////////////////// void Show_AD(){LCD_Show_Number(0,0,AD_Value[0]);LCD_Show_Number(30,0,AD_V alue[1]);LCD_Show_Number(0,1,AD_Value[2]);LCD_Show_Number(30,1,AD_V alue[3]);LCD_Show_Number(0,2,AD_Value[4]);LCD_Show_Number(30,2,AD_V alue[5]);LCD_Show_Number(0,3,AD_Value[6]);LCD_Show_Number(30,3,AD_V alue[7]);LCD_Show_Number(0,4,AD_Value[8]);LCD_Show_Number(30,4,AD_V alue[9]);LCD_Show_Number(0,5,AD_Value[10]);LCD_Show_Number(30,5,AD_V alue[11]);LCD_Show_Number(0,6,AD_Value[12]);LCD_Show_Number(30,6,AD_V alue[13]);LCD_Show_Number(60,0,AD_V alue[14]);LCD_Show_Number(60,1,AD_V alue[15]);LCD_Show_Number(60,2,AD_V alue[16]);}////////////////////////////////////////////////////////////////////////////////////////////////void SetBusCLK_64M(void){CLKSEL=0X00; //disengage PLL to systemPLLCTL_PLLON=1; //turn on PLLSYNR =0xc0 | 0x07;REFDV=0x80 | 0x01;POSTDIV=0x00; //pllclock=2*osc*(1+SYNR)/(1+REFDV)=128MHz;_asm(nop); //BUS CLOCK=64M_asm(nop);while(!(CRGFLG_LOCK==1)); //when pll is steady ,then use it;CLKSEL_PLLSEL =1; //engage PLL to system;}/////////////////////////////////////////////////////////////////////////////////////////////////void Dly_ms(int ms){int ii,jj;if (ms<1) ms=1;for(ii=0;ii<ms;ii++)for(jj=0;jj<5341;jj++); //64MHz--1ms}////////////////////////////////////////////////////////////////////////////////////////////////unsigned char SciRead() //串口接受函数{if(SCI1SR1_RDRF==1) //表明数据从位移寄存器传输到SCI数据寄存器{SCI1SR1_RDRF=1; //读取数据寄存器会将RDRF清除重新置位return SCI1DRL; //返回数据寄存器的数据}}void uart_putchar(unsigned char message)//串口发送函数{while(SCI1SR1_TC!=1); //这句话很重要,第一个发送完在发送第二个,否则发送错误//PORTB=~PORTB; //改变一次发送一次SCI1DRL=message;}///////////////////////////////////////////////////////////////////////////////////void stop(){DisableInterrupts;PWMDTY0=50;PWMDTY1=0;Dly_ms(900);PWMDTY0=0;PWMDTY1=0;while(PORTB_PB6==1) ; //等待开始键按下{while(1){LCD_Show_Number(0,0,Angle_cache[0]);LCD_Show_Number(27,0,Angle_cache[1]);LCD_Show_Number(54,0,Angle_cache[2]);LCD_Show_Number(0,1,Angle_cache[3]);LCD_Show_Number(27,1,Angle_cache[4]);LCD_Show_Number(54,1,Angle_cache[5]);LCD_Show_Number(0,2,Angle_cache[6]);LCD_Show_Number(27,2,Angle_cache[7]);LCD_Show_Number(54,2,Angle_cache[8]);LCD_Show_Number(0,3,Angle_cache[9]);LCD_Show_Number(27,3,Angle_cache[10]);LCD_Show_Number(54,3,Angle_cache[11]);LCD_Show_Number(0,4,Angle_cache[12]);LCD_Show_Number(27,4,Angle_cache[13]);LCD_Show_Number(54,4,Angle_cache[14]);LCD_Show_Number(0,5,Angle_cache[15]);LCD_Show_Number(27,5,Angle_cache[16]);LCD_Show_Number(54,5,Angle_cache[17]);/////////////////////////////////////////////////显示记忆数据}}}/////////////////////////*while(1){for(i=1150;i<1750;i++){PWMDTY23=i;LCD_Show_Number(0,1,i);Dly_ms(100);}} */////////////////////////////****************************************************************************** **************************************/void LCD_init(void){//先设置为输出SETBIT(LCD_DIR,SCLK);// DDRD|=SCLK;SETBIT(LCD_DIR,SDIN);//DDRC|=SDIN;SETBIT(LCD_DIR,LCD_DC);//DDRC|=LCD_DC;SETBIT(LCD_DIR,LCD_CE);//DDRC|=LCD_CE;SETBIT(LCD_DIR,LCD_RST);//DDRC|=LCD_RST;// 产生一个让LCD复位的低电平脉冲CLEARBIT(LCD_PORT,LCD_RST);//LCD_RST = 0;delay_1us();SETBIT(LCD_PORT,LCD_RST);//LCD_RST = 1;// 关闭LCDCLEARBIT(LCD_PORT,LCD_CE);//LCD_CE = 0;delay_1us();// 使能LCDSETBIT(LCD_PORT,LCD_CE);//LCD_CE = 1;delay_1us();LCD_write_byte(0x21, 0); // 使用扩展命令设置LCD模式LCD_write_byte(0xc8, 0); // 设置偏置电压LCD_write_byte(0x06, 0); // 温度校正LCD_write_byte(0x13, 0); // 1:48LCD_write_byte(0x20, 0); // 使用基本命令LCD_clear(); // 清屏LCD_write_byte(0x0c, 0); // 设定显示模式,正常显示LCD_set_XY(0,1);// 关闭LCDCLEARBIT(LCD_PORT,LCD_CE);//LCD_CE = 0;}/****************************************************************************** **************************************/void LCD_clear(void){unsigned int i;LCD_write_byte(0x0c, 0);LCD_write_byte(0x80, 0);for (i=0; i<500; i++){LCD_write_byte(0, 1);}}/****************************************************************************** **************************************/void delay_1us(void) //1us延时函数{unsigned int i;for(i=0;i<5;i++);}/********************************************************************************************************************/void LCD_set_XY(unsigned char X, unsigned char Y){LCD_write_byte(0x40 | Y, 0);// columnLCD_write_byte(0x80 | X, 0);// row}/****************************************************************************** **************************************/LCD_write_point(unsigned char X, unsigned char Y){unsigned int temp=0;if(poy!=X){potemp1=0x00;potemp2=0x00;potemp3=0x00;potemp4=0x00;potemp5=0x00;potemp6=0x00;}poy=X;if(Y<=8){if(pox!=1) potemp1=0x00;pox=1;temp=potemp1|tabpoint[Y];LCD_set_XY(X,8);LCD_write_byte(temp, 1);potemp1=temp;}else if(Y<=16){if(pox!=2) potemp2=0x00;pox=2;temp=potemp2|tabpoint[Y-8];LCD_set_XY(X,9);LCD_write_byte(temp, 1);potemp2=temp;}else if(Y<=24)if(pox!=3) potemp3=0x00;pox=3;temp=potemp3|tabpoint[Y-16]; LCD_set_XY(X,10);LCD_write_byte(temp, 1); potemp3=temp;}else if(Y<=32){if(pox!=4) potemp4=0x00;pox=4;temp=potemp4|tabpoint[Y-24]; LCD_set_XY(X,11);LCD_write_byte(temp, 1); potemp4=temp;}else if(Y<=40){if(pox!=5) potemp5=0x00;pox=5;temp=potemp5|tabpoint[Y-32]; LCD_set_XY(X,12);LCD_write_byte(temp, 1); potemp5=temp;}else if(Y<=48){if(pox!=6) potemp6=0x00;pox=6;temp=potemp6|tabpoint[Y-40]; LCD_set_XY(X,13);LCD_write_byte(temp, 1); potemp6=temp;}//for(temp=0;temp<50000;temp++);/****************************************************************************** **************************************/void LCD_write_char(unsigned char c){unsigned char line;c -= 32;for (line=0; line<6; line++){LCD_write_byte(font6x8[c][line], 1);}}void LCD_write_char2(unsigned char X, unsigned char Y,unsigned char c){unsigned char line;LCD_set_XY(X,Y);c -= 32;for (line=0; line<6; line++){LCD_write_byte(font6x8[c][line], 1);}}/****************************************************************************** **************************************//*-----------------------------------------------------------------------LCD_write_english_String : 英文字符串显示函数输入参数:*s :英文字符串指针;X、Y : 显示字符串的位置,x 0-83 ,y 0-5-----------------------------------------------------------------------*/void LCD_write_english_string(unsigned char X,unsigned char Y,char *s){LCD_set_XY(X,Y);while (*s){LCD_write_char(*s);s++;}}/********************************************************************************************************************//*-----------------------------------------------------------------------LCD_write_chinese_string: 在LCD上显示汉字输入参数:X、Y :显示汉字的起始X、Y坐标;ch_with :汉字点阵的宽度num :显示汉字的个数;line :汉字点阵数组中的起始行数row :汉字显示的行间距-----------------------------------------------------------------------*//*void LCD_write_chinese_string(unsigned char X, unsigned char Y,unsigned char ch_with,unsigned char num,unsigned char line,unsigned char row){unsigned char i,n;LCD_set_XY(X,Y); //设置初始位置for (i=0;i<num;){for (n=0; n<ch_with*2; n++) //写一个汉字{if (n==ch_with) //写汉字的下半部分{if (i==0) LCD_set_XY(X,Y+1);else{LCD_set_XY((X+(ch_with+row)*i),Y+1);}}LCD_write_byte(HZK[line+i][n],1);}i++;LCD_set_XY((X+(ch_with+row)*i),Y);}}*//****************************************************************************** **************************************//*-----------------------------------------------------------------------LCD_draw_map : 位图绘制函数输入参数:X、Y :位图绘制的起始X、Y坐标;*map :位图点阵数据;Pix_x :位图像素(长)Pix_y :位图像素(宽)-----------------------------------------------------------------------*/void LCD_draw_bmp_pixel(unsigned char X,unsigned char Y,unsigned char *map,unsigned char Pix_x,unsigned char Pix_y){unsigned int i,n;unsigned char row;if (Pix_y%8==0){row=Pix_y/8; //计算位图所占行数}else{row=Pix_y/8+1;}for (n=0;n<row;n++){LCD_set_XY(X,Y);for(i=0; i<Pix_x; i++){LCD_write_byte(map[i+n*Pix_x], 1);}Y++; //换行}}/****************************************************************************** **************************************//*-----------------------------------------------------------------------LCD_write_byte : 写数据到LCD输入参数:data :写入的数据;command :写数据/命令选择;-----------------------------------------------------------------------*/void LCD_write_byte(unsigned char dat, unsigned char command){unsigned char i;CLEARBIT(LCD_PORT,LCD_CE);// 使能LCD_CE = 0if (command == 0){CLEARBIT(LCD_PORT,LCD_DC);// 传送命令LCD_DC = 0;}else{SETBIT(LCD_PORT,LCD_DC);// 传送数据LCD_DC = 1;}for(i=0;i<8;i++){//delay_1us();if(dat&0x80){SETBIT(LCD_PORT,SDIN);//SDIN = 1;}else{CLEARBIT(LCD_PORT,SDIN);//SDIN = 0;}CLEARBIT(LCD_PORT,SCLK);//SCLK = 0;dat = dat << 1;SETBIT(LCD_PORT,SCLK);//SCLK = 1;}SETBIT(LCD_PORT,LCD_CE);//LCD_CE = 1;}void LCD_Show_Number (unsigned char X,unsigned char Y,unsigned int number) {LCD_set_XY(X,Y);LCD_write_char2(X,Y,number/1000+48);LCD_write_char2(X+6,Y,number%1000/100+48);LCD_write_char2(X+12,Y,number%100/10+48);LCD_write_char2(X+18,Y,number%10+48);}。

飞思卡尔智能车程序汇总

飞思卡尔智能车程序汇总
#include "lcd5110.h"
#include "24c02.h"
#include "button.h"
#define servo_period 20 //ms
#define motor_pwm_frequ 1 //khz
void delay(unsigned int ms)
{
unsigned int i;
PWMPER23 = 80/4*servo_period*125;
PWMPER01 = 80/4*servo_period*125;
PWMDTY67 =0;
PWMDTY45 =0;
PWMDTY23 =0;
PWMDTY01 =0;
}
void main(void) {
/* put your own code here */
disply_listchar(0,3," TURN POWER OFF ",1);
disply_listchar(0,4,"=================",1);
disply_listchar(0,5," ",1);
delay(setnum[1]*100);
PORTB_PB0=0;
}
}
3.电机程序
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
unsigned char j;
for(i=0;i<ms;i++)
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include "includes.h"
/*位置PID调节*/
#define Ki_p 0
#define Kp_p 9/20
#define Kd_p 20/18
void Va_0(char);//加速
void Va_1(char);//减速
void Va_2(char);//减速
void Va_3(char);//减速
void fun0(void);
void fun1 (void);
void fun2(void);
void fun3(void);
void fun4(void);
void fun5(void);
void fun6(void);
void delay2(int x);
#define cycle 2 //圈数
void startpointIdentify()//起始识别
/*起始点识别*/
{char RaceS1 = RWS[0]+RWS[9]+RWS[1]+RWS[8]+RWS[2]+RWS[7];
char RaceS2 = RWS[0]+RWS[1]+RWS[2]+RWS[3]+RWS[4]+RWS[5]+RWS[6]+RWS[7]+RWS[8]+RWS[9];
if((RaceS1==6)&&(!WB))// RaceS1==6保证是正向通过,(!WB)
{
WB=1; //出发点判断打开
Pulse=0; //开始记判断距离
}
if((RaceS2==10)&&(WB==1)&&(!WBOff)) //若RaceS2值为10表示通过的事交叉线
{
WBOff=1; //WBOff=1表示通过的是十字交叉线;
}
if((Pulse>=5000)&&(WB==1))//判断距离是5000个码盘脉冲,计数结束后进入最终判断,同时初始化数据以便下一次判断;
{if(WBOff==0)
++Start; //Start表示经过出发点的次数;
else
Start=Start;
WBOff=0;
WB=0;
Pulse=0;
// PORTA=Start;
}if(Start>=cycle+1)
{
WB1=1;
if(Pulse>=5000)
{
WB1=0;
Pulse=0;
//DstV=0;
stop_flag = 0;
//delay2(10000);
}
}
}
int e,es=0;
int ee[10];
int cach[201];
int DstV = 0;
char flag_0;
char flag_y;
char stop_flag = 1;
char a_flag;
void SystemInit()
{
flag_0 = -1;
CRGInit();
ECTInit();//使能脉冲计数器
ATDInit();
PWMInit();
PWME=0Xaa; //使能PWM输出
DDRA = 0x00;
EnableInterrupts;
DDRB = 0xff;
//PORTB = 0x55;
ADvalueInit();// 初始化
}
char RWS[10]; //为全局布尔数组
char WBOff=0,WB=0,WB1=0; //为全局布尔数int Pulse=0; //为型全局变量
char Start=0; //经过起始点次数,为全局变量void startpointIdentify();
void main(void)
{
SystemInit();
DstV =108;
flag_0 = 0;
for(;;)
{
if(flag_0==2)
{
biliY();
chushihua();//计算ie
cache_replace();
ie=-ie; //反向加到舵机上
cach[0]=(int)(ie*100); //处理完所有数据,
ee[0] = cach[0]*Kp_p;
e = cach[0]*Kp_p+(cach[0]-cach[7])*Kd_p;// /70*CurrentSpeed;
if(e>600)
e=600;
if(e<-600)
e=-600;
ee[3] = cach[0] -cach[2];
if(stop_flag == 1)
{
aa = PORTA;
aa = aa&0xf0;
switch(aa)
{
case 0x00:fun0();break;//冲弯道速度比较快,且第二圈速度会减速case 0x20:fun1();break;//冲弯道速度比较快
case 0x30:fun2();break;//匀速
case 0x50:fun3();break;//冲直道
case 0x80:fun4();break;//快速直道,
case 0x90:fun5();break;//稳定跑
default :fun3(); break;//
}
}
else
{
DstV = 2;
PWMDTY45 = 4400+e;
if(SysTimer>200)
{
DstV = 0;
for(;;)
{
PWMDTY45 = 4400;
}
}
}
startpointIdentify(); //起点识别,到指定圈数后停止flag_0 = 0;
ATDInit();
}
}
}
void Va_0(char x) //加速0
{
DstV=DstV+3;
if(DstV>=x)
DstV=x;
}
void Va_1(char x)//加速1
{
DstV=DstV+5 ;
if(DstV>=x)
DstV=x;
}
void Va_2(char x)//减速2
{
DstV=DstV-5;
if(DstV<=x)
DstV=x;
}
void Va_3(char x)//减速3
{
DstV=DstV-1;
if(DstV<=x)
DstV=x;
}。

相关文档
最新文档