完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
STM32 的定时器,除了 TIM6 和 TIM7,其他定时器都有输入捕获功能。 STM32定时器检测是否有信号,若有信号(上升沿),则定时器开始计时,直至检测到下降沿计时结束。这期间的脉宽长度*定时器的检测频率(定时器初始化时配置好的)即为实际的时长。 实际的时长*声速=距离 TIM_TimeBaseStructure.TIM_Period=65536-1; 定时器计数达到65535后溢出 TIM_TimeBaseStructure.TIM_Prescaler=7200-1; 预分频值,实际检测频率为72000 000/7200=10 000Hz,周期为100us。 每100us+1。 定时器触发一次的时间为:(7200/72000 000)*65536 定时器中断函数: void TIM2_IRQHandler(void) { if((TIM2CH1_CAPTURE_STA&0X80)==0)//未捕获 1000 0000 { if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET) { if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到高电平 0100 0000 { if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//溢出处理 0011 1111 { TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获一次 1000 0000 TIM2CH1_CAPTURE_VAL=0XFFFF; }else TIM2CH1_CAPTURE_STA++; } } if(TIM_GetITStatus(TIM2,TIM_IT_CC1) !=RESET) //捕获到上升沿中断 { if(TIM2CH1_CAPTURE_STA & 0x40) //捕获到一个下降沿 0100 0000 { TIM2CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次上升沿 1000 0000 TIM2CH1_CAPTURE_VAL = TIM_GetCounter(TIM2); TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=0 设置上升沿捕获 } else { //还没有捕获到新的上升沿 TIM2CH1_CAPTURE_STA=0; //清空 TIM2CH1_CAPTURE_VAL=0; TIM_SetCounter(TIM2,0); TIM2CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿 0100 0000 TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //CC1P=1 设置为下降沿捕获 } } } TIM_ClearITPendingBit(TIM2,TIM_IT_CC1|TIM_IT_Update); /*清除中断标志位*/ } 捕获基本思路: 首先设置两个变量Capture_State和Capture_Value。 其中 Capture_State,是用来记录捕获状态,该变量类似一个寄存器(其实就是个变量,只是我们把它当成一个寄存器那样来使用)。 另外一个变量 Capture_Value,则用来记录捕获到下降沿的时候,TIM2_CNT的值。现在我们来介绍一下,捕获高电平脉宽的思路:首先,设置 TIM2_CH1 捕获上升沿(这在TIM2的初始化函数执行的时候就设置好了),然后等待上升沿中捕获断到来,当捕获到上升沿中断,此时如果 Capture_State的第 6 位为 0,则表示还没有捕获到新的上升沿,就先把 Capture_State、Capture_Value和 TIM2->CNT 等清零,然后再设置 Capture_State的第 6 位为 1,标记捕获到高电平,最后设置为下降沿捕获,等待下降沿到来。如果等待下降沿到来期间,定时器发生了溢出,就在Capture_State里面对溢出次数进行计数,当最大溢出次数来到的时候,就强制标记 捕获完成 (虽然此时还没有捕获到下降沿 )。 当下降沿到来的时候,先设置Capture_State的第 7 位为 1,标记成功捕获一次高电平,然后读取此时的定时器的捕获值到 Capture_Value里面,最后设置为上升沿捕获,回到初始状态。 这样,我们就完成一次高电平捕获了,只要 Capture_State的第 7 位一直为 1,那么就不会进行第二次捕获,我们在main函数处理完捕获数据后,将Capture_State置零,就可以开启第二次捕获。 主函数: 主要的宗旨就是: TIM2 的计数频率(根据TIM_Prescaler计算得来 每一次计数的时长)*高电平脉宽(计数个数)= 准确高电平持续时间。 while(1) { if(TIM2CH1_CAPTURE_STA&0X80)//成功捕获一次上升沿 { temp=TIM2CH1_CAPTURE_STA&0X3F; temp*=65536;/溢出时间总和 //对应和TIM_Period一致 TIM是16位的 最大即为65536 temp+=TIM2CH1_CAPTURE_VAL;//总计数总和 if(temp>1000) //省去一些干扰信号 { printf("电平持续时间:%d us ",temp*100);//us printf("%d ms ",temp/10);//ms printf("%d s ",temp/10000);//s printf("rn距离: 1500 m/s * %d ms= %dmrn",temp/10,temp*15/100);//s printf("rn");//空行 } TIM2CH1_CAPTURE_STA=0;/开启下一次捕获 } } (错误思路:通过TIM_Period和TIM_Prescaler把TIM时间算出来,乘以统计的数据temp)和代码中temp*=65536重复。 另外注意TIM2_IRQn对应的PA0引脚,工作模式为下拉输入。 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; |
|
|
|
只有小组成员才能发言,加入小组>>
调试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 13:11 , Processed in 0.750697 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号