在不使用多线程的情况下在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切換是沒有問題的