工具与软件:
我将把一个设计从 SDK 6.10.0.29移植到8.30.1.01。 ADCBuf 驱动程序出现问题。
我将在单次模式下使用它、以10 kHz 的频率每20秒左右采集400个样本。 这在 SDK 6.10领域非常有用、但现在对 ADCBuf_convert 的调用在经过一到两次调用后失败、返回代码变为-1。
为了便于演示、我更改了 adcbuffcontinuous 示例、以显示相同的行为。
为了进行演示、只需加载 adcbuContinuous 示例、并将 adcBufContinuousSampling.c 中的代码替换为以下代码。
您将注意到、在几个周期内、行168处的 ADCBuf_convert 调用将起作用、但它最终将在行171处进行捕获。 我无法看出为什么会发生这种情况。 有什么想法?
/* * Copyright (c) 2015-2024, 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> #include <mqueue.h> /* Driver Header files */ #include <ti/drivers/ADCBuf.h> /* Display Header files */ #include <ti/display/Display.h> /* Driver configuration */ #include "ti_drivers_config.h" #define ADCSAMPLESIZE (400) #define MAX_QUEUED_ADC_CONVERSIONS (4) #define QUEUED_ADC_MESSAGE_SIZE (sizeof(uint32_t) * ADCSAMPLESIZE) uint16_t sampleBufferOne[ADCSAMPLESIZE]; uint16_t sampleBufferTwo[ADCSAMPLESIZE]; uint32_t microVoltBuffer[ADCSAMPLESIZE]; uint32_t outputBuffer[ADCSAMPLESIZE]; uint32_t buffersCompletedCounter = 0; /* Display Driver Handle */ Display_Handle displayHandle; /* Used to pass ADC data between callback and main task */ static mqd_t queueReceive; static mqd_t queueSend; /* * 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 main thread. */ void adcBufCallback(ADCBuf_Handle handle, ADCBuf_Conversion *conversion, void *completedADCBuffer, uint32_t completedChannel, int_fast16_t status) { /* Adjust raw ADC values and convert them to microvolts */ ADCBuf_adjustRawValues(handle, completedADCBuffer, ADCSAMPLESIZE, completedChannel); ADCBuf_convertAdjustedToMicroVolts(handle, completedChannel, completedADCBuffer, microVoltBuffer, ADCSAMPLESIZE); /* Send ADC data to main thread using message queue */ mq_send(queueSend, (char *)microVoltBuffer, QUEUED_ADC_MESSAGE_SIZE, 0); } /* * ======== mainThread ======== */ void *mainThread(void *arg0) { Display_Params displayParams; ADCBuf_Handle adcBuf; ADCBuf_Params adcBufParams; ADCBuf_Conversion continuousConversion; ADCBuf_Conversion Conversion; struct mq_attr attr; uint32_t average; uint_fast16_t i = 0; /* Create RTOS Queue */ attr.mq_flags = 0; attr.mq_maxmsg = MAX_QUEUED_ADC_CONVERSIONS; attr.mq_msgsize = QUEUED_ADC_MESSAGE_SIZE; attr.mq_curmsgs = 0; queueReceive = mq_open("ADCBuf", O_RDWR | O_CREAT, 0664, &attr); queueSend = mq_open("ADCBuf", O_RDWR | O_CREAT | O_NONBLOCK, 0664, &attr); if ((queueReceive == (mqd_t)-1) || (queueSend == (mqd_t)-1)) { /* Failed to open message queue */ while (1) {} } /* Call driver init functions */ ADCBuf_init(); Display_init(); /* Configure & open Display driver */ Display_Params_init(&displayParams); displayParams.lineClearMode = DISPLAY_CLEAR_BOTH; displayHandle = Display_open(Display_Type_UART, &displayParams); if (displayHandle == NULL) { Display_printf(displayHandle, 0, 0, "Error creating displayHandle\n"); while (1) {} } Display_printf(displayHandle, 0, 0, "Starting the ADCBufContinuous example"); // /* 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 = 1000; // adcBuf = ADCBuf_open(CONFIG_ADCBUF_0, &adcBufParams); // /* Configure the conversion struct */ // continuousConversion.arg = NULL; // continuousConversion.adcChannel = CONFIG_ADCBUF_0_CHANNEL_0; // continuousConversion.sampleBuffer = sampleBufferOne; // continuousConversion.sampleBufferTwo = sampleBufferTwo; // continuousConversion.samplesRequestedCount = ADCSAMPLESIZE; while(1) { /* Set up an ADCBuf peripheral in ADCBuf_RECURRENCE_MODE_ONE_SHOT */ ADCBuf_Params_init(&adcBufParams); adcBufParams.callbackFxn = NULL; adcBufParams.recurrenceMode = ADCBuf_RECURRENCE_MODE_ONE_SHOT; adcBufParams.returnMode = ADCBuf_RETURN_MODE_BLOCKING; adcBufParams.samplingFrequency = 10000; adcBuf = ADCBuf_open(CONFIG_ADCBUF_0, &adcBufParams); /* Configure the conversion struct */ Conversion.arg = NULL; Conversion.adcChannel = CONFIG_ADCBUF_0_CHANNEL_0; Conversion.sampleBuffer = sampleBufferOne; Conversion.sampleBufferTwo = NULL; Conversion.samplesRequestedCount = ADCSAMPLESIZE; if (adcBuf == NULL) { /* ADCBuf failed to open. */ while (1) {} } /* Start converting. */ if (ADCBuf_convert(adcBuf, &Conversion, 1) != ADCBuf_STATUS_SUCCESS) { /* Did not start conversion process correctly. */ while (1) {} } /* Adjust raw ADC values and convert them to microvolts */ ADCBuf_adjustRawValues(adcBuf, sampleBufferOne, ADCSAMPLESIZE, CONFIG_ADCBUF_0_CHANNEL_0); ADCBuf_convertAdjustedToMicroVolts(adcBuf, CONFIG_ADCBUF_0_CHANNEL_0, sampleBufferOne, (uint32_t*)outputBuffer, ADCSAMPLESIZE); ADCBuf_close(adcBuf); } /* * Wait for the message queue to receive ADC data from the callback * function. When data is received, calculate the average and print to UART */ while (1) { if (mq_receive(queueReceive, (char *)outputBuffer, QUEUED_ADC_MESSAGE_SIZE, NULL) == -1) { Display_printf(displayHandle, 0, 0, "Error receiving ADC message"); while (1) {} } Display_printf(displayHandle, 0, 0, "Buffer %u finished:", (unsigned int)buffersCompletedCounter++); /* Calculate average ADC data value in uV */ average = 0; for (i = 0; i < ADCSAMPLESIZE; i++) { average += outputBuffer[i]; } average = average / ADCSAMPLESIZE; /* Print average ADCBuf value */ Display_printf(displayHandle, 0, 0, " Average: %u uV", average); } }