Professional Documents
Culture Documents
11.1.1
For writing programs involving Timers 0 and 1 needs configuration of TMOD, TCON and IE registers. Summary of these registers are shown in Table 11-1. Table 11-1 Summary of configuration bits for TMOD, TCON and IE registers Bits 7 6 TMOD register GATE1 C/T1# TCON register TF1 TR1 Interrupt Enable (IE) Register EA TCON and IE registers are bit addressable 5 M11 TF0 ET2 4 M01 TR0 ES 3 GATE0 IE1 ET1 2 C/T0# IT1 EX1 1 M10 IE0 ET0 0 M00 IT0 EX0
Program Task 1 Write an assembly program that sets up Timer 0 in Mode 0 (as a 13 bit timer) with software gate and toggles state of pin P0.0 of AT89C52 at every Timer 0 interrupt.
Listing 11-1
$INCLUDE (reg52.inc) org 000h ljmp begin org 00Bh ljmp it_timer0 org 0100h begin: ANL TMOD,#0F0h ; Timer 0 mode 0 with software gate ; GATE0=0; C/T0#=0; M10=0; M00=0; MOV TH0,#00h MOV TL0,#00h SETB ET0 SETB EA SETB TR0 JMP $ ; init values ; ; enable timer0 interrupt ; enable interrupts ; timer0 run ; endless loop ; Main program starts at 100h ; ISR location for Timer 0 interrupt
; FUNCTION_PURPOSE: timer0 interrupt ; FUNCTION_OUTPUTS: P0.0 toggle period ; = 2 * 12* 8192 crystal Hz it_timer0: CLR TF0 CPL P0.0 ; reset interrupt flag (already done by hardware) ; P0.0 toggle when interrupted
RETI end
Program Task 2 Write an assembly program that sets up Timer 1 in Mode 0 (as a 13 bit timer) with software gate and toggles state of pin P0.0 of AT89C52 at every Timer 1 interrupt. Listing 11-2 Assembly Program Listing Timer 1 in Mode 0 (Software Gate) $INCLUDE (reg52.inc) org 000h ljmp begin org 01Bh ljmp it_timer1 org 0100h begin: ANL TMOD,#0Fh ; Timer 1 mode 0 with software gate ; GATE1=0; C/T1#=0; M11=0; M01=0; MOV TH1,#00h MOV TL1,#00h SETB ET1 SETB EA SETB TR1 JMP $ ; init values ; ; enable timer0 interrupt ; enable interrupts ; timer0 run ; endless loop ; Main program starts at 100h ; ISR location for Timer 1 interrupt
; FUNCTION_OUTPUTS: P0.0 toggle period ; = 2 * 12* 8192 crystal Hz it_timer1: CLR TF1 CPL P0.0 RETI end ; reset interrupt flag (already done by hardware) ; P0.0 toggle when interrupted
Note that in Program Tasks 1 and 2, the ISR location for Timer 0 and Timer 1 are different. Recall the vector addresses of different interrupts as shown in Table 11-2. When interrupts occur, the processor address pointer (instruction pointer) loads the processor assigned vector address and jumps to that address. In the main program body, the respective interrupt is enabled (ET0 = 1 or ET1 = 1) and than the global interrupt (EA = 1) by using the SETB instruction. Next the timer is enabled by setting TR0 or TR1 to 1. Table 11-2 Vector addresses of different interrupts External 0 Timer 0 (IE0) (TF0) 0003H 000BH External 1 Timer 1 (IE1) (TF1) 0013H 001BH Serial Port (RI or TI) 0023H Timer 2 (TF2 or EXF2) 002BH System Reset (RST) 0000H
Inside the ISR routine (it_timer0 or it_timer1), the interrupt flag (TF0 or TF1) is cleared to reset the interrupt. This is already done by hardware, however, to ensure that the system is ready for next interrupt, clear it inside the ISR. The last instruction in the ISR is the RETI (return from interrupt) that will popup all the necessary addresses/data from the stack. Assignments Exercise 11-1 Implement the program tasks 1 and 2, and determine the frequency of the pulses at P0.0 for a 20MHz crystal clock. Also verify the theoretical frequency output. See the waveform pattern using an oscilloscope and draw the waveform with time scale. Exercise 11-2 Configure Timer 0 as a 16 bit timer and toggle the state of P0.0 using Timer 0 interrupt. Measure the frequency and duty cycle of the pulses at P0.0 for a 20MHz crystal clock.
Also verify the theoretical frequency output. See the waveform pattern using an oscilloscope and draw the waveform with time scale. Exercise 11-3 Repeat Exercise 11-2 for Timer 1.
11.1.2
Timers 0 or 1 can be configured as a 16-bit Timer/Counter in Mode 1. For Timer 0, in mode 1 M10 = 0, M00 = 1. For Timer 1, in mode 1 M11 = 0 and M01 = 1. Lets use Timer 0 in mode 1 for the 16-bit timer. The assembly program for 16-bit timer and toggling pin P1.0 with timer 0 interrupt is shown in program task 3. Program Task 3 Write an assembly program that sets up Timer 0 in Mode 1 (as a 16 bit timer) with software gate and toggles state of pin P2.0 of AT89C52 at every Timer 0 interrupt. Listing 11-3 Assembly Program Listing Timer 0 in Mode 1 (Software Gate) and generating square wave pulses at P2.0 with Timer 0 interrupt. $INCLUDE (reg52.inc) org 000h ljmp begin org 00Bh ljmp it_timer0 org 0100h begin: ANL TMOD,#0Fh ORL TMOD,#01h MOV TH0,#00h MOV TL0,#00h SETB ET0 SETB EA ; Timer 0 mode 1 with software gate ; GATE0=0; C/T0#=0; M10=0; M00=1; ; init values ; ; enable timer0 interrupt ; enable interrupts ; Main program starts at 100h ; ISR location for Timer 0 interrupt
; FUNCTION_PURPOSE: timer 0 interrupt ; FUNCTION_OUTPUTS: P2.0 toggle period ; = 2 * 12* 65536 crystal Hz it_timer0: CLR TF0 CPL P2.0 RETI end ; reset interrupt flag (already done by hardware) ; P2.0 toggle when interrupted
With a 20 MHz crystal, the output frequency at P1.0 would be Program Task 4 Write an assembly program that sets up Timer 1 in Mode 1 (as a 16 bit timer) with software gate and toggles state of pin P2.0 of AT89C52 at every Timer 1 interrupt. Listing 11-4 Assembly Program Listing Timer 1 in Mode 1 (Software Gate) and generating square wave pulses at P2.0 with Timer 1 interrupt.
$INCLUDE (reg52.inc) org 000h ljmp begin org 01Bh ljmp it_timer1 org 0100h ; Main program starts at 100h ; ISR location for Timer 1 interrupt
begin: ANL TMOD,#0Fh ORL TMOD,#10h MOV TH1,#00h MOV TL1,#00h SETB ET1 SETB EA SETB TR1 JMP $ ; Timer 1 mode 1 with software gate ; GATE1=0; C/T1#=0; M11=0; M01=1; ; init values ; ; enable timer0 interrupt ; enable interrupts ; timer1 run ; endless loop
; FUNCTION_PURPOSE: timer 1 interrupt ; FUNCTION_OUTPUTS: P2.0 toggle period ; = 2 * 12* 65536 crystal Hz it_timer1: CLR TF1 CPL P2.0 RETI end ; reset interrupt flag (already done by hardware) ; P2.0 toggle when interrupted
11.1.3
C-Example
13-bit Timer Developing programs using C is comparatively easy and takes less time than assembly language. The SFR definitions are available in reg52x2.h header file.
Listing 11-5
#include "reg52x2.h" /** * FUNCTION_PURPOSE: This file set up timer 0 in mode 0 (13 bits timer) * with a software gate. */ void main(void) { TMOD &= 0xF0; /* Timer 0 mode 0 with software gate */ /* GATE0=0; C/T0#=0; M10=0; M00=0; */ TH0 = 0x00; TL0 = 0x00; ET0=1; EA=1; TR0=1; while(1); } /** * FUNCTION_PURPOSE: timer0 interrupt * FUNCTION_OUTPUTS: P2.0 toggle period = 2 * 12* 8192 Crystal Hz */ void it_timer0(void) interrupt 1 /* interrupt address is 0x000b */ { /* enable timer0 interrupt */ /* enable interrupts */ /* timer0 run */ /* endless loop*/ /* init values */
TF0 = 0;
/* reset interrupt flag (already done by hardware)*/ /* P2.0 toggle when interrupt */
P2_0 = ~P2_0; }
Although the SFR symbols used in example 11-5 are same as in assembly program, few things are new here. The shorthand &= is performing the AND immediate operation. Also look at the interrupt service routine and interrupt declaration. The interrupt declaration depends upon the compiler (the example is following RIDE compiler). The port bits are defined as Portname_bitname (Example: P2.0 is defined in reg52x2.h as P2_0). Large and complicated applications are difficult to manage using assembly as the file size becomes large. In such situations, the user can explore the power of C language that can easily manage complicated tasks with lesser text lines.
11.1.4
The 13-bit and 16-bit timer modes have limited applications. As modes 0 or 1 produces very low frequency, these modes are not suitable for generating variable width pulses at high frequency. The auto reload mode in fact can configure the timer with flexibility of output frequency. In mode 2 with software gate, the interrupt frequency is
For a crystal of 12 MHz, finterrupt can be varied from 3.9 kHz to 1 MHz. The following program will produce a PWM pulse train at P2.0 with a duty of 80% at 1 kHz. The PWM frequency is obtained from the equation
... 11-1
... 11-2 For fPWM = 1 kHz and N = 30, reload_value = 201. Listing 11-6 80% duty. C program listing of PWM pulse generated at P2.0 of AT89C52 at 1 kHz and
#define reload_value
201
#include "reg52x2.h" /** * PURPOSE: This file set up timer 0 in mode 2 with a software gate */ unsigned char count = 0, count_max = 30; void main(void) { TMOD &= 0xF0; TMOD |= 0x02; TH0 = reload_value; TL0 = reload_value; ET0=1; EA=1; TR0=1; P2_0 = 0; while(1); } /* enable timer0 interrupt */ /* enable interrupts */ /* timer0 run */ /* Initialize P2.0 */ /* endless */ /* Timer 0 mode 0 with software gate */ /* GATE0=0; C/T0#=0; M10=1; M00=0; */ /* init values */
void it_timer0(void) interrupt 1 /* interrupt address is 0x000b */ { TF0 = 0; /* reset interrupt flag*/ count++;
Examine output of program 11-6 at P2.0 (pin 21) of AT89C52 with a 20 MHz crystal. It is supposed to produce a PWM waveform of 80% duty at 1 kHz. Exercise 11-4 Write an assembly program that would a generate a PWM waveform at P2.0 of AT89C52 with a variable duty. A low signal at P1.0 would increase the duty whereas a low signal at P1.1 would decrease the duty. The PWM switching frequency should remain constant at 1 kHz.
T2
Figure 11-1 PWM waveform generation technique using timer interrupt in auto reload mode PWM frequency and Duty Cycle Calculations In auto reload mode of Timer 0 or Timer 1, the interrupt occurs at the end of 256auto_reload_value. The time duration is given by,
... 11-3
... 11-4
... 11-5
... 11-6 From equation 11-5 and 11-6, it is evident that for constant switching frequency, the sum of RL_ON and RL_OFF should be kept constant. The duty cycle adjustment can be done by adjusting the vale of RL_ON and RL_OFF but the sum should be a constant value.
11.2.2
The AT89C52 can be used for dc motor speed control using pulse width modulation technique. The hardware schematic is shown in Figure 11-2. The scheme is an open loop control that would give variable duty PWM pulses at the Darlington transistor U2. Speed control is done by pressing switches SW1 and SW2. Pressing SW1 will increase the speed, while, pressing SW2 will decrease the speed. Because of using interrupts, on line control is possible without system interruption.
Figure 11-2 DC motor control using pulse width modulation driven from AT89C52 microcontroller
Listing 11-7
C program for PWM pulse generation at P2.0 with fixed switching frequency but variable duties depending on control inputs at P1.0 and P1.1.
#include "reg52x2.h"
duty = (256-RL_OFF)/[512-(RL_ON+RL_OFF)] */ unsigned char RL_ON = 192, RL_OFF = 64; bit flag = 1; unsigned int count = 0;
void main(void) { TMOD &= 0xF0; TMOD |= 0x02; TH0 = RL_ON; TL0 = RL_ON; ET0=1; EA=1; TR0=1; P2_0 = 0; while(1); } /* enable timer0 interrupt */ /* enable interrupts */ /* timer0 run */ /* Initialize P2.0 */ /* endless */ /* Timer 0 mode 0 with software gate */ /* GATE0=0; C/T0#=0; M10=1; M00=0; */ /* init values */
void it_timer0(void) interrupt 1 { TF0 = 0; if (flag == 1) { P2_0 = 0; TH0 = RL_OFF; } if (flag == 0) { P2_0 = 1; TH0 = RL_ON; } count++; if (count == 1000) {
if (P1_0 == 0) RL_ON++; if (RL_ON >240) RL_ON = 240; // Upper limit if (P1_1 == 0) RL_ON--; if (RL_ON < 16) RL_ON = 16; // Lower Limit RL_OFF = RL_total - RL_ON; count = 0;
} flag = ~flag;
11.2.3
Exercise 11-5
Exercise 11-6
Add the following features to the problem of Exercise 11-5: On reset or a new start, the motor will start with a low duty and gradually attain the set duty
11.2.4
In most applications there is a need for bidirectional speed/position control of DC motor. A dc motor drive capable of moving in both directions is often called a dc servo. A simple dc servo drive is shown in Figure 11-3. The scheme in this form can be used for bidirectional speed control. However, a position feedback would make it a servo. There are four inputs given from push buttons for controlling the motor. SW1 SW2 SW3 SW4 Forward or Reverse selection Increase Speed Decrease Speed Start/Stop Button
The fifth switch SW5 is for reset purpose. The DPDT relay controls the direction of motion of the motor by providing +Ve or Ve voltage across the dc motor armature. Motor speed is controlled by adjusting the PWM signal obtained from P2.1, with the Darlington transistor U5 acting as a chopper switch.
Figure 11-3 Bidirectional speed control of a dc motor using AT89C52 C Program Listing for Bidirectional Speed Control #include "reg52x2.h" bit onoff_flag = 1, Direction_old = 1,Direction_new = 1; bit ONOFF_old = 1, ONOFF_new = 1; unsigned int K1 = 500, K2 = 500, Kmax = 1000; void delay (unsigned int i) { while (i--); }
void main(void) { P2 = 0; while(1) /* endless */ { if (P1_1 == 0)K1++; if (K1 > 900) K1= 900; if(P1_2 == 0)K1--; if(K1 < 100) K1 = 100; K2 = Kmax - K1; P2_1 = onoff_flag; // PWM pattern sent to P2_1 delay(K1);
P0_0 = ~P0_0; P2_1 = 0; delay(K2); Direction_new = P1_0; if (Direction_new == 0 && Direction_old == 1) // PB1 pressed ? { P0_1 = ~P0_1; // Toggle if PB1 toggled P2_0 = ~P2_0; // Toggle Direction Relay } Direction_old = Direction_new;
ONOFF_new = P1_3; // Check state of on/off button if (ONOFF_new == 0 && ONOFF_old == 1) // PB4 pressed ? { onoff_flag = ~onoff_flag; /* Change Start/Stop state of the Motor if PB4 is pressed */ } ONOFF_old = ONOFF_new; } }