This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/MSP432P401R:计时器 A -超声波传感器 HC-SR04的捕获模式

Guru**** 2540720 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/861680/ccs-msp432p401r-timer-a---capture-mode-for-ultrasonic-sensor-hc-sr04

器件型号:MSP432P401R
主题中讨论的其他器件:4460

工具/软件:Code Composer Studio

您好!  

我尝试从 HCSR04获取以厘米为单位的测量值。 我已经执行  、修改了第44行和第45行。 我在 列 printf ("测量1 %i \n"meas1)中添加了;以在收到测量值时打印输出测量值。 如果我所输出的物体的样本距离传感器约10cm:

措施1 10516
测量1 49666
措施1 22997
测量1 63764
测量1 36141
测量1 9821
措施1 37
措施1 39586
测量1 13812
测量1 52755
措施1 27588
测量1 16081
测量1 56333
测量1 29705
措施1 3162
测量1 43098
测量1 16457
测量1 56342
测量1 30565
测量1 4821
措施1 44672
措施1 33393
测量1 7650
测量1 41721
测量1 41357
测量1 61195
测量1 50128
措施1 24761
措施1 64427
测量1 37530
测量1 11928
测量1 52452
措施1 23292
测量1 64951
措施1 38758
测量1 12566
测量1 51407
测量1 42480
测量1 17720
测量1 55112
测量1 29513
措施1 19707
测量1 58576
测量1 32103
测量1 7040
测量1 61467
测量1 20642
措施1 10391
测量1 65068
测量1 53756
测量1 42393
测量1 32610
测量1 56012
措施1 44669
测量1 34054
措施1 58689
措施1 32883
措施1 57672
测量1 32669
测量1 21598
测量1 62080
测量1 51102
测量1 24315
措施1 14081
测量1 7423
测量1 62643
测量1 51311
措施1 10443
测量1 49979
测量1 25411
测量1 63454
测量1 36915
测量1 11794
测量1 1642
措施1 41995
测量1 30202
措施1 4146
测量1 28636
测量1 3008
测量1 28608
测量1 16239
措施1 57237
测量1 31123
测量1 4064
测量1 43718
测量1 16956
测量1 8475
测量1 47844
措施1 21287
措施1 62099
测量1 35635
措施1 9989
测量1 49772
测量1 22966
测量1 12083
措施1 51187
测量1 12165
测量1 48357
测量1 38766
测量1 13215
措施1 53292
测量1 41796
措施1 16191
测量1 6029
测量1 45661
测量1 33639
测量1 8928
测量1 47028
测量1 20769
测量1 30260
测量1 5155
测量1 59807
测量1 33075
测量1 6982
措施1 46236
措施1 19808
测量1 59112
测量1 48377
测量1 24050
测量1 62639
测量1 36904
测量1 10630
测量1 50163
测量1 40678
测量1 13810
测量1 2941
测量1 43707
测量1 508
措施1 40329
测量1 30067
测量1 3223
测量1 45106
措施1 18391
测量1 58720
措施1 15376
测量1 38896
测量1 28896
措施1 37443
措施1 47298
测量1 21295
测量1 44301
测量1 34421
测量1 10353
测量1 47977
测量1 23231
测量1 63549
测量1 20008
测量1 62980
测量1 18836
测量1 58631
测量1 32945
测量1 7535
测量1 46705
测量1 20056
测量1 59798
测量1 33938
测量1 44482
测量1 53768
措施1 26863
措施1 15714
测量1 53144
措施1 13426
测量1 2403
测量1 56815
测量1 30923
测量1 7210
测量1 59372
测量1 34530
测量1 8179
措施1 46241
测量1 22025
措施1 11576
措施1 50009
测量1 39510
测量1 14232
测量1 23814
测量1 12365
测量1 52560
测量1 40939
测量1 15436
测量1 4944
测量1 43761
措施1 17465
措施1 26234
测量1 65208
措施1 39756
测量1 28576
测量1 4460
测量1 27612
措施1 3189
措施1 40341
测量1 1059
测量1 54404
测量1 27501
测量1 2366
测量1 40652
测量1 30642
测量1 5596
测量1 42805
措施1 18367
测量1 58656
措施1 30799
测量1 7123
措施1 59539
测量1 49710
测量1 9022
测量1 49493
测量1 22652
措施1 46298
测量1 20796
措施1 59382
测量1 33907
测量1 8443
测量1 60975
测量1 50529
测量1 8925
测量1 64678
测量1 39850
测量1 61871
测量1 38358
措施1 26183
测量1 1066
措施1 5269
测量1 29408
措施1 55468
测量1 10911
测量1 20796
测量1 45038
测量1 34744
测量1 23529
措施1 65463
测量1 38229
测量1 61480
测量1 35773
测量1 9138
测量1 50486
措施1 22753
测量1 12731
测量1 52889
测量1 42543
测量1 16379
措施1 4386
测量1 59805
措施1 33237
措施1 21977
测量1 11702
测量1 50661
测量1 2999
测量1 63920
测量1 40205
测量1 10802
测量1 51300
措施1 41671
措施1 14204
测量1 54636
测量1 43874
测量1 20759
措施1 7471
测量1 47403
措施1 20973
测量1 10180
测量1 49847
测量1 39346
措施1 14048
测量1 52678
措施1 11390
措施1 65283
测量1 40751
测量1 63600
测量1 37479
措施1 11514
测量1 20259
测量1 45668

