完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
原理:
声波遇到障碍物会反射,而声波的速度已知,所以只需要知道发射到接收的时间差,就能轻松计算出测量距离,再结合发射器和接收器的距离,就能算出障碍物的实际距离。 超声波原理图 以HC-SR04硬件为例,端口为VCC、Trig、Echo、GND。
部分程序 Trig程序 void Trig_Init(void) { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟 GPIO_Initure. Pin=GPIO_PIN_0;//PA8 GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出 GPIO_Initure.Pull=GPIO_PULLDOWN; //下拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET); HAL_GPIO_Init(GPIOA,&GPIO_Initure); } void CHL_capture(void) { TRIG1=1; delay_us(20); TRIG1=0; } Echo程序 #include "us015timer.h" #include "led.h" // PA1---Echo TIM2 CH2 //TIM2 捕获初始化 TIM_HandleTypeDef TIMx_Handler; //定时器3句柄 //定时器2通道1输入捕获配置 //arr:自动重装值(TIM2是16位的!!) //psc:时钟预分频数 void TIM2_CHx_Cap_Init(u32 arr,u16 psc) { TIM_IC_InitTypeDef TIMx_CHyConfig; TIMx_Handler.Instance=TIM2; //通用定时器2 TIMx_Handler.Init.Prescaler=psc; //分频系数 TIMx_Handler.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数器 TIMx_Handler.Init.Period=arr; //自动装载值 TIMx_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频因子 TIMx_Handler.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;//使能自动重载 HAL_TIM_IC_Init(&TIMx_Handler); //初始化输入捕获时基参数 TIMx_CHyConfig.ICPolarity=TIM_ICPOLARITY_RISING; //上升沿捕获 TIMx_CHyConfig.ICSelection=TIM_ICSELECTION_DIRECTTI;//映射到TI1上 TIMx_CHyConfig.ICPrescaler=TIM_ICPSC_DIV1; //配置输入分频,不分频 TIMx_CHyConfig.ICFilter=0; //配置输入滤波器,不滤波 HAL_TIM_IC_ConfigChannel(&TIMx_Handler,&TIMx_CHyConfig,TIM_CHANNEL_2);//配置TIM3通道3 HAL_TIM_IC_Start_IT(&TIMx_Handler,TIM_CHANNEL_2); //开启TIM2的捕获通道2,并且开启捕获中断 __HAL_TIM_ENABLE_IT(&TIMx_Handler,TIM_IT_UPDATE); //使能更新中断 HAL_NVIC_SetPriority(TIM2_IRQn,2,0); //设置中断优先级,抢占优先级2,子优先级0 HAL_NVIC_EnableIRQ(TIM2_IRQn); //开启ITM2中断通道 } //定时器2底层驱动,时钟使能,引脚配置 //此函数会被HAL_TIM_IC_Init()调用 //htim:定时器2句柄 void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim) { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_TIM2_CLK_ENABLE(); //使能TIM2时钟 __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟 GPIO_Initure.Pin=GPIO_PIN_1; //PA1 GPIO_Initure.Mode=GPIO_MODE_AF_INPUT; //复用推挽输入 GPIO_Initure.Pull=GPIO_PULLDOWN; //下拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 HAL_GPIO_Init(GPIOA,&GPIO_Initure); HAL_NVIC_SetPriority(TIM2_IRQn,2,0); //设置中断优先级,抢占优先级2,子优先级0 HAL_NVIC_EnableIRQ(TIM2_IRQn); //开启ITM2中断通道 } //捕获状态 //[7]:0,没有成功的捕获;1,成功捕获到一次. //[6]:0,还没捕获到低电平;1,已经捕获到低电平了. //[5:0]:捕获低电平后溢出的次数 u8 TIM2CH2_CAPTURE_STA=0; //输入捕获状态 u16 TIM2CH2_CAPTURE_VAL; //输入捕获值(TIM2是16位) //定时器2中断服务函数 void TIM2_IRQHandler(void) { HAL_TIM_IRQHandler(&TIMx_Handler); //定时器共用处理函数 } //定时器更新中断(计数溢出)中断处理回调函数, 该函数在HAL_TIM_IRQHandler中会被调用,实现多个计数器满装载的计数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//更新中断(溢出)发生时执行 { if((TIM2CH2_CAPTURE_STA&0X80)==0) //还未成功捕获上升沿 { if(TIM2CH2_CAPTURE_STA&0X40) //已经捕获到高电平了 { if((TIM2CH2_CAPTURE_STA&0X3F)==0X3F) //高电平太长了 { TIM2CH2_CAPTURE_STA|=0X80; //标记成功捕获了一次 TIM2CH2_CAPTURE_VAL=0XFFFF; }else TIM2CH2_CAPTURE_STA++; } } } //定时器输入捕获中断处理回调函数,该函数在HAL_TIM_IRQHandler中会被调用 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//捕获中断发生时执行 { if((TIM2CH2_CAPTURE_STA&0X80)==0) //还未成功捕获 { if(TIM2CH2_CAPTURE_STA&0X40) //捕获到一个下降沿 { TIM2CH2_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽 TIM2CH2_CAPTURE_VAL=HAL_TIM_ReadCapturedValue(&TIMx_Handler,TIM_CHANNEL_2);//获取当前的捕获值. TIM_RESET_CAPTUREPOLARITY(&TIMx_Handler,TIM_CHANNEL_2); //一定要先清除原来的设置!! TIM_SET_CAPTUREPOLARITY(&TIMx_Handler,TIM_CHANNEL_2,TIM_ICPOLARITY_RISING);//配置TIM2通道2上升沿捕获 }else //还未开始,第一次捕获上升沿 { TIM2CH2_CAPTURE_STA=0; //清空 TIM2CH2_CAPTURE_VAL=0; TIM2CH2_CAPTURE_STA|=0X40; //标记捕获到了上升沿 __HAL_TIM_DISABLE(&TIMx_Handler); //关闭定时器2 __HAL_TIM_SET_COUNTER(&TIMx_Handler,0); TIM_RESET_CAPTUREPOLARITY(&TIMx_Handler,TIM_CHANNEL_2); //一定要先清除原来的设置!! TIM_SET_CAPTUREPOLARITY(&TIMx_Handler,TIM_CHANNEL_2,TIM_ICPOLARITY_FALLING);//定时器2通道2设置为下降沿捕获 __HAL_TIM_ENABLE(&TIMx_Handler); //使能定时器2 } } } 主函数 int main() { HAL_Init(); //初始化HAL库 Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟,72M delay_init(72); //初始化延时函数 uart_init(9600); //初始化串口 LED_Init(); //初始化LED Trig_Init(); TIM2_CHx_Cap_Init(0xffff,7200-1); float len=0; u32 time=0; while(1) { u8 count=0; delay_ms(10); CHL_capture(); //PAout(0) if(TIM2CH2_CAPTURE_STA&0X80) //成功捕获到了一次高电平 { time=TIM2CH2_CAPTURE_STA&0X3F; time*=65536; //溢出时间总和 time+=TIM2CH2_CAPTURE_VAL; //得到总的高电平时间 len=time*1.7; if(len<20) LED0=0; else LED0=1; TIM2CH2_CAPTURE_STA=0; //开启下一次捕获 } printf("LENGHT:%f CMrn",len); //打印平均距离 } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1618 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1545 浏览 1 评论
979 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1597 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
645浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
516浏览 3评论
532浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
505浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 15:25 , Processed in 0.700986 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号