I ported known working code from a 1232 part to a 2252, and want to add an ADC
input on A15. I presently use A0, and it's working correctly. I am running
the IAR IDE.
Here's my setup code for the A0 and A15 ports. A0 reads battery voltage;
A15 will read a thermistor:
TurnOffADC kills to power to both the voltage monitor and the thermistor bias
after the conversion finishes. Called from the IRQ or inline. ADC readings are
read separately, after the ADC interrupt sets a flag. The interrrupt code is
working properly, as is the A0 code.
The temperature monitor runs in two modes - one with the IRQ disabled, where the
code polls for conversion done, and in the IRQ for normal usage. Neither method
returns anything but a reading of 0x37f. I put a breakpoint in the code at the
IRQ service routine, and it shows this value in ADC10MEM. I measured the voltage
on A15, and it should resolve to 0x1c2.
Anyone see what I am missing here? I've been beating on this for a couple
of days now, with no success.
Update - I forced the thermistor drive output high in code and tried reading the
ADC again - same result. There was some concern that the ADC was not being
allowed enogh settle time before reading.
Chuck
Reply by ckuecker2000●June 23, 20092009-06-23
Still having problems with the ADC10 in the 2252. I've been in touch with
TI's help line, and they made the suggestion that I modify and test some
sample code.
That worked fine, as far as reading A15. I get numbers that jive with
reality.
I attempted to translate the settings from the sample code back into my project
with no success.
Has anyone out there ever gotten a reading from A15 on the 2252 part? If so,
could you share your port setups and ADC setups, please? Until I solve this
problem, I'm going nowhere fast.
Reply by Hugh Molesworth●June 23, 20092009-06-23
You don't show the sequence of calls to the functions; when do you
call TurnOffADC()?
ie. are you doing this:
TurnOnADC();
TurnOffADC();
TurnOnADCTemp();
TurnOffADC();
or this:
TurnOnADC();
TurnOnADCTemp();
TurnOffADC();
If the former, then you might try explicitly setting ENC to '0' since
in my experience a write to ADC10CTL0 is unreliable unless ENC is set
to '0' prior to changing any other bits (this is mentioned in the
User Manual). I always do this first:
// Must disable ADC10 convertor before changing anything
ADC10CTL0 &= ~(ENC);
Hugh
At 08:37 AM 6/22/2009, you wrote:
Hello,
I ported known working code from a 1232 part to a 2252, and want to
add an ADC input on A15. I presently use A0, and it's working
correctly. I am running the IAR IDE.
Here's my setup code for the A0 and A15 ports. A0 reads battery
voltage; A15 will read a thermistor:
TurnOffADC kills to power to both the voltage monitor and the
thermistor bias after the conversion finishes. Called from the IRQ or
inline. ADC readings are read separately, after the ADC interrupt
sets a flag. The interrrupt code is working properly, as is the A0 code.
The temperature monitor runs in two modes - one with the IRQ
disabled, where the code polls for conversion done, and in the IRQ
for normal usage. Neither method returns anything but a reading of
0x37f. I put a breakpoint in the code at the IRQ service routine, and
it shows this value in ADC10MEM. I measured the voltage on A15, and
it should resolve to 0x1c2.
Anyone see what I am missing here? I've been beating on this for a
couple of days now, with no success.
The 'TurnOn' functions are called to start a conversion. The
present
code only uses the interrupt-driven version of the temperature reading.
The IRQ handler sets a flag, and the reading is taken in the main loop
if the flag is set. The 'TurnOffADC' call is made after reading the
ADC
value in all cases.
My A0 reading is still working fine, and A15 reliably returns 895 or
896. The TI demo code with my modifications reads A15 correctly - I can
see the value change if I put a breakpoint after the reading and put my
finger over the thermistor and remove it while running the code. Normal
room-temperature readings are around 400 counts.
It's got to be something in how the ports are set up - I feel it, but I
can't see it.
Chuck
--- In m..., Hugh Molesworth
wrote: >
> You don't show the sequence of calls to the functions; when do you
> call TurnOffADC()?
>
> ie. are you doing this:
> TurnOnADC();
> TurnOffADC();
> TurnOnADCTemp();
> TurnOffADC();
>
> or this:
> TurnOnADC();
> TurnOnADCTemp();
> TurnOffADC();
>
> If the former, then you might try explicitly setting ENC to '0'
since
> in my experience a write to ADC10CTL0 is unreliable unless ENC is set
> to '0' prior to changing any other bits (this is mentioned in the
> User Manual). I always do this first:
> // Must disable ADC10 convertor before changing anything
> ADC10CTL0 &= ~(ENC);
>
> Hugh
Reply by Hugh Molesworth●June 23, 20092009-06-23
Ah-ha!, try this:
P4SEL |= 0x40; // P4.6 should be ADC input
Also P4.6 is also set as an output, not an input, when an i/o port.
It's not terribly well documented which port pin directions are
controlled by PxSEL and which are not, and I would advise the
following (which you were doing at one time):
P4OUT = 0xBF;
Hugh
At 01:26 PM 6/23/2009, you wrote:
>My newest, also non-working, code:
>
>void TurnOnADC(void)
>{
> ADC10CTL0 &= ~ENC; // Allow changes to ADC10CTL0 and ADC10CTL1
> P2OUT |= POUT_BATTERY_CHECK;
> ucADCSampled = FALSE;
> ADC10CTL1 = INCH_0; // Select Channel 0
> ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
>}
>
>void TurnOnADCTemp(uchar irq)
>{
> ADC10CTL0 &= ~ENC; // Allow changes to ADC10CTL0 and ADC10CTL1
> P4OUT |= POUT_TEMP_CHECK;
> ucADCSampled = FALSE;
> ADC10CTL1 = INCH_15; // Select Channel 15
>
> if(irq)
> {
> ADC10CTL0 |= ADC10IE; // Enable IRQ if needed
> }
>
> ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
>}
>
>void TurnOffADC(void)
>{
> ADC10CTL0 &= ~ENC;
> P2OUT &= ~POUT_BATTERY_CHECK;
> P4OUT &= ~POUT_TEMP_CHECK;
> ucADCSampled = FALSE;
>}
>My setup, done at startup:
>
> P2DIR = 0xD2; // 11010010
> P2OUT = 0x00; // 00000000
> P2SEL = 0xC0;
> P2IES = 0x20;
> P2IFG = 0x00; // Clear all Port 2 interrupt flags.
> P2IE = 0x20; // D 8-29-03 interrupt for set button on Port 2.
>
> ADC10CTL0 &= ~ENC;
> ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10SR + ADC10IE; // ADC10ON,
>interrupt enabled - was ADC10SHT_3
> ADC10AE0 = 0x01; // P2.0 ADC channel A0 select
> ADC10AE1 = 0x80; // P4.6 ADC channel A15 select
> ADC10DTC1 = 0; // Disable ADC data transfer
>
> P4DIR = 0xFF; // 0xBF; // 10111111
> P4OUT = 0x00; // 00000000
>The 'TurnOn' functions are called to start a conversion. The
present
>code only uses the interrupt-driven version of the temperature reading.
>The IRQ handler sets a flag, and the reading is taken in the main loop
>if the flag is set. The 'TurnOffADC' call is made after reading the
ADC
>value in all cases.
>
>My A0 reading is still working fine, and A15 reliably returns 895 or
>896. The TI demo code with my modifications reads A15 correctly - I can
>see the value change if I put a breakpoint after the reading and put my
>finger over the thermistor and remove it while running the code. Normal
>room-temperature readings are around 400 counts.
>
>It's got to be something in how the ports are set up - I feel it, but I
>can't see it.
>
>Chuck
>--- In m..., Hugh Molesworth
>wrote:
> >
> > You don't show the sequence of calls to the functions; when do you
> > call TurnOffADC()?
> >
> > ie. are you doing this:
> > TurnOnADC();
> > TurnOffADC();
> > TurnOnADCTemp();
> > TurnOffADC();
> >
> > or this:
> > TurnOnADC();
> > TurnOnADCTemp();
> > TurnOffADC();
> >
> > If the former, then you might try explicitly setting ENC to '0'
since
> > in my experience a write to ADC10CTL0 is unreliable unless ENC is set
> > to '0' prior to changing any other bits (this is mentioned in
the
> > User Manual). I always do this first:
> > // Must disable ADC10 convertor before changing anything
> > ADC10CTL0 &= ~(ENC);
> >
> > Hugh
>
>
>
Reply by ckuecker2000●June 23, 20092009-06-23
Hi, Hugh,
No joy. Actually, I had that setting in there earlier, along with the 0xBF for
P4OUT. Still no workee.
The TI demo code has P4OUT set to 0xFF, and it works fine. They leave P4SEL set
to the power-up default value.
Here's the TI demo code, as I modified it. I set a breakpoint right after
the conversion finished, and saw the ADC value changing as expected with
temperature while running the code:
//******************************************************************************
// MSP430F22x4 Demo - ADC10, Sample A7, 1.5V, TA1 Trig, Ultra-Low Pwr
//
// Description: A7 is sampled 1024/second (32xACLK) with reference to 1.5V.
// All activity is interrupt driven with proper usage of MSP430 low-power
// modes, ADC10 and Vref demonstrated. Timer_A with both TA1/TA0 used in
// upmode to drive ADC10 conversion (continuous mode can also be used).
// Inside of TA0_ISR software will enable ADC10 and internal reference and
// allow > 30us delay for Vref to stabilize prior to sample start. Sample
// start is automatically triggered by TA1 every 32 ACLK cycles. ADC10_ISR
// will disable ADC10 and Vref and compare ADC10 conversion code. Internal
// oscillator times sample (16x) and conversion (13x). If A7 > 0.2Vcc,
// P1.0 is set, else reset. Normal Mode is LPM3.
// //* An external watch crystal on XIN XOUT is required for ACLK *//
//
// +-----(0.9766us)---------\\------------------>+
// TA0_ISR TA1 ADC10_ISR TA0_ISR TA1
// -----+------------+------------+-----------\\------+------------+----->
// Enable ADC Trigger ADC Disable ADC
// and Vref Compare
// +-( >30us--->+
//
//
// MSP430F22x4
// -----------------
// /|\| XIN|-
// | | | 32kHz
// --|RST XOUT|-
// | |
// >---|P3.7/A7 P1.0 |--> LED
//
// A. Dannenberg
// Texas Instruments Inc.
// October 2006
// Built with IAR Embedded Workbench Version: 3.41A
//******************************************************************************
#include "msp430x22x2.h"
I do not use the timer to trigger conversions in my code - that's done by
higher level code under control by a master processor. That, unfortunately, is
the only difference I can see. Probably been staring at it too long.
I will tackle this again tomorrow - it's been a long day.
Chuck
--- In m..., Hugh Molesworth wrote: >
> Ah-ha!, try this:
> P4SEL |= 0x40; // P4.6 should be ADC input
>
> Also P4.6 is also set as an output, not an input, when an i/o port.
> It's not terribly well documented which port pin directions are
> controlled by PxSEL and which are not, and I would advise the
> following (which you were doing at one time):
> P4OUT = 0xBF;
>
> Hugh
>
> At 01:26 PM 6/23/2009, you wrote:
>
Reply by Hugh Molesworth●June 23, 20092009-06-23
I had a look at the schematic for P4.6 on the 2252 and indeed
ADC10AE1.7 does over-ride both P4DIR.6 and P4SEL.6. P4REN.6 must be
set to '0', but that should be the case on a PUC. If the pull-up were
enabled though, it might explain your readings. It might be worth a
try explicitly disabling this resistor.
Interestingly there is an errata for this resistor - PORT10:
"When the pullup/pulldown resistor for a certain port pin is enabled
(PxREN.y = 1) and the module port pin function is selected (PxSEL.y 1), the
pullup/pulldown resistor configuration of this pin is
controlled by the respective module output signal (Module X OUT)
instead of the port output register (PxOUT.y).
Workaround: None. Do not set PxSEL.y and PxREN.y at the same time."
On P4.6 the Module X OUT function is from Timer B TBOUTH.
Since INCH15 is the only link from the ADC10 to the pin, it might pay
to hardwire the pin momentarily to Gnd & then Vcc and see if the ADC
reading you are getting "follows" to some extent, which in turn might
indicate a problem with the port pin configuration.
So otherwise that leaves timing; it might pay to try inserting a
delay after you enable the port power pin before you enable the ADC10
for the temp sensor; maybe it just isn't turning on fast enough :-)
Hugh
At 01:58 PM 6/23/2009, you wrote:
Hi, Hugh,
No joy. Actually, I had that setting in there earlier, along with the
0xBF for P4OUT. Still no workee.
The TI demo code has P4OUT set to 0xFF, and it works fine. They leave
P4SEL set to the power-up default value.
Here's the TI demo code, as I modified it. I set a breakpoint right
after the conversion finished, and saw the ADC value changing as
expected with temperature while running the code:
//******************************************************************************
// MSP430F22x4 Demo - ADC10, Sample A7, 1.5V, TA1 Trig, Ultra-Low Pwr
//
// Description: A7 is sampled 1024/second (32xACLK) with reference to 1.5V.
// All activity is interrupt driven with proper usage of MSP430 low-power
// modes, ADC10 and Vref demonstrated. Timer_A with both TA1/TA0 used in
// upmode to drive ADC10 conversion (continuous mode can also be used).
// Inside of TA0_ISR software will enable ADC10 and internal reference and
// allow > 30us delay for Vref to stabilize prior to sample start. Sample
// start is automatically triggered by TA1 every 32 ACLK cycles. ADC10_ISR
// will disable ADC10 and Vref and compare ADC10 conversion code. Internal
// oscillator times sample (16x) and conversion (13x). If A7 > 0.2Vcc,
// P1.0 is set, else reset. Normal Mode is LPM3.
// //* An external watch crystal on XIN XOUT is required for ACLK *//
//
// +-----(0.9766us)---------\\------------------>+
// TA0_ISR TA1 ADC10_ISR TA0_ISR TA1
// -----+------------+------------+-----------\\------+------------+----->
// Enable ADC Trigger ADC Disable ADC
// and Vref Compare
// +-( >30us--->+
//
//
// MSP430F22x4
// -----------------
// /|\| XIN|-
// | | | 32kHz
// --|RST XOUT|-
// | |
// >---|P3.7/A7 P1.0 |--> LED
//
// A. Dannenberg
// Texas Instruments Inc.
// October 2006
// Built with IAR Embedded Workbench Version: 3.41A
//******************************************************************************
#include "msp430x22x2.h"
I do not use the timer to trigger conversions in my code - that's
done by higher level code under control by a master processor. That,
unfortunately, is the only difference I can see. Probably been
staring at it too long.
I will tackle this again tomorrow - it's been a long day.
Chuck
--- In m..., Hugh Molesworth wrote:
>
> Ah-ha!, try this:
> P4SEL |= 0x40; // P4.6 should be ADC input
>
> Also P4.6 is also set as an output, not an input, when an i/o port.
> It's not terribly well documented which port pin directions are
> controlled by PxSEL and which are not, and I would advise the
> following (which you were doing at one time):
> P4OUT = 0xBF;
>
> Hugh
>
> At 01:26 PM 6/23/2009, you wrote:
>
Reply by ckuecker2000●June 25, 20092009-06-25
Hi, Hugh,
I should let you know the outcome of this odyessey. The problem turned out to be
a bit of orphan code that was getting executed immediately after I set up to
measure A15. This code switched the ADC input back to A0 - so in effect the
'constant' I was seeing was the battery monitor voltage - which never
changes when I'm running on a bench supply.
So, all is well now, and the unit is operating as it should. Thanks for all the
suggestions.
Chuck Kuecker
--- In m..., Hugh Molesworth wrote: >
> I had a look at the schematic for P4.6 on the 2252 and indeed
> ADC10AE1.7 does over-ride both P4DIR.6 and P4SEL.6. P4REN.6 must be
> set to '0', but that should be the case on a PUC. If the pull-up
were
> enabled though, it might explain your readings. It might be worth a
> try explicitly disabling this resistor.
>
> Interestingly there is an errata for this resistor - PORT10:
> "When the pullup/pulldown resistor for a certain port pin is enabled
> (PxREN.y = 1) and the module port pin function is selected (PxSEL.y > 1), the
pullup/pulldown resistor configuration of this pin is
> controlled by the respective module output signal (Module X OUT)
> instead of the port output register (PxOUT.y).
> Workaround: None. Do not set PxSEL.y and PxREN.y at the same time."
> On P4.6 the Module X OUT function is from Timer B TBOUTH.
>
> Since INCH15 is the only link from the ADC10 to the pin, it might pay
> to hardwire the pin momentarily to Gnd & then Vcc and see if the ADC
> reading you are getting "follows" to some extent, which in turn might
> indicate a problem with the port pin configuration.
>
> So otherwise that leaves timing; it might pay to try inserting a
> delay after you enable the port power pin before you enable the ADC10
> for the temp sensor; maybe it just isn't turning on fast enough :-)
>
> Hugh