Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

adc12_single.c

By: a guest on Nov 3rd, 2011  |  syntax: C  |  size: 4.55 KB  |  views: 40  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1.  
  2. #include "io430.h"
  3.  
  4.  
  5. void SetConversion(unsigned int value);
  6. unsigned int GetConversion(void);
  7. void WaitConversion(void);
  8.  
  9. #define NUMBER_SAMPLES  (3)
  10.  
  11. void SetDCORegisters(unsigned char bcsctl, unsigned char dcoctl)
  12. {
  13.     char    current_rsel = (BCSCTL1 & 0x0F);
  14.     char    new_rsel = (bcsctl & 0x0F);
  15.  
  16.     /* Clear DCO bits initially to prevent going over
  17.      * frequency during change (see device errata sheet).
  18.      */
  19.     DCOCTL = 0;
  20.  
  21.     /* Apply intermediate step */
  22.     if ((current_rsel > 13 && new_rsel < 13) |
  23.         (current_rsel < 13 && new_rsel > 13))
  24.     {
  25.         BCSCTL1 = (BCSCTL1 & 0xF0) | 13;
  26.     }
  27.  
  28.     /* Set new range */
  29.     BCSCTL1 = (BCSCTL1 & 0xF0) | bcsctl;
  30.  
  31.     /* Set target DCO and modulation fields */
  32.     DCOCTL = dcoctl;
  33. }
  34.  
  35. int main( void )
  36. {
  37.     unsigned int    sample;
  38.     unsigned int    samples[NUMBER_SAMPLES] = {0};
  39.     int             sample_index;
  40.     unsigned long   total;
  41.  
  42.     /* Stop watchdog timer to prevent time out reset */
  43.     WDTCTL = WDTPW + WDTHOLD;
  44.  
  45.     if ((CALDCO_1MHZ != 0xFF) && (CALBC1_1MHZ != 0xFF))
  46.     {
  47.         SetDCORegisters(CALBC1_1MHZ, CALDCO_1MHZ);
  48.     }
  49.     BCSCTL2 = (BCSCTL2 & ~(DIVM1|DIVM0|DIVS1|DIVS0)) | DIVM_0 | DIVS_0;
  50.  
  51.     /* Wait for oscillator startup */
  52.     while (IFG1_bit.OFIFG)
  53.     {
  54.         unsigned char tdelay = 0xFF;
  55.         IFG1_bit.OFIFG = 0;
  56.         while (tdelay > 0)
  57.         {
  58.             tdelay--;
  59.         }
  60.     }
  61.  
  62.     __enable_interrupt();
  63.  
  64.  
  65.     while (1)
  66.     {
  67.         total = 0;
  68.  
  69.         /* Ensure ADC12 is configurable */
  70.         ADC12CTL0 &= ~ENC;
  71.  
  72.         /* Convert from memory control 0,
  73.          * Use ADC12SC for S/H
  74.          * Use pulse mode for sample timing
  75.          * Do not invert S/H signal
  76.          * ADC12 clock divider = 1
  77.          * Sourced from ACLK
  78.          * Repeat single channel mode
  79.          */
  80.         ADC12CTL1 = CSTARTADD_0 | SHS_0 | SHP | ADC12DIV_0 | ADC12SSEL_1 | CONSEQ_0;
  81.  
  82.         /* Select input range from internal Vref+ to AVss and temperature sensor channel */
  83.         ADC12MCTL0 = SREF_1 | INCH_10;
  84.  
  85.         /* Clear any pending interrupt for result 0 */
  86.         ADC12IFG &= ~BIT0;
  87.  
  88.         /* Enable interrupts for result 0 */
  89.         ADC12IE |= BIT0;
  90.  
  91.         /* Complete configuration and enable conversions.
  92.          * Don't care about SHT1x
  93.          * Sample hold time is 4 ADC12CLKs @ 32768 = 122us (needs to be minimum 30us for temperature channel)
  94.          * Multiple Sample and Convert (MSC) set for repeated conversion
  95.          * Reference voltage 2.5
  96.          * Enable reference
  97.          * Enable ADC12
  98.          * No MEMx overflow
  99.          * No conversion time overflow
  100.          * Enable conversions
  101.          */
  102.         ADC12CTL0 = SHT0_0 | REF2_5V | REFON | ADC12ON | ENC;
  103.  
  104.         for (sample_index = 0; sample_index < NUMBER_SAMPLES; ++sample_index)
  105.         {
  106.             /* Start conversion - could be done at same time as above statement,
  107.              * could have ENC set along with it. Can also set up once and just use
  108.              * this for each conversion (only works when SC is the trigger).
  109.              */
  110.             ADC12CTL0 |= ADC12SC;
  111.             WaitConversion();
  112.  
  113.             sample = GetConversion();
  114.             samples[sample_index] = sample;
  115.             total += sample;
  116.         }
  117.  
  118.         // Disable ADC12
  119.         /* Disable conversions so we can configure the module */
  120.         ADC12CTL0 &= ~(ENC);
  121.  
  122.         /* Disable reference and module */
  123.         ADC12CTL0 &= ~(REFON | ADC12ON);
  124.  
  125.         /* Disable interrupts */
  126.         ADC12IE &= ~BIT0;
  127.     }
  128. }
  129.  
  130.  
  131. #pragma vector=ADC12_VECTOR
  132. __interrupt void ADC12ISR(void)
  133. {
  134.     switch (__even_in_range(ADC12IV, ADC12IV_ADC12IFG15))
  135.     {
  136.         case ADC12IV_ADC12IFG0:
  137.             SetConversion(ADC12MEM0);
  138.             __low_power_mode_off_on_exit();
  139.             break;
  140.  
  141.         default:
  142.             break;
  143.     }
  144. }
  145.  
  146. static volatile unsigned int    s_conversion_complete;
  147. static volatile unsigned int    s_sample;
  148.  
  149. void SetConversion(unsigned int value)
  150. {
  151.     s_sample = value;
  152.     s_conversion_complete = 1;
  153. }
  154.  
  155. unsigned int GetConversion(void)
  156. {
  157.     unsigned int value;
  158.     ADC12IE &= ~BIT0;
  159.     value = s_sample;
  160.     ADC12IE |= BIT0;
  161.     return (value);
  162. }
  163.  
  164.  
  165. void WaitConversion(void)
  166. {
  167.     unsigned int wait;
  168.  
  169.     __disable_interrupt();
  170.     wait = s_conversion_complete;
  171.     while (0 == wait)
  172.     {
  173.         __low_power_mode_3();
  174.         __disable_interrupt();
  175.         wait = s_conversion_complete;
  176.     }
  177.     s_conversion_complete = 0;
  178.     __enable_interrupt();
  179. }
  180.  
  181.