Good evening,
My group and I are working on a project using the TIVA C Series TM4C123GLaunchPad for our university that consist in the following:
- Configuring the signal from an electret microphone to the ADC, using analogic steps such as AGC. This step is completely done, giving as a result a perfectly defined signal between 0V and 3.0V at the ADC input, with a bandwith between 200Hz and 4KHz.
- Sampling the voice signal with the microcontroller.
- Sending the data to the UART and receiving it with MATLAB.
In step 2 is where our problems begin. We tested the code with a function generator, using senoidal signals between 200 Hz and 4KHz. MATLAB graphs show strange results, since for some frecuencies it displays a correct waveform, but for others they are just nonesense. But that's not our answer. The fact is, we are not getting the samples we actually need. We are getting around 40 samples when we need at least 20K samples for a correct voice sampling. It's like our program works extremely 'slow' and we don't know where are we making a mistake.
For instance, we worked on the idea of storing those ADC samples in a vector and then when the ADC process is complete, send them to the UART, but we actually don't know quite how to do it. What we like to do is to set a time to the ADC to 'listen' and then display the waveform the best it can.
Also, we are asking for some details about how the ADC works, since we read a lot of datasheets but we couldn't realise very well how it works and when do we must read the convertion results.
Our code (made in CCS v5) looks like the following:
************************************************************************************************************************************************
************************************************************************************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/debug.h"
#include "driverlib/sysctl.h"
#include "driverlib/adc.h"
#include "driverlib/gpio.h"
#include "driverlib/uart.h"
int main(void)
{
uint32_t ui32ADC0Value[4]; // Variable for getting ADC values.
volatile uint32_t ui32VoiceSample[4]; // Variable for storing ADC0 FIFO values.
uint8_t i = 0; // Loop counter controller.
volatile uint8_t flag = 0; // Flag counter controller.
volatile uint8_t counter = 0; // Timing counter controller.
char d[4]; // Character array for storing ADC Data for TX.
SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ); // Clock Configuration.
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // Enable Port A Peripheral.
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // Enable Port E Peripheral.
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // Enable Port F Peripheral.
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); // LED's as outputs.
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4); // Switch 1 as input.
GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4, GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU); // Pull-up for Switch 1.
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // Enable UART0 Peripheral.
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); // UART0 Configuration.
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // PA0 as UART0RX & PA1 as UART0TX.
UARTFIFOEnable(UART0_BASE); // UART0 FIFO Buffer Enable
UARTEnable(UART0_BASE); // Enable UART0.
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_5); // Pin PE5 as ADC input (CH8).
GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_5,GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); // Pull-up for ADC input.
SysCtlADCSpeedSet(SYSCTL_ADCSPEED_1MSPS); // Define ADC Sample Rate as 1MSPS.
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); // Enable ADC0.
ADCHardwareOversampleConfigure(ADC0_BASE,64); // Hardware Oversampling Configuration.
ADCSequenceDisable(ADC0_BASE, 0); // Disable ADC0 before setting it.
ADCReferenceSet(ADC0_BASE,ADC_REF_INT); // Set internal reference as 3V.
ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0); // Sequence Sampling as 1 (SS1).
ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH8); // Reads from CH8.
ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH8); // Reads from CH8.
ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH8); // Reads from CH8.
ADCSequenceStepConfigure(ADC0_BASE, 1, 3, ADC_CTL_CH8|ADC_CTL_IE|ADC_CTL_END); // Reads from CH8 as the last sequence.
ADCSequenceEnable(ADC0_BASE, 1); // Enable ADC0.
while(1)
{
if (GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4) == 0x00) // When SW1 is pressed, the program begins.
{
flag = 1;
counter = 0;
}
if(flag == 0)
{
}
else // Sampling begins.
{
ADCIntClear(ADC0_BASE, 1); // Clear ADC0 Interrupt.
ADCProcessorTrigger(ADC0_BASE, 1); // Trigger ADC Convertion.
while(!ADCIntStatus(ADC0_BASE, 1, false))
{
}
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 8); // Green LED indicates that the ADC is ACTIVE.
ADCSequenceDataGet(ADC0_BASE,1 , ui32ADC0Value); // Grab the entire FIFO.
for (i = 0; i < 4; i++)
{
ui32VoiceSample[i] = ui32ADC0Value[i]; // Stores the FIFO into the variable.
}
for (i = 0; i < 4; i++)
{
a[3] = ui32VoiceSample[i]%10 + 48; // Convert the first 8 bits to char.
ui32VoiceSample[i] = ui32VoiceSample[i]/10 ;
a[2] = ui32VoiceSample[i]%10 + 48; // Convert the second 8 bits to char.
ui32VoiceSample[i] = ui32VoiceSample[i]/10 ;
a[1] = ui32VoiceSample[i]%10 + 48; // Convert the third 8 bits to char.
a[0] = ui32VoiceSample[i]/10 + 48; // Convert the fourth 8 bits to char.
UARTCharPutNonBlocking(UART0_BASE, d[0]); // Send first character.
UARTCharPutNonBlocking(UART0_BASE, d[1]); // Send second character.
UARTCharPutNonBlocking(UART0_BASE, d[2]); // Send third character.
UARTCharPutNonBlocking(UART0_BASE, d[3]); // Send fourth character.
UARTCharPutNonBlocking(UART0_BASE, '\n'); // Send new line character.
SysCtlDelay(2000000); // System delay.
}
counter ++; // Increment counter.
if(counter == 100) // Counter controls the time the ADC is "listening".
{
flag = 0;
}
}
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0x00); // Green LED OFF indicates that the program is complete.
}
}
*************************************************************************************************************************************************
*************************************************************************************************************************************************
And our MATLAB scripts looks like the following:
*************************************************************************************************************************************************
*************************************************************************************************************************************************
function Version_2_8(samples)
close all;
clc;
result = (0);
delete (instrfind({'port'},{'COM4'}));
port = serial('COM4');
port.BaudRate = 115200;
fopen(port);
counter = 1;
while counter <= samples
ylim ([0 5.1]);
xlim ([0 salmples]);
ADCvalue = fscanf(port,'%d')';
result(counter) = ADCvalue(1);
stem(result);
drawnow;
counter = counter + 1;
end;
fclose (port);
delete (port);
clear all;
*****************************************************************************************************************
*****************************************************************************************************************
We aprecciate any kind of help or advise, since we are quite new in this topics and we want to learn as much as we can about it. Thank you very much for your time.