⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 提供一些飞思卡尔智能车比赛的源代码
💻 C
字号:
#include <hidef.h>      /* common defines and macros */
#include <mc9s12dg128.h>     /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"
#define curve_speed 0x20    //弯道速度
#define straight_speed 0x30 //直道速度
#define left_black 33       //左边激光管黑线的判断边界
#define right_black 33      //右边激光管黑线的判断边界
#define curve_number 2      //确定为弯道的计数数值
#define straight_number 4   //确定为直道的计数数值
uchar v_ref=0x40;//速度设定值
uchar left_laser[2]={0,0};//左边的激光管采样值
uchar right_laser[2]={0,0};//右边的激光管采样值
uchar left_filter=0;//左边激光管滤波后的采样值
uchar right_filter=0;//右边激光管滤波后的采样值
uchar left_mark=0;//检测到左弯
uchar right_mark=0;//检测到右弯
uchar try_ad1;
uchar try_ad2;
void ad_init()//初始化ad
{
  ATD0CTL2=0XC0;//ad模块上电,快速清零,无等待模式,禁止外部触发,中断禁止
  ATD0CTL3=0X10;//2个ad转换
  ATD0CTL4=0X87;//8位ad精度,1MHZadclock,adclock=bus/2/[psr+1]
  ATD0CTL5=0XB0;//右对齐,无符号,多通道,通道0开始
  ATD0DIEN=0X00;//禁止数字输入
}
void get_ad()//获取激光管的值
{
  uchar flag=0;
  while(flag<=2) 
  {
    
    while(ATD0STAT1_CCF0!=1)
    ;
    left_laser[flag]=ATD0DR0;
    while(ATD0STAT1_CCF1!=1)
    ;
    right_laser[flag]=ATD0DR1;
    flag++;
    
  }
  left_filter=(left_laser[0]+left_laser[1])/2;
  right_filter=(right_laser[0]+right_laser[1])/2;
  left_laser[0]=0;
  left_laser[1]=0;
  right_laser[0]=0;
  right_laser[1]=1;
  //left_filter=try_ad1;
  //right_filter=try_ad2;
}
void deal_ad()//处理ad采样程序
{
  get_ad();
  if(left_filter<=left_black) 
  {
    left_filter=0;
    left_mark=1;   //左侧有黑线
  } 
  else 
  {
    left_filter=0;
    left_mark=0;     //左侧无黑线
  }
  if(right_filter<=right_black) 
  {
    right_filter=0;
    right_mark=1;  //右侧有黑线
  } 
  else
  {
    right_filter=0;
    right_mark=0;  //右侧无黑线
  }
}
void accelerate()//激光管控制速度调整程序 
{
  static uchar straight_count=0;//直道计数
  static uchar curve_count=0;//弯道计数
  static uchar straight_mark=0;//直道标志
  static uchar curve_mark=0;//弯道标志
  static uchar curve_state=0;//检测状态为弯道
  static uchar straight_state=0;//检测状态为直道
  static uchar check_state=0;//有检测到需要的信号
  deal_ad();
  if(left_mark==1||right_mark==1)   //判断是否有弯道
  {
    curve_state=1;                  //检测到弯道
    straight_state=0;               //检测的不是直道
    check_state=1;                  //检测到需要的信息
  }
  if(left_mark==0&&right_mark==0)   //判断是否有直道
  {
    curve_state=0;                  //检测到不是弯道
    straight_state=1;               //检测到是直道
    check_state=1;                  //检测到需要的信息
  }
  if(check_state)                   //是否检测到有用的信息
  {
      if(curve_state==1)            //检测到弯道弯道计数增加
         curve_count++;
      else                          //不是检测到弯道重新计数
         curve_count=0;
      if(straight_state==1)         //检测到直道直道计数增加 
         straight_count++;
      else                          //不是检测到直道重新计数
         straight_count=0;
  }
  if(curve_count==curve_number)     //判断确认是否为弯道
  {
    curve_mark=1;                   //确认是弯道的标志
    straight_mark=0;                //重新计数同时消除直道标志
    straight_count=0;
    curve_count=0;
  }
  if(straight_count==straight_number) //判断确认是否为直道
  {
    straight_mark=1;                  //确定是直道的标志
    straight_count=0;                 //重新计数同时消除弯道标志
    curve_mark=0;
    curve_count=0;
  }
  if(curve_mark==1)                   //判断是否为弯道
    v_ref=curve_speed;                //设定速度为弯道速度
  if(straight_mark==1)                //判断是否为直道
    v_ref=straight_speed;             //设定速度为直道速度
  try_ad1=v_ref;//读当前速度
  try_ad2=v_ref;//读当前速度 
}
void sci_init()//串口sci初始化
{
  uchar clear;
  SCI0BDH=0X00;
  SCI0BDL=0X0D;//设置波特率为38400
  SCI0CR1=0X13;//设置9位数据开启奇偶校验采用偶校验
  SCI0CR2=0X0C;//始能接收发送
  clear=SCI0SR1;//清楚sci状态寄存器
}
void sci_trans(uchar ch)//串口发送程序
{
  SCI0DRL=ch;
  while(SCI0SR1_TDRE!=1)
    ;
  SCI0SR1_TDRE=0;
}
void TimerOverflow(void) //使用定时器延时程序 
{
/* This function waits for th timer overflow.
Then it changes the LEDs bargraph display */
  while (TCNT != 0x0000);
  while (TCNT == 0x0000);
  while(TCNT!=0X0000);
  while(TCNT=0X0000);
}
void main(void) {
  uchar a=0xaa;
  uchar b=0xbb;
  uchar c=0xcc;
  sci_init();
  ad_init();
  DDRB=0XFF;
  PORTB=0XAA;
  TSCR1 = 0x80; /* enable timer TCNT */
  TSCR2 = 0x07; /* TCNT prescaler setup */
    /* put your own code here */
  EnableInterrupts;

  for(;;) 
  {
    //delay();
    //get_ad();
    accelerate();
    TimerOverflow();
    sci_trans(a);
    sci_trans(try_ad1);
    sci_trans(b);
    sci_trans(try_ad2);
    sci_trans(c);
    continue;
    
  } /* wait forever */
  /* please make sure that you never leave this function */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -