Red de conocimiento informático - Material del sitio web - Cómo utilizar el microcontrolador 51 para realizar la visualización del espectro de señales de audio (que se muestran en la pantalla LCD)

Cómo utilizar el microcontrolador 51 para realizar la visualización del espectro de señales de audio (que se muestran en la pantalla LCD)

Es algo difícil hacer FFT con 51. Puede utilizar la máquina 51 mejorada (RAM) como programa de referencia: #includelt;

#define uchar unsigned char;

#define uint unsigned int

#define canal 0x01 //Establece el canal AD en P1.1

//-------- ----- --------------------------------------------- ----- ------bit SDA_R=P1^2;

bit SDA_R_TOP=P1^3

bit SDA_G=P1^4;

bit SDA_G_TOP =P1^5

bit STCP=P1^6;

bit SHCP=P1^7; ----- --------------------------------------------- ----- ----------

//-------------------- ------ -------------------------------------------- ------ -------------------------------------------- ---

//Ampliar 128 veces La tabla de enteros sin (128) después de , 80, 85, 89, 94, 98, 102, 105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126, 126, 126, 126, 125, 124, 123, 121, 119, 117, 114, 112, 108, 105, 102, 98, 94, 89, 85, 80, 75, 70, 65, 59, 54, 48, 42, 36, 30, 24, 18, 12, 6, 0, -6, -12, -18, -24, -30, -36, -42, -48, -54, -59, -65, -70, -75, -80, -85, -89, -94, -98, -102, -105, -108, -112, -114, -117, -119 , -121, -123, -124, -125, -126, -126, -126, - 126, -126, -125, -124, -123, -121, -119, -117, -114, - 112, -108, -105, -102, -98, -94, -89, -85, -80, -75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6};//Después de ampliar 128 veces la tabla de enteros cos (128)

código char COS_TAB[128] = { 127, 126, 126

, 125, 124, 123, 121, 119, 117, 114, 112, 108, 105, 102, 98, 94, 89, 85, 80, 75, 70, 65, 59, 54, 48, 42, 36, 30 , 24, 18, 12, 6, 0, -6, -12, -18, -24, -30, -36, -42, -48, -54, -59, -65, -70, -75, -80, -85, -89, -94, -98, -102, -105, -108, -112, -114, -117, -119, -121, -123, -124, -125, -126 , -126, -126, -126, -126, -125, -124, -123, -121, -119, -117, -114, -112, -108, -105, -102, -98, - 94, -89, -85, -80, -75, -70, -65, -59, -54, -48, -42, -36, -30, -24, -18, -12, -6, 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 59, 65, 70, 75, 80, 85, 89, 94, 98, 102, 105, 108, 112, 114, 117, 119, 121, 123, 124, 125, 126, 126};//Lista de secuencias de almacenamiento de muestreo

código char LIST_TAB[128] = {0, 64, 32, 96, 16, 80, 48, 112,

8, 72, 40, 104, 24, 88, 56, 120,

4, 68, 36, 100, 20, 84, 52, 116,

p>

12, 76, 44, 108, 28, 92, 60, 124,

2, 66, 34, 98, 18, 82, 50, 114,

10, 74, 42, 106, 26, 90, 58, 122,

6, 70, 38, 102, 22, 86, 54, 118,

14, 78 , 46, 110, 30, 94, 62, 126,

1, 65, 33, 97, 17, 81, 49, 113,

9, 73, 41, 105 , 25, 89, 57, 121,

5, 69, 37, 101, 21, 85, 53, 117,

13, 77, 45, 109, 29, 93 , 61, 125,

3, 67, 35, 99, 19, 83, 51, 115,

11, 75, 43, 107, 27, 91, 59, 123 ,

7, 71, 39, 103, 23, 87, 55, 119,

15, 79, 47, 111, 31, 95, 63, 127

};

uchar COUNT=0, COUNT1=0, ADC_Count=0, LINE=15, G, T;

uchar i, j, k, b, p

int Temp_Real,Tem

p_Imag, temp; // Variable temporal intermedia

uint TEMP1;

int xdata Fft_Real[128]

int xdata Fft_Image[128]; parte imaginaria

uchar xdata LED_TAB2[64]; //Registra si el flotador necesita pausar

