You are on page 1of 4

CONSTRUCTION

MICROCONTROLLER-BASED
INDUSTRIAL TIMER
JAYARAMAN KIRUTHI VASAN

ndustrial timers can be constructed using discrete components including up/down


counters and timers. However, to incorporate various facilities like setting
the count, start, stop, reset and display, these circuits would require too
many ICs and discrete components.
A microcontroller-based industrial
timer can be programmed and used
as a timer, counter
and time totaliser.
Here is a simple design based on 40-pin
Atmel
AT89S52
microcontroller that
performs count-down
operation up to 9999
minutes/second with
four 7-segment displays showing the actual time left. The relay energises as you
press the start switch
and remains on till the
countdown reaches
0000. Four tactile,
push-to-on switches
are used to start/stop,
select either minutes
or seconds, and set the
initial value for countdown operation (using up and down
keys).

vice with 8 kB of program flash


memory, 256 bytes of RAM, 32 I/O
lines, Watchdog timer, two data pointers, three 16-bit timer/counters, a sixvector two-level interrupt architecture,
a full-duplex serial port, on-chip oscillator and clock circuitry. The powerdown mode saves the RAM contents
but freezes the oscillator, disabling all
other chip functions until the next interrupt or hardware reset is activated.
Port P0 of microcontroller AT89S52

UMAR
SUNIL K

is configured for segments of the 7segment display. Port 0 is an 8-bit


open-drain bidirectional I/O port. Port
0 is pulled up with 10-kilo-ohm resistor network RNW1. Port pins P0.0
through P0.6 are connected to pins of
segments a through g via resistors
R2 through R8, respectively. Port P0.7
is connected to decimal via resistor R9.
Resistors R2 through R9 are used as
current limiter for various segments of
displays, respectively.

Circuit
description
Fig. 1 shows the circuit
of
the
microcontroller-based
industrial timer. The
microcontroller is
Atmel AT89S52 (IC1),
which is a 40-pin deWWW.EFYMAG.COM

JUNE 2007

CONSTRUCTION

Port 2 is used to control DIS1


through DIS4. Port 2 is an 8-bit bidirectional I/O port with internal pullups. When port-2 pin is low, the transistor conducts and provides supply
to the common pin of 7-segment display. Port pins P2.5 through P2.2 control DIS1 through DIS4 with the help
of transistors T1 through T4, respectively.
The microcontroller drives the 7segment displays in multiplex mode.
This helps in reducing current consumption while maintaining the
brightness of the display. For driving
the displays, timer 2 inside the
microcontroller is used. It enables display of each digit every two milliseconds.
For driving the displays, the microcontroller
uses port-0 to send the
segment outputs. It selects the corresponding
units, tens, hundreds
and thousands displays
through P2.5, P2.4, P2.3
and P2.2, respectively.
Four pins of port 1 are
used for various switches
like select, up, down and
start/stop. Port 1 is an 8bit bidirectional I/O port
with internal pull-ups.
Switches S1 through S4
are connected to pins 5
through 8 of the
microcontroller and used
for select, up, down and
start/stop functions, respectively.
Pin P3.7 controls relay RL1. When pin P3.7
goes high, transistor T5 is
driven into saturation
JUNE 2007

and
relay
RL1
energises. Diode D1
serves as a free-wheeling diode. Any appliance can be connected
with contacts of relay
RL1.
Power-on-reset is
achieved by connecting resistor R1 and capacitor C1 to pin 9 of
the microcontroller.
Other ends of the capacitor and resistor are connected to Vcc and ground,
respectively. Switch S5 is used for
manual reset. The microcontroller is
operated with the clock derived from
a 20MHz crystal oscillator.
Power supply. Fig. 2 shows the circuit of the power supply. The AC
mains is stepped down by transformer
X1 to deliver a secondary output of
7.5V at 350 mA. The transformer output is rectified by a full-wave bridge
rectifier BR1, filtered by capacitor C5
and regulated by IC2. Capacitor C6 bypasses any ripple present in the regulated output. Unregulated power supply is used for relay RL1.
An actual-size, single-side PCB layout for the microcontroller-based in-

PARTS LIST
Semiconductor:
IC1
IC2
T1-T4
T5
BR1
D1
DIS1-DIS4

