Use of 74259 8-Bit Adressable Latch

This is a suppliment to the "Use of a Printer Port for Control and Data Acquisition" Manual. It will be included with all future orders of the manual. If you have already purchased a manual and desire a hard copy of this suppliment, please send me e-mail and I will ship you a free copy.

pha@access.digex.net/~pha

The text follows. Admittedly, it isn't terribly useful without the figures, but hopefully, it is sufficient for anyone to determine if a hard copy will be of value. (Apologies for some of the tabs).

Use of the 74259 Addressable Latch for Individual Output Bit Control.

The 74259 8-bit addressable latch / 3 to 8 line decoder permits individual 
output bits to be modified.

Use of a Single 74259.

Refer to Figure 1 which illustrates an interface of the printer port's Data 
Port with a single 74259. Such an arrangement might be used to control 
individual lamps, motors and other devices.  The design of driver circuits to 
interface TTL with such devices is discussed in Vol 1.

Note that the bit to be modified is selected using the latch select inputs A, 
B and C.  The data state to be written to that bit position is identified on 
the Data In lead.  The data is propagated to the output of the latch when the 
/G terminal is brought low and it is latched when the /G terminal goes from a 
"zero" to "one" state.

Thus, the sequence is to first "set up" the bit address (A, B and C) and the 
Data In with the /G input high.  Once this has stabilized, the /G is 
momentarily brought low and then high. 

A typical C routine is illustrated in program ADR_LTC1.C.  Sample calls are 
illustrated in lines 15-23.  Note the call to the output_bit function is of 
the form;

     output_bit(bit_pos, bit_state);

Thus;

     output_bit(7, 0);

sets bit position 7 to a logic 0.

Provision at line 39 is made for clearing the entire latch as might be done 
at boot-up by bringing bit 6 of the Data Port low.  Note that in setting 
bits, this clear lead must be high (line 32).

/*
** Program ADR_LTC1.C
**
** Illustrates how to control individual bits with 74X259 8-bit
** addressable latch.
**
** P. H. Anderson, MSU, 5 April, '96
*/

#include stdio.h>                                     /* 1 */
#include <dos.h>                                       /* 2 */
                                                       /* 3 */
#define DATA 0x03bc                                    /* 4 */
#define STATUS DATA+1                                  /* 5 */
#define CONTROL DATA+2                                 /* 6 */
                                                       /* 7 */
void output_bit (int bit_pos, int bit_state);          /* 8 */
void clear_latch(void);                                /* 9 */
                                                       /* 10 */
void main(void)                                        /* 11 */
{                                                      /* 12 */
   clear_latch();                                      /* 13 */
   /* example - set outputs to 1001 1010 */            /* 14 */
   output_bit(0, 0);                                   /* 15 */
   output_bit(1, 1);                                   /* 16 */
   output_bit(2, 0);                                   /* 17 */
   output_bit(3, 1);                                   /* 18 */
                                                       /* 19 */
   output_bit(4, 1);                                   /* 20 */
   output_bit(5, 0);                                   /* 21 */
   output_bit(6, 0);                                   /* 22 */
   output_bit(7, 1);                                   /* 23 */
}                                                      /* 24 */
void output_bit (int bit_pos, int bit_state)           /* 25 */
{                                                      /* 26 */
/* sets output at defined bit position (0-7) to 1 or 0 */
                                                       /* 28 */
   int out_patt = 0x00;                                /* 29 */
   outportb(CONTROL, 0x01^0x0b);  /* set STROBE to one just
          to be sure */                              /* 31 */
   out_patt = (bit_state <<7) | 0x40 | bit_pos;        /* 32 */
   outportb(DATA, out_patt);  /* output the out_patt *//* 33 */
                                                       /* 34 */
   outportb(CONTROL, 0x00^0x0b); /* bring STROBE low *//* 35 */
   outportb(CONTROL, 0x01^0x0b); /* bring STROBE high */
}                                                      /* 37 */
                                                       /* 38 */
void clear_latch(void)                                 /* 39 */
{                                                      /* 40 */
   outportb(DATA, 0x00);                               /* 41 */
}                                                      /* 42 */
                                                       /* 43 */

Control of Stepping Motor and Individual Bits.

Refer to Figure 2.  Note that a stepping motor is controlled by the lower 
four bits of the 279 latch.  The upper bits may be used to control lamps, 
relays, actuators, etc.  Control of a stepping motor is discussed in Volume 1.


/*
** Program ADR_LTC2.C
**
** Illustrates how to control a stepping motors on lower four
** bits of a 74X259 8-bit addressable latch.  Upper four may be
** used for individual setting of bits.
**
** P. H. Anderson, MSU, 5 April, '96
*/

