【年中粉丝节】+超声波距离传感器 今天分享下板子上比较大的传感器,就是超声波距离传感器。使用超声波距离传感器就比较简单了。 首先看下超声波测距传感器的原理,一端发射声波,当声波被物体阻挡就会反射回来。被接收端收到,只要我们算好这中间的时间差,加上声音传播速度就能算出距离,有如下公式: 原理图是这样的比较负责了,用了一个555定时器产生38Khz的方波,接收端其实是使用了一个CX20106A的红外解码芯片,其实这样是频率对上了,之后是为了程序方便,初始化一个定时器中断,每10US中断一次,然后把接收端也放一个中断,这样,开始发射时计数清空,然后定时器中断计数,这样来算时间,之后通过IO中断,来判断接收到了。在根据上面公式就能算出距离了。 - void Ultrasonic_Port()
- {
-
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
- //改变指定管脚的映射 GPIO_Remap_SWJ_JTAGDisable JTAG-DP 失能 + SW-DP使能
- GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
-
- //PB6-SCL PC2-ADDR
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //PA15
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //复用推挽输出
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOB,&GPIO_InitStructure);
- }
-
-
- void Ultrasonic_TIM(uint16_t arr,uint16_t psc)
- {
-
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
-
- //定时器TIM3初始化
- TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
- TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
- //TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
-
- //中断优先级NVIC设置
- NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 8; //从优先级3级
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
- NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
-
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
- TIM_Cmd(TIM3, DISABLE); //使能TIMx
- }
-
- void Ultrasonic_EXTI()
- {
- EXTI_InitTypeDef EXTI_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟
-
- //GPIOE.2 中断线以及中断初始化配置 下降沿触发
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource8);
-
- EXTI_InitStructure.EXTI_Line=EXTI_Line8; //KEY2
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
- EXTI_InitStructure.EXTI_LineCmd = ENABLE;
- EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
-
- NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键KEY2所在的外部中断通道
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级2,
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7; //子优先级2
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
- NVIC_Init(&NVIC_InitStructure);
-
- }
-
- void Ultrasonic_Init()
- {
- Ultrasonic_Port();
- Ultrasonic_TIM(9,71);//10us
- Ultrasonic_EXTI();
- }
-
-
- //超声波测距
- void Ultrasonic_Ranging()
- {
- INC = 1; //关发射
- delay_us(3);
- INC = 0;
-
- TIM_Cmd(TIM3,ENABLE);
- //EXTI_ClearITPendingBit(EXTI_Line4);
- TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
-
- Ultrasonic_Num = 0; // 定时器清零
-
- delay_ms(30); //等待一段时间,等待发送超声波控制信号
- INC = 1;
- delay_ms(5);
- }
-
- //定时器3中断服务程序
- void TIM3_IRQHandler(void) //TIM3中断
- {
- if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) //检查TIM3更新中断发生与否
- {
- Ultrasonic_Num++;
- }
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx更新中断标志
- }
-
- //外部中断2服务程序
- void EXTI9_5_IRQHandler(void)
- {
- if(EXTI_GetITStatus(EXTI_Line8) == SET)
- {
- if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_8) == RESET)
- {
- TIM_Cmd(TIM3,DISABLE);
- Ultrasonic_Value = Ultrasonic_Num;
- Ultrasonic_Value =(float)Ultrasonic_Value*1.73; // 计算距离定时10us,S=Vt/2(减2是误差补尝)
- dis = (uint16_t)Ultrasonic_Value;
- }
- EXTI_ClearITPendingBit(EXTI_Line8);
- }
- }
复制代码
实际测算还是会有点误差的。 |