TODOPIC
Microcontroladores PIC => dsPIC => Mensaje iniciado por: RemiWish en 20 de Noviembre de 2008, 21:38:57
-
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 memory
A nuestra forma de ver, parece ser que el error es de memoria de datos
Por 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 */
-
¿Puedes pegar también el fichero .GLD que estás usando?
-
¿Puedes pegar también el fichero .GLD que estás usando?
Muchas gracias nocturno por tu interes, a continuacion te adjunto el archivo .GLD que estamos usando
P30F2010.gld
Por cierto, el cristal que estamos trabajando es de 20MHz
-
Veo que en tu programa haces esto:
fractcomplex sigCmpx[FFT_BLOCK_LENGTH]
__attribute__ ((section (".ydata, data, ymemory"),
aligned (FFT_BLOCK_LENGTH * 2 *2))) = {};
pero la sección ydata no está definida en el GLD.
¿Has declarado el array en esa zona de memoria por alguna razón?
En el GLD de un 30F6014 aparece esto referente a esa sección, no sé si te servirá:
/*
** Y Initialized Data
*/
.ydata MAX( (__YDATA_BASE + SIZEOF( .ybss)), ALIGN(2)) :
{
*(.ydata);
} >data
-
Veo que en tu programa haces esto:
fractcomplex sigCmpx[FFT_BLOCK_LENGTH]
__attribute__ ((section (".ydata, data, ymemory"),
aligned (FFT_BLOCK_LENGTH * 2 *2))) = {};
pero la sección ydata no está definida en el GLD.
¿Has declarado el array en esa zona de memoria por alguna razón?
En el GLD de un 30F6014 aparece esto referente a esa sección, no sé si te servirá:
/*
** Y Initialized Data
*/
.ydata MAX( (__YDATA_BASE + SIZEOF( .ybss)), ALIGN(2)) :
{
*(.ydata);
} >data
Hola nocturno..
En efecto revisamos el fichero gld de nuestro dspic y del dspic 30f6014 y no encontramos el segmento de código que nos diste.
Pero ¿por qué? cuando usamos una FFT_BLOCK_LENGTH de 32 si sale, el problema está en la de 64. Aunque en el fichero twiddleFactors.c no estan declarados para una FFT_BLOCK_LENGTH de 32, solo de 64 hasta 512. Nos inventamos los de 32. Pero creo que ese no es el problema....
Igual el programa compila normalmente, no da ningun error, no será en la trnsmisión a través del UART el problema??
Adjuntamos la pantalla que obtenemos luego de la compilacion:
Clean: Deleting intermediary and output files.
Clean: Deleted file "C:\Documents and Settings\Renato Zea\Escritorio\fourier bien\ANALIZADOR DINAMICO\Fourier.o".
Clean: Deleted file "C:\Documents and Settings\Renato Zea\Escritorio\fourier bien\ANALIZADOR DINAMICO\SetChanADC10.o".
Clean: Deleted file "C:\Documents and Settings\Renato Zea\Escritorio\fourier bien\ANALIZADOR DINAMICO\ConfigIntADC10.o".
Clean: Deleted file "C:\Documents and Settings\Renato Zea\Escritorio\fourier bien\ANALIZADOR DINAMICO\ConvertADC10.o".
Clean: Deleted file "C:\Documents and Settings\Renato Zea\Escritorio\fourier bien\ANALIZADOR DINAMICO\OpenADC10.o".
Clean: Deleted file "C:\Documents and Settings\Renato Zea\Escritorio\fourier bien\ANALIZADOR DINAMICO\ReadADC10.o".
Clean: Deleted file "C:\Documents and Settings\Renato Zea\Escritorio\fourier bien\ANALIZADOR DINAMICO\BusyADC10.o".
Clean: Deleted file "C:\Documents and Settings\Renato Zea\Escritorio\fourier bien\ANALIZADOR DINAMICO\twiddleFactors.o".
Clean: Deleted file "C:\Documents and Settings\Renato Zea\Escritorio\fourier bien\ANALIZADOR DINAMICO\Fourier.cof".
Clean: Deleted file "C:\Documents and Settings\Renato Zea\Escritorio\fourier bien\ANALIZADOR DINAMICO\Fourier.hex".
Clean: Done.
Executing: "C:\Archivos de programa\Microchip\MPLAB C30\bin\pic30-gcc.exe" -mcpu=30F2010 -x c -c "Fourier.c" -o"Fourier.o" -g -Wall -mlarge-data -msmall-scalar
Fourier.c: In function 'main':
Fourier.c:249: warning: control reaches end of non-void function
Fourier.c:249:20: warning: no newline at end of file
Executing: "C:\Archivos de programa\Microchip\MPLAB C30\bin\pic30-gcc.exe" -mcpu=30F2010 -x c -c "C:\Archivos de programa\Microchip\MPLAB C30\src\peripheral_30F_24H_33F\src\pmc\adc\SetChanADC10.c" -o"SetChanADC10.o" -g -Wall -mlarge-data -msmall-scalar
Executing: "C:\Archivos de programa\Microchip\MPLAB C30\bin\pic30-gcc.exe" -mcpu=30F2010 -x c -c "C:\Archivos de programa\Microchip\MPLAB C30\src\peripheral_30F_24H_33F\src\pmc\adc\ConfigIntADC10.c" -o"ConfigIntADC10.o" -g -Wall -mlarge-data -msmall-scalar
Executing: "C:\Archivos de programa\Microchip\MPLAB C30\bin\pic30-gcc.exe" -mcpu=30F2010 -x c -c "C:\Archivos de programa\Microchip\MPLAB C30\src\peripheral_30F_24H_33F\src\pmc\adc\ConvertADC10.c" -o"ConvertADC10.o" -g -Wall -mlarge-data -msmall-scalar
Executing: "C:\Archivos de programa\Microchip\MPLAB C30\bin\pic30-gcc.exe" -mcpu=30F2010 -x c -c "C:\Archivos de programa\Microchip\MPLAB C30\src\peripheral_30F_24H_33F\src\pmc\adc\OpenADC10.c" -o"OpenADC10.o" -g -Wall -mlarge-data -msmall-scalar
Executing: "C:\Archivos de programa\Microchip\MPLAB C30\bin\pic30-gcc.exe" -mcpu=30F2010 -x c -c "C:\Archivos de programa\Microchip\MPLAB C30\src\peripheral_30F_24H_33F\src\pmc\adc\ReadADC10.c" -o"ReadADC10.o" -g -Wall -mlarge-data -msmall-scalar
Executing: "C:\Archivos de programa\Microchip\MPLAB C30\bin\pic30-gcc.exe" -mcpu=30F2010 -x c -c "C:\Archivos de programa\Microchip\MPLAB C30\src\peripheral_30F_24H_33F\src\pmc\adc\BusyADC10.c" -o"BusyADC10.o" -g -Wall -mlarge-data -msmall-scalar
Executing: "C:\Archivos de programa\Microchip\MPLAB C30\bin\pic30-gcc.exe" -mcpu=30F2010 -x c -c "twiddleFactors.c" -o"twiddleFactors.o" -g -Wall -mlarge-data -msmall-scalar
twiddleFactors.c:58: warning: missing braces around initializer
twiddleFactors.c:58: warning: (near initialization for 'twiddleFactors[0]')
Executing: "C:\Archivos de programa\Microchip\MPLAB C30\bin\pic30-gcc.exe" -mcpu=30F2010 "Fourier.o" "SetChanADC10.o" "ConfigIntADC10.o" "ConvertADC10.o" "OpenADC10.o" "ReadADC10.o" "BusyADC10.o" "twiddleFactors.o" "C:\Archivos de programa\Microchip\MPLAB C30\lib\libp30F2010-coff.a" "C:\Archivos de programa\Microchip\MPLAB C30\lib\libp30F2010-elf.a" "C:\Archivos de programa\Microchip\MPLAB C30\lib\libdsp-coff.a" -o"Fourier.cof" -Wl,-L"C:\Archivos de programa\Microchip\MPLAB C30\lib",--script="C:\Archivos de programa\Microchip\MPLAB C30\support\gld\p30f2010.gld",-Map="Fourier.map",--report-mem
Program Memory Usage
section address length (PC units) length (bytes) (dec)
------- ------- ----------------- --------------------
.reset 0 0x4 0x6 (6)
.ivt 0x4 0x7c 0xba (186)
.aivt 0x84 0x7c 0xba (186)
.text 0x100 0x3aa 0x57f (1407)
.isr 0x4aa 0x2 0x3 (3)
.const 0x500 0x80 0xc0 (192)
.dinit 0x580 0xc2 0x123 (291)
__FOSC 0xf80000 0x2 0x3 (3)
__FWDT 0xf80002 0x2 0x3 (3)
__FBORPOR 0xf80004 0x2 0x3 (3)
__FGS 0xf8000a 0x2 0x3 (3)
Total program memory used (bytes): 0x8eb (2283) 18%
Data Memory Usage
section address alignment gaps total length (dec)
------- ------- -------------- -------------------
.nbss 0x800 0 0x1c (28)
.ndata 0x81c 0 0x2 (2)
.ydata 0x900 0 0x100 (256)
Total data memory used (bytes): 0x11e (286) 55%
Dynamic Memory Usage
region address maximum length (dec)
------ ------- ---------------------
heap 0 0 (0)
stack 0x81e 0xe2 (226)
Maximum dynamic memory (bytes): 0xe2 (226)
Executing: "C:\Archivos de programa\Microchip\MPLAB C30\bin\pic30-bin2hex.exe" "C:\Documents and Settings\Renato Zea\Escritorio\fourier bien\ANALIZADOR DINAMICO\Fourier.cof"
Loaded C:\Documents and Settings\Renato Zea\Escritorio\fourier bien\ANALIZADOR DINAMICO\Fourier.cof.
BUILD SUCCEEDED: Fri Nov 21 12:29:46 2008