Jump to content


  • Content Count

  • Joined

  • Last visited

Reputation Activity

  1. Like
    ahgan84 reacted to gwdeveloper in About DMA on ADC12.   
    Hello ahgan84, I looked at the code you posted on E2E. For scanning all 15 channels, you're probably going about it the wrong way. You can use the multi-sample, repeat-sequence (CONSEQ_3) modes of the ADC instead of turning the ADC off and on to change channels. That method (in my example) was only implemented to eliminate scanning of all channels when only 12-14 were needed. The issue with repeat-sequence is that if you want to sample channels 3-5, you will be sampling 0-5 -you only pick the last channel of the sequence. If you change to that method, your loop becomes 1/14th of what it was. You will only need once "while(adcbusy)"
    Yes, sample less times. Less clock cycles per sample. Bitwise Division.
    Use the repeat-sequence mode. You were right about the minor changes. You will also need to increase the size of the ADCdata storage array to the # of samples * # of channels. Then it's just about filtering each channels data.
    For example:(I pulled this from some code where I sample 6 channels, repeat-sequence)

    right_cal = 0; for (r=ADCRIGHT; r < MAXADC; r+=6) { right_cal += ADCdata[r]; } right_cal /= SAMPLES;
    You'll notice that the incrementer is increased by 6 each time. So, this will filter the data for channel 5. The array is 48 bytes, which is 6 channels, 8 samples each.
    And here is just a quick copy from some of adc10 code. It's a loop(repeats 50 times) that samples the 6 channels and averages each of the 2 channels needed.

    void ADC10_init(void) { ADC10CTL0 &= ~ENC; ADC10CTL0 = ADC10ON + MSC + ADC10SHT_2 + SREF_0; ADC10CTL1 = CONSEQ_3 + ADC10SSEL_1 + ADC10DIV_0 + SHS_0 + INCH_5; ADC10AE0 = 0x30; ADC10DTC0 = ADC10CT; ADC10DTC1 = 48; ADC10SA = (unsigned int)ADCdata; ADC10CTL0 |= ENC; } // collect 50 averaged samples for calibration of phototransistors for (i = 0; i < 50; i++) { // sample ADC10 and use DTC ADC10CTL0 &= ~ENC; while (ADC10CTL1 & BUSY); // Wait if ADC10 core is active ADC10SA = (unsigned int)ADCdata; // Data buffer start ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start for (c = 0; c < 3; c++) { shiftByte(color[c]); __delay_cycles(25000); } // get float of left channel P1.4 left_cal = 0; for (l=ADCLEFT; l < MAXADC; l+=6) { left_cal += ADCdata[l]; } left_cal /= SAMPLES; // get float of right channel P1.5 right_cal = 0; for (r=ADCRIGHT; r < MAXADC; r+=6) { right_cal += ADCdata[r]; } right_cal /= SAMPLES; } }
    Also, for the oversampling, check out the recent post by dangerous prototypes. http://dangerousprototypes.com/2012/01/01/app-note-enhancing-adc-resolution-by-oversampling/
  2. Like
    ahgan84 reacted to gwdeveloper in About DMA on ADC12.   
    There are values for TBCCR0 and TBCCR1, because that's how TI created their example. You can configure the Timer in multiple ways and for different windows. Using their example, the window is between 0xFFFE (65,535-1) and 0x8000 (32768). Ultimately, those example numbers are arbitrary and can be adjusted for your needs. This means you determine the values for the CCR registers.
    You do not need to use a Timer to trigger the ADC. In can be triggered by software. There is no "better" method, it's all on how you want to write your program. Need all the Timers for other functions? Use software control. Have an extra TimerA or TimerB? Use one of those.
    The comment states block address because that's how the writer viewed it. My init is commented in the way that I view it:

    __data16_write_addr( (unsigned short)&DMA0SA, (unsigned long)&ADC12MEM0 ); // dma single source address __data16_write_addr( (unsigned short)&DMA0DA, (unsigned long)&ADCdata[0] ); // destination array
    That simply shows that we are sourcing from ADC12MEM0 as our single source address register. The destination, in my example, is an array as 64 samples will be sampled so the data is stored. The DMA settings determine how the destination address will be incremented.

    // repeat; increment dest address; enable dma; enable interrupt; high level DMA0CTL = DMADT_4 + DMADSTINCR_3 + DMAEN + DMAIE + DMALEVEL;
    I don't like how TI's example creates the destination address as DMA_DST. With all caps, it almost makes it look like a DMA register and not a storage variable. If you look at the beginning of the code it's "unsigned int DMA_DST". The example is simply enabling the DMA and writing ADC12MEM0 to the variable DMA_DST. With my example, the DMA moves ADC12MEM0 to ADCdata[x]. 'x' is incremented by the DMA, where the maximum of x is the block size; 64 in my case.
    I'd really recommend that you read the TimerA (or , ADC12 and DMA sections of the slaa144h (MSP430x2xx Family
    User's Guide). Also, search the web for "MSP430 Timer" and "MSP430 DMA".
  3. Like
    ahgan84 reacted to TopHatHacker in About I2C in msp430.   
    well i may be whhhaaaaay off but the way i've used i2c in the past is set a variable/flag/message/something so that the next time the master polls for information, whatever info you wanted to give to the master, the master will come and get it. I don't think it does transmit and receive in the traditional sense, but in programming you can implement something. I believe its mostly for getting information from peripherals.. the only time i've used it was to get 3axis data off a wii nunchuck. oh and here's the wiki on i2c.. not sure it helps anything... but i did go through the effort of googling for it, so you can have it http://en.wikipedia.org/wiki/I%C2%B2C
    I'm sure there will be a post after this one that explains i2c in a better fashion
  4. Like
    ahgan84 reacted to nobody in About simultaneous converting for ADC12   
    No. It is impossible.
    Use chip with more than one independent ADC's (like MSP430AFE2xx). Or use external sample and hold devices.
  5. Like
    ahgan84 reacted to bluehash in Reduce noise on ADC12   
    No, you cannot use Veref+, Vref-/Veref-, Temperature diode, AVcc-AVss/2 as ADCs.
  6. Like
    ahgan84 reacted to gwdeveloper in About I2C   
    Hello ahgan84. You'll want to refer to the MSP430x2xx Family User's Guide, slaa144h.pdf. [tipdf]slau144h[/tipdf] 14.1 covers devices with the Universal Serial Interface (USI) and 17.1 covers devices with the Universal Serial Communications Interface (USCI) I2C modes.
    Basically, if your device has USI, you won't use UCBxTXBUF at all. And if you have USCI, you won't use USISRL.
  7. Like
    ahgan84 reacted to gwdeveloper in About ADC   
    Reference voltage = "the largest signal the ADC is to convert for comparisons"
  8. Like
    ahgan84 reacted to xpg in About ADC   
    Correct, though in the opposite order (A7, then A6 down until A0).
  9. Like
    ahgan84 reacted to pabigot in About the ADC workshop tutorial (Lab4).   
    What xpg said. One thing to be aware of is that the offset (error) for a particular part can be as much as as 20 degrees in either direction, making calibration pretty important. In fact, in higher-end parts, the measured ADC values at at 30 Cel and 85 Cel for each reference voltage are stored in the TLV section , and measurement is done by linear interpolation between those values rather than assuming a fixed delta per degree. Strong recommendation to at least do a single-point calibration.
    INCH_11 is also interesting as it measures V_MID (V_CC/2.0), letting you know what voltage is being provided to the chip. This can give you an indication that battery levels are dropping enough to affect the performance of other components on the board, and help ensure comparability for measurements over time or between devices that might be influenced by available power (such as a radio).
    Other ADC applications include soil moisture sensors, ambient light intensity measurement via a photo diode or resistor, etc.
  10. Like
    ahgan84 reacted to xpg in About the ADC workshop tutorial (Lab4).   
    The ADC10 supports multiple external input channels and has various internal ones as well (where channel 10 is the internal temperature sensor). So, INCH_10 specifically selects the internal temperature sensor.
    The raw value as generated from the ADC10 can be converted into a voltage using the formula provided in the section 22.2.1 of the MSP430x2xx Family User's Guide (assuming that the ADC10 is configured for straight binary format):

    tempraw = 1023 * (Vin - Vr-) / (Vr+ - Vr-)
    SREF_1 is set and the reference is 1.5V, Vr+ is 1.5V and Vr- is Vss (0V), the formula ends up being:

    tempraw = 1023 * Vin / 1.5 => Vin = tempraw*1.5 / 1023
    From the voltage the temperature can be calculated by using the formula in section 22.2.8 of the User's Guide:

    V=0.00355(TEMPC)+0.986 => TEMPC = (V-0.986)/0.00355
    A tempraw value of 734 corresponds to 1.08V, which in turn corresponds to 25.4 degrees celcius.
  • Create New...