#include <stdio.h>                                            /* 1 */
#include <dos.h>                                              /* 2 */
                                                              /* 3 */
#define DATA 0x03bc                                           /* 4 */
#define STATUS DATA+1                                         /* 5 */
#define CONTROL DATA+2                                        /* 6 */
                                                              /* 7 */
#define CW 0                                                  /* 8 */
#define CCW 1                                                 /* 9 */
                                                              /* 10 */
void output_bit (int bit_pos, int bit_state);                 /* 11 */
void clear_latch(void);                                       /* 12 */
void output_step_patt(int step_patt);                         /* 13 */
void turn_motor(int direction, int num_8_steps, int speed);   /* 14 */
                                                              /* 15 */
                                                              /* 16 */
void main(void)                                               /* 17 */
{                                                             /* 18 */
   clear_latch();                                             /* 19 */
   /* example - exercise motor and also play with four bits   /* 20 */
 on high nibble */                                            /* 21 */
   output_bit(7, 0);  /* example set high four bits to 0110   /* 22 */
 */                                                           /* 23 */
   output_bit(6, 1);                                          /* 24 */
   output_bit(5, 1);                                          /* 25 */
   output_bit(4, 0);                                          /* 26 */
                                                              /* 27 */
   turn_motor(CW, 32, 100);  /* turn 32 * 8 steps at slow s   /* 28 */
peed */                                                       /* 29 */
   delay(1000);  /*pause for a second */                      /* 30 */
   turn_motor(CCW, 5, 30);  /* other way for 5 * 8 steps at   /* 31 */
 fast speed */                                                /* 32 */
                                                              /* 33 */
   turn_motor(CW, 32, 100);  /* turn 32 * 8 steps at slow s   /* 34 */
peed */                                                       /* 35 */
   delay(1000);  /*pause for a second */                      /* 36 */
   turn_motor(CCW, 5, 30);  /* other way for 5 * 8 steps at   /* 37 */
 fast speed */                                                /* 38 */
}                                                             /* 39 */
                                                              /* 40 */
void turn_motor(int direction, int num_8_steps, int speed)    /* 41 */
{                                                             /* 42 */
   int step_patts[8] = {0x01, 0x03, 0x02, 0x06, 0x04, 0x0c,   /* 43 */
                    0x08, 0x09};                          /* 44 */
   int I, j;                                                  /* 45 */
   if (direction == CW)                                       /* 46 */
   {                                                          /* 47 */
      for (I=0; i<num_8_steps; I++)                          /* 48 */
      {                                                      /* 49 */
         for(j=0; j<8; j++)                                  /* 50 */
         {                                                   /* 51 */
            output_step_patt(step_patts[j]);                /* 52 */
            delay(speed);                                   /* 53 */
         }                                                   /* 54 */
      }                                                      /* 55 */
   }                                                          /* 56 */
   else                                                       /* 57 */
   {                                                          /* 58 */
      for (i=0; i<num_8_steps; I++)                          /* 59 */
      {                                                      /* 60 */
         for(j=7; j>=0; j--)                                 /* 61 */
         {                                                   /* 62 */
            output_step_patt(step_patts[j]);                /* 63 */
            delay(speed);                                   /* 64 */
         }                                                   /* 65 */
      }                                                      /* 66 */
   }                                                          /* 67 */
}                                                             /* 68 */
                                                              /* 69 */
                                                              /* 70 */
void output_step_patt(int step_patt)                          /* 71 */
/* outputs state of each of the four windings */              /* 72 */
{                                                             /* 73 */
   int winding, bit_state;                                    /* 74 */
   for(winding=0; winding<4; winding++)                       /* 75 */
   {                                                          /* 76 */
     bit_state = step_patt & 0x01;                           /* 77 */
     output_bit (winding, bit_state);                        /* 78 */
     step_patt = step_patt>>1;                               /* 79 */
   }                                                          /* 80 */
}                                                             /* 81 */
                                                              /* 82 */
void output_bit (int bit_pos, int bit_state)                  /* 83 */
{                                                             /* 84 */
/* sets output at defined bit position (0-7) to 1 or 0 */     /* 85 */
                                                              /* 86 */
   int out_patt = 0x00;                                       /* 87 */
   outportb(CONTROL, 0x01^0x0b);  /* set STROBE to one just   /* 88 */
 to be sure */                                                /* 89 */
   out_patt = (bit_state <<7) | 0x40 | bit_pos;               /* 90 */
   outportb(DATA, out_patt);  /* output the out_patt */       /* 91 */
                                                              /* 92 */
   outportb(CONTROL, 0x00^0x0b); /* bring STROBE low */       /* 93 */
   outportb(CONTROL, 0x01^0x0b); /* bring STROBE high */      /* 94 */
}                                                             /* 95 */
                                                              /* 96 */
