Docstoc

Digital Input Output _DIO_

Document Sample
Digital Input Output _DIO_ Powered By Docstoc
					V      Digital Input Output (DIO) Rev 21 June 2007

Most of the pins on the MCU can handle DIO.

Digital means having two states 0 or 1 which can have a number of meanings: OFF or ON,
FALSE or TRUE, LOW or HIGH voltage.

For a pin, digital output means that the pin acts as a power supply that can be set to a high
voltage (+5 V) or to a low voltage (0 V or ground). Both these values are approximate but no
other values are possible.

Digital input means that the pin acts as a voltmeter that can detect whether the pin is connected
to a high voltage (+5 V) or to a low voltage (0 V or ground). If you connect the pin to 4 V it will
probably read that voltage as high. If you connect the pin to 1 V it will probably read that voltage
as low. If you connect the pin to 2.5 V it probably won’t be able to decide if the input is high or
low it may randomly oscillate between reading high and low. Note the “probably”. The datasheet
specifies which ranges of voltages will be read as high and which will be read as low.

The pins on the MCU that have DIO functionality are grouped into sets of eight called ports. On
the PIC18F4525 we have 4 ports: PORTA, PORTB, PORTC, and PORTD. The PORTA pins are
labelled RA0 to RA7 on the pin-out diagram Figure V-1 below. For example RA0 is pin 2.




                                    Figure V-1: Pinout diagram.

Similarly the other port pins are labelled RBn, RCn, and RDn where n is 0 to 7.

We configure the pins for DIO using non-standard PIC specific C language statements. We can
configure a port as a group or individually. Figure V-2 shows the code for an entire port while
Figure V-3 shows the code for working with an individual pin.


                                                                                                  1
          RA7             RA0

TRISA = 0b00011000;              // configures PORTA for input and output


        outputs         inputs

                            Figure V-2: C code for configuring an entire port.



TRISAbits.TRISA3 = 1; // set RA3 as input
TRISAbits.TRISA1 = 0; // set RA1 as output
                           Figure V-3: C code for configuring individual pins.


TRIS is short for tri-state. The pins have three states

                           output                                   input
              High             Low                  High impedance
              +5 V             0V                   (meaning large resistance)
                                                    Note : Voltmeters need a large
                                                    resistance to work properly

TRISA, TRISB, etc., are the names of special 8-bit wide areas of RAM on the MCU that hold the
DIO configuration values. TRISA, etc., are called Special Function Registers (SFR). There are
SFRs for functions other than DIO as well. All the SFRs have structures defined in the header
file p18f4525.h so that each bit can be addressed individually. For example TRISAbits.TRISA3
is the 4th bit (remember we start from 0, so 3 is the 4th bit) of that 8-bit area. The structures have
the same name as the SFRs.

//excerpt from p18f4525.h
extern volatile near unsigned char                     TRISA;
extern volatile near struct {
  unsigned TRISA0:1;
  unsigned TRISA1:1;
  unsigned TRISA2:1;
  unsigned TRISA3:1;
  unsigned TRISA4:1;
  unsigned TRISA5:1;
  unsigned TRISA6:1;
  unsigned TRISA7:1;
} TRISAbits;



In output mode, we can set whether the pin is high of low using another SFR. Each port has its
own SFR. The SFRs are PORTA to PORTD. Again the SFR, PORTx, refers to a specific 8 bits
of RAM memory of the MCU.


                                                                                                    2
Again we can set all the pins of a port to any combination of high or low all at once or we can do
any individual pin. See Figure V-4 and Figure V-5 for example code.

TRISA = 0b00011000;             // configures PORTA for input and output
PORTA = 0b11101000;             // set various pins high or low

     set high                set low
         Does nothing – pins are
         inputs not outputs!

                     Figure V-4: C code for configuring and setting an entire port.


TRISAbits.TRISA3 = 0; // set RA3 as output
TRISAbits.TRISA1 = 0; // set RA1 as output

PORTAbits.RA3 = 1; // set RA3 high
PORTAbits.RA1 = 0; // set RA1 low
                     Figure V-5: C code for configuring and setting individual pins.


