微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 飞思卡尔智能车dg128单片机控制程序代码介绍

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

时间:10-02 整理:3721RD 点击:
以下是飞思卡尔智能车dg128单片机控制程序代码介绍:
#include <hidef.h>      /* common defines and macros */
#include <mc9s12dg128.h>     /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"
#pragma CODE_SEG __NEAR_SEG NON_BANKED
//定义全局变量
int blackline=500;
unsigned int Get_pulse;
int qian[11];                                        //AD转换结果
int hou[3];
int dw_result[4];                                    //档位信号
int dangwei;                                   
int pianxin_a[11]={115,85,62,41,20,0,-20,-41,-62,-85,-115};  //两排灯距离中线的偏移量
int go=0;
int qidian,once;
int speed;                                      //要求速度
int counter_a,counter_1,counter_2,counter_3,counter_b;      //前后两排在黑线阀值上的灯数
int one,two,three; int x;                           //前后排灯在黑线上的灯编号
int biga,bigb,bigc; int bigd;                     //前排最大的三个电压值he后排的最大值
int tan_o,tan_n1,tan_n2,tan_n3,tan_n4,tan_n5,tan_n6;
int tan_n;    //前,后次偏角正弦
int away_o,away_n;                                //前后次车身中线偏移量
int kj;int kp;int zhuan,o;                          //控制舵机的参数
int jia_1,jia_2,jia_3;                                           //速度参数
int sudu;                                        //真实速度
                                   
//函数声明
void system_init(void);               //模块初始化函数
void clock_init(void);
void PWM_init(void);
void AD_Init(void);
void set_parameter(void);             //键盘输入参数显示
void Infrared_detect(void);           //红外检测速
void data_handle(void);
void direct_ctl(void);                //方向控制
void steer_ctl(void);                 //舵机控制
void slow1(void);                 
void slow2(void);
void slow3(void);
void slow4(void);
void slow5(void);
void slow6(void);
                     //刹车程序