void clear_latch(void)                                        /* 97 */
{                                                             /* 98 */
   outportb(DATA, 0x00);                                      /* 99 */
}                                                             /* 100 */
                                                              /* 101 */
                                                              /* 102 */

Control of Two Stepping Motors.

See Figure #3.  This is the same as previous routines except that functions 
"turn_motor" and "output_step_patt" have been modified to allow the 
identification of the motor, either 0 (low nibble) or 1.            


/*
** Program ADR_LTC3.C
**
** Illustrates how to control two stepping motors. Motor 0 is on lower four
** bits of a 74X259 8-bit addressable latch.  Motor 1 is on upper bits.
**
** P. H. Anderson, MSU, 5 April, '96
*/

#include <stdio.h>                                            /* 1 */
#include <dos.h>                                              /* 2 */
                                                              /* 3 */
#define DATA 0x03bc                                           /* 4 */
#define STATUS DATA+1                                         /* 5 */
#define CONTROL DATA+2                                        /* 6 */
                                                              /* 7 */
#define CW 0                                                  /* 8 */
#define CCW 1                                                 /* 9 */
                                                              /* 10 */
void output_bit (int bit_pos, int bit_state);                 /* 11 */
void clear_latch(void);                                       /* 12 */
void output_step_patt(int motor, int step_patt);              /* 13 */
void turn_motor(int motor, int direction, int num_8_steps,    /* 14 */
int speed);                                                   /* 15 */
                                                              /* 16 */
void main(void)                                               /* 17 */
{                                                             /* 18 */
   clear_latch();                                             /* 19 */
   /* example - exercise motors */                            /* 20 */
   turn_motor(0, CW, 32, 100);                                /* 21 */
             /* turn motor 0 CW 32 * 8 steps at slow speed    /* 22 */
*/                                                            /* 23 */
   delay(1000);  /*pause for a second */                      /* 24 */
   turn_motor(0, CCW, 5, 30);                                 /* 25 */
             /* other way for 5 * 8 steps at fast speed */    /* 26 */
                                                              /* 27 */
   turn_motor(1, CW, 32, 100);                                /* 28 */
             /* turn motor 1 CW 32 * 8 steps at slow speed    /* 29 */
*/                                                            /* 30 */
   delay(1000);  /*pause for a second */                      /* 31 */
   turn_motor(1, CCW, 5, 30);                                 /* 32 */
             /* other way for 5 * 8 steps at fast speed */    /* 33 */
}                                                             /* 34 */
                                                              /* 35 */
void turn_motor(int motor, int direction, int num_8_steps,    /* 36 */
int speed)                                                    /* 37 */
{                                                             /* 38 */
   int step_patts[8] = {0x01, 0x03, 0x02, 0x06,               /* 39 */
                        0x04, 0x0c, 0x08, 0x09};              /* 40 */
   int i, j;                                                  /* 41 */
   if (direction == CW)                                       /* 42 */
   {                                                          /* 43 */
      for (i=0; i<num_8_steps; I++)                          /* 44 */
      {                                                      /* 45 */
         for(j=0; j<8; j++)                                  /* 46 */
         {                                                   /* 47 */
            output_step_patt(motor, step_patts[j]);         /* 48 */
            delay(speed);                                   /* 49 */
         }                                                   /* 50 */
      }                                                      /* 51 */
   }                                                          /* 52 */
   else                                                       /* 53 */
   {                                                          /* 54 */
      for (i=0; i<num_8_steps; I++)                          /* 55 */
      {                                                      /* 56 */
         for(j=7; j>=0; j--)                                 /* 57 */
         {                                                   /* 58 */
            output_step_patt(motor, step_patts[j]);         /* 59 */
            delay(speed);                                   /* 60 */
         }                                                   /* 61 */
      }                                                      /* 62 */
   }                                                          /* 63 */
}                                                             /* 64 */
                                                              /* 65 */
                                                              /* 66 */
void output_step_patt(int motor, int step_patt)               /* 67 */
/* outputs state of each of the four windings */              /* 68 */
{                                                             /* 69 */
   int winding, bit_state;                                    /* 70 */
   for(winding=0; winding<4; winding++)                       /* 71 */
   {                                                          /* 72 */
     bit_state = step_patt & 0x01;                           /* 73 */
     if (motor == 0)                                         /* 74 */
     {                                                       /* 75 */
        output_bit (winding, bit_state);                     /* 76 */
     }                                                       /* 77 */
     else                                                    /* 78 */
     {                                                       /* 79 */
        output_bit (winding+4, bit_state);                   /* 80 */
     }                                                       /* 81 */
     step_patt = step_patt>>1;                               /* 82 */
   }                                                          /* 83 */
}                                                             /* 84 */
                                                              /* 85 */
