在不使用多线程的情况下在buffer模式下能否实现多通道采集
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.
多线程跟ADC多通道无关,不论是单通道采集还是多通道采集,都是一个线程。推荐看一下这边的例程:http://dev.ti.com/tirex/explore/node?node=AC.rsUKsVvdCiKwydCQGYg__eCfARaV__LATEST
是,类似下面这样:
/* 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;
我修改了一下源碼內的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); } }
是的
/* * 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); } } }
/*!
* @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时是使用ADCBUF_close关闭再开启新的channel么,切换时需要使用sleep函数来进行延时是么,这个时间大概多久呢
照理說可以直接調用ADCBuf_convert去切換ADC channel、你試試改一下我的程序測試一下就知道了
我試著while loop里只留下ADCBuf_convert切換是沒有問題的