代码如下:
//超声波工作
void SR04_Work()
{
double t1,t2;
double distance,m;
//1.给传感器一个脉冲-测距 E0-高-delay-低
SW_E0(1);//对ODR置位
My_Delay_US(10);//10us
SW_E0(0);//对ODR复位
//2.等E1-高电平 记录时间t1-发射信号时间
while(1)
{
if(Check_E1()==1)
{
t1=US_Tick;
break;
}
}
//3.等E1-低电平 记录时间t2-接收信号时间
while(1)
{
if(Check_E1()==0)
{
t2=US_Tick;
break;
}
}
//4.计算距离
distance=(t2-t1)/1000000.0f*340.0f/2.0f*100.0f;
printf("%.2lfcm\n",distance);
}
原理如下:
模块原理:
(1)采用 IO 触发测距,给至少 10us 的高电平信号;
(2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;
(3)有信号返回,通过 IO 输出一高电平,高电平持续的时间就是
(4)超声波从发射到返回的时间.测试距离=(高电平时间*声速(340M/S))/2;
工作原理:
以下为配置超声波相关的函数:
//PE0 OUT Trig
void GPIOE0_Init()
{
RCC->AHB1ENR |= 1<<4;
GPIOE->MODER &= ~(3<<0);
GPIOE->MODER |= (1<<0);
GPIOE->OTYPER &= ~(1<<0);
GPIOE->OSPEEDR |= (3<<0);
GPIOE->PUPDR &= ~(3<<0);
GPIOE->PUPDR |= (2<<0);
}
void SW_E0(int c)
{
if(c == 0)
GPIOE->BSRRH = 1<<0;//对ODR复位
else
GPIOE->BSRRL = 1<<0;//对ODR置位
}
//
//PE1 IN Echo
void GPIOE1_Init_IN()
{
RCC->AHB1ENR |= 1<<4;
GPIOE->MODER &= ~(3<<2);
GPIOE->PUPDR &= ~(3<<2);
GPIOE->PUPDR |= (2<<2);
}
int Check_E1()
{
int r = GPIOE->IDR & (1<<1);
if(r!=0)
return 1;
else
return 0;
}
//
//Timer4
u32 US_Tick; //1us计数
void Timer4_Init()
{
RCC->APB1ENR |= 1<<2;
TIM4->PSC=42-1; //预分频器
//Timer2的参考频率 84Mhz / 84 = 100Hz
TIM4->ARR=2-1; //设定计数器自动重装值
// 1秒产生一次中断
TIM4->DIER |= 1<<0; //允许更新中断
TIM4->CR1 |= 1<<0; //启动定时器
MY_NVIC_InitG2(0,1,TIM4_IRQn);//使能中断向量 配置优先级
}
//Timer2的中断回调函数
void TIM4_IRQHandler(void)
{
//了解是否进入了溢出中断
int r = TIM4->SR & 0x0001;
if(r!=0) //sr 第0位 为1
{
TIM4->SR &= ~(1<<0);//清中断
US_Tick++;
}
}