void output_bit (int bit_pos, int bit_state)                  /* 86 */
{                                                             /* 87 */
/* sets output at defined bit position (0-7) to 1 or 0 */     /* 88 */
                                                              /* 89 */
   int out_patt = 0x00;                                       /* 90 */
   outportb(CONTROL, 0x01^0x0b);                              /* 91 */
                /* set STROBE to one just to be sure */       /* 92 */
   out_patt = (bit_state <<7) | 0x40 | bit_pos;               /* 93 */
   outportb(DATA, out_patt);  /* output the out_patt */       /* 94 */
                                                              /* 95 */
   outportb(CONTROL, 0x00^0x0b); /* bring STROBE low */       /* 96 */
   outportb(CONTROL, 0x01^0x0b); /* bring STROBE high */      /* 97 */
}                                                             /* 98 */
                                                              /* 99 */
void clear_latch(void)                                        /* 100 */
{                                                             /* 101 */
   outportb(DATA, 0x00);                                      /* 102 */
}                                                             /* 103 */
                                                              /* 104 */
                                                              /* 105 */

Control of up to 16 Stepping Motors.

See Figure #4.  

A 74138 one-of-eight decoder has been added so as to provide the addressing 
capability of up to eight latches.  

The identification of the bit position and the data bit as well as the clear 
function are controlled by Data Port outputs, 2, 3 and 4, 7 and 6 as above. 
These are tied to all eight latches.  The specific latch is addressed using 
the 74138 decoder.  A momentary low on the /STROBE causes the outpu
t of the 138 determined by the sate of Data port outputs 3, 4 and 5 to go 
similarly go momentarily low, thus latching the data into the selected latch.

Note that functions "turn_motor", "output_step_patt" and "output_bit" have 
been modified to permit the latch (0-7) to be identified.  Note that the 
latch address is handled in line 113 by shifting the latch ID into the bit 5, 
4 and 3 positions.

Individual bits may also be assigned to positions not assigned to stepping 
motors.  For example, if the lower four bits on latch 4 are not assigned to a 
stepper, the "output_bit" function may be called directly;

     output_bit(4, 3, 1);

which sets bit 3 on latch 4 to a logic one.  
   

/*
** Program ADR_LTC4.C
**
** Illustrates how to control eight groups of two stepping motors.  Each
** of eight latches is identified 0 - 7.  On each 259 latch, motor 0 is
** associated with the lower four bits, motor 1 with the higher four.
**
** P. H. Anderson, MSU, 5 April, '96
*/

#include <stdio.h>                                            /* 1 */
#include <dos.h>                                              /* 2 */
                                                              /* 3 */
#define DATA 0x03bc                                           /* 4 */
#define STATUS DATA+1                                         /* 5 */
#define CONTROL DATA+2                                        /* 6 */
                                                              /* 7 */
#define CW 0                                                  /* 8 */
#define CCW 1                                                 /* 9 */
                                                              /* 10 */
void output_bit (int latch, int bit_pos, int bit_state);      /* 11 */
void clear_latches(void);                                     /* 12 */
void output_step_patt(int latch, int motor, int step_patt);   /* 13 */
                                                              /* 14 */
void turn_motor(int latch, int motor, int direction,          /* 15 */
                  int num_8_steps, int speed);             /* 16 */
                                                              /* 17 */