void speed_ctl(void);                 //速度控制
void motor_ctl(void);                 //电机控制
void PACBInit(void);
void MDCInit(void);
//++++++++++++++++++++++++++++++++++++++++++++
//主函数开始
void main(void)
{
DisableInterrupts;
system_init();   //系统初始化
set_parameter();
PACBInit();
MDCInit();
EnableInterrupts;
for(;;)   
    {
      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
unsigned int begin=0;
  MCFLG = 0x80;
  { number_count ++;
    if( number_count==125)        //0.125秒取一次
      {
    number_count=0;
    Get_pulse = PACN10;   //get pluse 脉冲数
    PACN10 = 0X0000;
       }   
   }
  {
start++;
    if(start>100)        //3sec
    {begin++; start=0;
     if(begin>22)
      go=1;
   
    if(begin<150&&begin>22)
    go=2;  
      
      
    if(begin>=150)
    go=3;   
    }
   
   }
}
//-----系统初始化-----------------------
void system_init(void) //system initiat
{DDRB=0xff;
clock_init();      //clock initiat
PWM_init();           //pwm initiat
AD_Init();         //ATD initiat
}
void clock_init(void)                  //时钟初始化
{   
    CLKSEL=0X00;    //disengage PLL to system
    PLLCTL_PLLON=1;   //turn on PLL
    SYNR=2;         
    REFDV=1;          //pllclock=2*osc*(1+SYNR)/(1+REFDV)=24MHz;
    _asm(nop);          //BUS CLOCK=16M
    _asm(nop);
    while(!(CRGFLG_LOCK==1));   //when pll is steady ,then use it;
    CLKSEL_PLLSEL =1;          //engage PLL to system;
}
void AD_Init(void)
{  
  ATD0CTL2=0xC0;   //AD模块上电, 快速清零, 无等待模式, 禁止外部触发, 中断禁止     
  ATD0CTL3=0x44;   //每次转换8个序列, FIFO, Freeze模式下继续转   
  ATD0CTL4=0x02;   //10位精度, 采样时间为2个AD时钟周期,ATDClock=4MHz
  ATD0CTL5=0xB0;   //右对齐无符号,,连续转换 ,8轮流通道采样
  ATD0DIEN=0x00;   //禁止数字输入
  ATD1CTL2=0xC0;   //AD模块上电, 快速清零, 无等待模式, 禁止外部触发, 中断禁止     
  ATD1CTL3=0x44;   //每次转换8个序列, FIFO, Freeze模式下继续转   
  ATD1CTL4=0x02;   //10位精度, 采样时间为2个AD时钟周期,ATDClock=4MHz
  ATD1CTL5=0xB0;   //右对齐无符号,,连续转换 ,8轮流通道采样
  ATD1DIEN=0x00;   //禁止数字输入
}
void PWM_init(void)
{
PWME  =0x00;      //关闭
PWMPOL=0xff;      //先高电平
PWMCAE=0x00;      //左对齐
PWMCLK=0x0c;      //选择0,1,4,5通道时钟源头A   2,3通道时钟源头SB,6,7为时钟B
PWMPRCLK=0x33;    //时钟预分频0通道为8
//设置舵机
PWMCTL_CON01=1;   //使得通道0,1成为16位pwm
PWMPER0 =0x75;      
PWMPER1 =0x30;    //舵机的频率是: 24M/8/30000=100Hz,T=10ms
PWMDTY01=4500;    // 对应为4500/30000的占空比,待调整                          
//设置电机
PWMSCLB =50;      // 24MHZ/8/2/50=300K
PWMPER2 =100;     //电机的频率是: 24M/8/2/50/500=300Hz,T=5ms
PWMDTY2 =0;      //用于测试电机                                             
PWMPER3 =100;    //电机的频率是:  24M/8/2/50/500=300Hz,T=5ms
PWMDTY3 =0;      //用于测试电机
//小灯输出
PWMPER4 =79;    //小灯的频率是: 24M/8/79=38kHz
PWMDTY4 =30;
PWMPER7 =79;      //小灯的频率是: 24M/8/79=38kHz
PWMDTY7 =30;
DDRP    =0xff;    //控制输出
PWME    =0x9f;    //开放通道0,1 ,3,4,5,6,7
}
void PACBInit()
{
  TCTL4 = 0X02;       //下降沿捕捉脉冲
  PBCTL = 0x40;       //级联两个8位累加器(PAC0和PAC1)
  ICPAR = 0X03;       //使能累加器
  PACN10 = 0X0000;
}
void MDCInit(void)
{
  MCCTL = MCCTL&0Xfb; //模数计数器禁止运行
  MCCTL = 0Xe3;       //允许中断,模数计数方式
                      //返回时重新加载所用的常数,分频常数为16
  MCCTL = MCCTL|0X04; //模数计数器使能
  MCCNT = 1500;       //(1/24M)*16*1500= 1ms
  MCCTL = MCCTL|0X08 ; //把模数常数寄存器的值加载到模数计数器FLMC;
}
void set_parameter(void)//----------参数设置----------
{
  
blackline=500;
tan_n=0;
qidian=0,once=0;
speed=0;
counter_a=0,counter_b=0;      //前后两排在黑线阀值上的灯数
one=5;two=4;three=6;x=1;                           //前后排灯在黑线上的灯编号
biga=0;bigb=0;bigc=0; bigd=0;                     //前排最大的三个电压值he后排的最大值
tan_o=0,tan_n=0;                                   //前,后次偏角正弦
tan_n1=0;tan_n2=0;tan_n3=0;tan_n4=0;tan_n5=0;
away_o=0,away_n=0;                                //前后次车身中线偏移量
kj=0;kp=0;
zhuan=0;
}
//----------红外检测---------
void Infrared_detect(void)
{
  
while(!ATD0STAT1_CCF0);        
qian[0] = ATD0DR0;   
while(!ATD0STAT1_CCF1);        
qian[1] = ATD0DR1;   
while(!ATD0STAT1_CCF2);        
qian[2] = ATD0DR2;
while(!ATD1STAT1_CCF4);        
qian[3] = ATD1DR4;   
while(!ATD0STAT1_CCF3);        
qian[4] = ATD0DR3;   
while(!ATD0STAT1_CCF4);         
qian[5] = ATD0DR4;  
while(!ATD0STAT1_CCF5);         
qian[6] = ATD0DR5;  
while(!ATD1STAT1_CCF5);         
qian[7] = ATD1DR5;  
while(!ATD0STAT1_CCF6);         
qian[8] = ATD0DR6;   
while(!ATD0STAT1_CCF7);         
qian[9] = ATD0DR7;   
               
while(!ATD1STAT1_CCF0);        
qian[10] =  ATD1DR0;   
while(!ATD1STAT1_CCF1);        
hou[0] =  ATD1DR1;
while(!ATD1STAT1_CCF2);        
hou[1] = ATD1DR2;  
while(!ATD1STAT1_CCF3);           //AD0所有和AD1前4个用作探测信号接受     
hou[2] = ATD1DR3;
  
while(!ATD1STAT1_CCF6);          //档位通道开始        
dw_result[0] = ATD1DR6;  
while(!ATD1STAT1_CCF7);         
dw_result[1] = ATD1DR7;  
                                //档位通道结束
}

void data_handle(void)                                 //数据处理   
{
int n;  
counter_a=0,counter_b=0;
for(n=0;n<=10;n++)
{
if(qian[n]>blackline)
counter_a++;
}
for(n=0;n<=2;n++)
{
if(hou[n]>blackline)
counter_b++;
}
dangwei=0;
for(n=0;n<3;n++)
  
  {
  if(dw_result[n]>600) dangwei++;                        // 统计档位数目
  }
    switch( one )            //for testing
              
              {
                 case 10:  PORTB=0xf0;break;
                 case 9:  PORTB=0xfe;break;
                 case 8:  PORTB=0xfd;break;
                 case 7:  PORTB=0xfb;break;
                 case 6:  PORTB=0xf7;break;
                 case 5:  PORTB=0xaa;break;
                 case 4:  PORTB=0xef;break;
                 case 3:  PORTB=0xdf;break;
                 case 2:  PORTB=0xbf;break;
                 case 1:  PORTB=0x7f;break;
                 case 0: PORTB=0x0f;break;
                 default:break;
                  
              }  
{//判断起始点,参数待调整
  if(((qian[1]>blackline&&qian[9]>blackline&&qian[2]>blackline
  
  &&qian[10]>blackline)||(qian[1]>blackline&&qian[9]>blackline
  
  &&qian[0]>blackline&&qian[8]>blackline))&&(qian[3]<blackline
  
  ||qian[4]<blackline||qian[6]<blackline||qian[7]<blackline)
  
  &&(counter_a>4&&counter_a<8))
  {
    once++;tan_n=tan_o;away_n=away_o;
  }
if(once>1&&counter_a<4)
{
if(go==2){qidian=1;once=0;}
if(go==3){qidian++;once=0;}
}
}
if(counter_a>5&&qian[4]>blackline&&qian[5]>blackline&&qian[6]>blackline&&
(qian[3]>blackline||qian[7]>blackline))    //过十字交叉线时或过起始线
   {tan_n=tan_o; away_n=away_o;}
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;}}
  
