Home > Electronic Tutorials > Microcontroller Based Schematics > AT89C2051 Real Time Controller Circuit

Microcontroller Based Schematics, Projects, Tutorials

AT89C2051/4051
Scanning 7-Segment Display and Keypad

Author: Wichit Sirichote

Since the output buffer of  P1 can sink 20mA (each output pin, but maximum IOL for all outputs was limited at 80mA), thus we can use P1 to drive LED display directly. As shown in the circuit, Two common-anode 7-segment LEDs are connected to P1 with 180 Ohms current limiting resistor. Each segment of two LED are tied in parallel to P1. Q1 and Q2 are activated by logic low of P3.0 and P3.1, sourcing +5V to common anode pins. P3.4 read logic low if either S1 or S2 was pressed while scanning period have made.
 

7 Segment & Keypad Diagram

7-seg.c

7-SEG.C
7-SEG.HEX

The program demonstrates simple counting down clock. S1 is used for setting time to 99, S2 for start count down.

/*
 * 7-seg.c
 * Driving 2-digit 7-segment Common Anode LED & keypad
 * Copyright (C) 1999 Wichit Sirichote
 * compiled with Dunfield Micro-C for 8051 Release 3.2
 * c:\mc\cc51 7-seg -i h=c:\mc m=t
 */

#include c:\mc\8051io.h  /* include i/o header file */
#include c:\mc\8051reg.h

extern register char cputick; // cputick was incremented every 10ms

register unsigned char flag1;
unsigned register char sec,digit,buffer[2];
register char key;

char convert[10] = {0x3F,0x0c,0x76,0x5e,0x4d,0x5b,0x7b,0x0e,0x7f,0x5f};
 

/*  my LED's segment pin designation (differs from standard)
   b
     __
 a  |__| c
 f   |   | d
      --
     e
*/

#define setValue 99

main()
{
          flag1 = 0;
          sec = setValue;
          timeToBuffer();
          serinit(9600); // set timer0 to be 16 bit counter
          while(1){

               while(cputick < 10)
                scanLED();
            // execute the following functions every 100ms
                cputick = 0;
                timeToBuffer();
                keyexe();
                countdown();
                  }
}
 

scanLED() /* scan 2-digit LED and 2-key switch, if key pressed key = 0-1
else key = -1 */

{
    int i;
    digit = 0x02;    // scan code 00000010
    key = -1;
    for( i = 0; i < 2; i++)  /* 2-DIGIT scanning */
    {
        P3 = ~digit;      /* send complement[digit] */
        P1 = ~buffer[i];  /* send complement[segment] */
        delay(1);         /* delay 1ms */
        P1 = 0xff;        /* off LED */
        if ((P3 & 0x10) == 0) /* if key pressed P3.4 became low */
           key = i;       /* save key position to key variable */
        digit>>=1;        /* next digit */
    }
}

timeToBuffer() // converts binary data in sec to 7-segment pattern
{
    buffer[0] = convert[sec%10];
    buffer[1] = convert[sec/10];
}

countdown()
{
    if ((flag1 & 0x02) != 0)
        sec--;
        if (sec == 0 )
                flag1 &= ~0x02;  // clear run bit
}

keyexe()
{
    if (key != -1)
    {
      switch(key){
        case (0): /* key position 0 */
        reset();  /* service key 0 */
        break;
        case (1): /* key position 1 */
        run();    /* service key 1 */
                }

    }
}

reset()
{
        sec = setValue;  // reload set value
        timeToBuffer();
        flag1 &= ~0x02;  // stop counting down
}

run()
{
        if (sec != 0)
        flag1 |= 0x02; // start counting down
}


Exercises
  • countdown( ) function decrements time every 0.1sec or 100ms, try change to 1 sec.
  • use logic probe check at P3.7, is there a pulse observed? use this pin connects a small transistor that drives a buzzer, modify the source program to activate buzzer when count value is zero.
  • see CLOCK CONTROLLER, for details of scanning four digit LEDs and four key switches.
Note: To report broken links or to submit your projects please send email to Webmaster

Discover

     more......