void main(void)                                               /* 18 */
{                                                             /* 19 */
   clear_latches();                                           /* 20 */
   /* example - exercise motors */                            /* 21 */
   turn_motor(0, 0, CW, 32, 100);                             /* 22 */
   /*turn motor 0 on latch 0 CW 32 * 8 steps at slow speed*/  /* 23 */
                                                              /* 24 */
   delay(1000);  /*pause for a second */                      /* 25 */
   turn_motor(0, 0, CCW, 5, 30);                              /* 26 */
   /*turn same motor other way for 5 * 8 steps at fast speed  /* 27 */
                                                              /* 28 */
                                                              /* 29 */
   turn_motor(0, 1, CW, 32, 100);                             /* 30 */
   /*turn motor 1 on latch 0 CW 32 * 8 steps at slow speed*/  /* 31 */
                                                              /* 32 */
   delay(1000);  /*pause for a second */                      /* 33 */
   turn_motor(0, 1, CCW, 5, 30);                              /* 34 */
   /*turn same motor other way for 5 * 8 steps at fast speed*//* 35 */
                                                              /* 36 */
                                                              /* 37 */
   turn_motor(1, 1, CW, 32, 100);                             /* 38 */
   /*turn motor 1 on latch 1 CW 32 * 8 steps at slow speed*/  /* 39 */
                                                              /* 40 */
   delay(1000);  /*pause for a second */                      /* 41 */
   turn_motor(1, 1, CCW, 5, 30);                              /* 42 */
   /* other way for 5 * 8 steps at fast speed */              /* 43 */
                                                              /* 44 */
   turn_motor(7, 0, CW, 32, 100);                             /* 45 */
   /*turn motor 0 onlatch 7 CW 32 * 8 steps at slow speed*/   /* 46 */
                                                              /* 47 */
   delay(1000);  /*pause for a second */                      /* 48 */
   turn_motor(7, 0, CCW, 5, 30);                              /* 49 */
   /* other way for 5 * 8 steps at fast speed */              /* 50 */
}                                                             /* 51 */
                                                              /* 52 */
void turn_motor(int latch, int motor,                         /* 53 */
                int direction, int num_8_steps, int speed)    /* 54 */
{                                                             /* 55 */
   int step_patts[8] = {0x01, 0x03, 0x02, 0x06,               /* 56 */
                        0x04, 0x0c, 0x08, 0x09};              /* 57 */
   int i, j;                                                  /* 58 */
   if (direction == CW)                                       /* 59 */
   {                                                          /* 60 */
      for (i=0; i<num_8_steps; I++)                          /* 61 */
      {                                                      /* 62 */
         for(j=0; j<8; j++)                                  /* 63 */
         {                                                   /* 64 */
            output_step_patt(latch, motor, step_patts[j]);  /* 65 */
            delay(speed);                                   /* 66 */
         }                                                   /* 67 */
      }                                                      /* 68 */
   }                                                          /* 69 */
   else                                                       /* 70 */
   {                                                          /* 71 */
      for (i=0; i<num_8_steps; I++)                          /* 72 */
      {                                                      /* 73 */
         for(j=7; j>=0; j--)                                 /* 74 */
         {                                                   /* 75 */
            output_step_patt(latch, motor,                  /* 76 */
                                          step_patts[j]);     /* 77 */
            delay(speed);                                   /* 78 */
         }                                                   /* 79 */
      }                                                      /* 80 */
   }                                                          /* 81 */
}                                                             /* 82 */
                                                              /* 83 */
                                                              /* 84 */
void output_step_patt(int latch, int motor, int step_patt)    /* 85 */
/* outputs state of each of the four windings */              /* 86 */
{                                                             /* 87 */
   int winding, bit_state;                                    /* 88 */
   for(winding=0; winding<4; winding++)                       /* 89 */
   {                                                          /* 90 */
     bit_state = step_patt & 0x01;                           /* 91 */
     if (motor == 0)                                         /* 92 */
     {                                                       /* 93 */
        output_bit (latch, winding, bit_state);              /* 94 */
     }                                                       /* 95 */
     else                                                    /* 96 */
     {                                                       /* 97 */
        output_bit (latch, winding+4, bit_state);            /* 98 */
     }                                                       /* 99 */
     step_patt = step_patt>>1;                               /* 100 */
   }                                                          /* 101 */
}                                                             /* 102 */
                                                              /* 103 */
void output_bit (int latch, int bit_pos, int bit_state)       /* 104 */
{                                                             /* 105 */
/* sets output at defined bit position (0-7) to 1 or 0 */     /* 106 */
                                                              /* 107 */
   int out_patt = 0x00;                                       /* 108 */
   outportb(CONTROL, 0x01^0x0b);                              /* 109 */
                   /* set STROBE to one just to be sure */    /* 110 */
/                                                             /* 111 */
   out_patt                                                   /* 112 */
    = (bit_state <<7) | 0x40 | (latch << 3) | bit_pos;   /* 113 */
                                                              /* 114 */
   outportb(DATA, out_patt);  /* output the out_patt */       /* 115 */
                                                              /* 116 */
   outportb(CONTROL, 0x00^0x0b); /* bring STROBE low */       /* 117 */
   outportb(CONTROL, 0x01^0x0b); /* bring STROBE high */      /* 118 */
}                                                             /* 119 */
                                                              /* 120 */
void clear_latches(void)                                      /* 121 */
{                                                             /* 122 */
   outportb(DATA, 0x00);                                      /* 123 */
}                                                             /* 124 */