by Rob Toulson and Tim Wilmshurst from textbook "Fast and Effective Embedded Systems Design: Applying the ARM mbed"

Dependencies:   mbed

main.cpp

Committer:
robt
Date:
2013-06-16
Revision:
0:dd98f6992fa6

File content as of revision 0:dd98f6992fa6:

/* Program Example 14.5: A bar graph meter for ADC input, using control registers to set up ADC and digital I/O                         
                                                       */
// variable declarations                                              
char ADC_channel=1;     // ADC channel 1
int  ADCdata;           //this will hold the 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 PINSEL1        (*(volatile unsigned long *)(0x4002C004))
#define PCONP          (*(volatile unsigned long *)(0x400FC0C4))
#define AD0CR          (*(volatile unsigned long *)(0x40034000))
#define AD0GDR         (*(volatile unsigned long *)(0x40034004))
#define FIO2DIR0       (*(volatile unsigned char *)( 0x2009C040))
#define FIO2PIN0       (*(volatile unsigned char *)( 0x2009C054))  

int main() {
  FIO2DIR0=0xFF;// set lower byte of Port 2 to output, this drives bar graph

//initialise the ADC
  PINSEL1=0x00010000; //set bits 17-16 to 01 to enable AD0.1 (mbed pin 16)
  PCONP |= (1 << 12);                // enable ADC clock
  AD0CR =   (1 << ADC_channel)       // select channel 1 
           | (4 << 8)       // Divide incoming clock by (4+1), giving 4.8MHz
           | (0 << 16)      // BURST = 0, conversions under software control  
           | (1 << 21)      // PDN = 1, enables power
           | (1 << 24);     // START = 1, start A/D conversion now 
  
  while(1) {                      // infinite loop
    AD0CR = AD0CR | 0x01000000;   //start conversion by setting bit 24 to 1,
                                                               //by ORing
    // wait for it to finish by polling the ADC DONE bit         
    while ((AD0GDR & 0x80000000) == 0) {  //test DONE bit, wait till it’s 1
    }
    ADCdata = AD0GDR;            // get the data from AD0GDR
    AD0CR &= 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 - this gives convenient range of just over one thousand. 
    ADCdata=(ADCdata>>6)&0x03FF;    //and mask      
    DigOutData=0x00;                //clear the output buffer
    //display the data
    if (ADCdata>200)
      DigOutData=(DigOutData|0x01);  //set the lsb by ORing with 1
    if (ADCdata>400)
      DigOutData=(DigOutData|0x02);  //set the next lsb by ORing with 1
    if (ADCdata>600)
      DigOutData=(DigOutData|0x04);
    if (ADCdata>800)
      DigOutData=(DigOutData|0x08);
    if (ADCdata>1000)
      DigOutData=(DigOutData|0x10);   
      
    FIO2PIN0 = DigOutData;        // set port 2 to Digoutdata
    delay();      // pause
   }     
}

void delay(void){            //delay function.
    int j;                      //loop variable j
    for (j=0; j<1000000; j++) {
        j++;
        j--;                      //waste time
    }
}