Advertisement
Guest User

adc12.c

a guest
Nov 3rd, 2011
198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.54 KB | None | 0 0
  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_2;
  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 | MSC | REF2_5V | REFON | ADC12ON | ENC;
  103.  
  104.         /* Start conversion - could be done at same time as above statement,
  105.          * could have ENC set along with it. Can also set up once and just use
  106.          * this for each conversion (only works when SC is the trigger).
  107.          */
  108.         ADC12CTL0 |= ADC12SC;
  109.  
  110.         for (sample_index = 0; sample_index < NUMBER_SAMPLES; ++sample_index)
  111.         {
  112.             WaitConversion();
  113.  
  114.             sample = GetConversion();
  115.             samples[sample_index] = sample;
  116.             total += sample;
  117.         }
  118.  
  119.         // Disable ADC12
  120.         /* Disable conversions so we can configure the module */
  121.         ADC12CTL0 &= ~(ENC);
  122.  
  123.         /* Disable reference and module */
  124.         ADC12CTL0 &= ~(REFON | ADC12ON);
  125.  
  126.         /* Disable interrupts */
  127.         ADC12IE &= ~BIT0;
  128.     }
  129. }
  130.  
  131.  
  132. #pragma vector=ADC12_VECTOR
  133. __interrupt void ADC12ISR(void)
  134. {
  135.     switch (__even_in_range(ADC12IV, ADC12IV_ADC12IFG15))
  136.     {
  137.         case ADC12IV_ADC12IFG0:
  138.             SetConversion(ADC12MEM0);
  139.             __low_power_mode_off_on_exit();
  140.             break;
  141.  
  142.         default:
  143.             break;
  144.     }
  145. }
  146.  
  147. static volatile unsigned int    s_conversion_complete;
  148. static volatile unsigned int    s_sample;
  149.  
  150. void SetConversion(unsigned int value)
  151. {
  152.     s_sample = value;
  153.     s_conversion_complete = 1;
  154. }
  155.  
  156. unsigned int GetConversion(void)
  157. {
  158.     unsigned int value;
  159.     ADC12IE &= ~BIT0;
  160.     value = s_sample;
  161.     ADC12IE |= BIT0;
  162.     return (value);
  163. }
  164.  
  165.  
  166. void WaitConversion(void)
  167. {
  168.     unsigned int wait;
  169.  
  170.     __disable_interrupt();
  171.     wait = s_conversion_complete;
  172.     while (0 == wait)
  173.     {
  174.         __low_power_mode_3();
  175.         __disable_interrupt();
  176.         wait = s_conversion_complete;
  177.     }
  178.     s_conversion_complete = 0;
  179.     __enable_interrupt();
  180. }
  181.  
  182.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement