lunes, 6 de febrero de 2017

PRACTICA # 21 MICROPHONE AND SPEAKER

OBJETIVO:
       Haremos uso del A/D 12 bits, D/A 10 bits del MCU R5F563NB. El micrófono y la bocina con la que cuenta la tarjeta de evaluación YRDKRX63N. Grabaremos 30,000 muestras del ADC a 10 Khz para posteriormente reproducirlas en el DAC de 10 bits.
  • Inicializaremos el módulo ADC Y DAC
  • Muestreamos ADC a 10 Khz
  • Reproducción del buffer en el DAC a 10 Khz.

DESARROLLO:
  •  Del YRDKRX63N schematic se muestra los componentes del circuito de audio:
Puente en el pin 2 y 3 del Jp17


PASOS:
  • Creación de un proyecto:
1.- Abrir el software e2studio
2.- New/ C Project / Renesas RXC ToolChain


3.- Seleccionar el target R5F563NB, debug hardware Segger jLink, después next


 4.- Seleccionar C/C++ Source file y por ultimo Finish.


6.- Las rutinas de inicialización y muestreo del ADC y el DAC son:

void R_ADC_Create(void)
{   
              /* Power up the S12ADC */
                MSTP(S12AD) = 0;

        // microphone p45
                PORT4.PDR.BIT.B2  = 0;    /* Set I/O pin direction to input. */
                PORT4.PMR.BIT.B2  = 0;    /* First set I/O pin mode register to GPIO mode. */
                MPC.P45PFS.BYTE = 0x80;   /* Set port function register to analog input, no interrupt. */

                /* ADCSR: A/D Control Register
                b7    ADST     0 a/d conversion start, Stop a scan conversion process
                b6    ADCS     0 Scan mode select, Single-scan mode
                b5    Reserved 0 This bit is always read as 0. The write value should always be 0.
                b4    ADIE     0 Disables conversion complete IRQ to ICU
                b3:b2 CKS      3 A/D conversion clock select = PCLK/2
                b1    TRGE     0 Disables conversion to start w/ trigger
                b0    EXTRG    0 Trigger select, Scan conversion start by a timer source or software
                        */
                S12AD.ADCSR.BYTE = 0x0C;

                /* ADANS1: A/D Channel Select Register 1
                        b15:b5  Reserved: These bits are always read as 0. The write value should always be 0.
                b4:b0   ANS1:     Selects analog inputs of the channels AN016 to AN020 that are subjected to A/D conversion
                */
                S12AD.ADANS1.WORD = 0x0000;

                /* ADADS0: A/D-converted Value Addition Mode Select Register 0
                b15:b0  ADS0: A/D-Converted Value Addition Channel Select for AN000 to AN015.
                */
                S12AD.ADADS0.WORD = 0x0000;

                /* ADADS1: A/D-converted Value Addition Mode Select Register 1
                        b15:b5  Reserved: These bits are always read as 0. The write value should always be 0.
                b4:b0   ADS1: A/D-Converted Value Addition Channel Select for AN016 to AN020.
                */
                S12AD.ADADS1.WORD = 0x0000;

                /* ADADC: A/D-Converted Value Addition Count Select Register
                b1:b0   ADC: 00 = 1 time conversion (same as normal conversion)
                */
                S12AD.ADADC.BYTE = 0x00;   /* 1-time conversion */

                /* ADCER: A/D Control Extended Register
                b15     ADRFMT:0  Right align the data in the result registers
                b5      ACE:0 Disables automatic clearing of ADDRn after it is read
                */
                S12AD.ADCER.WORD = 0x0000;   /* Right align data, automatic clearing off. */

                /* ADSTRGR: A/D Start Triggger Select Register
                b7:b4   Reserved. Always read/write 0.
                b3:b0   ADSTRS: 0, Software trigger or ADTRG0#
                */
                S12AD.ADSTRGR.BYTE = 0x00;

               // tSCAN = tD + (tCONV × N) + tED   // pag. 1734  N -> is number of channels to convert, ADCLK = PCLK/2 = 24 Mhz
               // tD = 2PCLK + 3ADCLK = 2*(1/48Mhz) + 3*(1/24Mhz) = 0.16 us
               // tCONV = 50ADCLK = 50*(1/24Mhz) = 2 us
               // N = 1
               // tED = 1PCLK + 2ADCLK = 1*(1/48Mhz) + 2*(1/24Mhz) = 0.1 us
               // tSCAN = 0.16 us + (2 us × 1) + 0.1 us = 2.26 us
               // F = 1 / 2.26 us = 442.4 kz
}
void SR_VOICE_PLAYBACK_INIT(void)
{
            LED4_PDR = 1;         // PIN como output
            LED4_PMR = 0;         // como I/O general
            LED4 = OFF_;          // se inicializa a 0 la salida

            AMP_SHDN_PDR  = 1;    // PIN como output
            AMP_SHDN_PMR  = 0;    // como I/O general
            AMP_SHDN      = 1;    // se inicializa a 1 la salida

            SPKR_GAIN_PDR = 1;    // PIN como output
            SPKR_GAIN_PMR = 0;    // como I/O general
            SPKR_GAIN = 1;        // se inicializa a 1 la salida

            R_ADC_Create();    // inicializa ADC 12 bits 2.26 us de muestreo

            // Enable DA1 DAC output
            MSTP(DA) = 0;
            // P05 is DA1, enable output
            PORT0.PDR.BIT.B5 = 0; // como entrada  Nota: si la pongo como salida no sirve :(
            PORT0.PMR.BIT.B5 = 0;  // como I/O
            MPC.P05PFS.BYTE = 0x80;    // P05 is used as analog pin

            DA.DADPR.BIT.DPSEL = 0;  // Data loaded LSB-aligned
            DA.DACR.BIT.DAE = 1;     // enables coversion
            DA.DACR.BIT.DAOE1 = 1;   // channel DA1 enabled
}

