10 years, 2 months ago.

ADC set up

Hi forum, I am trying to set up the ADC to read pins 16-20 inclusive, this is the code I came up with, but it is not reading pin18, all the other pins are working as expected. could someone please give me a pointer on how i can fix it. Thanks for reading .

include the mbed library with this snippet

#include "mbed.h"


/*
adc input using control register
*/

Serial pc(USBTX, USBRX);

// variable declarations
char channel = 1;           // ADC channel 1
int ADCdata;                    // this will hold result of the conversion
int DigOutData = 0;             // a buffer for the output display pattern

// function prototype
void delay(void);

// define addresses of control registers, as pointers to volatile data
//(i.e the memory contents)




#define PINSEL3     (*(volatile unsigned long *)(0x4002C00C)
#define PINSEL1     (*(volatile unsigned long *)(0x4002C004))
#define PCONP       (*(volatile unsigned long *)(0x400FC0C4))
#define ADOCR       (*(volatile unsigned long *)(0x40034000))
#define ADOGDR      (*(volatile unsigned long *)(0x40034004))
#define FIO2DIR0    (*(volatile unsigned long *)(0x2009C040))
#define FIO2PIN0    (*(volatile unsigned long *)(0x2009C054))

int main(){
    
    // intilialize the ADC
    PINSEL1 = 0x150000;        // set bits 17-16, 19-18, 20-21 to 01 to enable AD0.1, AD0.2, AD0.3 (mbed pin 16,17,18)
    PINSEL3 = 0xF0000000;       // sets bits 29-28, 31-30 to 11 to enable AD0.4, AD0.5 (mbed pin 19, 20)
    PCONP   |=  (1 << 12);       // enable ADC clock 

    while(1){
        for(chanel =1; channel << 7; channel += 1){ 
        ADOCR   = ( 1 << channel)|( 1 << 8)|(0 << 16)|(1<<21)|(1<<24);      // enable ADC clock, select channel, divide incoming by (1+1), giving 4.8MHz, BURST = 0, conversation under software control, PDN =1, enables power, START = 1 start A/D conversion now
            ADOCR = ADOCR | 0x01000000; // start conversion by setting bit 24 to 1 by ORing
                                    // wait for the conversion to finish by polling the ADC DONE bit

            while((ADOGDR & 0x80000000) == 0)
            {
            // test DONE bit, wait till it's 1
            }
            ADCdata = ADOGDR;           // get data from ADOGDR
            ADOCR &= 0xF8FFFFFF;        // stop ADC by setting START bits to zero
                                    // shift data 4 bits to right justify, and 2 more to give 10-bit ADC
                                    // value given a between 0 & 1024 = 2^8
            ADCdata=(ADCdata>>6)&0x03FF;    // and mask
            DigOutData = 0x00;              // clear the output buffer

            //displaying the data
            pc.printf("ADC reading in channel %d is %d  \n", channel, ADCdata);
            if(channel = 6){
                channel = 1;
            
            }
        }
    }    
}

1 Answer

10 years, 2 months ago.

I have not checked all the ADC bit settings, but there is something wrong in your for-loop. You have a typo in the first field: chanel rather than channel. That should not compile. The second field seems wrong also: (channel << 7) is a shift left. I suppose you are aiming for : (channel < 7) to test for maximum channel number of 6. The test at the end of the for-loop does not work, it resets channel to 1, but the for-loop will increment it also. The next value will be 2. Anyhow, the test should not be needed when the for-loop is fixed. Why do you sample 6 channels when you want only 5? BTW why dont you use the AnalogIn method?

Accepted Answer

thank you, I've corrected the typo and fixed the for-loop. I accidentally upload a previous version but not the version that is compiling. I'm trying to learn how the chip works beyond the libraries, i've worked with the libraries and want to explore more of the chip and how it works. Thank you for your fast response.

posted by Donald K 12 Feb 2014