显然、这些数字不是以厘米为单位、也不是一致的读数。 在脚本中、meas1是一个整数、因此这就是我尝试将其打印为的结果。 是否缺少转换?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果您要在中讨论代码  

    https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/607119

    看起来他没有完全完成。

    这些值以 SMCLK 周期为单位、其中 SMCLK=3MHz (333nsec)。 meas1本身并不是很有用、有趣的是脉宽、这是差异(((meas2-meas1)&0xFFFF)、它进入数据表中的公式。 我(模糊)记得公式需要用微秒、因此您需要除以3。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢、是的、这是我提到的代码。  

    我现在的问题是、我从未检测到下降沿、因此我不会进入其他环路并获得一个测量值2。 是否还有其他东西我必须通过线或代码来检测 P2IN&0x10? 以下是用于参考的中断循环:

    voidTA0_N_IRQHandler(void)
    {
        intrising  = 0;
        Timer_A_clearCaptureCompareInterrupt(TIMER_A0_BASE,
                TIMER_A_CAPTURECOMPARE_REGISTER_1);
        if(P2IN&0x10) rising=1; elserising=0;
        if(rising) // Start
        {
            meas1 = Timer_A_getCaptureCompareCount(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1);
        }
        else
        {
            meas2 = Timer_A_getCaptureCompareCount(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_1);
        }
    }
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    > TIMER_A_CAPTUREMODE_RISING_EDGE,          // Rising Edge and falling

    我怀疑他打算:

    > TIMER_A_CAPTUREMODE_RISING_AND_FALLING_EDGE, // Rising Edge and falling

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    使用该修复、我将获得上升和下降测量值。 数据表包含以下转换公式:

    测试距离=(高电平时间×声速(340M/S)/2、

    我使用以下行在代码中执行转换:

    int diff=((meas2-meas1)&0xFFFF);
    //int distCM=(diff/3000000)*340/2;
    int distCM=(diff*170)/3000000;
    printf ("距离:%i cm \n"、distCM);

    无论我保持传感器还是来回移动传感器、我都只能得到0-3cm 之间的值。 持有这种价值观的不一致仍然使我相信我的问题不是转换问题。 此外、代码中存在很多滞后、当我暂停代码时、代码通常位于延迟环路中。

    下面是我通过保持静止或移动传感器获得的示例:

    措施2 19599

    距离:1厘米

    措施1 40528

    距离:2厘米

    措施2 32299

    距离:3厘米

    测量1 7705

    距离:1厘米

    措施2 29517

    距离:1厘米

    措施2 54117

    距离:2厘米

    测量1 9145

    距离:2厘米

    测量2 59060

    距离:2厘米

    测量1 32526

    距离:1厘米

    措施2 32498

    距离:3厘米

    措施1 22439

    距离:0厘米

    措施2 11283

    距离:3厘米

    测量1 59847

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    1) 1)我发现的第一个数据表建议采用公式 cm = usec/58、即1 cm 为58 us。 这与您使用的公式相同、但形式更简单。 由于每个节拍为1/3 μ s、因此 cm =节拍/3/58。 我提到这一点、因为您的公式可能会根据大(3M)除数截断。 我建议您现在使用更简单的公式。

    2) 2)每次捕获后、代码似乎都会生成结果、但看起来并不正确。 发送脉冲后、您应该得到两次捕获、然后才能产生有用的结果。 因此、我怀疑您会遇到非常大的(假 )差异、这种差异(只是勉强)会通过(1)中的截断实现。 您在代码中的哪个位置插入了算术?

    3) 3) delay 函数使用 for ()循环来实现延迟、这是众所周知不可靠的。 我建议您摆脱所有延迟呼叫、并将其替换为以下内容:

    #define Hz  24000000UL  //从 CS_DCO_FREQUENCY 24中删除24MHz

    _DELAY_CYCLES (Hz/2);   //延迟半秒。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您帮助我完成这一过程。 在执行您的三个建议后、这就是我的代码现在的样子:

    #include "driverlib.h"
    #include 
    
    #define Hz 24000000UL // 24MHz From CS_DCO_FREQUENCY 24
    
    // Timer_A 连续模式配置参数*/
    const Timer_A_ContinuousModeConfig continuousModeConfig =
    {
    Timer_A_CLOCKSOURCE_SMCLK、 // SMCLK 时钟源
    Timer_A_CLOCKSOURCE_divider _1、 // SMCLK/1 = 3MHz
    Timer_A_TAIE_INTERRUPT_DISABLE、 //禁用计时器 ISR
    Timer_A_skip_clear // Skup 清除计数
    器};
    
    // Timer_A 捕获模式配置参数*/
    const Timer_A_CaptureModeConfig CaptureModeConfig =
    {
    Timer_A_CAPTURECOMPARE 寄存器_1、 // CC 寄存器2
    Timer_A_CAPTUREMODE_RISE_AND_FALLING_EDGE、//上升沿和下降沿 Timer_A_CAPTUREMODE_RISE_EDGE、 //上升沿和下降沿
    Timer_A_CAPTURE_INPUTSELECT_CCIxA、 // CCIxA 输入选择
    Timer_A_CAPTURE_synchronous、 //同步捕捉
    Timer_A_CAPTURECMPARE 中断_ENABLE、//启用中断
    Timer_A_OUTPUTMODE_OUTBIVALUE //输出位值
    };
    
    int meas1 = 0;
    int meas2 = 0;
    int meas1Count=0;
    int takVal=0;
    
    int main (void)
    {
    /*停止看门狗计时器*/
    MAP_WDT_A_HOLDTimer();
    
    CS_setDCOCenteredFrequency (CS_DCO_FREQUENCY 24); // 24000000 Hz
    
    CS_initClockSignal (CS_MCLK、CS_DCOCLK_select、CS_clock_divider);// 24000000 Hz
    CS_initClockSignal (CS_SMCLK、CS_DCOCLK_select、CS_clock_divider);// 3000000 Hz
    
    /*将 P2.4配置为捕捉的外设输入*/
    GPIO_setPeripheralModuleFunctionInputPin (GPIO_PORT_P2、GPIO_PIN4、GPIO_PRIMARY_MODULE_Function);
    GPIO_setAsOutputPin (GPIO_PORT_P1、GPIO_PIN5);
    
    /*配置捕获模式*/
    Timer_A_initCapture (timer_A0_BASE、&captureModeConfig);
    
    /*配置连续模式*/
    Timer_A_configureContinuousMode (timer_A0_BASE、连续模式配置);
    
    /*启用中断*/
    INTERRUPT_enableInterrupt (INT_TA0_N);
    interrupt_enableMaster();
    
    /*启动 Timer32 */
    Timer32_initModule (TIMER32_0_base、TIMER32_prescaler_1、TIMER32_32位、TIMER32_PERiod_MODE);
    Timer32_disableInterrupt (TIMER32_0_BASE);
    Timer32_setCount (TIMER32_0_BASE、1);
    Timer32_startTimer (TIMER32_0_base、true);
    
    /*在连续模式下启动 Timer_A0 */
    Timer_A_startCounter (timer_A0_BASE、timer_A_Continuous_mode);
    while (1)
    {
    GPIO_setOutputHighOnPin (GPIO_PORT_P1、GPIO_PIN5);
    Timer32_setCount (TIMER32_0_BASE、24 * 10);
    while (Timer32_getValue (TIMER32_0_BASE)> 0);//等待10us
    GPIO_setOutputLowOnPin (GPIO_PORT_P1、GPIO_PIN5); //软件延迟
    _DELAY_CYCLES (Hz/2); //延迟半秒。
    // _DELAY_CYCLES (Hz/2); //延迟半秒。
    // _DELAY_CYCLES (Hz/2); //延迟半秒。
    // _DELAY_CYCLES (Hz/2); //延迟半秒。
    // _DELAY_CYCLES (Hz/2); //延迟半秒。
    // _DELAY_CYCLES (Hz/2); //延迟半秒。
    
    if (TakeVal=1){
    取出 Val = 0;
    int diff=((meas2-meas1)&0xFFFF);
    //int distCM=(diff/3000000)*340/2;
    //int distCM=(diff*170)/3000000;
    int distCM=(diff /3)/58;
    printf ("距离:%i cm \n"、distCM);
    }
    
    }
    
    
    void TA0_N_IRQHandler (void)
    {
    INT Rising = 0;
    
    Timer_A_clearCaptureCompareInterrupt (timer_A0_BASE、
    Timer_A_CAPTURECOMPARE 寄存器1);
    
    if (P2IN&0x10) rising=1;否则 rising=0;
    
    if (上升)//开始
    {
    meas1 = Timer_A_getCaptureCompareCount (timer_A0_BASE、timer_A_CAPTUREMPARE 寄存器_1);
    printf ("测量1 %i \n"meas1);
    meas1Count=1;
    }
    其他
    {
    meas2 = Timer_A_getCaptureCompareCount (timer_A0_BASE、timer_A_CAPTURECMPARE 寄存器_1);
    printf ("测量2 %i \n"meas2);
    如果(meas1Count=1){//if meas1已经被收集
    meas1Count=0;//重置 meas1计数
    TakeVal=1;//转换标志
    }
    }
    
    

    当我注释掉 meas1和 meas2打印输出时、这是一个典型输出:

    距离:0 cm
    距离:137 cm
    距离:147 cm
    距离:135
    cm
    距离:227 cm
    距离:136 cm
    距离:222 cm
    距离:131 cm
    距离
    :133 cm
    距离:129 cm
    距离:228 cm
    距离:237 cm
    距离:135 cm
    

    当我将 print 语句保留在中时、这是一个典型的输出:

    测量1
    1测量2 11537
    距离:66 cm
    测量1 47626
    测量2 55703
    距离: 46 cm
    测量1 27494
    测量2 29699
    测量1 23192
    测量2 65385
    测量1 8440
    测量2 16585
    测量1 24577
    测量2 32799
    测量2 427
    测量1 59435
    测量2 1113
    测量2 33962
    测量1 43383
    测量1 10885
    测量2 2588
    测量1 61997
    措施1 45161
    措施1 27988
    措施1 11263
    措施2 3016
    措施2 51416
    措施2 33972
    措施2 43254
    措施2 26443
    措施1 35817
    措施1 33857
    措施1 1960
    措施1 345
    措施1 48697
    措施1 31889
    措施2 53372
    措施1 63311
    措施1 15686
    措施1 48716
    措施2 40190
    措施2 23186
    措施1 32531
    措施2 39627
    措施1 33550
    措施2 55807
    措施2 53844
    措施1 13498
    措施1 62052
    措施1 44944
    措施1 12568
    措施1 45714
    措施1 13870
    措施1 46865
    措施2 4102
    措施 2 52800
    测量1 60952
    测量2 18678
    测量2 51661
    距离:323厘米
    

    我一直在讨论添加到代码中的半秒延迟、以尝试获得更一致/更可靠的测量结果。 是否有比猜测和检查更有条理的方法? 此外、我知道 print 语句会减慢代码速度、但我不知道为什么一行会有多个上升测量值和下降测量值。

    距离:0厘米
    距离:137厘米
    距离:147厘米
    距离:144厘米
    距离:135厘米
    距离:227厘米
    距离:136厘米
    距离:222厘米
    距离:131厘米
    距离:133厘米
    距离:134厘米
    距离:129厘米
    距离:228厘米
    距离:237厘米
    距离:135厘米

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我想知道您是否会收到额外的回声;我不知道 HCS04是否会屏蔽这些回声、但只有第一个回声很有趣。 我建议:

    1)请勿延迟(在输出脉冲之后)等待结果、而是立即开始查看。 即消除延迟并更换

    > if (takeval=1)

    使用

    > while (takeval=0)/*empty*/;//旋转至第一个脉冲

    (随后的花括号是冗余的。)

    2) 2)声明"评估"为"易失性"

    3) 3)从 ISR 中删除 printf()-s。 如果您获得多个脉冲、它们将使计时失真。

    4) 4)捕获并显示结果后、延迟一段时间、直到事情安静下来。 多长时间? 400cm*58usec=23.2msec。 数据表建议等待至少60ms。 要使其可读、您可能需要接近该半秒的时间。