XS128超声波程序

来源:互联网 发布:金山毒霸如何备份软件 编辑:程序博客网 时间:2024/04/29 07:09

程序有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        //开中断 
}

 

 

拿去吧,电路图.....

 

原创粉丝点击