XS128超聲波程序

程序有2個。。一個是自己搭的,一個是買的模塊。自己搭的測距能到1.6M,模塊能到4M。

 

模塊程序

 

void PLL_Init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1)
{                   //PLLCLK=2*16M*(2+1)/(0+1)= 96M
   SYNR  = 0xC2;        //總線頻率爲PLL頻率的一半48M
   REFDV = 0xC0;
   ECLKCTL &= ~0x80;
   while(!(CRGFLG&0x08)); //自循環語句,等待時鐘頻率穩定後允許鎖相環時鐘作爲系統時鐘
   CLKSEL=0x80;           //選擇鎖相環頻率爲系統時鐘頻率
}


//-------------------------真#定時器初始化---------------------------------------------
void PIT_Init(void)
{  
    //----------------------定時10uS,控制採樣頻率---------------------------------------  
    PITMUX_PMUX0=0;         //使用微計數器0
    PITMTLD0 = 1;            //微時鐘0設置爲99
    PITLD0 = 239;             //time-out period = (PITMTLD + 1) * (PITLD + 1) / fBUS.
                            //溢出時間爲  2 * 240 / 48000000 = 10us                              
}

 

 


uint Time = 0;

char Error_Flag = 0;

void delay(uint t)
{
    while(t--);
}

float Ranging(void)
{
    float Length = 0;     //距離,單位釐米(CM?
    int Count = 0;
   
    PORTA_PA0  = 1;  
    delay(15);
    PORTA_PA0  = 0;
   
    while(1)
    {
       if(PORTA_PA1 == 1) break;   //等待
       if(PORTA_PA1 == 0) Count++;
       if(Count >= 400){Error_Flag = 1;return 0;}
    }
   
      
    Time = 0;
   
    PITCFLMT_PITE=1;        //定時器使能 
    PITCE_PCE0=1;           //定時器0使能
    PITINTE_PINTE0=1;       //定時器中斷0使能
    EnableInterrupts        //開中斷                             
   
    while(1)
    {
      if(PORTA_PA1 == 0) break;   //等待
      if(Time >= 5000) {Error_Flag = 1;return 0;}   //超時
    }   
    DisableInterrupts     //關中斷 
   
    Length = (float)((17*Time)/100.0); //340m/s * T
   
    delay(0xffff);            //延時避免干擾
    delay(0xffff);            //延時避免幹
    delay(0xffff);            //延時避免干擾
    delay(0xffff);            //延時避免干擾
   
    return Length;
}

 

void main(void)
{
  float  Length_T = 0;
  float  Length = 0;
  char   Count = 3;
 
  PLL_Init(); 
  lcd_init();
  PIT_Init();

  //Send_Data(test,2,2);

  DisableInterrupts     //關中斷
 
  DDRB_DDRB7 = 1;     //test
 
  DDRA_DDRA0 = 1;     //超聲波控制A0
 
  DDRA_DDRA1 = 0;     //超聲波接受A1

  for(;;)
  { 
    
     while(Count--)
     { 
       
        Length = (float)(Ranging()/3.0);        
        if(Error_Flag == 0) Length_T += Length;
        if(Error_Flag == 1) Count += 1;
       
        Error_Flag = 0;
     }
    
     Count = 3;
    
     ClearScreen();
    
     Show_Flaot(Length_T,2,2);
    
     Length_T = 0; 
    
           
  }
}

 


#pragma CODE_SEG NON_BANKED
void interrupt 66 Timer1_IRQ(void) //5MS
{
     PITTF_PTF0=1;         //清中斷標誌位
     Time++;        //10us
}

 

 

 

自己搭的程序


uint Time = 0;

char Error_Flag = 0;

void delay(uint t)
{
    while(t--);
}

