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.

sample code problem, analog to digital converter.



I am currently working on a project where i need the adc conversion functionality of the msp430 so I started with some of the provided example code, specifically msp430g2x33_adc10_02 provided on Ti's website. The exact code is as follows:

#include <msp430.h>

int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE;
__enable_interrupt(); // Enable interrupts.
TACCR0 = 30; // Delay to allow Ref to settle
TACCTL0 |= CCIE; // Compare-mode interrupt.
TACTL = TASSEL_2 | MC_1; // TACLK = SMCLK, Up mode.
LPM0; // Wait for delay.
TACCTL0 &= ~CCIE; // Disable timer Interrupt
__disable_interrupt();
ADC10CTL1 = INCH_1; // input A1
ADC10AE0 |= 0x02; // PA.1 ADC option select
P1DIR |= 0x01; // Set P1.0 to output direction

for (;;)
{
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
__bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exi
if (ADC10MEM < 0x88) // ADC10MEM = A1 > 0.2V?
P1OUT &= ~0x01; // Clear P1.0 LED off
else
P1OUT |= 0x01; // Set P1.0 LED on
}
}

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
}

#pragma vector=TIMER0_A0_VECTOR
__interrupt void ta0_isr(void)
{
TACTL = 0;
LPM0_EXIT; // Exit LPM0 on return
}



my problem is with p1.1, this code is supposed to be sampling this pin (A1 aka p1.1) but is outputting a voltage of 3.52 volts. Why is this, and how do i get it to stop outputting and take in an input like the code says its supposed to do? Also I have the Msp4302553 version.

thanks in advance ! 

  • Hi Garret,

    At a quick glance it appears you never explicitly set P1.1 as an input, you only configure the ADC to sample this pin.

    When you set P1.0 as an output you are only modifying that bit in the register, all others remain untouched. P1.1 is probably set and you have to clear it.

    You could change this line of code;    

    P1DIR |= 0x01; // Set P1.0 to output direction

    To this, if your hardware allows for all other pins on port 1 to be inputs;

    P1DIR = 0x01; // Set P1.0 to output direction, P1.1 - P1.7 to input direction

    Or add this to your code (see red text below):

    P1DIR |= 0x01; // Set P1.0 to output direction

    P1DIR &= ~0x02;  // Set P1.1 to input direction

    Cheers

  • garrett barbour said:
    my problem is with p1.1, this code is supposed to be sampling this pin (A1 aka p1.1) but is outputting a voltage of 3.52 volts.

    You did not specify voltage source you measure with p1.1! Is it potentiometer? How do you measure "output voltage" when you see 3.52V? Doing your work did you connect to p1.1 anything that can source voltage higher than VCC (3.52V)?

  • Raffaele Iacobelli said:
    At a quick glance it appears you never explicitly set P1.1 as an input, you only configure the ADC to sample this pin.

    Raffaele, if you read device datasheet, (Table 16. Port P1 (P1.0 to P1.2) Pin Functions), it says that when ADC input is selected then P1DIR.x bit is "don't care". So setting direction as you say actually does not change anything. Problem is somewhere else - either no voltage source on ADC input pin or pin protection diode shorted to VCC by excess voltage.

  • Ilmars said:
    (Table 16. Port P1 (P1.0 to P1.2) Pin Functions), it says that when ADC input is selected then P1DIR.x bit is "don't care". So setting direction as you say actually does not change anything.

    That's not quite right.

    For operating the ADC on this pin, the digital I/O pins are a don't care indeed. But if you don't set the ADC10AE.x bit, the digital I/O is still active on this pin and may affect your signal source. The ADC will deactivate output and input drivers while sampling, but external capacitances may still suffer from any previously active digital output.

    The schematic above the cited table tells this.

  • After two hours struggling with our Launchpad having a 3.55 volt level on P1.1 we figured out that the backchannel UART is driving both pins 1.1 and 1.2 high!   It is BARELY shown on the schematic... you have to jump back to page 1 and notice that the TX/RX from the debugger are connected to 1.1 and 1.2.

    Removing the two jumpers solves the problem.

    It's always the simple stuff :)

  • Yes it's hard to follow the schematic that BxXDI trace goes to two IC's and the end there is Pull-Up(s).
    I assume the signaling is done open-drain-style as to be safe, but with 47K as pull-up could not be very fast. 
    But I guess there are other reasons it can only do 9600 baud anyway.

  • Tony Philipsson said:
    But I guess there are other reasons it can only do 9600 baud anyway.

    You’re right, Tony. As you can see in the schematics, BRXDI/BTXDI go to P3.1/3.1 of the TUSB, which are plain digital I&I pins. The backchannel UART is a software UART that uses normal I/O pins to simulate an UART bridge. Due to processing power, the baudrate is limited to 9600Bd. The hardware UART of the TUSB (UTXD/URXD, which can do 115200Bd easily) is used for the JTAG communication.

    I also agree that printed schematics are often difficult to read. If you have the original Eagle sheet file, it is easy, using highlighting of a segment.
    But since in Eagle, you can just name two segments the same and have them connected, it isn’t obvious by the printout to see what’s logically connected.
    In my own schematics, I always use BUS symbols to mark where a signal reaches further than just the visibly drawn local area. At least you know then, that there is more.

**Attention** This is a public forum