PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
adc4simul.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 // setup an output to help us measure ADC IRQ responses
39 #define CONFIG_LED2() CONFIG_RB5_AS_DIG_OUTPUT()
40 #define LED2 _LATB5
41 
42 #define ADC_LEN 10
43 #define ADC_NSTEPS 1024
44 #define ADC_12BIT_FLAG 0
45 
46 uint16_t au16_buffer[8];
47 volatile uint16_t au16_sum[8];
48 volatile uint8_t u8_gotData;
49 
50 /***
51  *** HERE IS THE CODE!
52  ***
53  ***/
54 void _ISR _ADC1Interrupt (void) {
55  static uint8_t u8_adcCount=64;
56  uint8_t u8_i;
57  uint16_t* au16_adcHWBuff = (uint16_t*) &ADC1BUF0;
58 
59  /* If ADC is writing in the 2nd half of the buffer, so determine which
60  * half of the buffer is valid (and caused this interrupt), then fetch
61  * that half into our local array of ADC results.
62  */
63  if (AD1CON2 & ADC_ALT_BUF_STATUS_2) {
64  for ( u8_i=0; u8_i<8; u8_i++) {
65  au16_buffer[u8_i] += au16_adcHWBuff[u8_i];
66  } //end for()
67  } else {
68  for ( u8_i=8; u8_i<16; u8_i++) {
69  au16_buffer[u8_i-8] += au16_adcHWBuff[u8_i];
70  } //end for()
71  } // end if-else
72 
73  _AD1IF = 0; //clear the interrupt flag
74  // we got the data, so start the sampling process again
75  SET_SAMP_BIT_ADC1();
76 
77  u8_adcCount--;
78  if (u8_adcCount==0) {
79  u8_adcCount = 64;
80  u8_gotData = 1;
81  for ( u8_i=0; u8_i<8; u8_i++) {
82  au16_sum[u8_i] = au16_buffer[u8_i];
83  au16_buffer[u8_i] = 0;
84  } //end for()
85  };
86 
87  // toggle an LED so we can measure how often ADC IRQs are coming in
88  LED2 = !LED2;
89 }
90 
91 /** \file
92  * Simultaneously samples four channels and uses a timer used to trigger conversions.
93  * Ping-pong buffering is used.
94  * Conversion results are printed to screen.
95  * (HEX values and voltages are printed.)
96  * This is only for PIC24 CPUs without DMA.
97 */
98 
99 int main (void) {
100  uint8_t u8_i;
101  uint16_t u16_pot;
102  uint32_t u32_ticks;
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_AN2_AS_ANALOG();
112  CONFIG_AN12_AS_ANALOG();
113 
114  CONFIG_LED2();
115 
116  u8_gotData = 0;
117 
118  // configure T2/T3 as 32-bit timer to trigger every 1/64 second
119  T3CONbits.TON = 0;
120  T2CONbits.TON = 0;
121  T2CON = T2_32BIT_MODE_ON | T2_PS_1_1 | T2_SOURCE_INT;
122  TMR3 = 0;
123  TMR2 = 0;
124  u32_ticks = usToU32Ticks(15625, getTimerPrescale(T2CONbits)) - 1; // # of ticks for 1/64 seconds
125  PR3 = u32_ticks>>16;
126  PR2 = u32_ticks & 0xFFFF;
127  T2CONbits.TON = 1;
128 
129  configADC1_Simul4ChanIrq(12, ADC_CH123_POS_SAMPLEA_AN0AN1AN2, ADC_CONV_CLK_10Tcy );
130  SET_SAMP_BIT_ADC1();
131 
132  while (1) {
133  while (!u8_gotData) {
134  doHeartbeat();
135  }
136  u8_gotData = 0;
137  for ( u8_i=0; u8_i<4; u8_i++) {
138  u16_pot = au16_sum[u8_i];
139  f_pot = (3.3 / 1023 / 64 ) * u16_pot;
140  printf("r");
141  outChar( '0'+u8_i );
142 #ifdef SMALLRAM
143  {
144  uint16_t ui16_potmv;
145  ui16_potmv = f_pot*1000;
146  printf(":0x%04X=%d mV ", u16_pot, ui16_potmv );
147  }
148 #else
149  printf(":0x%04X=%1.3fV ", u16_pot, (double) f_pot );
150 #endif
151  } //end for()
152  printf("\n");
153  } //endof while()
154 } // endof main()