Let’s use this last bit of code to write a program that would actually set these pins when loaded
onto the PIC.

// testDIO.c configure and set RA3 (pin 5) and RA1 (pin 3)
#include <p18f4525.h>

#pragma   config   WDT = OFF
#pragma   config   OSC = INTIO7        // puts osc/4 on pin 14 to check freq
#pragma   config   MCLRE = OFF
#pragma   config   LVP = OFF
#pragma   config   PBADEN = OFF

void main(void)
{
  TRISAbits.TRISA3 = 0; // set RA3 as output
  TRISAbits.TRISA1 = 0; // set RA1 as output

 PORTAbits.RA3 = 1; // set RA3 high
 PORTAbits.RA1 = 0; // set RA1 low

  while(1); // run forever
}
// end program




Q. The diagram below represents your MCU programmed with the previous code. The vertical
lines represent the power and ground lines of the breadboard. Four voltmeters are connected to
the breadboard and pins on the MCU. Note that when a red (dashed) lead (V on the DMM) is


                                                                                                3
connected to a higher voltage point and a black (solid) lead (COM on the DMM) is connected to
a lower voltage point, the voltmeter will register a positive value. Reverse the connections and
the value will be negative. What is the reading on each voltmeter?

                                                VDD
                                                +5 V
                                                                    V1
                     MCU

                                                                                V2
                         RA1


                         RA3                                   V3
                                                                               V4
                                 VSS
                                 0V
V1 = __________________                      V2 = _________________

V3 = __________________                      V4 = _________________



Q. How would you change the code example to change the sign of the sign of the voltage
readings?



Digital Output and Controls

Digital output can be used to control devices attached to
the MCU. This can be as simple as turning on a light when           MCU
certain conditions are met to more operating more complex
                                                                                      R
devices such as a liquid crystal display (LCD).
                                                                         RA1                      I

The key to control is using the pins to provide power to
circuits. Figure V-7 shows the simplest circuit for each pin
– a single resistor.                                                     RA3
                                                                                                  I
                                                                                      R
The diagram shows the diagram of the conventional
current (i.e. running from high to low).
                                                               Figure V-6: Powering a circuit using
The current is determined from Ohm’s law, I = V/R, where       a pin.
V is the voltage difference across the resistor.

WARNING! The pins and MCU have a maximum current they can provide (source) or that they


                                                                                                      4
can accept (sink). Exceeding these limits can alter the operation of the MCU or burn it out.
According to Section 26.0 of the PIC18F4525 datasheet, the maximum current sourced or sunk
by any pin is 25 mA. The total current that can be sourced or sunk by all the pins operating at the
same time is 200 mA.

The pin can supply 5 V and a maximum current of 25 mA. From this we can determine the
smallest equivalent resistance that any circuit attached to a pin can have, R = 5 V / 25 mA = 200
. Any resistor or 200  or bigger should be safe to use with the MCU.

Since we cannot see currents the circuit in Figure V-7 is not very impressive. To see something
happen we usually add LEDs to the circuit as shown below in Figure V-8. LEDs are convenient
to use because they require less than 5 volts to operate. LEDs have a very small resistance of
around 10  so we must use them in series with a resistor to keep the pin currents within
acceptable limits. LEDs are diodes and diodes only carry current in one direction. Therefore how
you connect the LED to a pin is important. There are two LED orientations that cause each LED
to light up using the previous code.

                                    MCU

                                                      R
                                         RA1


                                         RA3
                                                      R



                                   Figure V-7: Controlling LEDs.




Digital Input and Sensors

Digital input can be used to let the MCU sense the outside world. This can be as simple as
determining whether a button is pressed or not to interpreting a digital signal from another device
such as a printer. Consider the case of an entire port, PORTA, whose pins have been configured
as inputs (digital voltmeters) using the TRISA SFR. The PORTA SFR continuously monitors
the pins and holds their current state.

