分享一个输入捕获做的超声波测距

2019-07-20 13:33发布

还是比较准的
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
13条回答
Jim0706
2019-07-21 19:23
本帖最后由 Jim0706 于 2017-5-29 01:19 编辑
stthb 发表于 2017-5-25 20:54
哪位大佬给分享一下超声波测距的代码

[mw_shl_code=c,true]int main(void)
{
        u8 key;
        u32 distance,temp;
        NVIC_SetPriorityGrouping(7-2);//分组写在主函数里,只写一次
        led_init();
        key_init();
        uart1_init(115200);
  HC_SR04_Init();
        
        while(1)
        {
                Trig = 0;
                delay_ms(20);
                Trig = 1;
                delay_us(20);
                Trig = 0;
               
                if(TIM2CH3_CAPTURE_STA & 0x80)
                {
                        temp = TIM2CH3_CAPTURE_STA & 0x3f;
                        temp *= 0XFFFFFFFF;                                          //溢出时间总和
                        temp += TIM2CH3_CAPTURE_VAL;
                        TIM2CH3_CAPTURE_STA = 0;
                }
                distance = (temp*340/200)/100;
                printf("distance %d cm ",distance);
                delay_ms(500);
        }
}[/mw_shl_code]
[mw_shl_code=c,true]#ifndef _HC_SR04_H
#define _HC_SR04_H

//PA1 Trig  PA2 Echo
#include "stm32f4xx.h"
#include "io_bit.h"
#define Echo PAin(2)
#define Trig PAout(1)


extern u8  TIM2CH3_CAPTURE_STA;        //输入捕获状态                                                   
extern u32        TIM2CH3_CAPTURE_VAL;        //输入捕获值
void HC_SR04_Init(void);
void TIM2_Init(void);
        



#endif
[/mw_shl_code]
[mw_shl_code=c,true]#include "stm32f4xx.h"
#include "HC_SR04.h"

void HC_SR04_Init(void)
{
        //PA1 Trig  PA2 Echo 复用功能
        RCC->AHB1ENR        |=            0X01<<0;
        GPIOA->MODER         &=          ~(0x03<<2|0x03<<4);
        GPIOA->MODER         |=                  (0x01<<2|0x02<<4);
        GPIOA->OTYPER         &=         ~(0x03<<1);
        GPIOA->OSPEEDR  &=         ~(0x03<<2);
        GPIOA->OSPEEDR  |=          (0x02<<2);
        GPIOA->PUPDR    &=         ~(0x03<<2);
        GPIOA->AFR[0]   &= 0xfffff0ff;
        GPIOA->AFR[0]   |= 0x000001ff;
        TIM2_Init();
}
//用定时器2来捕获
void TIM2_Init(void)
{
        //PA2 通道3
        RCC->APB1ENR |= 0X01<<0;//开启定时器2
        TIM2->ARR = 9999;
        TIM2->PSC = 83;
        
        TIM2->CCMR2 |= 0X01;//CC3配置为输入,IC3映射到TI3上
        TIM2->CCMR2 |= 0X00<<2;//无预分频
        TIM2->CCMR2 |= 0X03<<4;//配置输入滤波器 8个定时器时钟周期滤波
        
        TIM2->CCER  |= 0X01<<8;  //CC1E=1         允许捕获计数器的值到捕获寄存器中
        TIM2->CCER  |= 0X00<<9;  //CC1P=0        上升沿捕获
        TIM2->DIER  |= 0X01<<3;  //允许CC3IE捕获中断                                
        TIM2->DIER  |= 0X01<<0;         //允许更新中断        
        
        TIM2->CR1   |= 0X01<<0;  //使能
        
        NVIC_SetPriority(TIM2_IRQn,NVIC_EncodePriority(7-2,1,2));
        NVIC_EnableIRQ(TIM2_IRQn);
}

//定时器2输入捕获中断
//捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到低电平;1,已经捕获到低电平了.
//[5:0]:捕获低电平后溢出的次数(对于32位定时器来说,1us计数器加1,溢出时间:4294秒)
u8  TIM2CH3_CAPTURE_STA;        //输入捕获状态                                                   
u32        TIM2CH3_CAPTURE_VAL;        //输入捕获值
void TIM2_IRQHandler(void)
{
        if((TIM2CH3_CAPTURE_STA&0x80) == 0)//还未成功捕获        
        {
                if((TIM2->SR & 0x01))
                {
                        if((TIM2CH3_CAPTURE_STA&0x40))//已经捕获到高电平
                        {
                                if((TIM2CH3_CAPTURE_STA&0x3f) == 0x3f)//是否溢出
                                {
                                        TIM2CH3_CAPTURE_STA = 0x80;//标记成功捕获了一次
                                        TIM2CH3_CAPTURE_VAL = 0xFFFF;
                                }
                                else
                                        TIM2CH3_CAPTURE_STA++;
                        }               
                }
                if(TIM2->SR & (0X01<<3))//捕获3发生捕获事件
                {
                        if((TIM2CH3_CAPTURE_STA&0x40))//捕获到升沿
                        {
                                TIM2CH3_CAPTURE_STA |= 0x80;//标记成功捕获了一次
                                TIM2CH3_CAPTURE_VAL = TIM2->CCR3 ;//& 0X00FF;
                                TIM2->CCER &= ~(0X03<<9);//改为上升沿捕获
                        }
                        
                        else//第一次捕获上升沿
                        {
                                TIM2CH3_CAPTURE_VAL = 0;
                                TIM2CH3_CAPTURE_STA = 0;
                                TIM2->CNT = 0;
                                TIM2CH3_CAPTURE_STA |= 0x40;//标记捕获到了上升沿
                                TIM2->CCER |= 0X01<<9;//改为下降沿捕获
                        }
                }
        }
        TIM2->SR &= ~(0X01|0X01<<3);//清除中断标志位
}



[/mw_shl_code]这是我根据这个贴来弄的F4mini板,可以运行的代码。你参考下

一周热门 更多>