示例#1
0
文件: main.c 项目: KennyRIM/OpenTag
void sub_adc_measurement(ot_int* buffer) {
/// This is a blocking ADC capture routine.  It should run in 50us or less.

    /// 1. Universal ADC config
    ///    <LI> Reset REFMSTR, REFVSEL_1 = 2.0V </LI>
    ///    <LI> Voltage Tsample > 1.2us, Temp Tsample > 30us, so use ADCCLK/32
    ///         for Voltage, ADCCLK/768 for Temp.</LI>
    ///    <LI> Also in ADCCTL0, use multisample mode, use REF=2.0V </LI>
    ///    <LI> Use MEM7 (Temp) & MEM8 (Volt), Use internal sampling timer, use MODCLK </LI>
    ///    <LI> Use 12 bit mode, use fast mode </LI>
    ///    <LI> MEM7 is Temp, MEM8 is Volt </LI>
    REFCTL0     = REFMSTR + REFON + REFVSEL_1;
    ADC12CTL0   = 0;
    ADC12CTL0   = ADC12SHT1_3 + ADC12SHT0_7 + ADC12MSC + ADC12REFON + ADC12ON;
    ADC12CTL1   = ADC12CSTARTADD_7 + ADC12SHP + ADC12CONSEQ_1;
    ADC12CTL2   = ADC12RES_2;
    ADC12MCTL7  = ADC12SREF_1 + ADC12INCH_10;
    ADC12MCTL8  = ADC12SREF_1 + ADC12INCH_11 + ADC12EOS;

    /// 2. Start ADC and Wait for ADC to finish.  Wait 75us for REF.
    ///    Grab the data, then kill everything
    platform_swdelay_us(75);
    ADC12CTL0  |= ADC12ENC;
    ADC12CTL0  |= ADC12SC;
    while ((ADC12CTL1 & ADC12BUSY) == ADC12BUSY);

    ADC12CTL0  &= ~(ADC12ENC | ADC12SC);
    ADC12CTL0  &= ~(ADC12ON + ADC12REFON);
    REFCTL0    &= ~(REFMSTR + REFON + REFGENACT);

    /// 3. Convert Temperature:
    ///@todo Build a Fixed-Point Model instead of this heavy floating point one.
    ///
    /// This temperature conversion method pulls device-specific calibration
    /// data from the TLV space and uses it to produce a linear model to map
    /// the acquired ADC value.
    {
        float val_dC;
        val_dC      = tmodel.slope_dC*(float)ADC12MEM7 + tmodel.offset_dC;
        buffer[0]   = (ot_int)val_dC;
    }

    /// 4. Convert Voltage:
    /// Vdd is acquired as 12 bit number representing Vdd/2 in 1/4095V units.
    /// x(V) = 4095*(Vdd/2)/1.93V; x(mV) = (4095/2*1930mV)Vdd ~= Vdd
    //buffer[1]   = volt;                           // Cheap way, not accurate
    buffer[1]   = (ot_int)((float)ADC12MEM8 * (3860.f/4095.f));      // Higher accuracy method
}
示例#2
0
void sub_adc_measurement(ot_int* buffer) {
/// This is a blocking ADC capture routine.  It should take about 1.6 ms.
/// @todo change the algorithm to fixed-point.
    float scratch;

    ADC12CTL0   = 0;

    // Reset REFMSTR to hand over control to: REFVSEL_1 = 2.0V, ADC12_A ref control registers  
    REFCTL0     = REFMSTR + REFON + REFVSEL_1;    
    ADC12CTL0   = ADC12SHT1_12 + ADC12SHT0_12 + ADC12REFON + ADC12ON + ADC12MSC;                        
    ADC12CTL1   = ADC12SHP + ADC12CONSEQ_1;     // enable sample timer
    ADC12CTL2   = ADC12RES_2 + ADC12SR;         // 12-bit mode, 50ksps
    ADC12MCTL0  = ADC12SREF_1 + ADC12INCH_10; 
    ADC12MCTL1  = ADC12SREF_1 + ADC12INCH_11 + ADC12EOS;      

    // REFO is supposed to startup in 25us...
    platform_swdelay_us(25);
    
    // Start conversion
    ADC12CTL0  |= ADC12ENC;
    ADC12CTL0  |= ADC12SC; 
  
    while ((ADC12CTL1 & ADC12BUSY) == ADC12BUSY);

    ///@note I think floats are bad, but at the moment I don't care to untangle
    ///      this knot into fixed-point (same goes for below)
    scratch     = (float)ADC12MEM1;
    scratch     = ((scratch * 2.0f / 4095) * 2 * 1000 - 100);
    buffer[0]   = (ot_int)scratch;
    
    scratch     = (float)ADC12MEM0;
    scratch     = ((scratch * 2.0f / 4095) * 100);
    scratch     = scratch*24.0f/725*100;
    buffer[1]   = (ot_int)scratch;
    
    // Shut everything down
    ADC12CTL0  &= ~(ADC12ENC | ADC12SC);
    ADC12CTL0  &= ~(ADC12ON + ADC12REFON);
    REFCTL0    &= ~(REFMSTR + REFVSEL_2 + REFON + REFGENACT); 
}