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.

CC1350 AD 采集

Other Parts Discussed in Thread: CC1350

在不使用多线程的情况下在buffer模式下能否实现多通道采集

  • 多线程跟ADC多通道无关,不论是单通道采集还是多通道采集,都是一个线程。推荐看一下这边的例程:http://dev.ti.com/tirex/explore/node?node=AC.rsUKsVvdCiKwydCQGYg__eCfARaV__LATEST

  • 但是adcbuffer连续测量只支持一个通道啊
  • 是的,CC1350支持多达8个adc channel,但是同一时刻只有一个通道能进行采样
  • 这个我知道。就是能不能切换测量通道
    这是我根据buffer例程改的四通道的,但是uart只有第一个通道的数据,其他三个通道均为0
    UART_Params uartParams;
    ADCBuf_Handle adcBuf;
    ADCBuf_Params adcBufParams;
    ADCBuf_Conversion continuousConversion[4];

    /* Call driver init functions */
    ADCBuf_init();
    UART_init();

    /* Create a UART with data processing off. */
    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);

    /* Set up an ADCBuf peripheral in ADCBuf_RECURRENCE_MODE_CONTINUOUS */


    int q;
    for(q=0;q<3;q++)
    {
    ADCBuf_Params_init(&adcBufParams);
    adcBufParams.callbackFxn = adcBufCallback;
    adcBufParams.recurrenceMode = ADCBuf_RECURRENCE_MODE_CONTINUOUS;
    adcBufParams.returnMode = ADCBuf_RETURN_MODE_CALLBACK;
    adcBufParams.samplingFrequency = 2;
    /* Create a UART with data processing off. */
    // uart = UART_open(Board_UART0, &uartParams);
    adcBuf = ADCBuf_open(Board_ADCBUF0, &adcBufParams);
    /* Configure the conversion struct */
    continuousConversion[q].arg = NULL;
    continuousConversion[q].adcChannel = q+2;
    continuousConversion[q].sampleBuffer = sampleBufferOne;
    continuousConversion[q].sampleBufferTwo = sampleBufferTwo;
    continuousConversion[q].samplesRequestedCount = ADCBUFFERSIZE/4;

    if (adcBuf == NULL){
    /* ADCBuf failed to open. */
    while(1);
    }

    /* Start converting. */
    if (ADCBuf_convert(adcBuf, &continuousConversion[q], 4) !=
    ADCBuf_STATUS_SUCCESS) {
    /* Did not start conversion process correctly. */
    while(1);
    }


    }
  • 1、不同的channel要定义不同的buffer,以下语句需要改
    continuousConversion[q].sampleBuffer = sampleBufferOne;
    continuousConversion[q].sampleBufferTwo = sampleBufferTwo;

    2、ADCBuf_RECURRENCE_MODE_CONTINUOUS模式下,会一直采样填充buffer,取消掉前一个再进行下一个channel的读取
    #ADCBuf_RECURRENCE_MODE_CONTINUOUS conversion can only be terminated using ADCBuf_convertCancel().
  • 那我需要4个channel,那还需要定义8个buf么??
  • 刚接触CC1350,可以说的详细点么
  • 是,类似下面这样:

    /* Configure the conversion struct */
    continuousConversion.arg = NULL;
    continuousConversion.adcChannel = Board_ADCBUF0CHANNEL0;
    continuousConversion.sampleBuffer = sampleBufferOne;
    continuousConversion.sampleBufferTwo = sampleBufferTwo;
    continuousConversion.samplesRequestedCount = ADCBUFFERSIZE;
    
    ....
    
    /* Configure the conversion struct */
    continuousConversion2.arg = NULL;
    continuousConversion2.adcChannel = Board_ADCBUF0CHANNEL1;
    continuousConversion2.sampleBuffer = sampleBufferOne2;
    continuousConversion2.sampleBufferTwo = sampleBufferTwo2;
    continuousConversion2.samplesRequestedCount = ADCBUFFERSIZE;

  • 我根据你的提示更改代码但是读不出数据UART_Params uartParams;
    ADCBuf_Handle adcBuf;
    ADCBuf_Params adcBufParams;
    ADCBuf_Conversion continuousConversion[4];

    /* Call driver init functions */
    ADCBuf_init();
    UART_init();

    /* Create a UART with data processing off. */
    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);

    /* Set up an ADCBuf peripheral in ADCBuf_RECURRENCE_MODE_CONTINUOUS */
    ADCBuf_Params_init(&adcBufParams);
    adcBufParams.callbackFxn = adcBufCallback;
    adcBufParams.recurrenceMode = ADCBuf_RECURRENCE_MODE_CONTINUOUS;
    adcBufParams.returnMode = ADCBuf_RETURN_MODE_CALLBACK;
    adcBufParams.samplingFrequency = 200;
    adcBuf = ADCBuf_open(Board_ADCBUF0, &adcBufParams);



    /* Configure the conversion struct */
    continuousConversion[0].arg = NULL;
    continuousConversion[0].adcChannel = 2;
    continuousConversion[0].sampleBuffer = sampleBufferOne;
    continuousConversion[0].sampleBufferTwo = sampleBufferTwo;
    continuousConversion[0].samplesRequestedCount = ADCBUFFERSIZE/4;


    continuousConversion[1].arg = NULL;
    continuousConversion[1].adcChannel = 3;
    continuousConversion[1].sampleBuffer = sampleBufferOne2;
    continuousConversion[1].sampleBufferTwo = sampleBufferTwo2;
    continuousConversion[1].samplesRequestedCount = ADCBUFFERSIZE/4;




    continuousConversion[2].arg = NULL;
    continuousConversion[2].adcChannel = 4;
    continuousConversion[2].sampleBuffer = sampleBufferOne3;
    continuousConversion[2].sampleBufferTwo = sampleBufferTwo3;
    continuousConversion[2].samplesRequestedCount = ADCBUFFERSIZE/4;



    continuousConversion[3].arg = NULL;
    continuousConversion[3].adcChannel = 5;
    continuousConversion[3].sampleBuffer = sampleBufferOne4;
    continuousConversion[3].sampleBufferTwo = sampleBufferTwo4;
    continuousConversion[3].samplesRequestedCount = ADCBUFFERSIZE/4;

    if (adcBuf == NULL){
    /* ADCBuf failed to open. */
    while(1);
    }

    /* Start converting. */
    if (ADCBuf_convert(adcBuf, &continuousConversion[4], 4) !=
    ADCBuf_STATUS_SUCCESS) {
    /* Did not start conversion process correctly. */
    while(1);
    }

    如果将

    if (ADCBuf_convert(adcBuf, &continuousConversion[4], 4) !=
    ADCBuf_STATUS_SUCCESS) {
    /* Did not start conversion process correctly. */
    while(1);
    }
    中的&continuousConversion[4]改为 &continuousConversion[0]、 &continuousConversion[1]、 &continuousConversion[2]、 &continuousConversion[3]
    均只能读出单个通道的数据
    这是为什么
  • 上文的第二点建议是否采纳?
  • 未进行第二点,具体如何取消掉前一个再进行下一个channel的读取能否具体告知,或贴出代码
  • 我参考了msp432的adcbufmultichannel例程,没有发现其中有你所说的取消掉前一个再进行下一个channel的读取,能够解释一下怎样能够读取多通道么,搞了好久还是只能读取一个通道的数据
  • 我去测一下,可能需要花点时间
  • 麻烦了,万分感谢,希望及时回复

  • 我修改了一下源碼內的while(1)內容如下就可以切換channel了

        while(1) {
            sleep(2);
            UART_write(uart, "channel 1\n ",11);
            ADCBuf_close(adcBuf);
            adcBuf = ADCBuf_open(Board_ADCBUF0, &adcBufParams);
            continuousConversion.adcChannel = Board_ADCBUF0CHANNEL1;
            if (ADCBuf_convert(adcBuf, &continuousConversion, 1) !=
                    ADCBuf_STATUS_SUCCESS) {
                    /* Did not start conversion process correctly. */
                    while(1);
                }
            sleep(2);
            UART_write(uart, "channel 0\n ",11);
            ADCBuf_close(adcBuf);
            adcBuf = ADCBuf_open(Board_ADCBUF0, &adcBufParams);
            continuousConversion.adcChannel = Board_ADCBUF0CHANNEL0;
            if (ADCBuf_convert(adcBuf, &continuousConversion, 1) !=
                    ADCBuf_STATUS_SUCCESS) {
                    /* Did not start conversion process correctly. */
                    while(1);
                }
        }

  • 是cc1350的adcbufcontinous源码么,这个while(1)是文末的while(1)是么,可以贴出完整代码么,麻烦了
  • 是的

    /*
     * Copyright (c) 2015-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    /*
     *  ======== adcBufContinuousSampling.c ========
     */
    #include <stdint.h>
    #include <stdio.h>
    /* For sleep() */
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/ADCBuf.h>
    #include <ti/drivers/UART.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    #define ADCBUFFERSIZE    (50)
    #define UARTBUFFERSIZE   ((20 * ADCBUFFERSIZE) + 24)
    
    uint16_t sampleBufferOne[ADCBUFFERSIZE];
    uint16_t sampleBufferTwo[ADCBUFFERSIZE];
    uint32_t microVoltBuffer[ADCBUFFERSIZE];
    uint32_t buffersCompletedCounter = 0;
    char uartTxBuffer[UARTBUFFERSIZE];
    
    /* Driver handle shared between the task and the callback function */
    UART_Handle uart;
    
    /*
     * This function is called whenever an ADC buffer is full.
     * The content of the buffer is then converted into human-readable format and
     * sent to the PC via UART.
     */
    void adcBufCallback(ADCBuf_Handle handle, ADCBuf_Conversion *conversion,
        void *completedADCBuffer, uint32_t completedChannel)
    {
        uint_fast16_t i;
        uint_fast16_t uartTxBufferOffset = 0;
    
        /* Adjust raw ADC values and convert them to microvolts */
        ADCBuf_adjustRawValues(handle, completedADCBuffer, ADCBUFFERSIZE,
            completedChannel);
        ADCBuf_convertAdjustedToMicroVolts(handle, completedChannel,
            completedADCBuffer, microVoltBuffer, ADCBUFFERSIZE);
    
        /* Start with a header message. */
        uartTxBufferOffset = snprintf(uartTxBuffer,
            UARTBUFFERSIZE - uartTxBufferOffset, "\r\nBuffer %u finished.",
            (unsigned int)buffersCompletedCounter++);
    
        /* Write raw adjusted values to the UART buffer if there is room. */
        uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,
            UARTBUFFERSIZE - uartTxBufferOffset, "\r\nRaw Buffer: ");
    
        for (i = 0; i < ADCBUFFERSIZE && uartTxBufferOffset < UARTBUFFERSIZE; i++) {
            uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,
                UARTBUFFERSIZE - uartTxBufferOffset, "%u,",
            *(((uint16_t *)completedADCBuffer) + i));
        }
    
        /* Write microvolt values to the UART buffer if there is room. */
        if (uartTxBufferOffset < UARTBUFFERSIZE) {
            uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,
                UARTBUFFERSIZE - uartTxBufferOffset, "\r\nMicrovolts: ");
    
            for (i = 0; i < ADCBUFFERSIZE && uartTxBufferOffset < UARTBUFFERSIZE; i++) {
                uartTxBufferOffset += snprintf(uartTxBuffer + uartTxBufferOffset,
                    UARTBUFFERSIZE - uartTxBufferOffset, "%u,",
                    (unsigned int)microVoltBuffer[i]);
            }
        }
    
        /*
         * Ensure we don't write outside the buffer.
         * Append a newline after the data.
         */
        if (uartTxBufferOffset < UARTBUFFERSIZE) {
            uartTxBuffer[uartTxBufferOffset++] = '\n';
        }
        else {
            uartTxBuffer[UARTBUFFERSIZE-1] = '\n';
        }
    
        /* Display the data via UART */
        UART_write(uart, uartTxBuffer, uartTxBufferOffset);
    }
    
    /*
     * Callback function to use the UART in callback mode. It does nothing.
     */
    void uartCallback(UART_Handle handle, void *buf, size_t count) {
       return;
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        UART_Params uartParams;
        ADCBuf_Handle adcBuf;
        ADCBuf_Params adcBufParams;
        ADCBuf_Conversion continuousConversion;
    
        /* Call driver init functions */
        ADCBuf_init();
        UART_init();
    
        /* Create a UART with data processing off. */
        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);
    
        /* Set up an ADCBuf peripheral in ADCBuf_RECURRENCE_MODE_CONTINUOUS */
        ADCBuf_Params_init(&adcBufParams);
        adcBufParams.callbackFxn = adcBufCallback;
        adcBufParams.recurrenceMode = ADCBuf_RECURRENCE_MODE_CONTINUOUS;
        adcBufParams.returnMode = ADCBuf_RETURN_MODE_CALLBACK;
        adcBufParams.samplingFrequency = 200;
        adcBuf = ADCBuf_open(Board_ADCBUF0, &adcBufParams);
    
        /* Configure the conversion struct */
        continuousConversion.arg = NULL;
        continuousConversion.adcChannel = Board_ADCBUF0CHANNEL0;
        continuousConversion.sampleBuffer = sampleBufferOne;
        continuousConversion.sampleBufferTwo = sampleBufferTwo;
        continuousConversion.samplesRequestedCount = ADCBUFFERSIZE;
    
        if (adcBuf == NULL){
            /* ADCBuf failed to open. */
            while(1);
        }
    
        /* Start converting. */
        if (ADCBuf_convert(adcBuf, &continuousConversion, 1) !=
            ADCBuf_STATUS_SUCCESS) {
            /* Did not start conversion process correctly. */
            while(1);
        }
    
        /*
         * Go to sleep in the foreground thread forever. The ADC hardware will
         * perform conversions and invoke the callback function when a buffer is
         * full.
         */
        while(1) {
            sleep(2);
            UART_write(uart, "channel 1\n ",11);
            ADCBuf_close(adcBuf);
            adcBuf = ADCBuf_open(Board_ADCBUF0, &adcBufParams);
            continuousConversion.adcChannel = Board_ADCBUF0CHANNEL1;
            if (ADCBuf_convert(adcBuf, &continuousConversion, 1) !=
                    ADCBuf_STATUS_SUCCESS) {
                    /* Did not start conversion process correctly. */
                    while(1);
                }
            sleep(2);
            UART_write(uart, "channel 0\n ",11);
            ADCBuf_close(adcBuf);
            adcBuf = ADCBuf_open(Board_ADCBUF0, &adcBufParams);
            continuousConversion.adcChannel = Board_ADCBUF0CHANNEL0;
            if (ADCBuf_convert(adcBuf, &continuousConversion, 1) !=
                    ADCBuf_STATUS_SUCCESS) {
                    /* Did not start conversion process correctly. */
                    while(1);
                }
        }
    }
    

  • 你这样改代码只是在关闭以后开启,而不是多通道数据同时转换,实现ADCBuf_convert中定义的多通道同时转换,在msp432中的adcbufmultichannel历程中不是这样实现的,能否解惑为何 /* Configure the conversion struct */
    continuousConversion[0].arg = NULL;
    continuousConversion[0].adcChannel = Board_ADCBUF0CHANNEL0;
    continuousConversion[0].sampleBuffer = sampleBufferOne;
    continuousConversion[0].sampleBufferTwo = sampleBufferTwo;
    continuousConversion[0].samplesRequestedCount = ADCBUFFERSIZE/4;

    continuousConversion[1].arg = NULL;
    continuousConversion[1].adcChannel = Board_ADCBUF0CHANNEL1;
    continuousConversion[1].sampleBuffer = NULL;
    continuousConversion[1].sampleBufferTwo = NULL;
    continuousConversion[1].samplesRequestedCount = ADCBUFFERSIZE/4;






    if (adcBuf == NULL){
    /* ADCBuf failed to open. */
    while(1);
    }

    /* Start converting. */
    if (ADCBuf_convert(adcBuf, continuousConversion, 2) !=
    ADCBuf_STATUS_SUCCESS) {
    /* Did not start conversion process correctly. */
    while(1);
    }
    这个代码为何不能实现
    麻烦了
  • 我不清楚MSP432是怎樣,但是CC1350就只有一個ADC hw,可以接上不同的channel,所以你不可能同時去讀取不同channel的ADC,只能透過切換方式去達成不同channel的讀值
  • /*!
     *  @brief  Starts ADCBuf conversions on one or more channels.
     *
     *  @note When using #ADCBuf_RETURN_MODE_BLOCKING, this must be called from a
     *        thread context.
     *
     *  @param[in]  handle          An ADCBuf handle returned from ADCBuf_open()
     *
     *  @param[in]  conversions     A pointer to an array of #ADCBuf_Conversion
     *                              structures.
     *
     *  @param[in]  channelCount    The number of channels to convert on in this
     *  call. Should be the length of the @p conversions array. Depending on the
     *  device, multiple simultaneous conversions may not be supported. See device
     *  specific implementation.
     *
     *  @retval #ADCBuf_STATUS_SUCCESS  The conversion was successful.
     *  @retval #ADCBuf_STATUS_ERROR    The conversion failed.
     *
     *  @pre    ADCBuf_open() must have been called.
     *
     *  @sa     ADCBuf_convertCancel()
     *  @sa     ADCBuf_Return_Mode
     *  @sa     ADCBuf_Recurrence_Mode
     *  @sa     ADCBuf_Conversion
     */
    extern int_fast16_t ADCBuf_convert(ADCBuf_Handle handle,
                                       ADCBuf_Conversion conversions[],
                                       uint_fast8_t channelCount);

    这是结构体的注释,我没理解错的话是可以实现多通道的转换的,在我的代码里是什么样的问题,只能采集到一路数据呢

  • 同一时刻只支持一路channel采样。而且那个函数里也说了: Depending on the device, multiple simultaneous conversions may not be supported. See device specific implementation.
  • 那请问切换channel时是使用ADCBUF_close关闭再开启新的channel么,切换时需要使用sleep函数来进行延时是么,这个时间大概多久呢

  • 照理說可以直接調用ADCBuf_convert去切換ADC channel、你試試改一下我的程序測試一下就知道了

  • 我已经试过了,ADCBuf_convert切换不了,现在超级闹心,只能读出一路,麻烦您再给试一下,给个解释,麻烦您了
  • 我試著while loop里只留下ADCBuf_convert切換是沒有問題的

  • 您如果切换没有问题能否给出源码,我尝试 只留下ADCBUF_CONVERT,只能得到一个通道的数据,没有成功,时间比较久了,麻烦您再帮忙看一下