1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

ADC (audio sampling) and PWM (audio playback)

Discussion in 'Microcontrollers' started by MrNobody, Feb 13, 2008.

  1. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,019
    Likes:
    317
    Location:
    Brisbane Australia
    I think the clue is in the word errata. This is obviously a hardware bug that effects some ADC modules. If the Pic your using doesn't mention an errata sheet in the ADC section then I wouldn't worry about it. As you say, initialise it once and then just set the GO bit.

    Mike.
     
  2. MrNobody

    MrNobody New Member

    Joined:
    Aug 29, 2006
    Messages:
    251
    Likes:
    3
    Below is the code to read ADC input from RA0/AN0..
    In the register, i set Vref- to VSS and Vref+ to VDD..
    I am using 10MHz crystal with 4x PLL..

    However, the when I monitor both ADRESH and ADRESL register, the register value doesn't change even if I change the input voltage..

    I am not sure what I did wrong..

    Code (text):
    #include <p18F4620.h>
    #include <delays.h>
    #include <usart.h>
    #include <stdio.h>

    #pragma config WDT = OFF
    #pragma config MCLRE = ON
    #pragma config LVP = OFF
    #pragma config OSC = HSPLL
    #define CLOCK_FREQ      (40000000ul)      // Hz

    void ADCInit();
    void openPORTC();
    void UARTInit();

    void main()
    {
        openPORTC();
        ADCInit();
        UARTInit();


        printf("ADC Test");


        while(1)
        {  
            while(ADCON0bits.GO);

            //According to errata
            PRODL = ADCON2;
            ADCON2bits.ADCS0 = 1;
            ADCON2bits.ADCS1 = 1;
            ADCON2 = PRODL;

            printf("%c\r\n", ADRESH);
        }
    }


    void ADCInit()
    {
        ADCON1 = 0b00001110;
        ADCON0 = 0b00000011;
        ADCON2 = 0b00101010;
        ADCON0bits.ADON = 1;
    }


    void UARTInit()
    {
        SPBRG = 64;
        TXSTA = 0b00100010;
        RCSTA = 0b10010000;
        BAUDCON = 0b00000000;
        TRISC = 0b10000001;
    }
     
     
  3. bananasiong

    bananasiong New Member

    Joined:
    Mar 7, 2006
    Messages:
    1,893
    Likes:
    7
    Location:
    Malaysia
    Hi,
    I don't use C, but if I understand the code correctly, GO bit isn't set to start the conversion.
    ADCON0bits.GO = 1
    GO bit will be cleared once the conversion is done, so it has to be set again for the next conversion.
     
    • Like Like x 1
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,019
    Likes:
    317
    Location:
    Brisbane Australia

    I looked for the errata sheet but couldn't find it. Have you found it? I would be interested to see it.

    You may also want to check the TX pin, I believe it needs to be input for the UART to work.

    Mike.
     
  6. MrNobody

    MrNobody New Member

    Joined:
    Aug 29, 2006
    Messages:
    251
    Likes:
    3
  7. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,019
    Likes:
    317
    Location:
    Brisbane Australia
    I still didn't find an explanation of the work around.

    I think you should treat the chip as a fully working chip. Whatever your problem is not anything to do with an errata on chips that do TCPIP.

    Did you listen to Bananasiong.

    Post your most recent code and we will try and help.

    Mike.
     
  8. MrNobody

    MrNobody New Member

    Joined:
    Aug 29, 2006
    Messages:
    251
    Likes:
    3
    Yeah.. I tried what Bananasiong said and it works...
    here is my updated code for those that is also learning ADC..
    What is does is that it will sample voltage at AN0 and then send it through UART.

    Code (text):
    #include <p18F4620.h>
    #include <delays.h>
    #include <usart.h>
    #include <stdio.h>

    #pragma config WDT = OFF
    #pragma config MCLRE = ON
    #pragma config LVP = OFF
    //#pragma config OSC = HSPLL
    #define CLOCK_FREQ      (40000000ul)      // Hz

    void ADCInit();
    void UARTInit();

    void main()
    {
        ADCInit();
        UARTInit();


        printf("Test ADC");

        while(1)
        {  
            ADCON0bits.GO = 1;
            while(ADCON0bits.GO);

            PRODL = ADCON2;
            ADCON2bits.ADCS0 = 1;
                ADCON2bits.ADCS1 = 1;
                ADCON2 = PRODL;

            printf("%c", ADRESH);

        }
    }


    void ADCInit()
    {
        ADCON1 = 0b00001110;
        ADCON0 = 0b00000011;
        ADCON2 = 0b00101010;
        ADCON0bits.ADON = 1;
    }


    void UARTInit()
    {
        SPBRG = 64;
        TXSTA = 0b00100010;
        RCSTA = 0b10010000;
        BAUDCON = 0b00000000;
        TRISC = 0b10000001;
    }
    Oh.. by the way, the code above is only tested in Proteus.. I will try to sample sine wave and then look at the values..
     
    Last edited: Feb 15, 2008
  9. MrNobody

    MrNobody New Member

    Joined:
    Aug 29, 2006
    Messages:
    251
    Likes:
    3
    Oh.. by the way, in the code above i commented "//#pragma config OSC = HSPLL".
    That means that if I use 10MHz crystal, then the PIC is only running at 10MHz and not 40MHz rite..? If I want it to run at 40MHz then i need to uncomment that line rite..?

    After looking at the datasheet, i can only see that the PLL can only be set to 4 and no other value.. is that right..?
     
  10. bananasiong

    bananasiong New Member

    Joined:
    Mar 7, 2006
    Messages:
    1,893
    Likes:
    7
    Location:
    Malaysia
    Hi,
    Since the PIC takes 4 clock cycles to complete one instruction, if a 10 MHz crystal is used and PLL enabled, the clock is running at 40 MHz, but the instruction cycle is 10 MIPS.
    You can't run the PIC at 40 MIPS.
    If the PLL is enabled, the crystal used must be 10 MHz or below. If it's not enabled, the crystal can be used is up to 20 MHz.
     
  11. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,019
    Likes:
    317
    Location:
    Brisbane Australia
    I see your still doing the errata code. The fact you are running it on a simulator means there is no need for this. I doubt there is any need on the actual hardware as the errata is specific to TCP/IP.

    As for the question about the PLL, just try it.

    Mike.
    P.S. I do think it is polite when someone identifies your problem to acknowledge them. I'm talking about Bananasiong.
     
  12. MrNobody

    MrNobody New Member

    Joined:
    Aug 29, 2006
    Messages:
    251
    Likes:
    3
    Yeah.. I am still using the errata code.. coz the after trying all this, my tinal goal is to be able to send the voice through ethernet by using the TCP/IP stack..

    Yeah.. I will try the PLL..

    Oh.. i forgot to thank Bananasiong..

    Bananasiong:
    Thanks alot for your help..
    Ahh.. i know what i'll do.. I'll click on your "myminicity" and build one house for u.. hehee...


    P.S. umm..i dun really understand that PS part..
     
  13. bananasiong

    bananasiong New Member

    Joined:
    Mar 7, 2006
    Messages:
    1,893
    Likes:
    7
    Location:
    Malaysia
    Ahhaa.. :D
    My friend created that for me, but I don't know why did he select that country.
     
  14. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,019
    Likes:
    317
    Location:
    Brisbane Australia
    I was just saying that it is nice to acknowledge someone that has identified your problem. I was referring to the post where he explained that you have to set the Go bit to start a conversion.

    Mike.
     
  15. Hero999

    Hero999 Banned

    Joined:
    Apr 6, 2006
    Messages:
    14,902
    Likes:
    79
    Location:
    England
    Why do you want to do PWM?

    Are you using a class-D output stage or something?

    If you're just using the usual class AB stage then why not use an R2R converter?
     
  16. MrNobody

    MrNobody New Member

    Joined:
    Aug 29, 2006
    Messages:
    251
    Likes:
    3
    Sorry.. i dunno much about amplifier..
    I also don't know what R2R converter is.. but after going to http://www.eng.utah.edu/~bowen/DAC_Proj/8-bit_r2rdac_current_sources.html i think i kinda know what it is..
    Is it like, i use 8 pins as output connect to a series of resistors and finally to an op-amp. Some sort of DAC converter where the most current will be present where all the 8 pins is HIGH (0b11111111) and no current where none of the pins are HIGH (0b00000000).
    Won't that requires 8 pins on the PIC..?

    The only reason why i use PWM is because it is possible to use 1 pin to generate audio.. I don't need additional components except low pass filter and speaker..

    Actually, I my only focus is just to get some sound out..
     
  17. bananasiong

    bananasiong New Member

    Joined:
    Mar 7, 2006
    Messages:
    1,893
    Likes:
    7
    Location:
    Malaysia
    Since there's built in PWM module in the PIC, it is easier way. Besides the IO pins required, the programming part is also easier ;)
     
  18. ldanielrosa

    ldanielrosa New Member

    Joined:
    Jun 28, 2007
    Messages:
    18
    Likes:
    0
    Hero999, that's about how it looks. I'll also be making one as a proof of concept some day, though I won't throw nearly as much horsepower at it.

    For what it's worth I see it from the other end. I want full resolution, and at 10 bits going into an h-bridge it'll be 9 bits differential. I'll need a 128Tins (PWM can run at oscillator speed) (or some multiple thereof) to keep in step with the PWM hardware. At 10MIPS and a maximum sample frequency of 30kHz or so I'd use a timed interrupt every 512Tins to take a new sample in the ADC. That gives me four PWM periods for every analog sample, possibly buying me some slack with my filter.

    As for the sample rate, 10MIPS/512Tins is 19531.25 samples per second. Nyquist's limit is a brick wall, the actual cutoff is a bit lower. You'll get about 7.9 Khz
     
  19. atferrari

    atferrari Well-Known Member

    Joined:
    Oct 8, 2003
    Messages:
    2,812
    Likes:
    121
    Location:
    Buenos Aires - Argentina
  20. MrNobody

    MrNobody New Member

    Joined:
    Aug 29, 2006
    Messages:
    251
    Likes:
    3
  21. Oznog

    Oznog Active Member

    Joined:
    Apr 21, 2004
    Messages:
    2,879
    Likes:
    11
    Location:
    Austin, Tx
    Still saying this sounds way more difficult than it needs to be.
    dsPIC33F will do 40MIPs, and its 16-bit instruction set and DSP core is way more efficient per instruction. So if you need power that is it.

    An Si3000 codec is pretty much stock. That's like $2. It'll be a microphone preamp, software adjustable, and a headset amp (although it's a pretty weak one actually). Maxim-IC's "DirectDrive" is the BEST headphone driver, they have codecs which have it and they have basic analog amp chips with it.

    DirectDrive is where they use a charge pump to make a -Vdd and it's got an output that swings close to the rails with a high current capability. Then you can hook up a speaker without having to use differential mode OR large coupling caps and you still get +/- Vdd swing off of even 3.3V, which is nice- no separate regulator.

    BTW, I don't know if you noticed this or not, but the Nyquist limit doesn't eliminate signals over Fsamp/2. Those components, if present, produce noise in the ADC data. And a simple RC filter does not have a sharp enough cutoff for this, there are some 2-stage active filters people often use. In general a codec chip will not need this hardware because they use oversampling- the ADC samples at a very high rate and they use a digital decimation filter to kick it down to the 8khz voice sampling rate.

    I gotta note that making the filter costs about as much as just using the codec...
     
    Last edited: Feb 16, 2008

Share This Page