AT89S52 micrcontroller
7805 5V regulator
BC557 pnp transistor
BC547 npn transistor
1A bridge rectifier
1N4007 rectifier diode
LTS542 common-anode
display

Resistors (all -watt, 5% carbon):


R1, R14-R18
- 8.2-kilo-ohm
R2-R9
- 270-ohm
R10-R13
- 470-ohm
RNW1
- 10-kilo-ohm resistor
network
Capacitors:
C1
C2, C3
C4, C6
C5
Miscellaneous:
X1
XTAL
RL1
S1-S5
S6

10F,16V electrolytic
33pF ceramic disk
0.1F ceramic disk
1000F, 25V electrolytic

- 230V AC primary to 6V,


350mA secondary
transformer
- 20MHz crystal
- 6V, 1C/O relay
- Push-to-on switch
- On/off switch

dustrial timer (Fig. 1) including power


supply (Fig. 2) is shown in Fig. 3 and
its components layout in Fig.4.

Operation
Switch on the circuit using using ON/
OFF switch S6. The
microcontroller is reset
by power-on-reset and
then timer is in seconds
mode. The select key selects the mode between
seconds and minutes.
This is displayed as 0
for seconds and 1 for
minutes
on
the
hundreds digit display
(DIS3), respectively.
Up key increments
the time setting in seconds and minutes.
Down key decrements the time setting in
seconds and minutes.
After setting the desired time with the help
of up and down keys,
press start key. This
energises the relay. The
timer counts down for
the set time and once the
display becomes zero,
WWW.EFYMAG.COM

CONSTRUCTION
the relay de-energises.
The timer will stop before preset time by pressing start key again.

Software
The source program is
written in C language
and compiled with Keil
Microvision 3 IDE. It is
well commented and
easy to understand.
D o w n l o a d
C51V808A.EXE from
www.keil.com/demo/
eval/c51.htm. This file is
a freely available and
self-extracting setup program
for
Keil
Microvision 3 IDE.
Normally, when there
is no interrupt, the
microcontroller executes
while loop in the main
function. Here it scans
the keys and acts according to the key
pressed.
Two interrupts are enabled in the
software, namely, timer 0 and timer 2.
Timer 0 counts milliseconds, which are
then accumulated to seconds or minutes according to the user selection.
Timer 2 drives the displays in multiplex mode.
For time counting, timer 0 is

initialised
by
the
void
Timer0_init(unsigned
char
Timer0h,unsigned char Timer0l) function. Timer 0 interrupts the
microcontroller every millisecond.
When interrupted by timer 0, the
microcontroller executes the void
isr_t0(void) function wherein it increments two counter variables, namely,
Timer0Counter and LedCounter.

Timer0Counter is responsible for counting


the number of milliseconds elapsed and increments the minutes/seconds counter according
to the mode selected
(seconds or minutes
count). Once the set
value is reached, the
timer-0 interrupt is disabled and time counting
stops.
The LED counter
makes the dot LED of the
units digit flash every
second once.
Display-driving process is taken care of by
the built-in timer 2. Timer
2 is initialised by the void
Timer2_init(unsigned
char Timer2h,unsigned
char Timer2l) function.
Timer 2 gives an interrupt to the microcontroller to
switch on the common pin of each 7segment display for every two milliseconds. When an interrupt occurs, the
void isr_t2(void) function is executed
and the microcontroller returns to
while loop in the main function.
EFY note. The software and other
relevant files of this article have been
included in this months EFY-CD.

SOURCE PROGRAM
/*** Include Files ***/
#include <At89x52.h>
/*** RENAMING OF PORTS ****/
#define SegPort P0
#define DigPort P2
/* CODE FOR LIGHTING EACH SEGMENT OF
THE SEVEN SEGMENT LED DISPLAY */
#define seg_a 0xfe
#define seg_b 0xfd
#define seg_c 0xfb
#define seg_d 0xf7
#define seg_e 0xef
#define seg_f 0xdf
#define seg_g 0xbf
#define seg_dot 0x7f
/* SEVEN SEGMENT CODE FOR EACH NUMBER FROM 0 TO 9 ,DOT AND SPACE */
#define NUM_0 (seg_a & seg_b & seg_c & seg_d
& seg_e & seg_f)
#define NUM_1 (seg_b & seg_c)
#define NUM_2 (seg_a & seg_b & seg_d & seg_e
& seg_g)
#define NUM_3 (seg_a & seg_b & seg_c & seg_d
& seg_g)
#define NUM_4 (seg_b & seg_c & seg_f & seg_g)
#define NUM_5 (seg_a & seg_c & seg_d & seg_f

