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.

problem with the PxIN of the MSP430 :-(

Hello together,

i try since few hours to use the PxIN but i get allways the P1IN zero so low...i tried all combination with PxOUT, PxEN, PxSEL but without good results... i used the PxDIR as 0 for the PIN and i set the port as P1IN = 1 but the problem is that all the pins of the port are low so zero...can someone briefly tell me about the trick combination of PxSEL , PxIN, PxEN and and...

void main(void) //Main program
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

P1DIR=0x00;
P1OUT=0x00; 


for (;;)
{

P1DIR = 0x00;
P1IN = 0xFF;

}

}

  • Hi,

    Is this with the launchpad I take it? I assume you are using one of the switches on the launchpad? I found you'll need to configure the pin with a resistor to get it working. Here is some code I found which I don't quite remember writing... I was using interrupts with the switch rather than polling it but this setup should hopefully work for you. I might have a play about with it now and see if I can get it running again.

        P1DIR &= ~SWITCH;                                       // Switch Input
        P1REN |= SWITCH;                                        // Resistor
        P1OUT |= SWITCH;                                        // Pullup
    

    EDIT - Played around with some code there to refresh my memory. This works for me so hopefully should work for you (assuming you are using a launchpad.

    /* 
     * Small program to demonstrate using the switch on the launchpad.
     * Each time the switch is pressed the launchpad LEDs should ideally toggle 
     * values. Initially the green LED is lit.
     */
    
    #include "msp430g2553.h"
    
    #define SWITCH              BIT3
    #define SWITCH_PRESSED      0x00
    
    #define RED                 BIT0
    #define GREEN               BIT6 
    
    int main(void)
    {
        /* Disabling dog, setting up clock */
        WDTCTL = WDTPW + WDTHOLD;
        BCSCTL1 = CALBC1_1MHZ;
        DCOCTL = CALDCO_1MHZ;
    
        /* Setting up Switch */
        P1OUT = 0x00;
        P1DIR &= ~SWITCH;                               // Set the switch pin to input
        P1REN |= SWITCH;                                // Use an internal resistor
        P1OUT |= SWITCH;                                // The internal resistor is pullup
    
        /* Setting up Launchpad LEDs */
        P1DIR |= RED + GREEN;                           // Launchpad LEDs for output
        P1OUT |= GREEN;                                 // Green LED lit at startup
    
    
        while (1)
        {
            if ((P1IN & SWITCH) == SWITCH_PRESSED)
            {
                /* Hang until the switch is released. */
                while((P1IN & SWITCH) == SWITCH_PRESSED); 
    
                P1OUT ^= GREEN | RED;                   // Toggle Launchpad LEDs
            }
        }
    
        return 0;
    }

    The reason for this resistor configuration is we need to create a potential divider for the switch so we can clearly tell when the switch is pressed (low voltage at the pin), and when the switch is open  (high voltage at the pin). To be honest I am not sure enabling the internal resistor is quite necessary on the launchpad, as I have a feeling the switch already has a pullup resistor and a capacitor across it (the capacitor helps with a difference issue with switches which is called bounce) but I don't have a schematic at hand to check this. However if you are not using a launchpad a pullup or pulldown resistor is something you have to consider implementing - ideally an external one.

    Once you configure the PxDIR register for input its the PxIN register you then check to see the status of the pin. (NB the above example uses polling to check the status of the switch - in an infinite loop the register keeps getting checked to see if the pin is low / the switch is pressed. It is more efficient however to use interrupts to handle monitoring the pin, allowing the launchpad to remain in a low powered state until the switch is pressed and the interrupt service routine is called).

  • yes i use the launchpad...but i tried with your sug. but it does not work :-(... i need instructions which turn my port to "IN"...i´m tired and i´m  trying all possibilities...but i get allways low as value by the PxIN :-(...

  • I was editing my above post when you replied. See if the sample program works for you and if there are any particulars you don't get back to me :)

  • you are a treasure :-) . the code is so helpful for me. but i don´t understand why i have to follow those 3 instructions to get the high PIN. And i don´t understand why i have at the beginning of the debugging the value P1IN : 00000110  so the P1.1 and P1.2  as default....

    so thanks thanks thanks

  • Hey,

    Sorry you couldn't elaborate a bit more on your questions?

    I'm not quite sure if this is me being paranoid but I don't generally trust the values in P1IN for any pin that hasn't been configured as an input (Setting its bit in P1DIR low). I could be wrong but because the chip has separate OUT and IN registers I am not sure if the value in PxIN should/would reflect the state at the pin when the pin is configured as an output.

    The value in PxIN (a read only) register reflects the logical state of the pin(s) at the moment in time you read it. For any unconnected pin this could be 1 or 0 (there is no guarantee) as that pin is "floating". So you could be seeing this - especially if the values in 1.1 and 1.2 fluctuate. However these two pins can be used for UART communications via USB to your PC - so it is very likely these pins are being read high because of this as the default UART logic level is 1. There should be jumpers connecting these pins to the emulation part of the launchpad, labelled TXD and RXD if you remove these jumpers I think the pins should read low or at least fluctuate more regularly.

  • Alan said:
    The value in PxIN (a read only) register reflects the logical state of the pin(s) at the moment in time you read it. For any unconnected pin this could be 1 or 0 (there is no guarantee) as that pin is "floating". So you could be seeing this - especially if the values in 1.1 and 1.2 fluctuate. However these two pins can be used for UART

     Hi Alan, IMHO you are right, PxIN read te status of the input pin but from schematic is unclear how interact from schmitt trigger logic, so in the case PxDIR is in the output direction input gate is disabled so PxOUT or peripheral out is read instead of pin level.\

     The two input of P1IN are high due to USART as you wrote, TX is in the mark state and RX has probably a pullup to avoid line in space status(low).

     To help our friend:

     PxDIR set the pin as output where bit are 1 and input if bit are 0

     PxREN enable the resistor to have a pullup (PxOUT.y=1) or pulldown (PxOUT.y=0) in parallel to output

     PxOUT set the value of bit if PxDIR.y = 1

     PxIN read the status of pin if input or OUTPUT driver value if pin is output mode

     PxSEL select the alternate funcion for the pin, generally this set the input or output mode regardless of PxDIR

     FOr more detail browse the datasheet specific to the chip are you using and refer to family user guide for general register programming.

  • Thanks,

    now i understand the purpose of the PxIN. So the PxIN is only a read port. so i must set the port to output high to get high by the PxIN. So if i use the switch, and the switch during pushing brings the potential to GND so the value in the port will be change and i can read the LOW with PxIN.

  • Aymen Ben said:

    Thanks,

    so i must set the port to output high to get high by the PxIN.

    Not quite, the PxOUT register has two functions. Here you are not technically setting the pin to output high, but are altering the circuit to bias the pin high. To quote the family user guide:

    Each bit in each PxOUT register is the value to be output on the corresponding I/O pin when the pin is
    configured as I/O function, output direction, and the pullup/down resistor is disabled.
    Bit = 0: The output is low
    Bit = 1: The output is high
    If the pin's pullup/pulldown resistor is enabled, the corresponding bit in the PxOUT register selects pullup
    or pulldown.
    Bit = 0: The pin is pulled down
    Bit = 1: The pin is pulled up

    So by setting the bit in P1REN high AND the same bit in P1OUT high its enabling an internal pull up resistor on this pin.

    If the bit for the pin in question in P1REN was high and P1OUT was low it would be an internal pull down resitor - this is undesired due to the switch circuit in question. I'm pretty sure that P1REN /P1OUT for the switch doesn't have to be used at all as I believe the launchpad has an external pullup for the switch.

  •  

    Aymen Ben said:
    so i must set the port to output high to get high by the PxIN. So if i use the switch, and the switch during pushing brings the potential to GND so the value in the port will be change and i can read the LOW with PxIN.

     Hi, not really, you need have input mode to read PIN state otherwise you read output driver status, in other word if internal logic are driving pin HI and external pin is shorted to ground you read HI and not low.

     If you need use a switch that close to ground you need a pullup, ie if you need use the one on P1.3 of launchpad this sequance is needed:

    #define SW2 BIT3

    .....

    P1REN|=SW2;   // enable resistor on pin

    P1DIR&=~SW2;   // Set pin input mode

    P1OUT|=SW2;   // pullup mode

    P1SEL&=~SW2;   // Assign pin to I/O subsystem

    ........

     if(P1IN&SW2)

     // pin high action

     else

     // pin low action

    .........................

     if(!(P1IN&SW2))

     // Button pressed

     else

     // Button released

  • Alan said:
    pretty sure that P1REN /P1OUT for the switch doesn't have to be used at all as I believe the launchpad has an external pullup for the switch.

     Hi take care of this resistor, it is present on releases before the 1.5 then is removed to leave pin free of any load.

     Otherwise is a bad idea add a component that is not really needed due to uP features!

  • Roberto Romano said:
     Hi Alan, IMHO you are right, PxIN read te status of the input pin but from schematic is unclear how interact from schmitt trigger logic

    usually, PxIN shows the state of th einput pin, no matter whether the pin in input or output direction.
    However, on some MSPs and depending on the additional module functionality, sometimes PxIN is latched when a module funciton is selected. (but more commonly, the module input is latched when the pin in in GPIO mode)
    Details can be found in the individual device datasheets and are often different for every single pin or different roups of pins.
    And unfortunately, sometimes the schematics aren't correct too (sometimes obviously, sometimes less obvious).However, PxIN is always read-only.

    Roberto Romano said:
     PxIN read the status of pin if input or OUTPUT driver value if pin is output mode

    Normally, the PxDIR value doesn't matter. There are a only few exeptions on some MSPs.
    Roberto Romano said:
     PxIN read the status of pin if input or OUTPUT driver value if pin is output mode
    Nope. It is almost always the current pin status. If you override a high output by shorting the pin to GND, PxIN.y will be zero even if PxOUT.y is one.

    Roberto Romano said:
     PxSEL select the alternate funcion for the pin, generally this set the input or output mode regardless of PxDIR

    No. PxSEL selects module usage. However, PxDIr may switch between two different (and independent) module funcitons, of which one is an input t a module and one is an output from a (perhaps even different) module.

    AFAIK, the USCI is the only module that controls the direction of the port pin by itself (as this is required for SPI and I2C funcitonality, where pin direction changes during operation or based on operating mode)

     

  •  Hi Jeans, this is related to G series on launchpad and G series has a bidirectional driver and P1IN is read on internal driver side so if you short pin to ground or VCC still internal level is read. To clean this question tomorrow I try on a Launchpad and then I post result. If the reason is in your favour then again we discovered another wrong schematic on Data sheet.

  • Roberto Romano said:
    his is related to G series on launchpad and G series has a bidirectional driver and P1IN is read on internal driver side so if you short pin to ground or VCC still internal level is read

    I always wondered what this shortcut/bridge in the pin schematics shall be. As it is drawn, it makes teh output of the schmitt trigger fight the output of the PxSEL-controlled switch.
    But yoU're right, on the newer 2x21/2x31 datasheet slas594i, there is now another driver behind the switch, and only this one or the input driver are active. It's still drawn a bit strange (you'll have to look twice to get hwo it works) but at least it seems electrically correct now.

    You're right, on G devices, the input is effectively disabled in out put mode.
    IMHO a step back, since you know the output value already, because you have access to the PxOUT register.
    I don't know why they made this change, as it is different to all other MSPs. But maybe it has something to do with the PINOSC feature.

    It looks like my documentation comment has resulted in a documentation change - and I didn't notice :)

**Attention** This is a public forum