0% found this document useful (0 votes)
290 views41 pages

Parallel Port I/O

The 18f242 has three parallel ports: PORTA, PORTC, PORTB. PORTB pins can either be an input or output - the data direction is controlled by the corresponding bit in the TRISA, TRISB, TRISC registers ('1' = input, '0' = output) Individual PORT bits are named as RB0, RB1,.RA0, etc. So this can be used in C code instead of using the bittst macro

Uploaded by

vesterever
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
290 views41 pages

Parallel Port I/O

The 18f242 has three parallel ports: PORTA, PORTC, PORTB. PORTB pins can either be an input or output - the data direction is controlled by the corresponding bit in the TRISA, TRISB, TRISC registers ('1' = input, '0' = output) Individual PORT bits are named as RB0, RB1,.RA0, etc. So this can be used in C code instead of using the bittst macro

Uploaded by

vesterever
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 41

Parallel Port I/O

The simplest type of I/O via the PIC18F242 external pins is


parallel port I/O.
The 18F242 has three parallel ports:
PORTA – 7 bits, bidirectional
PORTB – 8 bits, bidirectional
PORTC – 8 bits, bidirectional
We will use PORTB pins most of the time because the PORTA,
PORTC pins will be used for other functions beside parallel I/O.
Each pin on these ports can either be an input or output – the
data direction is controlled by the corresponding bit in the
TRISA, TRISB, TRISC registers (‘1’ = input, ‘0’ = output).
LATA, LATB, LATC are latches that hold the last value written
to ports A, B, C. V 0.6 1
PORTB Example
Set the upper four bits of PORTB to outputs, lower
four bits to be inputs:
TRISB = 0x0f;

Drive RB4, RB5 high; RB6, RB7 low:

PORTB = 0x30; Test returns true while RB2=0


so loop exited when RB2=1
Wait until input RB2 is high:
while (!bittst(PORTB,2)) ;

Wait until input RB3 is low: Test returns true while RB3=1
while (bittst(PORTB,3)) ; so loop exited when RB3=0
V 0.6 2
PORTB Example (cont.)
Individual PORT bits are named as RB0, RB1, ..RA0, etc. so
this can be used in C code instead of using the bittst macros.

Wait until input RB2 is high:


Test returns true while RB2=0
while (!RB2) ; so loop exited when RB2=1

Wait until input RB3 is low: Test returns true while RB3=1
while (RB3) ; so loop exited when RB3=0

V 0.6 3
Vdd Switch Input
10K
18F242 External pullup
RB3 When switch is pressed
RB3 reads as ‘0’, else
reads as ‘1’.

If pullup not present, then


18F242 don’t do input would float when
RB3
this! switch is not pressed, and
input value may read as
‘0’ or ‘1’ because of
system noise.

V 0.6 4
PORTB Pin Diagram: RB2:RB0
If TRIS bit a 0, tri-state
buffer is enabled, value
in data latch drives the IO
pin.

If TRIS bit a 1, tri-state


buffer is disabled, IO pin
either floats or is driven
by an external driver.

V 0.6 5
Aside: Tri-State Buffer (TSB) Review
A tri-state buffer (TSB) has input, output, and output-
enable (OE) pins. Output can either be ‘1’, ‘0’ or ‘Z’
(high impedance).
Y A Y
A
OE OE OE = 0, then switch closed
OE = 1, then switch open

Output Enable
(OE) of TSB. If
asserted, output =
input. If negated,
output is high
impedance
(output
V 0.6 disconnected)
6
Bi-directional, Half-duplex Communication
driver driver
PIC18 enabled disabled PIC18
TRIS D Q Q D TRIS
0 1
data bus data bus
D Q Q D

Q D D Q
rd_port rd_port

driver driver
PIC18 disabled enabled PIC18
TRIS D Q Q D TRIS
data bus 1 0 data bus
D Q Q D

Q D D Q
rd_port rd_port
V 0.6 7
PORTB weak pullups
Can enable weak pullups on all
RB pins configured to be inputs
by clearing the RBPU bit in the
OPTION register
RBPU = 0;
or
bitclr(INTCON2,7);

Copyright
Microchip,
from PIC18xx2
Datasheet
DS39564B

Removes the need for an


external pullup. V 0.6 8
Why are weak pullups useful?

If enabled, removes need for external pullup resistor on low-


true input switch.

V 0.6 9
LATB versus PORTB
A read of LATB
returns the value
of the latch that
drives the external
pin.

A read of PORTB
returns the value of
the external PIN.
LATB holds the last
value written to
PORTB while
PORTB is the value of
the external pin. V 0.6 10
PORTA Parallel IO
On the 18F242, the PORTA RA0:RA3 and RA5 pins are also
used for as the inputs to the analog-to-digital converter
module.
By default, they are analog input pins, not bi-directional
digital I/O pins. If a read is done on these pins while they are
configured as analog inputs, a ‘0’ will always be returned.
To enable RA0:RA3, RA5 pins to functions as digital pins,
the ADCON1 (A/D configuration register) must be set to the
value 0x06:
// configure port A to be all digital inputs
TRISA = 0xff;
ADCON1 = 0x06;

