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

📄 msp430.txt

📁 基于TI低功耗单片机MSP430449系列的智能车程序
💻 TXT
字号:
#include "msp430x44x.h"
#define uchar unsigned char 
#define uint unsigned int

#define LCD_en 0x80
#define LCD_wr 0x40
#define LCD_rs 0x20

void  msec(uint msec_number);            //延时程序(单位ms)
void ceju(void);      
void dlms(void);                       //小延时子程序
void stop(void);

void T_L(void);                          //小车转向控制
void T_R(void);
void go(void);

void LCD_int(void);                    //LCD 初始化
void LCD_w_data(uchar data);
void LCD_w_com(uchar com);
void display(uchar b);

void  xs_shuzu(uchar *strand);        //显示xs_shuzu("字符串%")

uint count=0;
uchar i=0;
uchar csflag = 1;
float dis=0,dis_l,dis_r;

void  light(void);                    //光敏传感
uint result[4];
float L_V,M_V,R_V,C_V;
uchar flag_dir = 3;
uchar pan = 0;     

uchar count_timer=0;                  //两个基本计时变量
uchar timer = 0;

uchar r=0;                            
uchar count_iron = 0;                 //记录铁片数量和路程
uchar icount_dis = 0;
float iron_dis[5];

double dis_data;

 void main(void)
{
  
  WDTCTL = WDTPW + WDTHOLD;    // 停止看门狗 
  SCFQCTL=99;
  M_V = 2.5;                   //M_V置初值 方便最后停入车去
  
  P3DIR |= 0x0f;
  P3SEL |= 0x00;               //车轮转向控制口
  P3OUT = 0x0f;
  
  P4DIR |= 0x08; 
  P4SEL = 0x00;
  
  P1SEL |= 0x04;               //P1_3口为第二功能捕获
  P1DIR |= 0x10;
  P1OUT &= ~0x10;
  
  P2SEL |= 0x01;               //P2_0口第二功能捕获
  P2DIR |= 0xE0;
  
  P2IE |= 0x10;                //P2.4用于检测铁片口
  P2IES |= 0x10;               //下降沿触发
  P2IFG &= ~0x10;              //清除中断标志
  
  P1IE |= 0x08;                //P1.3用于霍尔开关检测
  P1IES |= 0x08;
  P1IFG &= ~0x08;              
  
  
  P5SEL |= 0x00;               //P5.0~P5.7 LCD数据口
  P5DIR |= 0xFF;               //LCD控制口初始化
  
  P6SEL = 0xA3;                //P6第二功能AD开启
  
  LCD_int();
  
  xs_shuzu("Ready!%");
  
  IE2 |= BTIE;                 //基本定时器启动
  FLL_CTL0 |= XCAP14PF;
  BTCTL = BTDIV+BTIP1+BTIP0;
  _EINT();
  

  while(pan==0)
  {
    pan = P4IN&(0x07);
  }
  
  
  /**第一任务 循迹行进**/
  
  while(count!=300)                  
  {
    pan = P4IN&(0x07);
    switch(pan)
    {
      case 0x02: go();
            break;
      case 0x01: T_R();
            break;
      case 0x04: T_L();
            break;
      case 0x00: {
                  count++;
                  go();
                  break;
                }
      default: go();
            break;           
    }
    dlms();
  }
  stop();
  //LCD_w_com(1);                    //清屏
  //xs_shuzu("Stop!%");
  count = 0;                       //count变量复位
  
  P1OUT |= 0x08;
  msec(1000);
  P1OUT ^= 0x08;
  msec(1000);
  P1OUT ^= ~0x08;
  msec(1000);
  P1OUT ^= ~0x08;
  msec(1000);
  P1OUT ^= ~0x08;
  msec(1000);
  P1OUT ^= ~0x08;                  //发出断续声光信号
  
  P1IE &= ~0x04;                   //关闭霍尔开关
  P2IE &= ~0x10;
  T_L();
  msec(300);
  go();
  msec(300);
  
  while(1)
  {
  csflag = 0;
  ceju();                     //左超声头测距
  dis_l = dis;  
    
  csflag = 1;
  ceju();                      //右超声头测距
  dis_r = dis;
 
  if((dis_l<35)||(dis_r<35))
  {
     if(dis_l<dis_r){T_R();flag_dir = 0;}
     else if(dis_l>dis_r){T_L();flag_dir = 1;}
     while((dis_l<15)||(dis_r<15)){
        csflag = 1;
        ceju();                      //右超声头测距
        dis_r = dis;    
        csflag = 0;
        ceju();                     //左超声头测距
       
        dis_l = dis; 
        
        if(flag_dir == 0)T_R();
        else if(flag_dir == 1)T_L();
        msec(90);
         }
     flag_dir = 3;
     
     go();
     msec(100);
    }
  else 
    {
       light();
       if((L_V<0.8)||(M_V<0.8)||(R_V<0.9)||(C_V<0.9))
        {
           if((L_V<M_V)&&(L_V<R_V)&&(L_V<C_V))T_L();
           else if((M_V<L_V)&&(M_V<R_V)&&(M_V<C_V))go();
           else if((R_V<M_V)&&(R_V<L_V)&&(R_V<C_V))T_R();
           else if((C_V<M_V)&&(C_V<R_V)&&(C_V<L_V)){T_R();msec(550);}
           //msec(250);
           //go();
           //msec(100);
        }
       else go();  
    }
  if(M_V<0.135)break;
   }
  stop();
  LCD_w_com(1);                       //清屏
  xs_shuzu("Destiny!%");
  
  LCD_w_com(0xC1);                    //显示全程时间
  LCD_w_data(timer/10+0x30);
  LCD_w_data(timer%10+0x30);
  IE2 &= ~BTIE;                       //关闭基本定时器中断
  while(1)                            //交替显示
   {
    LCD_w_com(0x80);
    xs_shuzu("IRON: %");                    //实时刷新铁片数量
    for(count_iron = 0; count_iron<3; count_iron++)
    {
      LCD_w_com(0xC8);
      dis_data = iron_dis[count_iron+1];
      display(2);
      xs_shuzu("cm%");
      msec(2000);
    }
   }  
}

