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.

[参考译文] CC2650:在 adcbufcontinuous 中、调用回调函数的时间是错误的?

Guru**** 2558250 points
Other Parts Discussed in Thread: CC2650

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1065400/cc2650-in-adcbufcontinuous-the-time-to-call-the-callback-function-is-wrong

器件型号:CC2650
Thread 中讨论的其他器件: SYSBIOS

TI 工程师、

我尝试了“adcbufContinuous_CC2650_LAUNCHXL_TI”示例,我设置了“adcBufParams.samplingFrequency = 1000;”和“#define ADCBUFFERSIZE  (25)"。 我在 ADC 回调函数中添加了一些代码、以打印时间戳、如图所示。

回调函数应每25ms 执行一次、但它打印的时间戳显示 它每24.85ms 执行一次。

我真的很困惑为什么时间小于25ms,因为25*0.001=0.025s。  

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

    您能否尝试更改缓冲器大小和 频率并提供结果?   BIOS_getCpuFreq 的返回值是多少? 主时钟为 ADC 和 GPTimer 供源、后者决定采样频率。

    此致、
    Ryan

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

    您好、Ryan、

     正如您在 https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1065350/launchxl-cc2650-how-to-configure-the-clock-source-of-clock-module/3941418#3941418中所说的那样

    我将 adcBufParams.samplingFrequency = 1000;和#define ADCBUFFERSIZE  (25)。  我添加了 Power_setDependency (PowerCC26XX_XOSC_HF);在 main()中,并通过  convisionStartFxn 中的 OSCClockSourceGet (OSC_SRC_CLK_HF)检查它是否成功,在 convisionStartFxn 中,我获得 BIOS_getCpuFreq 的值。 但我没有 为新的 CPU 频率重新配置时钟、也没有更改计时器/时钟源。

    现在、我获得了以下结果:

    "
    OSCClockSourceGet 1:

    频率:0、48000000


    1时间戳2194:


    2时间戳4393:

    (笑声)

    40时间戳99705:


    41时间戳102204:

    (笑声)

    80时间戳199716:


    81时间戳202218:

    "

    "OSCClockSourceGet 1:"显示我成功地将时钟源设置为  XOSC_HF、 并且 CPU 频率为48MHz。 我 有一个问题、需要 在需要更改 CPU 频率时?  由于 XOSC_HF 在内部加倍以创建48MHz 时钟、我也许不需要更改 CPU 频率?

    至于时间戳、每个数据包需要24.99ms~25.02ms、这更准确。 但是 、102204-2194=100010=1000.1ms、 202218-102204=100,014=1000.14ms。 我检查过很多次、每40个数据包的时间为 1000.1ms~1000.14ms、应为1000ms。 您是否知道为什么会发生这种情况? 这是正常情况吗?

    谢谢你

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

    请允许我在此处发布我的代码。


    *==== adcBufContinuousSampling.c ====
    *

    #include
    #include
    /* XDCtools 头文件*/
    #include
    #include
    #include
    /* BIOS 头文件*/
    #include
    #include

    /* TI-RTOS 头文件*/
    #include
    #include
    #include "driverlib/osc.h"
    #include
    #include

    #IF 定义(CC2650DK_7ID)||定义(CC1310DK_7xD)
    #include
    #endif

    /*示例/板头文件*/
    #include "Board.h"

    #define TASKSTACKSIZE (768)
    #define ADCBUFFERSIZE (25)

    Task_Structtask0Struct;
    char task0stack[TASKSTACKSIZE];

    uint16_t sampleBufferOne[ADCBUFFERSIZE];
    uint16_t sampleBufferTwo_[ADCBUFFERSIZE];
    uint32_t microVoltBuffer[ADCBUFFERSIZE];
    uint32_t buffersCompletedCounter = 0;
    字符 uartTxBuffer[(10 * ADCBUFFERSIZE)+ 25];

    /*任务和回调函数之间共享的驱动程序句柄*/
    UART_Handle UART;
    int k;
    uint_fast16_t i;
    uint_fast16_t uartTxBufferOffset;
    /*
    *只要缓冲区已满,就会调用此函数。
    *然后将缓冲区的内容转换为可读格式和
    *通过 UART 发送到 PC。
    *
    *
    void adcBufCallback (ADCBuf_Handle handle、ADCBuf_Conversion *转换、
    void *完整的 ADCBuffer、uint32_t 完整通道){

    /*调整原始 ADC 值并将其转换为微伏*/
    ADCBuf_RawadjustValues (handle、completedADCBuffer、ADCBUFFERSIZE、
    完整通道);
    ADCBuf_convertAdjustedToMicroVolts (手柄、完整通道、
    完整的 ADCBuffer、microVoltBuffer、ADCBUFFERSIZE);

    int var=Clock_getTicks();
    K++;

    uartTxBufferOffset = System_sprintf (uartTxBuffer、
    "\r\n %d 时间戳%lu:\r\n"、k、var);

    uartTxBuffer[uartTxBufferOffset]='\n';
    /*通过 UART 发送数据*/
    UART_WRITE (UART、uartTxBuffer、uartTxBufferOffset + 1);

    /*
    *回调函数以在回调模式下使用 UART。 它什么也不做。
    *
    void uartCallback (UART_Handle handle、void *buf、size_t count){
    返回;

    /*
    *==== conversionStartFxn =====
    *此函数的任务是静态创建的。 请参阅工程的.cfg 文件。
    *
    void conversionStartFxn (UArg0、UArg0 arg1){
    UART_Params uartParams;
    ADCBuf_handle adcBuf;
    ADCBuf_Params adcBufParams;
    ADCBuf_Conversion 连续转换;

    /*
    *在本示例中、CC2650DK_7ID 和 CC1310DK_7xD 测量环境光传感器。
    *默认情况下不加电、以避免在其他示例中出现高电流消耗。
    *下面的代码打开传感器的电源。
    *
    #IF 定义(CC2650DK_7ID)||定义(CC1310DK_7xD)
    PIN_STATE 引脚状态;

    PIN_Config AlsPinTable[]=

    Board_ALS_PWR | PIN_GPIO_OUTPUT _EN | PIN_GPIO_HIGH | PIN_PushPull、//打开 ALS 电源*/
    PIN_TERMINATE /*终止列表*/
    };

    /*打开环境光传感器的电源*/
    PIN_OPEN (&pinState、AlsPinTable);
    #endif

    /*创建一个数据处理关闭的 UART。 *
    UART_PARAMS_INIT (uartParams);
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.writeMode = UART_MODE_CALLBACK;
    uartParams.writeCallback = uartCallback;
    uartParams.baudrate = 115200;
    UART = UART_OPEN (Board_UART0、uartParams);

    uint32_t osc_src=OSCClockSourceGet (OSC_SRC_CLK_HF);
    xdc_runtime_Types_FreqHz BIOS_cpufreq;
    BIOS_getCpuFreq (&BIOS_cpufreq);

    uartTxBufferOffset = System_sprintf (uartTxBuffer、
    "\r\n OSCClockSourceGet %u:\r\n"、osc_src);
    uartTxBufferOffset += System_sprintf (uartTxBuffer+ uartTxBufferOffset、
    "\r\n 频率:%u、%u\r\n"、BIOS_cpufreq.hi、BIOS_cpufreq.lo);

    uartTxBuffer[uartTxBufferOffset]='\n';
    /*通过 UART 发送数据*/
    UART_WRITE (UART、uartTxBuffer、uartTxBufferOffset + 1);

    /*在 ADCBuf_RECURE_MODE_连续 中设置 ADCBuf 外设*/
    ADCBuf_Params_init (&adcBufParams);
    adcBufParams.callbackFxn = adcBufCallback;
    adcBufParams.RecurrencedMode = ADCBuf_Recurrence_mode_continuous;
    adcBufParams.returnMode = ADCBuf_return_mode_callback;
    adcBufParams.samplingFrequency = 1000;
    adcBuf = ADCBuf_open (Board_ADCBuf0、&adcBufParams);


    /*配置转换结构*/
    //#define Board_ADCBufChannel0 (3) for DIO23作为 ADC 输入引脚
    continuousConversion.arg =空;
    continuousConversion.adcChannel = Board_ADCBufChannel0;
    continuousConversion.sampleBuffer = sampleBufferOne;
    continuousConversion.sampleBufferTwo = sampleBufferTwo;
    continuousConversion.samplesRequestedCount = ADCBUFFERSIZE;

    如果(!adcBuf){
    system_abort ("adcBuf did not open correctly \n");

    /*开始转换。 *
    if (ADCBuf_convert (adcBuf、连续转换、1)!=
    ADCBuf_STATUS_SUCCESS){
    system_abort ("未正确启动转换过程\n");

    /*
    *永久进入前台线程的睡眠状态。 数据将被收集
    *并在后台线程中传输
    *
    Task_sleep (BIOS_wait_forever);

    /*
    *==== main ====
    *
    int main (void){
    Task_Params taskParams;

    /*呼叫板初始化函数*/
    Board_initGeneral();
    Board_initADCBuf();
    Board_initUART();
    Power_setDependency (PowerCC26XX_XOSC_HF);

    /*构造 BIOS 对象*/
    Task_Params_init (&taskParams);
    taskParams.STACKSIZE = TASKSTACKSIZE;
    taskParams.stack =_task0Stack;
    Task_conversion (&task0Struct,(Task_FuncPtr) convisionStartFxn、
    taskParams、NULL);

    System_printf ("启动 ADC 连续采样示例\n"
    "系统提供商已设置为 SysMin。 停止目标以查看任何 SysMin "
    " ROV 中的内容。\n");

    /* SysMin 仅在您调用 flush 或 exit 时才会打印到控制台*/
    system_flush();

    /*启动 BIOS */
    BIOS_start();

    返回(0);

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

    考虑到晶体精度和为 ADC 中断计时的 GP 计时器的 TI 驱动程序缩放、您的结果现在似乎在合理范围内。  在您收集更多样本时、时间戳是否会继续漂移?

    此致、
    Ryan

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

    我获得了以下数据:

    1000Hz 采样率要收集1000个 ADC 数据、 理论时间与实际时间之间的差值:~0.11ms

    用于收集2000个 ADC 数据的1000Hz 采样率:~0.25ms

    10000Hz 采样率可收集1000 ADC 数据:~0.01ms

    收集  1000个 ADC 数据的100Hz 采样率:~1.23ms

    时间差似乎与 用于收集 ADC 的时间相关。 但 理论时间始终大于实际 时间。 您认为这是由晶体振荡器的偏斜造成的吗?

    (我犯了一个错误、即 实际时间总是大于理论时间。 2022.1.3)

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

    感谢您提供这些数据点。  您可以将终端的本地时间戳(一些人解释了启用该时间戳的方法)与时钟模块的 Get ticks 函数进行比较、以确定时钟精度。  否则、赤字是由用于在 ADC TI 驱动程序内初始化 GP 定时器的逻辑引起的、您可以尝试通过略微修改采样率值(例如、999Hz 而不是1000)来对此进行补偿。

    此致、
    Ryan