查看: 4124|回复: 1

[原创] 自平衡小车-2 超声测距

[复制链接]
  • TA的每日心情
    擦汗
    2021-7-5 15:45
  • 签到天数: 664 天

    连续签到: 1 天

    [LV.9]以坛为家II

    42

    主题

    1594

    帖子

    19

    金牌会员

    Rank: 6Rank: 6

    积分
    5618
    最后登录
    2021-12-22
    发表于 2017-10-15 18:29:24 | 显示全部楼层 |阅读模式
    本帖最后由 okwh 于 2017-11-11 23:41 编辑

    自平衡小车-2 超声测距

    本篇验证超声测距模块HC_SR04
    一、该模块参数 
    • 工作电压: 5V
    • 工作电流: 15mA
    • 工作频率:  40Hz
    • 测距范围: 2cm~4m
    • 测量角度:  15度
    • 触发信号: 10us TTL
    • 回声信号: TTL高电平持续时间

    superAu.png

    二、 设计(lpc54114板接口线定义见上篇表格)
         模块有引线4根,电源5V和地从Arduino电源接口提供 
         触发信号和回声信号接PIO0_21 和PIO0_20,对应CTimer3_MAT0和Ctimer3_CAP0功能。
         LPC54114的计时器功能很强大,每个计时器可同时实现4个匹配输出和4个输入捕获或多个PWM输出。简单的看,LPC54114的每个计时器至少可实现4个最简单计时器的功能。于是,我们可以很简单的用1个计时器绰绰有余地满足上面的时序图,完全控制超声测距模块(实际只使用了2个匹配、1个捕获捕2次)。
          这里使用Timer3的0号匹配MAT0-对应管脚PIO0_21用于生成触发信号;使用Timer3的0号捕获CAP 0-对应管脚PIO0_20,以中断方式用于捕获回声信号上升沿和下降沿对应的记数,进一步用获得两个记数的差计算超声探测距离;同时使用无输出的1号匹配MAT1控制测量周期


    三、编程
    基于例子SDK_2.2.1_LPCXpresso54114\boards\lpcxpresso54114\driver_examples\ctimer\simple_match修改。

    配置管脚PIO0_21和PIO0_20,增加到 pin_mux.c   
    1. #define PIN21_IDX                       21u   /*!< CTimer3_MAT0  Pin number for pin 21 in a port 0 */
    2. #define PIN20_IDX                       20u   /*!< CTimer3_CAP0  Pin number for pin 20 in a port 0 */
    3. ...........................

    4. const uint32_t port0_pin21_config = (         //P0_21 用于 CTIMER3_MAT0输出 触发 超声探测
    5.     IOCON_PIO_FUNC3 |                                        /* Pin is configured as CTIMER3_MAT0 */
    6.    // IOCON_PIO_MODE_INACT |                                   /* No addition pin function */
    7.           IOCON_MODE_PULLDOWN  |                                    //默认下拉
    8.     IOCON_PIO_INV_DI |                                       /* Input function is not inverted */
    9.     IOCON_PIO_DIGITAL_EN |                                   /* Enables digital function */
    10.     IOCON_PIO_INPFILT_OFF |                                  /* Input filter disabled */
    11.     IOCON_PIO_OPENDRAIN_DI                                   /* Open drain is disabled */
    12.   );
    13.   IOCON_PinMuxSet(IOCON, PORT0_IDX, PIN21_IDX, port0_pin21_config); /* PORT0 PIN21 (coords: 11) is configured as CTIMER3_MAT0 */
    14.   const uint32_t port0_pin20_config = (         //P0_20 用于 CTIMER3_Cap0输入  超声echo
    15.     IOCON_PIO_FUNC3 |                                        /* Pin is configured as CTIMER3_cap0 */
    16.    // IOCON_PIO_MODE_INACT |                                   /* No addition pin function */
    17.           IOCON_MODE_PULLDOWN  |                                    //默认下拉   要CAP高电平
    18.     IOCON_PIO_INV_DI |                                       /* Input function is not inverted */
    19.     IOCON_PIO_DIGITAL_EN |                                   /* Enables digital function */
    20.     IOCON_PIO_INPFILT_OFF |                                  /* Input filter disabled */
    21.     IOCON_PIO_OPENDRAIN_DI                                   /* Open drain is disabled */
    22.   );
    23.   IOCON_PinMuxSet(IOCON, PORT0_IDX, PIN20_IDX, port0_pin20_config); /* PORT0 PIN20 (coords: 11) is configured as CTIMER3_Cap0 */
    复制代码
    捕获回声中断:增加到 simple_match.c
    1. static uint32_t count0 = 0;       // one for Capture_RiseEdge
    2. static uint32_t count1 = 0;       // one for Capture_FallEdge
    3. void ctimer_cap_callback(uint32_t flags)
    4. {
    5.     if (count0==0)
    6.         count0 = CTIMER3->CR[0] ;//  CTIMER_CR_CAP(0) ;  //  CTIMER3   Capture_0  record
    7.     else
    8.         count1 =  CTIMER3->CR[0] ;//CTIMER_CR_CAP(0) ;  //  CTIMER3   Capture_0  record
    9. }
    10. ctimer_callback_t ctimer_callback_table[] =
    11. {
    12.     ctimer_cap_callback,
    13.     NULL,
    14.     NULL,
    15.     NULL,//ctimer_match1_callback,
    16.     NULL,
    17.     NULL,
    18.     NULL,
    19.     NULL
    20. };
    复制代码

    主函数: 修改增加到 simple_match.c
    1. #define CTIMER CTIMER3                 /* Timer 0 */
    2. #define CTIMER_MAT_OUT kCTIMER_Match_0 /* Match output 0  p0_21*/
    3. #define CTIMER_CAP_INP kCTIMER_Capture_0 /* Capture 0  p0_20*/
    4. #define BUS_CLK_FREQ CLOCK_GetFreq(kCLOCK_AsyncApbClk)

    5. int main(void)
    6. {
    7.     ctimer_config_t config;
    8.     ctimer_match_config_t matchConfig;

    9.     /* Init hardware*/
    10.     /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
    11.     CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

    12.     /* Enable the asynchronous bridge */
    13.     SYSCON->ASYNCAPBCTRL = 1;

    14.     /* Use 12 MHz clock for some of the Ctimers */
    15. //   CLOCK_AttachClk(kFRO12M_to_ASYNC_APB);   //kCLOCK_AsyncMainClk   kCLOCK_AsyncFro12Mhz
    16.     CLOCK_AttachClk(kMAIN_CLK_to_ASYNC_APB);//kCLOCK_AsyncMainClk);  //96MHz
    17.         
    18.     BOARD_InitPins();
    19.    BOARD_BootClockFROHF48M();
    20.         //  BOARD_BootClockFROHF96M();
    21.     BOARD_InitDebugConsole();

    22.     PRINTF("CTimer match example to toggle the output on a match\r\n");

    23.     CTIMER_GetDefaultConfig(&config);

    24.     CTIMER_Init(CTIMER, &config);
    25.     count0 =0;  count1 =0;
    26.                
    27.     matchConfig.enableCounterReset =  true;      //mat1 后复位 重记数  控制测量周期
    28.     matchConfig.enableCounterStop = false;      //mat后不停止
    29.     matchConfig.matchValue = BUS_CLK_FREQ /1;//0 ;   // BUS_CLK_FREQ/1  即1秒   这里每秒测一次  说明书要求 > 60ms
    30.     matchConfig.outControl = kCTIMER_Output_NoAction; //无输出关联 
    31.     matchConfig.outPinInitState = false;    // 无效  
    32.     matchConfig.enableInterrupt = false;       //匹配不中断
    33.     CTIMER_SetupMatch(CTIMER, kCTIMER_Match_1, &matchConfig);   //Timer3 mat1 no out

    34.     CTIMER_SetupCapture(CTIMER,CTIMER_CAP_INP,kCTIMER_Capture_BothEdge,true);   //捕获回声中断       ////Timer3 cap0 input p0_20, up echo start, down echo finish
    35.     CTIMER_RegisterCallBack(CTIMER, &ctimer_callback_table[0], kCTIMER_SingleCallback);//kCTIMER_MultipleCallback);  //echo fall intr
    36.                
    37.     matchConfig.enableCounterReset = false;// true;      //mat0不复位 继续记数
    38.     matchConfig.enableCounterStop = false;      //mat后不停止
    39.     matchConfig.matchValue = BUS_CLK_FREQ *11 / 1000000;   //    11us  触发  
    40.     matchConfig.outControl = kCTIMER_Output_Toggle;   //toggle输出
    41.     matchConfig.outPinInitState = true;//false;//   计时器开启前的高低。  初始化为下拉低
    42.     matchConfig.enableInterrupt = false;       //匹配不中断
    43.     CTIMER_SetupMatch(CTIMER, CTIMER_MAT_OUT, &matchConfig);    //Timer3 mat0 out p0_21  trig
    44.                
    45.     CTIMER_StartTimer(CTIMER);   //开始

    46.     while (1)
    47.     {
    48.        if (count1!=0)
    49.   {
    50.    PRINTF("CTimer cap     %d    %d  %d   mm\r\n",count0,count1,(int32_t)(abs(count1-count0)/48*0.17));    // 0.17 mm /us, 48MHz
    51.    count0 =0;  count1 =0;
    52.   }
    53.     }
    复制代码


    四、结果
    1)   放于桌面,对天花板测量: 距离1.847米,误差1cm左右;下图
    2)   用手在声纳前逐渐移动,可看到距离4~16cm; 误差5mm左右;下下图
    3)   10us触发信号,测距模块实际使用的可能是其上升沿触发,此信号长时间高电平没影响测距。

    小心问题: 
    1)   小于27mm, 约声音传播总时间约小于15 us时,误差变大,且距离反会大幅度变大,测量失效。(说明书:  20mm下限)
    2)   不同材质阻挡物声音反射效果不同,硬且平整材料 测距较准, 柔软弹性物质、有洞的材料如泡沫塑料、叉开的手指等 测距误差较大。3)   如果阻挡物在动态运动,也可能出现较大测距误差。
    测量echo高电平持续时间: 我以为可以在一个cap管脚上cap一个信号的升和降、队列记录两个记数,实际是cap记数记录,一个cap只有一个记录寄存器,所以使用中断先把升记下,再次中断就是降的计时记数。这样是 一个管脚、二次中断。
    还有一个办法,就是使用两个cap管脚接同一个echo信号,分别cap升和降,这样则需要两个管脚、降中断一个。 此未测试。

    天花板测距
    superAu0.png

    手移动:
    superAu1.png



    系列:


    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情

    2018-2-28 16:09
  • 签到天数: 65 天

    连续签到: 1 天

    [LV.6]常住居民II

    8

    主题

    238

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    488
    最后登录
    2019-9-18
    发表于 2017-10-16 09:00:08 | 显示全部楼层
    谢谢,学习下定时器!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-19 14:26 , Processed in 0.088292 second(s), 21 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表