void  msec(unsigned   int  msec_number)
{   uchar  msec_j ;
    msec_number *= 4;
    while ((msec_number--)!=0)
    {   msec_j=0;
        while(msec_j<123)
        {   msec_j++;
        }
    }
}

void T_L(void)
{
  count = 0;
  P3OUT = 0x0E;
}

void T_R(void)
{
  count = 0;
  P3OUT = 0x0B;
}

void go(void)
{
  //count = 0;
  P3OUT = 0x0A;
}

void ceju(void)
{
  i=0;
  while(i<4){
  
  TBCCTL0 = CCIE;
  
  TBCCR0 = 40;
  _BIS_SR(GIE);                       //开总中断允许
  TBCTL = TBSSEL1 + MC0; 
  
  
  if(i==3){
            TBCTL = TBSSEL1 + MC_0; 
            P4OUT |= 0x08;
            count=0;
            if(csflag==0)
            {
               
               CCTL1 &= ~CCIE;                   //关闭右头捕获
               CCTL1 &= ~CAP;
               CCTL2 = CAP+CM0+CCIE+SCS;        //左超声头测距
               TAR = 0;
               TACTL = TASSEL1+MC1;
            }
            else if(csflag==1)
            {
               CCTL2 &= ~CCIE;
               CCTL2 &= ~CAP;                     //关闭左头捕获
               CCTL1 = CAP+CM0+CCIE+SCS;
               TAR = 0;
               TACTL = TASSEL1+MC1;
            }
               //while(count<10)count++;            //延时消除假波
          }
  TBCTL = TBSSEL1 + MC0; 
  dis = 0;
  while(count<=20);                   //连续发送10个脉冲
  TBCCTL0 = 0x0000;                   //关闭Timer_B计数中断
  P4OUT |=0x08;                       //P1.0置高
  
  while((count<=2000)&&(i<5))count++;
  count=0;
  i++;}
  //dis = 0;
  msec(10);
  if(dis==0)dis=999;
}


void light(void)
{
  ADC12CTL0 = ADC12ON + MSC + SHT0_2;
  ADC12CTL1 = SHP + CONSEQ_1;
  ADC12MCTL0 = INCH_0;         //通道A0:左探光头
  ADC12MCTL1 = INCH_1;         //通道A1:中探光头
  ADC12MCTL5 = INCH_5;         //通道A2: 右探光头
  ADC12MCTL7 = INCH_7 + EOS;   //通道A2: 右探光头
  ADC12IE = 0x80;
  ADC12CTL0 |= ENC;            //使能转换
  _EINT();
  ADC12CTL0 |= ADC12SC;
  msec(10);
}

void dlms(void)
{
   unsigned int z;
   for(z=2200;z>0;z--){}
} 

void stop(void)
{
  P3OUT = 0x0F;
}

/***************LCD控制子程序********************/
void LCD_int(void)
{
  LCD_w_com(1);                    //清屏
  LCD_w_com(2);
  LCD_w_com(0x38);                 //显示模式
  LCD_w_com(0x08); 
  LCD_w_com(0x0E); 
  LCD_w_com(0x06);
  LCD_w_com(0x38);                 //显示开关
  LCD_w_com(0x80);                                 
}
 
  
void LCD_w_data(uchar data)
{ 
  uchar a;
  a = data;
  P2OUT |= LCD_en + LCD_rs + LCD_wr;
  P5OUT = a;
  P2OUT &= ~LCD_wr;
  msec(1);
  P2OUT &= ~LCD_en;
  msec(1);
  P2OUT |= LCD_en + LCD_rs + LCD_wr;
}