WWW.EFYMAG.COM

& seg_g)
#define NUM_6 (seg_a & seg_c & seg_d & seg_e
& seg_f & seg_g)
#define NUM_7 (seg_a & seg_b & seg_c)
#define NUM_8 (seg_a & seg_b & seg_c & seg_d
& seg_e & seg_f & seg_g)
#define NUM_9 (seg_a & seg_b & seg_c & seg_d
& seg_f & seg_g)
#define NUM_DOT (seg_dot)
#define NUM_SPACE 0Xff;
const unsigned char hex_table[] =
{
NUM_0,NUM_1,NUM_2,NUM_3,NUM_4,
NUM_5,NUM_6,NUM_7,
NUM_8,NUM_9,NUM_DOT
};
/* ADDRESS FOR SELECTING THE COMMON
PIN OF THE DISPLAY FOR EACH DIGIT */
#define UNITS 0xdf
#define TENS 0xef
#define HUNDS 0xf7
#define THS 0xfb
/* RELOAD VALUE FOR TIMER2 FOR INTERRUPT DURATION OF 2 MILLISECONDS */
#define TIMER2H_2MS 0xf2
#define TIMER2L_2MS 0xfb
/* RELOAD VALUE FOR TIMER0 FOR INTER-

RUPT DURATION OF 1 MILLISECOND */


#define TIMER0H_1MS 0xf9
#define TIMER0L_1MS 0x7e
/* VECTOR VALUE FOR TIMER INTERRUPT
*/
#define TIMER0VECTOR 1
#define TIMER2VECTOR 5
/* MINUTES AND SECONDS CONSTANTS */
#define SEC 999
#define MIN (60 * SEC)
/* VARIABLES DEFINITION */
unsigned char Units;
unsigned char Tens;
unsigned char Hunds;
unsigned char Ths;
unsigned int Timer0Counter=0;
unsigned char DisplayCounter=0;
unsigned int LedCounter=0;
unsigned char TimeDig;
unsigned int OneSecCount=0;
unsigned int SetSec=0;
unsigned char OneMinCount;
unsigned char key;
unsigned char KeyCount;
unsigned char Mode;
/* FUNCTION PROTOTYPES */
void
Timer0_init(unsigned
char
Timer0h,unsigned char Timer0l);

JUNE 2007

CONSTRUCTION
void
Timer2_init(unsigned
char
Timer2h,unsigned char Timer2l);
void Display(unsigned char Digit);
void IntToSevSeg(unsigned int TimeTemp);
void KeyDebounce(unsigned char dly);
void Keyscan(void);
/* RENAMING PORT PINS FOR EASY USAGE
*/
sbit RELAY = P3^7;
sbit SEL = P1^4;
sbit UP = P1^5;
sbit DN = P1^6;
sbit STRT = P1^7;
/* MAIN FUNCTION */
void main(void)
{
RELAY = 0;
Timer2_init(TIMER2H_2MS,TIMER2L_2MS);
Timer0_init(TIMER0H_1MS,TIMER0L_1MS);
TR0=0;
EA=1;
while(1)
{
if(TR0==0)IntToSevSeg(SetSec);
else if( (TR0==1)&& (Timer0Counter==0) )
IntToSevSeg(OneSecCount);
Keyscan();
switch(key)
{
case 4:
if(SetSec>0)
{
if(TR0==0)
{
OneSecCount
= SetSec;
RELAY = 1;
TR0=1;
}
else
{
TR0=0;
}
}
key=0;
break;
case 3:
SetSec;
if(SetSec>9999)
SetSec=9999;
key=0;
break;
case 2:
SetSec++;
if(SetSec>9999)
SetSec=0;
key=0;
break;
case 1:
Mode++;
if(Mode>1)Mode=0;
Hunds=hex_table[Mode];
Tens = NUM_SPACE;
Units = NUM_SPACE;
key=0;
KeyDebounce(10);
break;
}
}
}
/* TIMER INITIALISATION FUNCTIONS */
void
Timer0_init(unsigned
char
Timer0h,unsigned char Timer0l)
{
TMOD &= 0xf0;
TMOD |= 0x01;
TH0 = Timer0h;
TL0 = Timer0l;
ET0=1;
TR0=1;
}
void

