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

[复制链接]
 楼主| 北极星405 发表于 2016-4-19 20:55 | 显示全部楼层 |阅读模式
本帖最后由 北极星405 于 2016-4-19 20:55 编辑


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

原理.jpg

主要代码:
printf重定向:

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

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

  7.                 return ch;
  8. }



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

  4.     NVIC_PRIGroup_Enable(NVIC_PRIGROUP_1);

  5.     /* Enable the TIMER3 Interrupt */
  6.     NVIC_InitStructure.NVIC_IRQ                = TIMER3_IRQn;
  7.     NVIC_InitStructure.NVIC_IRQPreemptPriority = 0;
  8.     NVIC_InitStructure.NVIC_IRQSubPriority     = 1;
  9.     NVIC_InitStructure.NVIC_IRQEnable          = ENABLE;
  10.     NVIC_Init(&NVIC_InitStructure);
  11. }

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

  19.     TIMER_BaseInitPara TIM_TimeBaseStructure;

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

  32.     /* Input capture configuration */
  33.     TIM_ICInitStructure.TIMER_CH          = TIMER_CH_1;
  34.     TIM_ICInitStructure.TIMER_ICPolarity  = TIMER_IC_POLARITY_BOTH_EDGE;                                //TIMER_IC_POLARITY_RISING
  35.     TIM_ICInitStructure.TIMER_ICSelection = TIMER_IC_SELECTION_DIRECTTI;
  36.     TIM_ICInitStructure.TIMER_ICPrescaler = TIMER_IC_PSC_DIV1;
  37.     TIM_ICInitStructure.TIMER_ICFilter    = 0x0;
  38.     TIMER_ICInit(TIMER3, &TIM_ICInitStructure);

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

  41.     /* Clear the CH1 Interrupt flag an Enable the CH1 Interrupt Request */
  42.     TIMER_ClearIntBitState(TIMER3,TIMER_INT_CH1);
  43.     TIMER_INTConfig(TIMER3,TIMER_INT_CH1,ENABLE);
  44.                
  45.     /* TIMER enable counter*/
  46.     TIMER_Enable( TIMER3, ENABLE );
  47.                 printf("TIMER Init Finish!\r\n");
  48. }


  49. /**
  50.   * [url=home.php?mod=space&uid=247401]@brief[/url]  This function handles TIMER3 interrupt request.
  51.   * @param  None
  52.   * @retval None
  53.   */
  54. void TIMER3_IRQHandler(void)
  55. {
  56.         __IO uint8_t        PINSTATE=GPIO_ReadInputBit(GPIOA,GPIO_PIN_4);
  57.     if(TIMER_GetIntBitState(TIMER3,TIMER_INT_CH1)==ENABLE)
  58.     {
  59.                                
  60.       TIMER_ClearIntBitState(TIMER3,TIMER_INT_CH1);
  61.                         if(GPIO_ReadInputBit(GPIOA,GPIO_PIN_4)!=0)
  62.         {
  63.                                         readvalue1 = TIMER_GetCapture1(TIMER3);
  64. //                                        printf("readvalue1:%d\r\n",readvalue1);
  65.         }
  66.                         else if(GPIO_ReadInputBit(GPIOA,GPIO_PIN_4)==0)
  67.         {
  68.           readvalue2 = TIMER_GetCapture1(TIMER3);
  69.             if (readvalue2 > readvalue1)
  70.             {
  71.                 count = (readvalue2 - readvalue1);
  72.             }
  73.             else
  74.             {
  75.                 count = ((60000 - readvalue1) + readvalue2);
  76.             }
  77.                                                 count        =count-550;                         //这里有很大疑问!不减去550距离一直就多100mm,不知道哪里问题了……
  78.                                                 distance =195-count*17/100;
  79. //            printf("the value1 is %d,the value2 is %d,%dmm\r\n",readvalue1,readvalue2,count*17/100);
  80.             printf("µ±Ç°Ë®Î» %d mm\r\n\r\n",distance);
  81.         }
  82.                                 else
  83.                                         ;

  84.     }
  85. }
接线:
接线.jpg
用的定时器3 CH1,Echo接PC6,Trig接PA4

试验:
示意.jpg
结果:
221.jpg

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

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

秋风式街球 发表于 2016-4-19 21:21 | 显示全部楼层
楼主牛X  支持一下
whtwhtw 发表于 2016-4-19 22:45 | 显示全部楼层
这个偏差你需要看看是不是编程时候数据转换造成的
我使用超声波传感器时候是不需要修正的,脉宽时间除以2,再乘以声波速度就行了
vivilzb1985 发表于 2016-4-20 21:38 | 显示全部楼层
超声波做这个还是可以的,至于出现的问题看你计时计数时是否有操作误差的。
 楼主| 北极星405 发表于 2016-4-21 10:52 | 显示全部楼层
vivilzb1985 发表于 2016-4-20 21:38
超声波做这个还是可以的,至于出现的问题看你计时计数时是否有操作误差的。 ...

应该不是误差,就是计数值总有一个偏移
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

459

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部