float Ranging(void)
{
    float Length = 0;     //距離,單位釐米(CM)
   
    Time = 0; 
   
    PITCFLMT_PITE=1;        //定時器使能 
    PITCE_PCE0=1;           //定時器0使能
    PITINTE_PINTE0=1;       //定時器中斷0使能
    EnableInterrupts        //開中斷
   
    PWME_PWME0  = 1;           //使能PWM輸出
                               //發送40KHz調製信號
    delay(80);
    PWME_PWME0  = 0;                            
   
    delay(20);            //延時避免干擾
   
    while(1)
    {
      if(PORTA_PA0 == 0) break;   //等待
      if(Time >= 3000) {Error_Flag = 1;return 0;}   //超時
    }   
    DisableInterrupts     //關中斷 
   
    Length = (0.17 * Time);//340m/s * T
   
    delay(0xffff);            //延時避免干擾
     delay(0xffff);            //延時避免干擾
      delay(0xffff);            //延時避免干擾
   
    return Length;
}

 

void PLL_Init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1)
{                   //PLLCLK=2*16M*(2+1)/(0+1)= 96M
   SYNR  = 0xC2;        //總線頻率爲PLL頻率的一半48M
   REFDV = 0xC0;
   ECLKCTL &= ~0x80;
   while(!(CRGFLG&0x08)); //自循環語句,等待時鐘頻率穩定後允許鎖相環時鐘作爲系統時鐘
   CLKSEL=0x80;           //選擇鎖相環頻率爲系統時鐘頻率
}

void PWM_Init(void)
{
   PWMCTL = 0xA0;        //PWM 23 級聯(前輪舵機) PWM 67 級聯(搖頭舵機)
                         //PWM 4 PWM5 做電機控制(正反轉)
   PWMCAE = 0x00;        //PWM 左對齊輸出
   PWMPOL = 0x01;        //PWM 極性爲1
   PWMCLK = 0x01;        //PWM 0 選擇時鐘源 SA
   PWMPRCLK = 0x32;      //時鐘源 A = 48M/4  = 12M
                         //時鐘源 B = 48M/8  =  6M 
   PWMSCLA  = 0x01;      //時鐘源SA = A/(2*1) = 6M
   PWMSCLB  = 0x01;      //時鐘源SB = B/(2*1) = 3M
   //-----------------超聲波驅動--------------
   PWMPER0  = 150;          //頻率40KHz
   PWMDTY0  = 75;           //50%
  
   PWME_PWME0  = 0;           //禁止PWM輸出
}


//-------------------------真#定時器初始化---------------------------------------------
void PIT_Init(void)
{  
    //----------------------定時10uS,控制採樣頻率---------------------------------------  
    PITMUX_PMUX0=0;         //使用微計數器0
    PITMTLD0 = 1;            //微時鐘0設置爲99
    PITLD0 = 239;             //time-out period = (PITMTLD + 1) * (PITLD + 1) / fBUS.
                            //溢出時間爲  2 * 240 / 48000000 = 10us                              
}

 

 

void main(void)
{
  float  Length_T = 0;
  float  Length = 0;
  char Count = 3;
 
  PLL_Init(); 
  PWM_Init();
  lcd_init();
  PIT_Init();

  //Send_Data(test,2,2);

  DisableInterrupts     //關中斷
 
  DDRB_DDRB7 = 1;     //test
 
  DDRA_DDRA1 = 0;     //超聲波接受
 
  PWME_PWME0 = 1;   

  for(;;)
  { 
    
     while(Count--)
     { 
       
        Length = (Ranging()/10.0);        
        if(Error_Flag == 0) Length_T += Length;
        if(Error_Flag == 1) Count += 1;
       
        Error_Flag = 0;
     }
    
     Count = 10;
    
     ClearScreen();
    
     Send_Data((int)Length_T,2,2);
    
     lcd_putsf("CM",25,2);
    
     Length_T = 0; 
    
           
  }
}

 


#pragma CODE_SEG NON_BANKED
void interrupt 66 Timer1_IRQ(void) //5MS
{
     DisableInterrupts     //關中斷    
     PITTF_PTF0=1;         //清中斷標誌位
    
     Time++;        //10us
    
     EnableInterrupts        //開中斷 
}

 

 

拿去吧,電路圖.....

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章