bigd=0;
for(n=0;n<=2;n++)
{if(bigd<hou[n]){bigd=hou[n];x=n;}}
if(counter_a>5&&qian[4]>blackline&&qian[5]>blackline&&qian[6]>blackline)
one=5;
   if((one-two)==1||(two-one)==1)
{
     if(counter_a>0&&counter_a<3)
     {
       if( (biga-bigb)<=(bigb-bigc) )  tan_n=(pianxin_a[one]+pianxin_a[two])/2;
       else  tan_n=pianxin_a[one];
   
   
     
    if(counter_b>0)
   {
   
   switch(x)
   {case 1:
   {
    away_n=0; break;
   }
    case 0:
   {
    away_n=34; break;
   }   
    case 2:
   {
     away_n=-34; break;
   }   
   }
    }
   
   
    if(counter_b==0)
   
    {
    if(tan_n<=20&&tan_n>=-20)away_n=0;
    if(tan_n>20)away_n=17;
    if(tan_n<-20)away_n=-17;
   
    }
   
     }
      if(counter_a==0)
     {
if(tan_o<-100)     
tan_n=-120;
if(tan_o>100)
tan_n=120;
if(tan_o<100&&tan_o>-100)
tan_n=tan_o;
away_n=away_o;
     }
}
     
   tan_n1=tan_n2;tan_n2=tan_n3;tan_n3=tan_n4;tan_n4=tan_n5;tan_n5=tan_n6;tan_n6=tan_n;
    tan_n=(tan_n4+tan_n5+tan_n6+tan_n3+tan_n2+tan_n1)/6;
   
     if(tan_o<50&&tan_n>-50){
      
      if(tan_n-tan_o<-10||tan_n-tan_o>10) {
        tan_n=tan_o;  
      if((tan_n5-tan_n4>5&&tan_n4-tan_n3>4&&tan_n3-tan_n2>3)||(tan_n5-tan_n4<-5&&tan_n4-
tan_n3<-4&&tan_n3-tan_n2<-3)
      
      ||(tan_n5-tan_n4>0&&tan_n4-tan_n3>0&&tan_n3-tan_n2>0&&tan_n2-tan_n1>0)
      
      ||(tan_n5-tan_n4<0&&tan_n4-tan_n3<0&&tan_n3-tan_n2<0&&tan_n2-tan_n1<0))
      
      tan_n=tan_n6;
      }
   
     }
     
     
     
          if(tan_o>50||tan_n<-50){
      
      if(tan_n-tan_o<-15||tan_n-tan_o>15) {
        tan_n=tan_o;  
      if((tan_n5-tan_n4>5&&tan_n4-tan_n3>4&&tan_n3-tan_n2>3)||(tan_n5-tan_n4<-5&&tan_n4-
tan_n3<-4&&tan_n3-tan_n2<-3)
      
      ||(tan_n5-tan_n4>0&&tan_n4-tan_n3>0&&tan_n3-tan_n2>0&&tan_n2-tan_n1>0)
      
      ||(tan_n5-tan_n4<0&&tan_n4-tan_n3<0&&tan_n3-tan_n2<0&&tan_n2-tan_n1<0))
      
      tan_n=tan_n6;
      }
   
          }
   
      tan_o=tan_n;away_o=away_n;
}