void SR_VOICE_PLAYBACK(void)
{
             int index = 0;
            unsigned short  ADC12bits;

            S12AD.ADANS0.BIT.ANS0 = 0x20;   // selecciona el canal 5

    while (index < SAMPLE_SIZE)
    {
                        S12AD.ADCSR.BIT.ADST = 1;
                        while (S12AD.ADCSR.BIT.ADST == 1)
                        {
                                    __nop();
                        }
                        /* Convert conversion result into voltage */
                        ADC12bits = S12AD.ADDR5 & 0x0FFF;   // 12 bits
                        sample[index] = ADC12bits;
                        index++;
                        delay_100us(1);
    }

    LED4 = OFF_;
    delay_ms(1000);

    for (index = 0; index < SAMPLE_SIZE; index++)
    {
           DA.DADR1= sample[index]>>2; // 10 BITS
           delay_100us(1);
    }
}

7.- La función main queda como sigue:

#define SAMPLE_SIZE 30000
unsigned short sample[SAMPLE_SIZE];
void SR_VOICE_PLAYBACK(void);
void SR_VOICE_PLAYBACK_INIT(void);

void main(void)
{
            set_ipl( 0 );            // enable interrupts
            SR_Oscilador();          //  F = 96 Mhz
            SR_TIMER_0();            //  Inicializa el Timer 0 en cascada para 16 bits
            SR_VOICE_PLAYBACK_INIT();//  Se inicializan puertos, y DAC

            while(1)
            {
                         LED4 = ON_;           // para sincronizar cuando hablar
                         SR_VOICE_PLAYBACK();
            }
}

  • Agregar código, compilar y debug:
1.- Bajar el código de:
--> Practica #21

2.- Compilar con el icono del martillo, debug con el icono del insecto y correr software:


AUDIO: 



No hay comentarios.:

Publicar un comentario