程序有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 //开中断
}
拿去吧,电路图.....