uchar xdata LED_TAB[64] //Registra la columna roja

uchar xdata LED_TAB1[64]; //Registrar puntos flotantes

void Delay(uint a)

{

while(a--);

}void FFT()

{ //uchar X;

for( i=1; ilt;=7; i ) /* for(1) */

{

b=1;

b lt; = (i-1); ¿Cuántas filas se calculan? Por ejemplo, se calculan las filas 1 y 2 del primer polo, y el segundo nivel

for(j=0; jlt;=b-1; j) /* for (2). ) */

{

p=1;

p lt; p*j;

p>

for( k=j; klt; 128; k=k 2*b) /* para (3) base dos fft */

{

Temp_Real = Fft_Real[k]; Temp_Imag = Fft_Image[k]; temp = Fft_Real[k b]

Fft_Real[k] = Fft_Real[k] ((Fft_Real[k b]* COS_TAB[p])gt; gt ;7) ((Fft_Image[k b]*SIN_TAB[p])gt;gt;7);

Fft_Image[k] = Fft_Image[k] - ((Fft_Real [k b]*SIN_TAB[p] )gt;gt;7) ((Fft_Image[k b]*COS_TAB[p])gt;gt;7);

Fft_Real[k b] = Temp_Real - (( Fft_Real[k b]*COS_TAB[p ])gt;gt;7) - ((Fft_Image[k b]*SIN_TAB[p])gt;gt;7);

Fft_Image[k b] = Temp_Imag ((temp*SIN_TAB[p])gt;gt;7) - ((Fft_Image[k b]*COS_TAB[p])gt;gt;7

// Shift. Evita el desbordamiento. El resultado ya es 1/64 del valor original

Fft_Real[k] gt; 1 ;

Fft_Real[k b] gt;

Fft_Image[k b] gt;

}

}

// X=((((Fft_Real[1]* Fft_Real[1])) ((Fft_Image[1]*Fft_Image[1]) ) )gt; gt; 7);

Fft_Real[0]=Fft_Image[0]=0; //Eliminar el componente DC

// Fft_Real[63]=Fft_Image[ 63] =0;

for(j=0;jlt;64;j )

{

TEMP1=((((Fft_Real[j]* Fft_Real[ j])) ((Fft_Image[j]*Fft_Image[j])))gt;gt;1);//Encuentra la potencia

if(TEMP1gt;1)TEMP1--;

else TEMP1=0;

if(TEMP1gt;31)TEMP1=31;

if(TEMP1gt;(LED_TAB[j]))LED_TAB[j] =TEMP1;

if(TEMP1gt; (LED_TAB1[j]))

{ LED_TAB1[j]=TEMP1

LED_TAB2[j]=18; //Velocidad de cuadro de aviso=12

}

}

}void Init()

{

//- ----------------------------------------------- --- --------------------------------

P1ASF = 0x02; //0000, 0010, P1.1 se configurará como puerto analógico

AUXR1 amp;=0xFB; //1111, 1011, configure ADRJ=0

EADC=1; activado

ADC_CONTR = ADC_POWER | ADC_SPEEDHH | ADC_START |

//1110 1001 1 Encienda la fuente de alimentación de conversión A/D (ADC_POWER); 11 velocidades son 70 ciclos;

//0 indicador de interrupción borrado; 1 inicio de adc (el canal 001AD está abierto); aquí está P1.1);

//---------------------------------- ----------- --------------------------------------- -----------

P2M0=1

P0M0=1

TMOD=0X12; > TH0=0x30; // Frecuencia de muestreo de aproximadamente 20K (requiere que la banda de frecuencia completa esté por encima de 40K. Pero la mayor parte de la frecuencia de audio está por debajo de 10k, así que elijo el muestreo de 20K, que es más hermoso)

TL0=0x30;

TH1=0xEE;

TL1=0XC0

ET0=1 //Activar temporizador 0

TR0=0; //Apagar temporizador

ET1=1;

TR1=1

PT1=0; PT0=1;

IPH=PADCH;

IP=PADC; //Nivel de prioridad de interrupción

EA=1 //Interrupción total activada

p>

}

anular ADC_Finish() interrupción 5

{ ADC_CONTR amp;= !ADC_FLAG

Fft_Real[LIST_TAB[ADC_Count]]=( int)((ADC_RES)lt;lt;1) (ADC_RESLgt;gt;1)-256;/ /-512 //Almacenamiento de valores de muestreo en el orden de la tabla LIST_TAB,

// ADC_CONTR = ADC_POWER | ADC_SPEEDHH| ADC_START | // Para recolectar voltajes negativos, se utiliza la recolección de compensación. El voltaje se incrementa a 1/2 vcc, así que resta 256

if(ADC_Countlt;=127)ADC_Count;

else {EADC=0;TR0=0;}

p>

} void LED_Display() interrupción 3 // Interrumpe para mostrar una línea a la vez. . .

{

TH1=0xF3;

TL1=0X00;

para (G=0; Glt; 64; G) / /Rellene una línea de datos en la pantalla de matriz de puntos

{

if(LED_TAB[G]lt;=LINE 16)SDA_R_TOP=1;

else SDA_R_TOP= 0;

si(LED_TAB[G]lt;=LINE)SDA_R=1;

si no SDA_R=0; =1 ;SDA_G=0;}

más si(LED_TAB1[G]==(LINE 16)){SDA_G_TOP=0;}

más SDA_G=SDA_G_TOP =1 ;

SHCP=1;

}

STCP=0; 15- LÍNEA;

if(LINEgt;0)LINE--;

else LINE=15;

////////// // ///////////////

if(LED_TAB[COUNT]gt; 0)LED_TAB[COUNT]-- //Disminución de columna,

CONTAR ;

if(LED_TAB[COUNT]gt;0)LED_TAB[COUNT]--;

CONTAR ;

si(LED_TAB[COUNT ]gt; 0)LED_TAB[COUNT]--;

COUNT;

if(LED_TAB[COUNT]gt; 0)LED_TAB[COUNT]--;

COUNT ;

if(LED_TAB[COUNT]gt; 0)LED_TAB[COUNT]--; //Columna decreciente,

COUNT;

if (LED_TAB[ COUNT]gt;0)LED_TAB[COUNT]--;

COUNT ;

if(LED_TAB[COUNT]gt;0)LED_TAB[COUNT]--;

CONTAR;

if(LED_TAB[COUNT]gt;0)LED_TAB[COUNT]--;

CONTAR;

si( COUNTgt;= 64)COUNT=0; //Los objetos flotantes están disminuyendo

if(LED_TAB2[COUNT1]==0) //Determina si se necesita una pausa

{

if (LED_TAB1[COUNT1]gt; LED_TAB[COUNT1])LED_TAB1[COUNT1]--;//Disminuye si es mayor que la columna (mantén el flotador por encima de la columna)

}

más LED_TAB2[COUNT1]--;

COUNT1 ;

if(LED_TAB2[COUNT1]==0)

{

if(LED_TAB1[COUNT1]gt;LED_TAB[COUNT1])LED_TAB1[COUNT1 ]--;

}

else LED_TAB2[COUNT1]--;

COUNT1

if(LED_TAB2[COUNT1]= =0) //Determinar si se necesita una pausa

{

if(LED_TAB1[COUNT1]gt; LED_TAB[COUNT1])LED_TAB1[COUNT1]--;//Disminuir si es mayor que la forma de la columna (Mantenga el flotador encima de la columna)

}

else LED_TAB2[COUNT1]--

COUNT1; >

if( LED_TAB2[COUNT1]==0)

{

if(LED_TAB1[COUNT1]gt; LED_TAB[COUNT1])LED_TAB1[COUNT1]--; /p>

}

else LED_TAB2[COUNT1]--;

COUNT1;

if(COUNT1gt;=64)COUNT1=0;

}void Ad_Control() interrupción 1 //Controla la frecuencia de muestreo

{

ADC_CONTR = ADC_POWER | ADC_SPEEDHH| //Iniciar adquisición de AD

}

//=================================== ======== =========================================== ======== ===================

// ************** ***** principal() **********************************

// ======== =========================================== ======== =========================================== ======== === void main()

{

Init()

while(1)

<; p> {

ADC_Count=0

TR0=1;

EADC=1 //Habilitar la interrupción del temporizador 0 y habilitar ADC

while(ADC_Countlt; 128);

FFT();

//Operación FFT. y convertido a valor de potencia. . .

// TR1=1

}

}