Consider Figure V-9 below where certain pins are high, some low, and one left unconnected.




                                                                                                 5
                                                                 VDD


                                      RA0
                                      RA1
                                      RA2
                                      RA3
                             MCU
                                      RA4
                                      RA5
                                      RA6
                                      RA7

                                               VSS


                     Figure V-8: PORTA configured for input (reading voltages).


The code we would use to examine all these pins at once would be

// readPORTA.c configure and read PORTA pins
#include <p18f4525.h>

#pragma   config   WDT = OFF
#pragma   config   OSC = INTIO7     // puts osc/4 on pin 14 to check freq
#pragma   config   MCLRE = OFF
#pragma   config   LVP = OFF
#pragma   config   PBADEN = OFF

void main(void)
{
  unsigned char portvalue;

 TRISA = 0b11111111; // set RA0 to RA7 as inputs

 portvalue =     PORTA; // reads current digital voltages at PORTA and records
                        // values in portvalue which can hold 8 bits
  while(1);    // run forever
}
// end program

If this program was loaded into the MCU and run with the above circuit setup, the SFR PORTA
and portvalue would hold

               _1_ _?_ _1_ _0_ _0_ _0_ _1_ _1_
               RA7 RA6 RA5 RA4 RA3 RA2 RA1 RA0

RA6 is unconnected (it is said to be “floating”) and could randomly hold 0 or 1.

ReadPORTA.c is a useless program as we have not created a way for the MCU to tell us the
status of the input pins.


                                                                                         6
A better program follows. It monitors two input pins and depending on the status lights up two
LEDs attached to output pins (see circuit schematic Figure V-10 after code).

// LEDinputsensor.c configure RA3 and RA2 to light LEDS based on RA1 and RA0
#include <p18f4525.h>

#pragma   config   WDT = OFF
#pragma   config   OSC = INTIO7    // puts osc/4 on pin 14 to check freq
#pragma   config   MCLRE = OFF
#pragma   config   LVP = OFF
#pragma   config   PBADEN = OFF

void main(void)
{
  TRISAbits.TRISA3 = 0; // set RA3 as output
  TRISAbits.TRISA2 = 0; // set RA2 as output

 TRISAbits.TRISA1 = 1; // set RA1 as input
 TRISAbits.TRISA0 = 1; // set RA0 as input

 while(1) // monitor and read pins and light LEDs forever
   {
     PORTAbits.RA3 = PORTAbits.RA1;
      // whatever the value of input at RA1 use that value to turn RA3 on/off
     PORTAbits.RA2 = PORTAbits.RA0;
      // whatever the value of input at RA0 use that value to turn RA2 on/off
   }
}
// end program



                    VDD
                                              MCU

                                                                     R
                                                   RA3
                                           RA1

                                                   RA2
                                           RA0                       R


                                    VSS

                                   Figure V-9: Inputs and outputs.

In the circuit in Figure V-10 above, the LED at RA3 would be lit and the LED at RA2 would be
off. The nice thing about this circuit is that you can change the connections at RA1 and RA0 as
you wish.




                                                                                             7
Q. How would you change LEDinputsensor.c so that if RA1 is high, RA3 would be set low
(LED off) and the same for RA0 and RA2?


Q. If you do not change LEDinputsensor.c above, how could you change the LED circuits at
RA3 and RA2 so that if RA1 is high then RA3 is set low (LED off) and the same?




                                                                                      8
Buttons and DIO


Changing the voltage at an input between low and high when you wish it is easily accomplished
by a simple circuit of two resistors and a button or switch as shown in Figure V-11.

                               VDD

                                                       MCU

                    button        200                    RA2
                                                  RA0                 R
                              A           B       (large R)
                               10 k




                                      Figure V-10: A button input.

We need to spend a little time understanding how the button works. When the button is up, RA0
is connected to ground through the two resistors, so the voltage at the pin is 0.

The button is just a conducting piece of metal so when it is pressed down, point A is at the same
potential as VDD, +5 V. What will be the voltage at RA0, point B, in this case? We can figure
this out if we remember that the input pin has a large resistance (of about 10 k). We can model
the button circuit and the MCU as shown in Figure V-12 below.

                                   VDD                        MCU

                                          200          Rinput

                                      A            B
                                       10 k




                                     Figure V-11: Input resistance.