Timer2_init(unsigned

JUNE 2007

char

Timer2h,unsigned char Timer2l)


{
T2CON = 0x04;
T2MOD = 0x00;
TH2 = Timer2h;
RCAP2H=Timer2h;
TL2 = Timer2l;
RCAP2L=Timer2l;
ET2=1;
TR2=1;
}
/* KEYSCAN FUNCTIONS */
void Keyscan(void)
{
while( (SEL==0) || (STRT==0) )
{
KeyDebounce(1);
if(SEL==0)key=1;
else if(STRT==0)key=4;
}
if ((UP==0) || (DN==0) )
{
KeyCount;
if(KeyCount<1)KeyCount=1;
KeyDebounce(KeyCount);
if(UP==0)key=2;
else if(DN==0)key=3;
}
else
KeyCount=10;
}
void KeyDebounce(unsigned char dly)
{
unsigned int z;
while(dly>0)
{
dly;
for(z=0;z<8000;z++);
}
}
/* DISPLAY FUNCTIONS */
void Display(unsigned char DigCount)
{
switch(DigCount)
{
case 0:
DigPort = UNITS;
SegPort = Units;
break;
case 1:
DigPort = TENS;
SegPort = Tens;
break;
case 2:
DigPort = HUNDS;
SegPort = Hunds;
break;
case 3:
DigPort = THS;
SegPort = Ths;
break;
}
}
/* INTEGER VALUE TO SEVEN SEGMENT
CONVERSION FUNCTION */
void IntToSevSeg(unsigned int TimeTemp)
{
TimeDig = TimeTemp/1000;
TimeTemp -=(TimeTemp/1000)*1000;
if(TimeDig==0)
{
Ths=NUM_SPACE;
}
else
{
Ths = hex_table[TimeDig];
}
TimeDig = TimeTemp/100;

TimeTemp -=(TimeTemp/100)*100;
if((Ths==0xff)&&(TimeDig==0))
{
Hunds=NUM_SPACE;
}
else
{
Hunds = hex_table[TimeDig];
}
TimeDig = TimeTemp/10;
TimeTemp -=(TimeTemp/10)*10;
if((Hunds==0xff)&&(TimeDig==0))
{
Tens=NUM_SPACE;
}
else
{
Tens = hex_table[TimeDig];
}
TimeDig = TimeTemp%10;
Units = hex_table[TimeDig];
}
/* Interrupt Routines */
/* Drives LED Displays */
void isr_t2(void) interrupt TIMER2VECTOR
{
DisplayCounter++;//Increments every 50
ms.
if(DisplayCounter>3)DisplayCounter=0;
Display(DisplayCounter);
TF2 = 0;
}
/* Counts Seconds */
void isr_t0(void) interrupt TIMER0VECTOR
{
TH0 = TIMER0H_1MS;
TL0 = TIMER0L_1MS;
TF0=0;
Timer0Counter++;//Counts every 1msec.
LedCounter++;
if(LedCounter<200)
Units= Units & NUM_DOT;
else if( (LedCounter>=200) && (LedCounter
<999) )
Units = Units | 0x80;
else
LedCounter=0;
if(Mode==0)
{
if(Timer0Counter>SEC)
{
Timer0Counter=0;
OneSecCount;
if(OneSecCount==0)
{
//OneSecCount=0;
TR0=0;
RELAY = 0;
}
}
}
else if(Mode==1)
{

if(Timer0Counter>MIN)
{
Timer0Counter=0;
OneSecCount;
if(OneSecCount>MIN)
{
OneSecCount=0;
TR0=0;
RELAY = 0;
}
}
}

/****************** END *****************/

WWW.EFYMAG.COM

You might also like