This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello all,
I am working with an MSP430F5529 USB Experimenter's Board. I am using the following code snippet.
The code is successfully storing the sample values into signal_vector. I am able to display them on the LCD screen.
I would like to sample from another ADC pin, and display those conversion results simultaneously.
Would I be able to add lines to this existing code to read from multiple pins, or would I have to restructure the code entirely?
Thanks!
-Vincent
EDIT: How viable would it be to add the highlighted lines (to use P6.6 additionally)? I am trying it out now. Would there be a possibility for timing issues or other errors?
//*****************************************************************************
// Acquire signal on channel A7
//*****************************************************************************
void AcquireSignal(void)
{
unsigned char i;
// ADC configuration
ADC12CTL0 = ADC12SHT02 + ADC12ON; // Sampling time 16 cycles, ADC12 on
ADC12CTL1 = ADC12CSTARTADD_7 + ADC12SHP; // Use sampling timer
ADC12CTL1 = ADC12CSTARTADD_6 + ADC12SHP;
ADC12MCTL7 = ADC12INCH_7; // Use A7 as input
ADC12MCTL6 = ADC12INCH_6;
ADC12CTL0 |= ADC12ENC; // Enable conversions
P6SEL |= BIT7; // P6.7 ADC option select (A7)
P6SEL |= BIT6;
// Timer configuration
TA0CCTL0 = CCIE; // CCR0 interrupt enabled
TA0CCR0 = freq; // Sampling frequency
TA0CTL = TASSEL_2 + MC_1 + TACLR; // SMCLK, upmode, clear TAR
// Trigger off
trigger = 0; // Turn off trigger flag
i = 0; // Sample counter
while(i < 90)
{
__bis_SR_register(LPM0_bits + GIE); // LPM0, TimerA0 ISR will force exit
ADC12CTL0 |= ADC12SC; // Start sampling/conversion
while (!(ADC12IFG & BIT7)); // wait channel A7 EOC
while (!(ADC12IFG & BIT6));
if (trigger == 0) // If trigger flag is off
{ // check sample
if ((ADC12MEM7 >> 6) > val_level) trigger = 1; // Trigger flag is on
}
if (trigger == 1) // If trigger flag is on
{
signal_vector [i] = 54 - ( ADC12MEM7 >> 6); // Store sample
if (signal_vector [i] > 53) signal_vector [i] = 54;
if (signal_vector [i] < 10) signal_vector [i] = 10;
//store value from P6.6 in a similar fashion
i++; // Increment sample counter
}
}
TA0CTL = 0x00; // Stop TimerA0
}
The ADC12 can only sample one input channel at a time. However, it can work on a 'list' of input channels, one after another.
To do so, you program one ADC12MCTLx (x = 0..15) for each input channel. 'x' is just an index number and not related to the input pin, so you can start with ADC12MCTL0, even if the first channel to sample is A6. The number of this first ADC12MCTLx register for such a 'sequence' is the one to write at ADC12CTL1. The last ADC12MCTLx gets the EOS bit set to indicate the end of the sequence. You can configer the individual ADC12MCTLx register for any input channel.
Next is that you need to tell the ADC12 that it shall sample a sequence. THis is done by setting ADC12CONSEQ_1
You may also chose to either trigger each conversion of teh sequence individually, or do them all at once as fast as possible. In the latter (recommended) case, set ADC12MSC bit.
Now you start the ocnversion by setting the ADC12SC bit and when it clears again (or when the ADC12IFG.x bit of the last index of the sequence is set), you'll have the result for the channel configured in ADC12MCTLx in ADC12MEMx.
It is a bad choice that in your demo code, the ADC12MCTL7 register was used to sample A/ input, as this implies a connection between ADC12MCTLx and Ax that doesn't exist. Your sequence may as well be "A5,A3,A6,A3" (note the duplicate, so A3 is sample dtwice as often as the others) or anything else.
Jens-Michael Gross said:It is a bad choice that in your demo code...
I often find that the example/demo code does not necessarily demonstrate the best way to accomplish a task, especially when thinking in terms of incorporating the functionality into a larger program.
You're so right. Unfortunately, the demo codes, as they are, are the first thing noewcomers will see. So they start with them, often (as to be expected) without knowing why and how they work.Brian Boorman said:I often find that the example/demo code does not necessarily demonstrate the best way to accomplish a task, especially when thinking in terms of incorporating the functionality into a larger program.
Hi Jens-Michael,
Thank you for your response. I have not had the chance to try out your suggestion. I would like to discuss what I have worked out for learning purposes and then try your suggestions.
I have implemented code similar to what i posted above (less the highlighted portions) as follows:
{1} AcquireSignal()
Reads 90 samples from P6.6, stores to signal_vector[ ]
{2} AcquireSignal2()
Reads 90 samples from P6.7, stores to signal_vector2[ ]
{3} AcquireSignal3()
Reads 90 samples from P7.0, stores to signal vector3[ ]
What my program currently doing is calling all three of these and then printing the results to the LCD. However, different ordering of this process results in unexpected/undesired behavior (ie {1} - {2} - {3} has unexpected results, {3} - {2} - {1} functions correctly). Where in the code is the mux actually switching the input pin? I understand my implementation is not the best way to approach this, but I suspect that the undesirable behavior is a result of improper mux switching.
It's not so simple.Vincent Din said:Where in the code is the mux actually switching the input pin?
You can imagine the ADC12MCTLx registers as lines of a script. Each ADC12MCTLx register defines several actions: Input pin to use, reference to use, and whether this is the last 'line' of the 'script'.
ADC12STARTADD_x in ADC12CTL1 defines, on which 'line' of the 'script' to start. Depending on the conversion mode, it staretrs with this ADC12MCTLx register and converts depending on the settings found there, then either stops (single conversion), repeats (repeated single conversion) or continues with the next ADC12MCTLx register, doing what is defined there (sequence) until it reaches oen with the EOS (end of sequence) bit set.
Thsi way, you can program sequence of up to 16 independent conversions, and for each one you can freely define which input puin to use, which reference (internal, external or VCC, but you cannot switch between internal 1.5 and 2.5V) to use and whether it is the last one of a sequence.
You can even pre-define multiple independent sequences and then start one or the other (with ADC12STARTADD_x) when you need them. Or you have a sequence but sometimes run the second half only and sometimes the complete number of conversions, depending on where you set ADC12STARTADD_x.
In your code, when you run one input n times, then the next one for n times, you can either change the input channel in the ADC12MCTLx register or program different ADC12MCTLx registers and change the ADC12STARTADD_x setting.
Note that before changing the ADC12STARTADD_x value, or any of the ADC12MCTLx registers, you need to clear the ADC12ENC bit first. All bits that are grey on the users guide register description can only be modified safely when a certain other bit is set or cleared (e.g. SWRST for the USCI). Else the outcome is undefined.
**Attention** This is a public forum