
by Rob Toulson and Tim Wilmshurst from textbook "Fast and Effective Embedded Systems Design: Applying the ARM mbed"
main.cpp@0:dd98f6992fa6, 2013-06-16 (annotated)
- Committer:
- robt
- Date:
- Sun Jun 16 15:42:09 2013 +0000
- Revision:
- 0:dd98f6992fa6
by Rob Toulson and Tim Wilmshurst from textbook "Fast and Effective Embedded Systems Design: Applying the ARM mbed"
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
robt | 0:dd98f6992fa6 | 1 | /* Program Example 14.5: A bar graph meter for ADC input, using control registers to set up ADC and digital I/O |
robt | 0:dd98f6992fa6 | 2 | */ |
robt | 0:dd98f6992fa6 | 3 | // variable declarations |
robt | 0:dd98f6992fa6 | 4 | char ADC_channel=1; // ADC channel 1 |
robt | 0:dd98f6992fa6 | 5 | int ADCdata; //this will hold the result of the conversion |
robt | 0:dd98f6992fa6 | 6 | int DigOutData=0; //a buffer for the output display pattern |
robt | 0:dd98f6992fa6 | 7 | |
robt | 0:dd98f6992fa6 | 8 | // function prototype |
robt | 0:dd98f6992fa6 | 9 | void delay(void); |
robt | 0:dd98f6992fa6 | 10 | |
robt | 0:dd98f6992fa6 | 11 | //define addresses of control registers, as pointers to volatile data |
robt | 0:dd98f6992fa6 | 12 | //(i.e. the memory contents) |
robt | 0:dd98f6992fa6 | 13 | #define PINSEL1 (*(volatile unsigned long *)(0x4002C004)) |
robt | 0:dd98f6992fa6 | 14 | #define PCONP (*(volatile unsigned long *)(0x400FC0C4)) |
robt | 0:dd98f6992fa6 | 15 | #define AD0CR (*(volatile unsigned long *)(0x40034000)) |
robt | 0:dd98f6992fa6 | 16 | #define AD0GDR (*(volatile unsigned long *)(0x40034004)) |
robt | 0:dd98f6992fa6 | 17 | #define FIO2DIR0 (*(volatile unsigned char *)( 0x2009C040)) |
robt | 0:dd98f6992fa6 | 18 | #define FIO2PIN0 (*(volatile unsigned char *)( 0x2009C054)) |
robt | 0:dd98f6992fa6 | 19 | |
robt | 0:dd98f6992fa6 | 20 | int main() { |
robt | 0:dd98f6992fa6 | 21 | FIO2DIR0=0xFF;// set lower byte of Port 2 to output, this drives bar graph |
robt | 0:dd98f6992fa6 | 22 | |
robt | 0:dd98f6992fa6 | 23 | //initialise the ADC |
robt | 0:dd98f6992fa6 | 24 | PINSEL1=0x00010000; //set bits 17-16 to 01 to enable AD0.1 (mbed pin 16) |
robt | 0:dd98f6992fa6 | 25 | PCONP |= (1 << 12); // enable ADC clock |
robt | 0:dd98f6992fa6 | 26 | AD0CR = (1 << ADC_channel) // select channel 1 |
robt | 0:dd98f6992fa6 | 27 | | (4 << 8) // Divide incoming clock by (4+1), giving 4.8MHz |
robt | 0:dd98f6992fa6 | 28 | | (0 << 16) // BURST = 0, conversions under software control |
robt | 0:dd98f6992fa6 | 29 | | (1 << 21) // PDN = 1, enables power |
robt | 0:dd98f6992fa6 | 30 | | (1 << 24); // START = 1, start A/D conversion now |
robt | 0:dd98f6992fa6 | 31 | |
robt | 0:dd98f6992fa6 | 32 | while(1) { // infinite loop |
robt | 0:dd98f6992fa6 | 33 | AD0CR = AD0CR | 0x01000000; //start conversion by setting bit 24 to 1, |
robt | 0:dd98f6992fa6 | 34 | //by ORing |
robt | 0:dd98f6992fa6 | 35 | // wait for it to finish by polling the ADC DONE bit |
robt | 0:dd98f6992fa6 | 36 | while ((AD0GDR & 0x80000000) == 0) { //test DONE bit, wait till it’s 1 |
robt | 0:dd98f6992fa6 | 37 | } |
robt | 0:dd98f6992fa6 | 38 | ADCdata = AD0GDR; // get the data from AD0GDR |
robt | 0:dd98f6992fa6 | 39 | AD0CR &= 0xF8FFFFFF; //stop ADC by setting START bits to zero |
robt | 0:dd98f6992fa6 | 40 | // Shift data 4 bits to right justify, and 2 more to give 10-bit ADC |
robt | 0:dd98f6992fa6 | 41 | // value - this gives convenient range of just over one thousand. |
robt | 0:dd98f6992fa6 | 42 | ADCdata=(ADCdata>>6)&0x03FF; //and mask |
robt | 0:dd98f6992fa6 | 43 | DigOutData=0x00; //clear the output buffer |
robt | 0:dd98f6992fa6 | 44 | //display the data |
robt | 0:dd98f6992fa6 | 45 | if (ADCdata>200) |
robt | 0:dd98f6992fa6 | 46 | DigOutData=(DigOutData|0x01); //set the lsb by ORing with 1 |
robt | 0:dd98f6992fa6 | 47 | if (ADCdata>400) |
robt | 0:dd98f6992fa6 | 48 | DigOutData=(DigOutData|0x02); //set the next lsb by ORing with 1 |
robt | 0:dd98f6992fa6 | 49 | if (ADCdata>600) |
robt | 0:dd98f6992fa6 | 50 | DigOutData=(DigOutData|0x04); |
robt | 0:dd98f6992fa6 | 51 | if (ADCdata>800) |
robt | 0:dd98f6992fa6 | 52 | DigOutData=(DigOutData|0x08); |
robt | 0:dd98f6992fa6 | 53 | if (ADCdata>1000) |
robt | 0:dd98f6992fa6 | 54 | DigOutData=(DigOutData|0x10); |
robt | 0:dd98f6992fa6 | 55 | |
robt | 0:dd98f6992fa6 | 56 | FIO2PIN0 = DigOutData; // set port 2 to Digoutdata |
robt | 0:dd98f6992fa6 | 57 | delay(); // pause |
robt | 0:dd98f6992fa6 | 58 | } |
robt | 0:dd98f6992fa6 | 59 | } |
robt | 0:dd98f6992fa6 | 60 | |
robt | 0:dd98f6992fa6 | 61 | void delay(void){ //delay function. |
robt | 0:dd98f6992fa6 | 62 | int j; //loop variable j |
robt | 0:dd98f6992fa6 | 63 | for (j=0; j<1000000; j++) { |
robt | 0:dd98f6992fa6 | 64 | j++; |
robt | 0:dd98f6992fa6 | 65 | j--; //waste time |
robt | 0:dd98f6992fa6 | 66 | } |
robt | 0:dd98f6992fa6 | 67 | } |