写在前面注意的几点:
1、HC-SR04模块必须使用5V供电,不能是3.3V
2、若单是测距,无需使用中断
3、Echo和Trig两个引脚可以任意接可用的GPIO,和定时器无关
说一下超声波的工作原理

单片机给Trig引脚一个最少10us的高电平,然后拉低引脚,便启动了模块,
然后超声波就被发了出去,超声波遇到障碍物后返回被模块接收,Echo引脚会输出一段高电平,高电平的时间与距离成比例;
那么我们所需要做的就是出发Trig引脚,然后测出Echo持续高电平的时间
以下是GPIO的设置:
void Ultrasonic_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//Trig
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;//Echo
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
以下是定时器2设置
void Timer2_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitStructure.TIM_Prescaler = 71;
TIM_TimeBaseInitStructure.TIM_Period = 49999;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
}
以下是距离转换函数
u32 Distance_Calculate(u32 count)
{
u32 Distance = 0;
Distance = (u32)(((float)count / 58) * 100);
return Distance;
}
main函数
void main(void)
{
u32 count = 0;
u32 Distance = 0;
USART_Config();
NVIC_Configuration();
LED_Init();
Ultrasonic_Config();
Timer2_Config();
GPIO_ResetBits(GPIOB, GPIO_Pin_0);//点亮LED
printf("Test start!");
while(1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_8);//预先拉低Trig引脚
GPIO_SetBits(GPIOB, GPIO_Pin_8);
delay_nus(10);
GPIO_ResetBits(GPIOB, GPIO_Pin_8);//发出10us的脉冲
TIM2->CNT = 0;
while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 0);
TIM_Cmd(TIM2, ENABLE);
while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_9) == 1);
TIM_Cmd(TIM2, DISABLE);
count = TIM2->CNT;
Distance = Distance_Calculate(count);
printf("Distance = %d.", Distance / 100);
printf("%d cm\r\n", Distance % 100);
delay_nms(500);
}
}
1万+



被折叠的 条评论
为什么被折叠?



