打印

【GD32试用】+水族箱自动补水之——超声波液位检测

[复制链接]
1289|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 北极星405 于 2016-4-19 20:55 编辑


定时器的捕获让我用的非常困惑,到现在没弄太明白…………主要功能很简单就是超声波测距,只是这个用于鱼缸补水的,是测量液面的,对测得距离要运算一下,如下图



主要代码:
printf重定向:

int fputc(int ch, FILE *f)
{
                /* Place your implementation of fputc here */
                USART_DataSend( USART1, (uint8_t) ch );

                /* Loop until transmit data register is empty */
                while (USART_GetBitState ( USART1 , USART_FLAG_TC ) == RESET);

                return ch;
}



中断配置和中断函数:
void NVIC_ConfigurationTIMER(void)
{
    NVIC_InitPara NVIC_InitStructure;

    NVIC_PRIGroup_Enable(NVIC_PRIGROUP_1);

    /* Enable the TIMER3 Interrupt */
    NVIC_InitStructure.NVIC_IRQ                = TIMER3_IRQn;
    NVIC_InitStructure.NVIC_IRQPreemptPriority = 0;
    NVIC_InitStructure.NVIC_IRQSubPriority     = 1;
    NVIC_InitStructure.NVIC_IRQEnable          = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

void TIM3_Configuration(void)
{
    /* TIMER3 configuration: Input Capture mode -------------------
    The external signal is connected to TIMER1 CH1 pin(PE9)
    The Rising edge is used as active edge
    The TIMER1 CHCC1 is used to compute the frequency value
    ------------------------------------------------------------ */

    TIMER_BaseInitPara TIM_TimeBaseStructure;

       
    /* TIMER1 clock enable */
    RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_TIMER3,ENABLE);                                                //ÎÊÌ⾹Ȼ³öÔÚÕâÀ
                                                                                                                                                                                                                                                                                                //APB2µÄÍâÉèµ÷ÓÃÁËAPB1µÄÅäÖú¯Êý£¡
                                                                                                                                                                                                                                                                                                //RCC_APB2PeriphClock_Enable
    /* TIMER3  configuration */
    TIMER_DeInit(TIMER3);
    TIM_TimeBaseStructure.TIMER_Prescaler     = 71;
    TIM_TimeBaseStructure.TIMER_CounterMode   = TIMER_COUNTER_UP;
    TIM_TimeBaseStructure.TIMER_Period        = 60000;
    TIM_TimeBaseStructure.TIMER_ClockDivision = TIMER_CDIV_DIV1;
    TIMER_BaseInit(TIMER3,&TIM_TimeBaseStructure);

    /* Input capture configuration */
    TIM_ICInitStructure.TIMER_CH          = TIMER_CH_1;
    TIM_ICInitStructure.TIMER_ICPolarity  = TIMER_IC_POLARITY_BOTH_EDGE;                                //TIMER_IC_POLARITY_RISING
    TIM_ICInitStructure.TIMER_ICSelection = TIMER_IC_SELECTION_DIRECTTI;
    TIM_ICInitStructure.TIMER_ICPrescaler = TIMER_IC_PSC_DIV1;
    TIM_ICInitStructure.TIMER_ICFilter    = 0x0;
    TIMER_ICInit(TIMER3, &TIM_ICInitStructure);

    /* Auto-reload preload enable */
    TIMER_CARLPreloadConfig(TIMER3,ENABLE);

    /* Clear the CH1 Interrupt flag an Enable the CH1 Interrupt Request */
    TIMER_ClearIntBitState(TIMER3,TIMER_INT_CH1);
    TIMER_INTConfig(TIMER3,TIMER_INT_CH1,ENABLE);
               
    /* TIMER enable counter*/
    TIMER_Enable( TIMER3, ENABLE );
                printf("TIMER Init Finish!\r\n");
}


/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  This function handles TIMER3 interrupt request.
  * @param  None
  * @retval None
  */
void TIMER3_IRQHandler(void)
{
        __IO uint8_t        PINSTATE=GPIO_ReadInputBit(GPIOA,GPIO_PIN_4);
    if(TIMER_GetIntBitState(TIMER3,TIMER_INT_CH1)==ENABLE)
    {
                               
      TIMER_ClearIntBitState(TIMER3,TIMER_INT_CH1);
                        if(GPIO_ReadInputBit(GPIOA,GPIO_PIN_4)!=0)
        {
                                        readvalue1 = TIMER_GetCapture1(TIMER3);
//                                        printf("readvalue1:%d\r\n",readvalue1);
        }
                        else if(GPIO_ReadInputBit(GPIOA,GPIO_PIN_4)==0)
        {
          readvalue2 = TIMER_GetCapture1(TIMER3);
            if (readvalue2 > readvalue1)
            {
                count = (readvalue2 - readvalue1);
            }
            else
            {
                count = ((60000 - readvalue1) + readvalue2);
            }
                                                count        =count-550;                         //这里有很大疑问!不减去550距离一直就多100mm,不知道哪里问题了……
                                                distance =195-count*17/100;
//            printf("the value1 is %d,the value2 is %d,%dmm\r\n",readvalue1,readvalue2,count*17/100);
            printf("µ±Ç°Ë®Î» %d mm\r\n\r\n",distance);
        }
                                else
                                        ;

    }
}
接线:

用的定时器3 CH1,Echo接PC6,Trig接PA4

试验:

结果:



手边没有直尺,就找了个小米充电宝对比下,小米是92mm左右高度,这个页面略低于充电宝,测量结果86mm,还可以的

还有一个很大的疑问就是为什么读出来的数据有一个550左右的偏差,如上面代码中:
count        =count-550;                         //这里有很大疑问!不减去550距离一直就多100mm,不知道哪里问题了……
还请高人指点!
具体代码如下:
C文件.rar (2.53 KB)

沙发
秋风式街球| | 2016-4-19 21:21 | 只看该作者
楼主牛X  支持一下

使用特权

评论回复
板凳
whtwhtw| | 2016-4-19 22:45 | 只看该作者
这个偏差你需要看看是不是编程时候数据转换造成的
我使用超声波传感器时候是不需要修正的,脉宽时间除以2,再乘以声波速度就行了

使用特权

评论回复
地板
vivilzb1985| | 2016-4-20 21:38 | 只看该作者
超声波做这个还是可以的,至于出现的问题看你计时计数时是否有操作误差的。

使用特权

评论回复
5
北极星405|  楼主 | 2016-4-21 10:52 | 只看该作者
vivilzb1985 发表于 2016-4-20 21:38
超声波做这个还是可以的,至于出现的问题看你计时计数时是否有操作误差的。 ...

应该不是误差,就是计数值总有一个偏移

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

459

帖子

7

粉丝