Hola amigos, felicitaciones por el foro, me ha servido mucho para desarrollar mi proyecto de titulo.
Les comento que estoy tratando de realizar la FFt de una señal, la cual ingresa por el ADC del mismo dsPIC (30F2010) y transmitirla a un PIC (16F876A) via RS232, sin embargo tengo algunos inconvenientes con el proceso de transformacion, el objetivo es trabajar con un FFT_BLOCK_LENGTH de 256 o en su defecto de 128.
Hemos realizado y transmitido satisfactoriamente la FFT con un FFT_BLOCK_LENGTH de 32
, pero debido a la pobre resolucion tratamos de incrementar a 64,
la compilacion se realiza sin ningun problema pero al hacer las pruebas nos damos cuenta que el uart no transmite nada, se queda en estado alto.
Si intentamos con un FFT_BLOCK_LENGTH de 128 o 256 obtenemos el error:
Fourier.o: Link Error: Could not allocate section .ydata, size = 512 bytes, attributes = data ymemory
Link Error: Could not allocate data memoryA nuestra forma de ver, parece ser que el error es de memoria de datosPor favor nos seria de mucha ayuda que nos aporten con sus ideas y comentarios, a continuacion presentamos el programa que estamos utilizando, con sus respectivos archivos adjuntos.
PROGRAMA PRINCIPAL//INICIALIZACION DE PROGRAMA
#include <p30F2010.h>
#include <adc10.h>
//#include <stdio.h>
#include <dsp.h>
//#include <math.h>
#include <fft.h>
#include <uart.h>
_FOSC(CSW_FSCM_OFF & HS);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_OFF & MCLR_EN);
_FGS(CODE_PROT_OFF);
// Select the desired system clock speed here
#define THE_CLOCK_SPEED 20000000.0
//#define Fcy THE_CLOCK_SPEED / 4
//#define THE_I2C_BAUD_RATE 100000.0 // 100 KHz no slew
//#define Idle() {_asm_ volatile ("pwrsav #1");}
#define _PSVPAGE(n) __builtin_psvpage(n)
#define Etapas_filtro 1 //Se define el numero de etapas del filtro
fractcomplex sigCmpx[FFT_BLOCK_LENGTH]
__attribute__ ((section (".ydata, data, ymemory"),
aligned (FFT_BLOCK_LENGTH * 2 *2))) = {};
/* Global Definitions */
#ifndef FFTTWIDCOEFFS_IN_PROGMEM
fractcomplex twiddleFactors[FFT_BLOCK_LENGTH/2] /* Declare Twiddle Factor array in X-space*/
__attribute__ ((section (".xbss, bss, xmemory"), aligned (FFT_BLOCK_LENGTH*2)));
#else
extern const fractcomplex twiddleFactors[FFT_BLOCK_LENGTH/2] /* Twiddle Factor array in Program memory */
__attribute__ ((space(auto_psv), aligned (FFT_BLOCK_LENGTH*2)));
#endif
//DEFINICION DE VARIABLES
unsigned int canal, config_puerto, scanselect, adcon3_reg, adcon2_reg, adcon1_reg;
unsigned int baud, uartmode, uartsta;
unsigned int digital;
int cont = 0;
int desplazar;
fractional dato_fft;
fractional numero_x_k;
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
/// subrutinas ///
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
////////SUBRUTINA DE RETRASO/////
unsigned int temp_count;
void delay_ms(unsigned int delay_count)
{
temp_count = delay_count +1;
asm volatile("outer: dec _temp_count");
asm volatile("cp0 _temp_count");
asm volatile("bra z, done");
asm volatile("do #2495, inner" );
asm volatile("nop");
asm volatile("inner: nop");
asm volatile("bra outer");
asm volatile("done:");
}
void delay_us(unsigned int delayUs_count)
{
temp_count = delayUs_count +1;
asm volatile("outer1: dec _temp_count");
asm volatile("cp0 _temp_count");
asm volatile("bra z, done1");
asm volatile("do #245, inner1" );
asm volatile("nop");
asm volatile("inner1: nop");
asm volatile("bra outer1");
asm volatile("done1:");
}
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
/// PROGRAMA PRINCIPAL ///
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
int main (void)
{
/*CONFIGURACION UART1*/
//===================================================================================================
baud = 32; //9600 baudios para cristal de 7.3728 MHz con PLL x16....32 para cristal de 20 MHz.
uartmode = UART_EN &
UART_IDLE_CON &
UART_DIS_WAKE &
UART_DIS_LOOPBACK &
UART_DIS_ABAUD &
UART_NO_PAR_8BIT &
UART_1STOPBIT;
uartsta = UART_INT_TX_BUF_EMPTY & UART_TX_PIN_NORMAL & UART_TX_ENABLE & UART_ADR_DETECT_DIS;
OpenUART1(uartmode,uartsta,baud);
/*CONFIGURACION ADC*/
//===================================================================================================
ADCON1bits.ADON = 0;
canal = ADC_CH0_POS_SAMPLEA_AN0 &
ADC_CH0_NEG_SAMPLEA_NVREF &
ADC_CH0_POS_SAMPLEB_AN0 &
ADC_CH0_NEG_SAMPLEB_NVREF;
SetChanADC10(canal);
ConfigIntADC10(ADC_INT_DISABLE);
config_puerto = ENABLE_ALL_ANA;
scanselect = SCAN_NONE;
adcon3_reg = ADC_SAMPLE_TIME_1 &
ADC_CONV_CLK_INTERNAL_RC &
ADC_CONV_CLK_Tcy;
adcon2_reg = ADC_VREF_AVDD_AVSS &
ADC_SCAN_OFF &
ADC_CONVERT_CH0 &
ADC_SAMPLES_PER_INT_1 &
ADC_ALT_BUF_OFF &
ADC_ALT_INPUT_OFF;
adcon1_reg = ADC_MODULE_OFF &
ADC_IDLE_CONTINUE &
ADC_FORMAT_INTG &
ADC_CLK_AUTO &
ADC_SAMPLE_INDIVIDUAL &
ADC_AUTO_SAMPLING_ON;
OpenADC10(adcon1_reg, adcon2_reg, adcon3_reg, config_puerto, scanselect);
ADCON1bits.ADON = 1;
//==================================================================================================
#ifndef FFTTWIDCOEFFS_IN_PROGMEM /* Generate TwiddleFactor Coefficients */
TwidFactorInit (LOG2_BLOCK_LENGTH, &twiddleFactors[0], 0); /* We need to do this only once at start-up */
#endif
while (cont <= FFT_BLOCK_LENGTH)
{
ConvertADC10();
// delay_ms(100);
while(BusyADC10());
digital = ReadADC10(0);
delay_us(100);
if (digital >= 0x01FF)
{
numero_x_k = (digital - 0x01FF)*0x40;
}
else
{
numero_x_k = (0x01FF - digital)*(-0x40);
}
sigCmpx[cont].real = numero_x_k;
sigCmpx[cont].imag = 0x0000;
cont++;
}
//***************************************************************************
//***************************************************************************
/* Perform FFT operation */
#ifndef FFTTWIDCOEFFS_IN_PROGMEM
FFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx[0], &twiddleFactors[0], COEFFS_IN_DATA);
#else
FFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx[0], (fractcomplex *) __builtin_psvoffset(&twiddleFactors[0]), (int) __builtin_psvpage(&twiddleFactors[0]));
#endif
/* Store output samples in bit-reversed order of their addresses */
BitReverseComplex (LOG2_BLOCK_LENGTH, &sigCmpx[0]);
/* Compute the square magnitude of the complex FFT output array so we have a Real output vetor */
//SquareMagnitudeCplx(FFT_BLOCK_LENGTH, &sigCmpx[0], &sigCmpx[0].real);
cont = 0;
while (cont <= FFT_BLOCK_LENGTH)
{
if (sigCmpx[cont].real <= 0x7FFF)
{
dato_fft = sigCmpx[cont].real/0x40 + 0x01FF;
desplazar = dato_fft>>2;
}
else
{
dato_fft = 0x01FF - ( (0xFFFF - sigCmpx[cont].real - 1)/0x40);
desplazar = dato_fft>>2;
}
if (desplazar == 0x007F)
{
desplazar = 0;
}
//putsUART1(desplazar);
WriteUART1(sigCmpx[cont].real);
while (BusyUART1());
cont++;
}
CloseUART1();
//while (1); /* Place a breakpoint here and observe the watch window variables */
}//FIN DEL PROGRAMA
FFT.h/* Constant Definitions */
#define FFT_BLOCK_LENGTH 64 /* = Number of frequency points in the FFT */
#define LOG2_BLOCK_LENGTH 6 /* = Number of "Butterfly" Stages in FFT processing */
#define SAMPLING_RATE 100 /* = Rate at which input signal was sampled */
/* SAMPLING_RATE is used to calculate the frequency*/
/* of the largest element in the FFT output vector*/
#define FFTTWIDCOEFFS_IN_PROGMEM /*<---Comment out this line of the code if twiddle factors (coefficients) */
/*reside in data memory (RAM) as opposed to Program Memory */
/*Then remove the call to "TwidFactorInit()" and add the twiddle factor*/
/*coefficient file into your Project. An example file for a 256-pt FFT*/
/*is provided in this Code example */