This is an example demonstration how to programming MCS-51 to interface to shift register for expansion I/O.
Expansion Input
To expand Input we can use 74165 which is an 8–bit shift register with complementary outputs from the
last stage. Data may be loaded into the register either in parallel or in serial
form. When the Serial Shift/Parallel Load input is low, the data is loaded
asynchronously in parallel. When the Serial Shift/Parallel Load input is high,
the data is loaded serially on the rising edge of either Clock or Clock Inhibit
(see the Function Table).
74165 Block diagram

PIN DESCRIPTIONS
Parallel Data inputs. Data on these inputs are asynchronously
entered in parallel into the internal flip–flops when the
Serial Shift/Parallel Load input is low.
Serial Data input. When the Serial Shift/Parallel Load input
is high, data on this pin is serially entered into the first stage
of the shift register with the rising edge of the Clock.
Data–entry control input. When a high level is applied to
this pin, data at the Serial Data input (SA) are shifted into the
register with the rising edge of the Clock. When a low level is
applied to this pin, data at the Parallel Data inputs are
asynchronously loaded into each of the eight internal stages.
Clock inputs. These two clock inputs function identically.
Either may be used as an active–high clock inhibit. However,
to avoid double clocking, the inhibit input should go high only
while the clock input is high.
The shift register is completely static, allowing Clock rates
down to DC in a continuous or intermittent mode.
Complementary Shift Register outputs. These pins are the
noninverted and inverted outputs of the eighth stage of the
shift register.
From the detail above we can programming the software to control 74165 with KEIL C51 as following routine.
sbit LOAD = P2^3; // contect to pin 1 of 74165
sbit CLOCK = P2^4; // contect to pin 2 of 74165
sbit DO = P2^5; // contect to pin 9 of 74165
//---------------------------------------
// Get data N byte from 74165
// input : Address data buffer
// : Num_Of_Chip is the number of 74165
//---------------------------------------
void GET_INPUT_EX(unsigned char Num_Of_Chip,unsigned char * buff)
{
unsigned char i,k;
bit Dbit;
CLOCK = 1;
LOAD = 0; // Load data to serial shift register
LOAD = 1;
DO = 1;
for (i=0;i<Num_Of_Chip;i++)
{
for (k=0;k<8;k++)
{
Dbit = DO ? 1:0;
CLOCK = 0;
*(buff+i)<<=1;
*(buff+i) = *(buff+i) | Dbit;
CLOCK = 1;
}
}
LOAD = 0;
}
Expansion Output
To expansion output we can use 74595 which is 8-bit serial-input/serial or parallel output shift register with latched 3-state output. The 74595 consists of an 8–bit shift register and an 8–bit D–type latch
with three–state parallel outputs. The shift register accepts serial data and
provides a serial output. The shift register also provides parallel data to the
8–bit latch. The shift register and latch have independent clock inputs. This
device also has an asynchronous reset for the shift register.
74595 Block diagram

PIN DESCRIPTIONS
Serial Data Input. The data on this pin is shifted into the
8–bit serial shift register.
Shift Register Clock Input. A low– to–high transition on this
input causes the data at the Serial Input pin to be shifted into
the 8–bit shift register.
Active–low, Asynchronous, Shift Register Reset Input. A
low on this pin resets the shift register portion of this device
only. The 8–bit latch is not affected.
Storage Latch Clock Input. A low–to–high transition on this
input latches the shift register data.
Active–low Output Enable. A low on this input allows the
data from the latches to be presented at the outputs. A high
on this input forces the outputs (QA–QH) into the high–
impedance state. The serial output is not affected by this
control unit.
Noninverted, 3–state, latch outputs.
Noninverted, Serial Data Output. This is the output of the
eighth stage of the 8–bit shift register. This output does not
have three–state capability.
From the detail above we can programming the software to control 74165 with KEIL C51 as following routine.
sbit LATCH = P2^0; // connect to pin 12 of 74595
sbit CLOCK = P2^1; // connect to pin 11 of 74595
sbit DI = P2^2; // connect to pin 14 of 74595
//---------------------------------------
// Send data N byte to 74595
// input : Address data buffer
// : Num_Of_Chip is number of 74595
//---------------------------------------
void SEND_OUTPUT_EX(unsigned char Num_Of_Chip,unsigned char * buff)
{
unsigned char i,k;
LATCH = 0;
_nop_();
CLOCK = 0;
for (i=0;i<Num_Of_Chip;i++)
{
for (k=0;k<8;k++)
{
DI = (*(buff+i) & 0x80)? 1:0;
CLOCK = 1;
*(buff+i)<<=1;
CLOCK = 0;
}
}
LATCH = 1;
}
Here is the main loop of this example .The CPU will reads data from 74165 then send it to Hyper terminal on Windows and send to it 74595.
void main(void)
{
InitSerial();
while(1)
{
GET_INPUT_EX(0x01,&MyData[0]);
// read 1 byte to MyData[]
putchar(0x0C);
printf("%02bX\r\n",MyData[0]);
// Monitor data from 74165 on Hyper terminal
SEND_OUTPUT_EX(0x01,&MyData[0]);
// Send 1 byte from MyData[] to output
DelayMs(10);
}
}
|