Arduino IDE program to control 8253 Programmable interval timer

You can try the following. It compiles but isn't tested.

It assumes the use of an HC595 shift register to hold the D0..7 parallel data to to the 8253 (to save Teensy pins.) If you prefer to use parallel and have the pins available it'd be easy to switch it over.

All it does is send different count values to each of the three timers in the 8253 to produce different square wave. You can use a scope to see if it worked.

/*
 * Sketch: sketch_oct12c.ino
 * Target:  Teensy 2.0++
 *
 *  Drives HC595 serial shift register and 8253 to
 *  (hopefully!) demonstrate loading timers to produce 
 *  square waves.
 */

typedef enum
{
    COUNTER0 = 0,   //00
    COUNTER1,       //01
    COUNTER2,       //10
    WR_MODE_WORD   //11
    
}e8253_ADDRS_t;

//shift register pins
const uint8_t pinStrobe = 8;    //ST_CP of HC595
const uint8_t pinClock = 12;    //SH_CP of HC595
const uint8_t pinData = 11;     //DS of HC595
const uint8_t pinCS = 2;        //to 8253 chip-select
const uint8_t pinA0 = 3;
const uint8_t pinA1 = 4;
const uint8_t pinRD = 5;
const uint8_t pinWR = 6;

uint8_t timerData;
uint16_t timerValue;

void setup() 
{
    //set up GPIOs
    pinMode( pinStrobe, OUTPUT );    
    pinMode( pinCS, OUTPUT );
    pinMode( pinA0, OUTPUT );
    pinMode( pinA1, OUTPUT );
    pinMode( pinRD, OUTPUT );
    pinMode( pinWR, OUTPUT );

    digitalWrite( pinStrobe, HIGH );
    digitalWrite( pinCS, HIGH );
    digitalWrite( pinWR, HIGH );
    digitalWrite( pinRD, HIGH );

    //counter 0
    timerData = 0b00110110;     //counter 0, load least then most, Mode 3, binary count
    timerValue = 0x7fff;
    Write8253( WR_MODE_WORD, timerData );
    Write8253( COUNTER0, (uint8_t)(timerValue & 0x00ff) );
    Write8253( COUNTER0, (uint8_t)((timerValue >> 8) & 0x00ff) );

    //counter 1
    timerData = 0b01110110;     //counter 1, load least then most, Mode 3, binary count
    timerValue = 0xfff5;
    Write8253( WR_MODE_WORD, timerData );
    Write8253( COUNTER1, (uint8_t)(timerValue & 0x00ff) );
    Write8253( COUNTER1, (uint8_t)((timerValue >> 8) & 0x00ff) );

    //counter 2
    timerData = 0b10110110;     //counter 2, load least then most, Mode 3, binary count
    timerValue = 0x1000;
    Write8253( WR_MODE_WORD, timerData );
    Write8253( COUNTER2, (uint8_t)(timerValue & 0x00ff) );
    Write8253( COUNTER2, (uint8_t)((timerValue >> 8) & 0x00ff) );
    
}//setup

void loop() 
{
    //nothing to do in loop
    
}//loop

void Write8253( uint8_t address, uint8_t dataval )
{
    //shift data byte out to HC595 shift register
    digitalWrite( pinStrobe, LOW );
    shiftOut( pinData, pinClock, LSBFIRST, dataval );
    digitalWrite( pinStrobe, HIGH );

    //set address pins
    digitalWrite( pinA0, (address & 0x01) ? HIGH:LOW );
    digitalWrite( pinA1, (address & 0x02) ? HIGH:LOW );

    //wiggle CS and WR to send to 8253
    digitalWrite( pinCS, LOW );     //set chip select
    delayMicroseconds( 10 );        //wait >> Taw
    digitalWrite( pinWR, LOW );     //assert WR low
    delayMicroseconds( 10 );        //wait >> Tww
    digitalWrite( pinWR, HIGH );    //de-assert WR
    delayMicroseconds( 10 );        //wait >> Twa
    digitalWrite( pinCS, HIGH );    //de-assert CS
    
}//Write8253
1 Like