void LCD_w_com(uchar com)
{
  uchar b;
  b = com;
  P2OUT |= LCD_en + LCD_rs + LCD_wr;
  P2OUT &= ~LCD_rs;                    //切换为指令输入
  P5OUT = b;
  P2OUT &= ~LCD_wr;
  msec(1);
  P2OUT &= ~LCD_en;                    //下降沿输入数据
  msec(1);
  P2OUT |= LCD_en + LCD_rs + LCD_wr;
}

void  xs_shuzu(uchar *strand)
{   uchar xs_k=0;
    while(*(strand+xs_k)!='%')
    {   LCD_w_data(*(strand+xs_k));
        xs_k++;
    }
   msec(1);
}

void  display(uchar b)
{   uchar f_codef[5],f_codeb[4];
    uchar j;
    uint l;
    l=(uint)dis_data;
    dis_data=dis_data-l;
    j=5;
    while(j>0)
    {   f_codef[j-1]=l%10;
        l=l/10;
        j--;
    }
    l=(uint)dis_data*10000;
    j=4;
    while(j>0)
    {   f_codeb[j-1]=l%10;
        l=l/10;
        j--;
    }
    l=0;
    j=0;
    while(j<4)
    {   if(l==0)
        {   if(f_codef[j]!=0)
            {   LCD_w_data(f_codef[j]+0x30);
                l=1;
            }
        }
        else   LCD_w_data(f_codef[j]+0x30);
        j++;
    }
    LCD_w_data(f_codef[4]+0x30);
    xs_shuzu(".%");
    j=0;
    while(j<b)
    {   LCD_w_data(f_codeb[j]+0x30);
        j++;
    }
}


#pragma vector=TIMERB0_VECTOR
__interrupt  void Timer_B(void)
{
  P4OUT^=0x08;
  count=count+1;
}

#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A1(void)
{ 
  uchar flag=0;
  flag = TAIV;
  if(flag==4) count=CCR2;                        //count在此用于记录时间
  if(flag==2) count=CCR1;
  //count = CCR2;
  TACTL = TASSEL1+MC_0;                         //停止计数
  //CCTL1 = CAP+CM_0+CCIE+SCS; 
  // else CCTL2 = 0;
  dis=count;
  dis*=5.188147;
  dis*=0.0005;
  dis*=2;
  dis-=4;
  CCTL1 &= ~CCIE;                         //关闭中断允许 
  CCTL2 &= ~CCIE;
}

#pragma vector = ADC_VECTOR
__interrupt void ADC12ISR(void)
{
  result[0] = ADC12MEM0;
  L_V = (result[0]/2700.0)*2.5;
  result[1] = ADC12MEM1;
  M_V = (result[1]/2700.0)*2.5;
  result[2] = ADC12MEM5;  
  R_V = (result[2]/2700.0)*2.5;
  result[3] = ADC12MEM7;  
  C_V = (result[3]/2700.0)*2.5;
}

#pragma vector=PORT2_VECTOR      //P2.4检测铁片
__interrupt void PORT_2(void)
{
   P1IE &= ~0x04;                //暂时关闭P1.3口中断
   stop();
   P1OUT |= 0x10;                //发出声光信号
   LCD_w_com(0x80);
   count_iron ++;
   xs_shuzu("IRON: %");                    //实时刷新铁片数量
   LCD_w_data(count_iron + 0x30);
   
   msec(800);
   
   iron_dis[count_iron] = (icount_dis/2.0)*1.8*3.14; //计算铁片距起跑线的距离
   LCD_w_com(0xC8);
   LCD_w_com(0xC8);
   dis_data = iron_dis[count_iron];
   display(2);
   xs_shuzu("cm%");
   
   P1OUT ^= 0x10;                //发出声光信号
   msec(800);
   P1OUT ^= 0x10;                //发出声光信号
   msec(800);
   P1OUT ^= 0x10;                //发出声光信号
   msec(800);
   
   P2IFG &= ~0x10;
   P1IE |= 0x04;                 //恢复中断
   go();
}

#pragma vector=PORT1_VECTOR      //P1.3测速
__interrupt void PORT_1(void)   
{
    icount_dis ++;
    P1IFG &= ~0x08;
}

#pragma vector = BASICTIMER_VECTOR
__interrupt void basic_timer(void)
{
  
  if(count_timer == 9)
  {
    LCD_int();
    xs_shuzu("IRON: %");                    //实时刷新铁片数量
    LCD_w_data(count_iron + 0x30);
    LCD_w_com(0xC8);
    dis_data = iron_dis[count_iron];
    display(2);
    xs_shuzu("cm%");
    LCD_w_com(0xC1);
    timer += 1;
    if(timer>9)
    {
      LCD_w_data(timer/10+0x30);
      LCD_w_data(timer%10+0x30);
    }
    else LCD_w_data(timer+0x30);
    count_timer = 0;    
  }
   else count_timer++;
}
  

⌨️ 快捷键说明

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