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.

Reading I/O Pins

Other Parts Discussed in Thread: MSP430F1121A, MSP430G2553

Hi,

I am using MSP430F1121A STK ( that is MSP430F1121A Development Board) and working on its code in IAR Embedded Workbench 5.0 for MSP430.

I have 2  General Purpose I/O ports, P1 and P2. Can anyone provide me with the code for reading one of the pins of these ports ? For example,  I want to read the value coming out of the channel P2.2, that is, pin 2 of port 2. Are there any APIs available for this? I have downloaded the sample user codes, but couldn't find anything that would help me. Please let me know ASAP.

Thank You,

Warm Regards,

Sphurthi

  • All compilers for the MSP (IAR, CCE, MSPGCC) come with a bunch of C header files for all kinds of MSP processors.

    All you need to do is including the master header file into your project with
    #include <io.h>
    or
    #include <msp430x1121A.h>

    Check the code examples in your IAR installation fo which is the right name to use.

    After includign this header file, all port registers and bit meansings of your MSPs hardware are known to the compiler and can be used by your code.

    To answer your specific question, the expression
    (P2IN&0x4)
    resolves to 0 if the port pin is low, and 4 if the port pin is high. (the value for P2.1 would be 2, and 1 for P2.0)

    P2IN is an alias for the Port 2 input register of your MSP. It is defined in the above header files. This name is also used in the register description in the MSP family users guide and the device datasheet.

  • Thank you for your prompt reply. However, I have certain doubts on it :-

    Will I be able to just read if the pin is low or high or will I get some random value if the pin isn't connected to any external peripheral ? I haven't connected any battery or other such device to it yet but the plan is to be able to read the value of the channel and once I achieve that, connect it to a battery to read the battery status then. 

    I would include the header file you mentioned, but in order to be able to get and then store the read value into a variable , then what would be the lines of code for that ? Say, if I declare P2IN, that is P2 as input register and then if I want to store the value read from P2.2 into some 'a'. 

    Sorry for asking such naive questions but i'm a complete novice to this field and so in need of some guidance.

    Thank You,

    Regards,

    Sphurthi

     

  • Whether the pin is considered high or low depends on the voltage level currently observed at the pin when you read the P2IN register.

    If the pin is not connected to anything, it depends on several circumstances. Is it a schmitt-trigger input or a normal logic input? Notmal logic inputs have a certain threshold level. Above is high, below is low. Schmitt-Triggers, however, have some hysteresis. Once the input voltage has exceeded the threshold level (resulting in a 'high' reading), it needs to go down a certain amount below the threshold to be considered 'low'. To be taken as 'high' it needs to raise again by this amount, the hysteresis. The area between this high and low thresholds is not an 'uncertain' state, but extends the area of the current state. Whether the pin is a normal logic input (with a level below it is certainly detected as low, and a second level above it is certainly taken for high and an area in between where you cannot be sure) or a schmitt trigger, is documented in the device datasheet.

    Unconnected pins may receive radio signals (including those produced on their own circuit board) and swing between low and high. If you want a dure default reading, use a resistor agaonst either GND, for low, or VCC, for high default value, also called pull-down and pull-up. Some ports have optional pullup- or pull-down resistors built-in, others have always small pull-ups active when in input mode.

    If you want to read the (mroe or less) exact value of the voltage, you'll need to use an ADC or SD unit (Analog Digital Converter or Sigma Delta converter).

    While the Ports on the MSP are digital only, most MSPs have an ADC or SD module, whose inputs may be internally connected to the same physical pins as the Ports. How to program these units is a bit more complex, as you'll need to configure them for a certain reference voltage, sample times etc. If configured correctly, you'll end up with a value that is (so-to-speak) a percentage of the configured reference voltage. There are some application notes with sample code available at the TI website and there are other threads in this forum already dealing with this.

    About storing the value, the term I wrote (including the brackets) evaluates to a value which is either 0 or 4, depending on the current status of P2.2.

    P2IN is already declared in these header files. It is actually a variable that is placed at the memory location where the P2IN register is located. So every logical access of the P2IN variable accesses the current value of the P2IN hardware register. Each bit in this variable corresponds to one input pin of port 2. This is why I made the P2IN&4 calculation. It isolates the 3rd bit of P2IN, which corresponds to the physical port pin P2.2.

    if you want to store the result, just define a variable, let's name it myVar, and assign the result of the above expression to it.

    myVar = (P2IN&4);

    Ot, if you prefer a 0/1 value:

    if(P2IN&4) myVar=1; else myVar=0;

    You can always read the 'input value' od Port2 by accessing P2IN, even if the port is configured as output (using the P2DIR and P2OUT registers). Even more, if you assign an port pin to be high by P2OUT, and a stronger external connection pulls it low, you'll read it as low in P2IN.

    Much of this is explained in the "MSP430Xyyyy family users guide" documents (look out for the one for you processor family). It explains almost all about ports, registers, whatever.

    And the exact electrical specifications, including input circuit drawings etc are found in the device datasheets. All available at ti.com.

     

  • Hai Sphurthi,

                           " Will I be able to just read if the pin is low or high or will I get some random value if the pin isn't connected to any external peripheral ?" you wont get any random values (either 1 or 0) these are the possible cases. you get random vaues if u configured that pin as an ADC channel for measuring battery voltage. \

                         for ADC operations that value will be stored in one register called ADC10MEM . (ur totally new to Embedded field, am i right?).

                        if(P2IN&4) myVar=1; else myVar=0; this code is enough for checking the pin status,that is high(connected to supply through a register) or low(connected to ground through a register).

                        But for measuring the Battery voltage is totally a different task.

     

    Regards,

    Kshatriya.

  • Kshatriya said:
    you wont get any random values (either 1 or 0) these are the possible cases.


    If you cannot predict the outcome, it is random. No matter if the range of possible random values is 0..1, 0..255 or 0..4095 or even a one of a set of discrete values (e.g. 0 or 4). If the pin is set to high-impedance state (which is the default on most MSPs pins) and not connected to any peripheral, the input reading is random. It i smore likely to be '1' than '0', but you cannot be sure and the reading might change and/or swing periodical or non-preiodical based on many unknown external influences. (on good old bipolar TTL logic, unconnected pins were pulled high due to the inherent leakage currents of the input transistors, but this wasn't true anymore for CMOS logic and isn't for the low-power, low-leakage trimmed MSPs too)

    Kshatriya said:
    But for measuring the Battery voltage is totally a different task


    That's why I referred to the sample code for ADC or SD and the other threads here, covering the usage of the ADC10.

    An alternative is using a comparator (some MSPs have one) to just detect whether battery voltage is above or below a certain threshold (if the absolute value isn't important). It's even possible to just use a digital (schmitt trigger) input pin to detect whether battery voltage has dropped. It requires careful selection of some resistors and will only detect  a low-batt condition if the battery has been significantly higher before (hysteresis), but it is possible (and cheap).

  •  

    Hi Jens,

    I try to read an input pin. But I have a problem with the header file io430g2553 because Im using msp430g2553.h

    In io430g2553 it is defined:

    __no_init volatile union
    {
    unsigned __READ char P1IN; /* Port 1 Input */

    struct
    {
    unsigned __READ char P0 : 1; /* */
    unsigned __READ char P1 : 1; /* */
    unsigned __READ char P2 : 1; /* */
    unsigned __READ char P3 : 1; /* */
    unsigned __READ char P4 : 1; /* */
    unsigned __READ char P5 : 1; /* */
    unsigned __READ char P6 : 1; /* */
    unsigned __READ char P7 : 1; /* */
    }P1IN_bit;
    } @0x0020;


    enum {
    P0 = 0x0001,
    P1 = 0x0002,
    P2 = 0x0004,
    P3 = 0x0008,
    P4 = 0x0010,
    P5 = 0x0020,
    P6 = 0x0040,
    P7 = 0x0080
    };

    So I can write e.g. 

    //  SPI clock signal pin
    #define SCLK                   P1OUT_bit.P5 

    But in msp430g2553.h it is defined

    #define P1IN_ (0x0020u) /* Port 1 Input */
    READ_ONLY DEFC( P1IN , P1IN_)

    So how can I implement the code " #define SCLK       P1OUT_bit.P5" with this header file? I have already tried  " #define SCLK          P1OUT & 0x5" and it didnt help.

    Thanks!

     

     

     

     

     

  • Umm, first, since this is a different question on a different part, you should have started a different thread and not tag along on someone else's unresolved thread.

    However.....

    Yue Zhang said:

    But in msp430g2553.h it is defined

    #define P1IN_ (0x0020u) /* Port 1 Input */
    READ_ONLY DEFC( P1IN , P1IN_)

    So how can I implement the code " #define SCLK       P1OUT_bit.P5" with this header file? I have already tried  " #define SCLK          P1OUT & 0x5" and it didnt help.

    From msp430g2553.h in IAR Workbench....

    #define P1OUT_              (0x0021u)  /* Port 1 Output */
    DEFC(   P1OUT             , P1OUT_)

    and....
    #define BIT0                (0x0001u)
    #define BIT1                (0x0002u)
    #define BIT2                (0x0004u)
    #define BIT3                (0x0008u)
    #define BIT4                (0x0010u)
    #define BIT5                (0x0020u)
    #define BIT6                (0x0040u)
    #define BIT7                (0x0080u)

    So....

    #define SET_SCLK        P1OUT |= BIT5

    #define CLR_SCLK       P1OUT &= ~BIT5

    or, define your own structure in your source code:

    __no_init volatile struct{
        unsigned char P0: 1;
        unsigned char P1: 1;
        unsigned char P2: 1;
        unsigned char P3: 1;
        unsigned char P4: 1;
        unsigned char P5: 1;
        unsigned char P6: 1;
        unsigned char P7: 1;
    } MY_P1OUT @ P1OUT_;

    Then... #define SCLK MY_P1OUT.P5

  • Hi Brian,

    thanks for your reply. I have tried your second solution, but unfortunately it didn't help there are still hunderts of repetitive mistakes of the same types:

    Error[Pe020]: identifier "P2IN_bit" is undefined

    Error[Pe065]: expected a ";" 

    Error[Pe077]: this declaration has no storage class or type specifier 

    Error[Pe147]: declaration is incompatible with "struct <unnamed> volatile P1OUT_bit @ 0x21" 

    Error[Pe079]: expected a type specifier

    Error[Pe260]: explicit type is missing ("int" assumed) C

     

    Thanks!

     

     

     

     

     

     

     

  • It works in my test program, so I'm not sure what your issue is. Well, for one, it is complaining that you haven't declared P2IN_bit.

    Otherwise, the errors are meaningless without seeing the context of the source code.

  • Yue Zhang said:
    I try to read an input pin. But I have a problem with the header file io430g2553 because Im using msp430g2553.h
    In io430g2553 it is defined:

    The IO430 header files define bitfields for the port pins. However, bitfields on hardware registers are extremely inefficient. So the 'official' MSP430.h header files form TI don't provide them. The IO430 header files are considered deprecated for quite some time now but are of course still found in older (and unfortunately also newer) projects.
    IIRC, IAR still provides both, at least for the older processors.

    Instead, use bitwise OR and AND operations to set or clear bits in a processor register.

    Instead of P1IN_bit.P0 = 1; use P1IN |= BIT0;  (this directly translates into a BIT SET assembly instruction)
    and instead of P1IN_bit.P0 = 0 use P1IN &= ~BIT0; (C doesn't know of a BIT CLEAR operator, but a nary and with an inverse value (~) does the same and results in a BIT CLEAR assembly instruction.)

    This also allows you to set or clear multiple bits at once:
    P1IN |= (BIT0|BIT7);
    P1IN &= ~(BIT4|BIT6);

  • thanks a lot for your replies!

**Attention** This is a public forum