V 0.6 11
PORT A Pin Configuration

Bits 3:0 of ADCON1


control the
configuration of the
PORTA pins in terms
of digital vs. analog.
The datasheet in the
A/D section has a
complete description.

Copyright
Microchip,
from PIC18xx2
Datasheet
DS39564B

V 0.6 12
RA4 Pin: Open Drain Output
RA4 is different from RA0:RA3, RA5 in that it is an open drain
output. RA4 can only pull LOW, it cannot pull high.

P/N transistors both present, can Only N present, can only


pull high/low pull low

Copyright Microchip, from PIC18xx2 Datasheet DS39564B V 0.6 Copyright Microchip, from PIC18xx2 Datasheet DS39564B 13
Why Open Drain? Useful because can tie open-drain
outputs together without external logic,
only an external pullup.
Vdd
Assume CPUs A,B,C are all working on
Busy different tasks, and want to know when
CPU A LED all are finished.

18F242 When working on a task, a CPU asserts


RA4 low. When finished, negate RA4.
RA4 If any CPU is busy, LED will turn on. If
CPU B all CPUs finished, LED will turn off.
18F242 Cannot do this with non-open drain
RA4 output because of clash of some outputs
driving low, some high.
CPU C
This type of connection is often called a
18F242
wired-or. If CPU A or B or C is busy,
RA4
then LED is on.

V 0.6 14
Mixed Voltage Interfacing using Open
Drain Gates

V 0.6 15
PORTC Parallel IO
• We will not look at PORTC Parallel IO
• PORTC pins shared with many other functions of
the PIC18F242
• If parallel IO is needed, will always use PORTB
first, then PORTA if needed

V 0.6 16
ledflash.c Program Listing
Time delay implemented via
software loops – delay
depends upon clock
frequency and loop count
values.

Infinite loop simply


alternates between turning
LED ON (output port = 1),
then OFF (output port = 0),
with a time delay between
each port operation.

18F242
RB1

V 0.6 17
Copyright Thomson/Delmar Learning 2005. All Rights Reserved.
DelayUs, DelayMS

Better software delay loop routines. Maximum value of


DelayUs parameter depends upon clock value FOSC; _dcnt
calculation cannot exceed 255. V 0.6 18
Copyright Thomson/Delmar Learning 2005. All Rights Reserved.
LED/Switch IO: Count number of
press/releases