Point A is at 5 Volts when the button is pressed and there are two parallel paths to ground.
Because both paths are high resistance, very little current is flowing. That’s good because it
would just be wasting power. The branch to the input pin is a series circuit of the 200- resistor
and Rinput. If we recall the voltage divider circuit, the voltage at point B is easy to find

                                  VB = VA* Rinput / (200  + Rinput).

Since Rinput >> 200 , VB = VA.


                                                                                                9
Now consider the program below to work with the circuit in Figure V-11.

// buttonLED.c configure RA2 to light an LED based on RA0
#include <p18f4525.h>

#pragma   config   WDT = OFF
#pragma   config   OSC = INTIO7      // puts osc/4 on pin 14 to check freq
#pragma   config   MCLRE = OFF
#pragma   config   LVP = OFF
#pragma   config   PBADEN = OFF

void main(void)
{
  TRISAbits.TRISA2 = 0; // set RA2 as output

 TRISAbits.TRISA0 = 1; // set RA0 as input

 while(1) // monitor and read pins and light LED forever
   {
     PORTAbits.RA2 = PORTAbits.RA0;
     // whatever the value of input at RA0 use that value to turn RA2 on/off
   }
}
// end program



With buttonLED.c, if the button is pressed on and off, the LED flashes on and off in unison.

                                       button pressed – RA0 high
               V




                                               input signal                         t



                                       RA0 high – LED turned on
               V




                                                                                    t
                                                output signal

                              Figure V-12: Button input and LED output.



Note that the button and resistor circuit is a logic switch setting the input pin voltage high or low
but with very little current flow. This is in contrast to a mechanical switch, such a wall light
switch, which allows a large current to flow (see Figure V-14 below).


                                                                                                  10
                                            R

                                                    Switch

                                 Figure V-13: A mechanical switch.


Q. Why don’t we want to use a mechanical switch with the MCU as shown in the diagram
below?

                                                    MCU
                         R
                                                          RA2
                                                RA0                  R
                  VDD              Switch       (large R)




You can also use the button and resistor circuit as a toggle by modifying how the program reacts
to the change of state, high to low or low to high, at the input. With a toggle when you press and
release the button, the LED should stay on. When you press and the button the next time, the
LED should remain off. This behaviour is illustrated below.

                                      button pressed – RA0 high
              V




                                                input signal                      t


                                    toggled on – LED turned on
              V




                                                                                  t
                                                output signal

                                     Figure V-14: Toggle logic.


To create a toggle in software you must look for the times that the input signal goes from low to
high. When that occurs, you switch the output. A program to do this would look like




                                                                                               11
// toggleLED.c configure RA2 to light an LED based on RA0 off/ons
#include <p18f4525.h>

#pragma   config   WDT = OFF
#pragma   config   OSC = INTIO7   // puts osc/4 on pin 14 to check freq
#pragma   config   MCLRE = OFF
#pragma   config   LVP = OFF
#pragma   config   PBADEN = OFF

void main(void)
{
  unsigned char toggle_on = 0; // button is off
  TRISAbits.TRISA2 = 0; // set RA2 as output
  TRISAbits.TRISA0 = 1; // set RA0 as input

 PORTAbits.RA2 = 0; // turn LED off initially

 while(1) // monitor and read pins and light LED forever
   {
      if (toggle_on == 0 && PORTAbits.RA0)
         { // rising edge detected if PORTAbits.RA0 is 1 (on)
           PORTAbits.RA2 = !PORTAbits.RA2; // invert LED status
           toggle_on = 1; // button is on
         }

      if (toggle_on == 1 && !PORTAbits.RA0)
         { // falling edge detected if PORTAbits.RA0 is 0 (off)
           toggle_on = 0; // reset toggle_on to off (button is not pressed)
         }
   }
}
// end program




                                                                              12

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:8
posted:11/4/2011
language:English
pages:12