PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
adc7scan2.c
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 
30 #include "pic24_all.h"
31 #include "stdio.h"
32 
33 #ifdef _DMA0IF
34 #error "This processor selection has the DMA module; this code example is incompatible with a PIC24 CPU that has DMA."
35 
36 #endif
37 
38 #define CONFIG_LED2() CONFIG_RB0_AS_DIG_OUTPUT()
39 #define LED2 _LATB0
40 
41 // uncomment the next line to setup this project for a 12-bit ADC
42 #define USE_12BIT_ADC
43 
44 #ifdef USE_12BIT_ADC
45 #define ADC_LEN 12
46 #define ADC_NSTEPS 4096
47 #define ADC_12BIT_FLAG 1
48 #else
49 #define ADC_LEN 10
50 #define ADC_NSTEPS 1024
51 #define ADC_12BIT_FLAG 0
52 #endif
53 
54 volatile uint16_t au16_buffer[16];
55 volatile uint8_t u8_waiting;
56 
57 /***
58  *** HERE IS THE CODE!
59  ***
60  ***/
61 
62 void _ISR _ADC1Interrupt (void) {
63  uint8_t u8_i;
64  uint16_t* au16_adcHWBuff = (uint16_t*) &ADC1BUF0;
65 
66  /* If ADC is writing in the 2nd half of the buffer, so determine which
67  * half of the buffer is valid (and caused this interrupt), then fetch
68  * that half into our local array of ADC results.
69  */
70  if (AD1CON2bits.BUFS) {
71  for ( u8_i=0; u8_i<8; u8_i++) {
72  au16_buffer[u8_i] = au16_adcHWBuff[u8_i];
73  } //end for()
74  } else {
75  for ( u8_i=8; u8_i<16; u8_i++) {
76  au16_buffer[u8_i] = au16_adcHWBuff[u8_i];
77  } //end for()
78  } // end if-else
79 
80  AD1CON1bits.DONE = 0; /* do we really need to clear this? */
81  u8_waiting = 0; // signal to main() that data is ready
82  _AD1IF = 0; //clear the interrupt flag
83 
84  // toggle an LED so we can measure how often ADC IRQs are coming in
85  LED2 = !LED2;
86 }
87 
88 /** \file
89  * Performs a basic config of the ADC and samples seven channels sequentially
90  * with automatic channel scanning. ADC values are 12-bit results.
91  * Samples are obtained continuously. Uses ADC completion interrupts to get
92  * values from ADCxBUFn registers. Main routine fetches the "latest" values
93  * from memory.
94  *
95  * Conversion results are printed to screen to match adc2pots1.c project
96  * (HEX values and voltages are printed.)
97  * This is only for PIC24 CPUs without DMA.
98 */
99 
100 int main (void) {
101  uint8_t u8_i;
102  uint16_t u16_pot;
103  float f_pot;
104 
105  configBasic(HELLO_MSG);
106 
107  // make RA0/AN0/VREF+ a digital input to kill the pullup and
108  // set the TRISA bit, then make it ANALOG so the ADC will work
109  CONFIG_AN0_AS_ANALOG();
110  CONFIG_AN1_AS_ANALOG();
111  CONFIG_AN4_AS_ANALOG();
112  CONFIG_AN5_AS_ANALOG();
113  CONFIG_AN10_AS_ANALOG();
114  CONFIG_AN11_AS_ANALOG();
115  CONFIG_AN12_AS_ANALOG();
116 
117  CONFIG_LED2();
118 
119  configADC1_AutoHalfScanIrqCH0(ADC_SCAN_AN0 | ADC_SCAN_AN1 | ADC_SCAN_AN4 | \
120  ADC_SCAN_AN5 | ADC_SCAN_AN10 | ADC_SCAN_AN11 | ADC_SCAN_AN12, \
121  31, ADC_12BIT_FLAG);
122 
123  // wait for first conversion cycle to finish before proceeding
124  while ( !AD1CON1bits.DONE) {};
125 
126  while (1) {
127  while(u8_waiting) {}; // wait for valid data from ISR
128  u8_waiting = 1;
129  for ( u8_i=0; u8_i<16; u8_i++) {
130  u16_pot = au16_buffer[u8_i];
131  f_pot = 3.3 / ADC_NSTEPS * u16_pot;
132  printf("r");
133  if (u8_i < 10)
134  outChar( '0'+u8_i );
135  else
136  outChar( 'A'-10+u8_i );
137 #ifdef SMALLRAM
138  {
139  uint16_t ui16_potmv;
140  ui16_potmv = f_pot*1000;
141  printf(":0x%04X=%d mV ", u16_pot, ui16_potmv );
142  }
143 #else
144  printf(":0x%04X=%1.3fV ", u16_pot, (double) f_pot );
145 #endif
146  if ((u8_i % 4) == 3) printf("\n");
147  } //end for()
148  printf("\n");
149 
150  doHeartbeat();
151  DELAY_MS(1500);
152 
153  } //endof while()
154 } // endof main()
155