void direct_ctl(void)
{
   
        
                    if(tan_n>=-120&&tan_n<-90){kj=46;kp=12;}
                    if(tan_n>=-90&&tan_n<-60) {kj=47;kp=13;}
                    if(tan_n>=-60&&tan_n<-20) {kj=48;kp=14;}
                    if(tan_n>=-20&&tan_n<-8) {kj=46;kp=15;}   
                    if(tan_n>=-8&&tan_n<0)  {kj=45;kp=14;}
                    if(tan_n>=0&&tan_n<8)   {kj=45;kp=14;}
                    if(tan_n>=8&&tan_n<20)  {kj=46;kp=15;}
                    if(tan_n>=20&&tan_n<60)  {kj=48;kp=14;}
                    if(tan_n>=60&&tan_n<90)  {kj=47;kp=13;}
                    if(tan_n>=90&&tan_n<=120) {kj=47;kp=12;}
                    
   
zhuan=(tan_n*kj+away_n*kp)/10;
}
void steer_ctl(void)            //舵机控制
{
direct_ctl();
  
PWMDTY01=4620+zhuan;
}

                             //刹车函数参数待调整 j<?
void slow1(void)
{
int i;int j;
for(i=1;i<6;i++)
for(j=1;j<6;j++)
{
PWMDTY2=0;
PWMDTY3=10;}
PWMDTY3=0;
}
void slow2(void)
{
int i;int j;
for(i=1;i<8;i++)
for(j=1;j<7;j++)
{
PWMDTY2=0;
PWMDTY3=12;}
PWMDTY3=0;
}
void slow3(void)
{
int i;int j;
for(i=1;i<8;i++)
for(j=1;j<8;j++)
{ PWMDTY2=0;
PWMDTY3=14;}
PWMDTY3=0;
}
void slow4(void)
{
int i;int j;
for(i=1;i<10;i++)
for(j=1;j<15;j++)
{ PWMDTY2=0;
PWMDTY3=16;}
PWMDTY3=0;
jia_1++;}
void slow5(void)
{
int i;int j;
for(i=1;i<12;i++)
for(j=1;j<15;j++)
{ PWMDTY2=0;
PWMDTY3=18;}
PWMDTY3=0;
jia_2++;}
void slow6(void)
{
int i;int j;
for(i=1;i<15;i++)
for(j=1;j<13;j++)
{ PWMDTY2=0;
PWMDTY3=20;}
PWMDTY3=0;
jia_3++;}
void speed_ctl(void)
{
   sudu=167*Get_pulse/10;        //单位cm/s
   
   
   
   if(zhuan<50&&zhuan>-50)speed=42;
   if((zhuan<80&&zhuan>=50)||(zhuan<=-50&&zhuan>-80))speed=41;
   if((zhuan<110&&zhuan>=80)||(zhuan<=-80&&zhuan>-110))speed=40;   
   if((zhuan<140&&zhuan>=110)||(zhuan<=-110&&zhuan>-140))speed=39;
   if((zhuan<170&&zhuan>=140)||(zhuan<=-140&&zhuan>-170))speed=38;
   if((zhuan<200&&zhuan>=170)||(zhuan<=-170&&zhuan>-200))speed=37;
   if((zhuan<230&&zhuan>=200)||(zhuan<=-200&&zhuan>-230))speed=38;
   if((zhuan<270&&zhuan>=230)||(zhuan<=-230&&zhuan>-270))speed=39;        
   if((zhuan<310&&zhuan>=270)||(zhuan<=-270&&zhuan>-310))speed=40;
   if((zhuan<350&&zhuan>=310)||(zhuan<=-310&&zhuan>-350))speed=40;
   if((zhuan<380&&zhuan>=350)||(zhuan<=-350&&zhuan>-380))speed=40;
   if((zhuan<400&&zhuan>=380)||(zhuan<=-380&&zhuan>-400))speed=40;
   if((zhuan<440&&zhuan>=400)||(zhuan<=-400&&zhuan>-440))speed=39;
   if((zhuan<490&&zhuan>=440)||(zhuan<=-440&&zhuan>-490))speed=38;
   if((zhuan<550&&zhuan>=490)||(zhuan<=-490&&zhuan>-550))speed=37;
   if((zhuan<600&&zhuan>=550)||(zhuan<=-550&&zhuan>-600))speed=36;
   if(zhuan>600||zhuan<-600)speed=35;
}
void motor_ctl(void)
{ int i; int  t;
  speed_ctl();
if(go>0)
{
if(qidian<2){
switch(dangwei){
case 0: {
if(zhuan>530||zhuan<-530)
{
if(sudu>230)slow3();
}
t=speed+25-sudu/10;
if(t>30&&t<70)
PWMDTY2=speed+25-sudu/10;break;
}
                                                   
   case 1: {
   
   
        if(zhuan>300||zhuan<-300)
{
if(sudu>300)slow2();
if(sudu>330)slow3();
}
   
  if((zhuan<=500&&zhuan>300)||(zhuan<-300&&zhuan>=-500))
{
if(sudu>280)slow4();
}
if(zhuan>500||zhuan<-500)
{
if(sudu>220)slow5();
}
if(jia_1+jia_2+jia_3>1)
   {  for(i=0;i<500;i++) {
    PWMDTY2= 75;
   }
   jia_1=0;jia_2=0;jia_3=0;
   }
   
   t=speed+35-sudu/10;
if(t>20&&t<70)
    PWMDTY2=speed+38-sudu/12;break;
   
   
   }
   
   
   
     case 2: {
     if(zhuan>280||zhuan<-280)
{
if(sudu>250)slow2();
if(sudu>290)slow3();
}
  if((zhuan<=360&&zhuan>200)||(zhuan<-200&&zhuan>=-360))
{
if(sudu>240)slow4();
}
  if((zhuan<=530&&zhuan>360)||(zhuan<-360&&zhuan>=-530))
{
if(sudu>220)slow5();
}
if(zhuan>520||zhuan<-520)
{
if(sudu>220)slow6();
}
  if(jia_1+jia_2+jia_3>2)
   {  for(i=0;i<600;i++) {
    PWMDTY2= 80;
   }
   jia_1=0;jia_2=0;jia_3=0;
   }
   
      t=speed+70-sudu/9;
     if(t>20&&t<90)
      PWMDTY2=speed+70-sudu/9;break;
     }
                              
  default: PWMDTY2=50;break;
  
}
}
else
{
PWMDTY2=0;
}
}

这个是干什么的?

谢谢小编分享!

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top