V 0.6 19
Copyright Thomson/Delmar Learning 2005. All Rights Reserved.
Count #number of switch press/releases.
A common error:
alternate statements:
int i; if (RB6 == 0) {
TRISB = 0xEF;
RB4 = 0;
if (!(bittst(PORTB,6))) {
i = 0;
while (1) {
if (bittst(PORTB,6) == 0) {
if (!RB6) {
/* switch pressed, increment */
i++;
}
}
Will be incremented MANY times. A human CANNOT
press/release a switch faster than a few milliseconds, so code
in loop executed an unknown number of times.
V 0.6 20
Count #number of switch press/releases
Correct Solution:
int i;
TRISB = 0xEF;
RB4 = 0; while(bittest(PORTB,6));
i = 0;
while (1) {
// wait until button is pressed
while (RB6);DelayMs(30);
// wait for button to be released
while (!RB6);DelayMs(30);
i++;
} while(!bittest(PORTB,6));
Delay to let switch bounce settleV out.
0.6 21
Toggle LED for each switch press/release

V 0.6 22
Copyright Thomson/Delmar Learning 2005. All Rights Reserved.
Toggle LED for each switch press/release,
alternate solution
TRISB = 0xEF; RB4 = 0;
// LED initially off
while (1) {
while (RB6); DelayMs(30) // wait for press
while (!RB6); DelayMs(30) // wait for release
if (LB4) RB4 = 0;
else RB4 = 1; Reads bit 4 of LATB
}

Read LATB, bit 4 to return the last value written to


PORTB, bit4. This will set the RB4 output to a ‘0’ if it
is currently a ‘1’, to a ‘1’ if it is currently a ‘0’.

V 0.6 23
Toggle LED for each switch press/release
TRISB = 0xEF; RB4 = 0;
// LED initially off
while (1) {
while (RB6); DelayMs(30); // wait for press
while (!RB6); DelayMs(30); // wait for release
PORTB = LATB ^ 0x10;
}

This works because the ^ is the exclusive OR operation,


and an exclusive OR with a ‘1’ value will toggle that bit.

V 0.6 24
Another LED/Switch Problem
• a. LED initially off
• b. A press & release of switch turns LED on
• c. On next press & release, if RB7 is 0, go back to
“a”, else start LED blinking.
• d. On switch press, stop blinking, freeze LED ON
while button is held down. On button release, goto
“a”.

Translate the above word description into a Finite State


Machine (FSM) description (on next page). This gives you a
structured approach for solving IO problems.
V 0.6 25
Finite State Machine approach
for IO problem – provides a
more structured technique for
coding.

Copyright Thomson/Delmar Learning 2005. All Rights Reserved.

V 0.6 26
#define LED_OFF 0 // turn off
#define LED_ON 1 // turn on State
#define LED_BLINK 2 // start blinking
definitions
#define LED_STOP 3 // stop blinking
unsigned char state;
main(void){ Holds current state
serial_init(95,1);
pcrlf();
printf("Led Switch/IO started");
pcrlf();
state = LED_OFF; Configure,
// RB7, RB0 are inputs initialize state
TRISB = 0xEF; variable
LATB = 0x00;
// enable the weak pullup on port B
RBPU = 0;

V 0.6 27
while(1) { print statement for debugging
switch (state) {
case LED_OFF:
printf("LED_OFF");pcrlf();
Could use RB4 here
LATB4 = 0; as well
while(RB0);DelayMs(30); // wait for press
while(!RB0); DelayMs(30); // wait for release
state = LED_ON;
break;
change state so next time
case LED_ON: through case statement will
printf("LED_ON");pcrlf(); choose different case.
LATB4 = 1;
while(RB0); DelayMs(30); // wait for press
while(!RB0); DelayMs(30); // wait for release
if (RB7) state = LED_BLINK;
else state = LED_OFF;
Choose next state
break; based on RB7

V 0.6 28
case LED_BLINK:
printf("LED_BLINK");pcrlf();
// while not pressed
while (RB0) {
// toggle LED
if (LATB4) LATB4 = 0; Blink LED as long as
else LATB4 = 1; switch is not pressed
DelayMs(250);
}
DelayMs(30); Exit loop and change state
state = LED_STOP;
break;
on switch press
case LED_STOP:
printf("LED_STOP");pcrlf();
LATB4 = 1; // freeze on
// wait for release
Freeze LED on
while(!RB0);DelayMs(30); and exit state
state = LED_OFF; when switch is
break;
}
released.
}
} V 0.6 29
Typical Output to Console

V 0.6 30
LCD – Liquid Crystal Display Module

Liquid Crystal
Display (LCD)
module : K x N
where k is number
of characters
displayed, N is
number of lines.

8x2 Module

V 0.6 31
Liquid Crystal Display (LCD) module : K x N where k is
number of characters displayed, N is number of lines.
Internal memory has 80 locations (2 lines of 40 characters)
16x2 LCD

© Thomson/Delmar Learning, 2005 V 0.6 32


4-bit Interface, E is a data
strobe that clocks in data.
© Thomson/Delmar Learning, 2005
V 0.6 33
LCD Commands
When RS = 0, then byte that is sent is a command byte (clear
display, shift left, shift right, move cursor, etc).
When RS = 1, then byte that is sent is ASCII data that is written
to current cursor location, which is incremented by one after the
write.
If the R/W# input is low, then writing data. If R/W# is high, then
reading data. Can read a status code to determine if the LCD
module is finished with the last command or not.

V 0.6 34
LCD Commands

© Thomson/Delmar Learning, 2005


V 0.6 35
LCD Interface Code
These macros improve code portability if you need to use
different pins for the LCD interface.

V 0.6 36
© Thomson/Delmar Learning, 2005
write data or command to LCD

V 0.6 37
© Thomson/Delmar Learning, 2005
Comments on lcd_write
• ‘cmd’ is 8-bit data to write to LCD
• ‘data_flag’ – if ‘1’, then this is a data byte (set
RS=1), if ‘0’, then this is a command byte (set
RS=0).
• If ‘chk_busy’ is nonzero, then read status flag
from LCD and wait until LCD is non busy. If
‘chk_busy’ is zero, don’t check status flag, just
delay.
• if ‘dflag’ is zero, then only send upper four bits of
‘cmd’ (only needed after power up when LCD is
in 8-bit mode).

V 0.6 38
lcd_init() initializes the LCD module.
putch() is used by printf() function to write one character; define
this as write one character to LCD.

© Thomson/Delmar Learning, 2005


V 0.6 39
characters move across screen, right to left because of shift loop
© Thomson/Delmar Learning, 2005
V 0.6 40
What do you have to know?
• Parallel port usage of PORTA, PORTB
• How to use the weak pullups of PORTB
• How N/P type transistors work
• How a Tri-state buffer works
• How an open-drain output works and what it is
useful for.
• How to write C code for finite state machine
description of LED/Switch IO.
• Strobed IO for LCD display

V 0.6 41

You might also like