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

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* Program Example 14.5: A bar graph meter for ADC input, using control registers to set up ADC and digital I/O                         
00002                                                        */
00003 // variable declarations                                              
00004 char ADC_channel=1;     // ADC channel 1
00005 int  ADCdata;           //this will hold the result of the conversion
00006 int DigOutData=0;       //a buffer for the output display pattern
00007 
00008 // function prototype                                              
00009 void delay(void);
00010 
00011 //define addresses of control registers, as pointers to volatile data 
00012 //(i.e. the memory contents)
00013 #define PINSEL1        (*(volatile unsigned long *)(0x4002C004))
00014 #define PCONP          (*(volatile unsigned long *)(0x400FC0C4))
00015 #define AD0CR          (*(volatile unsigned long *)(0x40034000))
00016 #define AD0GDR         (*(volatile unsigned long *)(0x40034004))
00017 #define FIO2DIR0       (*(volatile unsigned char *)( 0x2009C040))
00018 #define FIO2PIN0       (*(volatile unsigned char *)( 0x2009C054))  
00019 
00020 int main() {
00021   FIO2DIR0=0xFF;// set lower byte of Port 2 to output, this drives bar graph
00022 
00023 //initialise the ADC
00024   PINSEL1=0x00010000; //set bits 17-16 to 01 to enable AD0.1 (mbed pin 16)
00025   PCONP |= (1 << 12);                // enable ADC clock
00026   AD0CR =   (1 << ADC_channel)       // select channel 1 
00027            | (4 << 8)       // Divide incoming clock by (4+1), giving 4.8MHz
00028            | (0 << 16)      // BURST = 0, conversions under software control  
00029            | (1 << 21)      // PDN = 1, enables power
00030            | (1 << 24);     // START = 1, start A/D conversion now 
00031   
00032   while(1) {                      // infinite loop
00033     AD0CR = AD0CR | 0x01000000;   //start conversion by setting bit 24 to 1,
00034                                                                //by ORing
00035     // wait for it to finish by polling the ADC DONE bit         
00036     while ((AD0GDR & 0x80000000) == 0) {  //test DONE bit, wait till it’s 1
00037     }
00038     ADCdata = AD0GDR;            // get the data from AD0GDR
00039     AD0CR &= 0xF8FFFFFF;         //stop ADC by setting START bits to zero
00040    // Shift data 4 bits to right justify, and 2 more to give 10-bit ADC 
00041    // value - this gives convenient range of just over one thousand. 
00042     ADCdata=(ADCdata>>6)&0x03FF;    //and mask      
00043     DigOutData=0x00;                //clear the output buffer
00044     //display the data
00045     if (ADCdata>200)
00046       DigOutData=(DigOutData|0x01);  //set the lsb by ORing with 1
00047     if (ADCdata>400)
00048       DigOutData=(DigOutData|0x02);  //set the next lsb by ORing with 1
00049     if (ADCdata>600)
00050       DigOutData=(DigOutData|0x04);
00051     if (ADCdata>800)
00052       DigOutData=(DigOutData|0x08);
00053     if (ADCdata>1000)
00054       DigOutData=(DigOutData|0x10);   
00055       
00056     FIO2PIN0 = DigOutData;        // set port 2 to Digoutdata
00057     delay();      // pause
00058    }     
00059 }
00060 
00061 void delay(void){            //delay function.
00062     int j;                      //loop variable j
00063     for (j=0; j<1000000; j++) {
00064         j++;
00065         j--;                      //waste time
00066     }
00067 }