Вы находитесь на странице: 1из 22

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.

a)

Chapter 6: Pulse width


modulation and the use
of programmable
interval timers
z
z

Learn about the method of pulse width modulation for signals


Learn how to generate pulse width modulated signals by software and
hardware methods
Learn to use a programmable interval timer 8254.

6.1

Introduction
As you might know that a digital logic voltage is normally at 0 or 5 V if it is not at the
float (or high impedance) state. So an output bit can carry only the information of 1 or 0
that is obviously too limited. As you may want a signal to be more expressive, the method
of pulse width modulation may be useful to you. That is, apart from the voltage level, the
time duration of the signal is also used to carry information.

T =Period 1ms
Toff2
S1

Toff1

time

Ton1
S2
Ton2

Figure 6. 1 Show two pulse width modulated signals

Lets look at the above figure. The two pulse width modulated signals (S1 and S2) have
the same period of 1ms, thus their frequency is 1KHz. However, it can be seen that their
relative on-time (Ton) and off-time (Toff) are different. It is by changing the ratio of
Ton/Toff, we may be able to encode a range of different information using one single bit.
So how much information can be represented by one bit? Of course it depends on the
resolution of the Ton and Toff times. For example, if the resolution or quantized level is
1s in the above case, that means the minimum Ton is 1s and maximum is 999s (for
the period is 1000s), therefore the encoded information would have the range from 1 to
999.

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

6.2

Why do we need pulse width modulation?


On/off

(MEL)
DC Motor

Battery +

Figure 6. 2 The on/off ratio of the power source determines the motor speed

An important application is speed control for Direct Current (DC) motors. If we change
the ratio of value Ton/Toff, and use it to turn on and off a DC motor regularly, we control
different amount of energy transmitted to the motor. Hence alters the speed of rotation of
the motor. The mathematical prove and relation between the rotation speed and Ton/Toff
are left to be an exercise for our students. (Note that the relation is directly proportional
but not linearly.)
Another application is to control servo (positional) motors. This kind of pulse width
modulation control scheme is widely used in servomotors for remote-control model toys.

6.3

How to achieve pulse width modulation? Software or hardware?


So how to generate precise pulse width of a fixed frequency signal. Your programming
knowledge may suggest to you the following program structure.
Main()
{ int I, t_period, T_on;
Problem:
for (;;)//endless loop
Interrupt may
{ for( I =0; I < T_period; I++) //loop for one cycle,
occur inside
{ if ( I < Ton_time)
here
output = 1; // on
else
output = 0 ; //off
}
}
}
This program can generate a pulse train of on and off signal levels but the timing is very
difficult to predict. If an interrupt happens in the middle of the loop, the ratio of Ton and
Toff may be changed. Also you do need to know the actual running timing for each
instruction in order to know the exact frequency of the pulses. So this pure software
method is not a practical one at all.
A more accurate method is the interrupt method and there are two types of such methods
you can choose from.

PWM Type I: Interrupt driven, software counter method

PWM Type II: Interrupt driven, hardware interval timer method

This chapter is organized as follows: We will first describe the theory of interrupt driven
software counter methods. Then we will discuss an experiment for the software counter
method. Finally, we will deal with the interrupt driven hardware counter method and
show you the design examples.

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

6.4

PWM Type I: Interrupt driven, software counter method


As we discussed before a processor can be programmed to accept hardware interrupt, the
rate of executing a particular Interrupt Service Routine (ISR) is fixed. For example, if it
accepts a timer interrupt 0 (/int0) at a rate of 1024Hz, that means it will execute the ISR
beginning at address location 0x0003 (redirected to 0x8003 in our 8031 SBC) 1024 times
per second. Or in the time axis, the time between the beginning of two interrupt ISRs is
dt=1/1024s. Here is the ISR timing diagram we are about to discuss.
Interrupts
occurrence
1024Hz
time

Figure 6. 3 Interrupt occurrence at a rate of 1024Hz

The ISR and the main program are as follows.


Unsigned char count1,out,Ton_required;
Main ( )
{
//doing something else
}
isr0( ) //ISR of /int0 at 0x8003 (set at 1024HZ interrupt rate), so dt=1/1024s
{
count1++; //count1 is the same number after 256/1024s, so period T is 256/1024s
if(count1 < Ton_required) //
out=1; // we can output the value of out to a 8255 output bit.
else
out=0;
}
Inside isr0( ), count1 is a global counter keeping track of how many isr0 ( ) has executed.
Since it is an unsigned char so it will reset after incrementing 256 times. Such that
count1 will start from 0, increment once after isr0( ) is executed once, till count1=255,
and then count1 will be equal to 0 again, and so on. If we look at the output bit out, it
will be 1 if count1 is less than Ton_required; it will be 0 if count1 is equal or bigger than
Ton_required.
Count1 increments after isr0( )
Counter value
is executed once, dt=1/1024s
255
Count1
Ton_required
Time
0
out

Figure 6. 4 PWM Type I: Interrupt driven, software counter method

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

If we look at one period of the output out cycle, which is the same as one period of the
counting of count1, we see the followings.
Interrupt
occurrences
Time-axis
dt
Out

T=256/1024s
dt
Ton*dt(s)
Ton*dt(s)

Figure 6. 5 One period of the out signal cycle.

Maximum Interrupt rate allowed


It is noted that there is a limitation to the maximum interrupt rate allowed. Since for each
interrupt, it uses some time for executing the ISR, therefore if another interrupt comes
before the current ISR is not completed yet, another interrupt may push the stack one
level deeper, and so on. After some time, the stack may overflow and the system hangs.
That means the stack pointer, because it keeps on increasing (or decreasing depending on
your processor), will points to an address without memory. One way to protect your
computer from being interrupted too fast is to mask off the interrupt bit when it enters the
ISR, that means when it is inside the ISR the 8031 will not entertain any interrupt request
until it has completed the current ISR and return back to main( ). In practice for the 8031,
the interrupt control bit is IE.7 (bit 7 of the IE register at address A8H of special function
registers). However, by doing so, some interrupt requests may be lost or ignored, so the
pulse width moderated pulses may not be generated as accurately you wish.

main( )

1st Interrupt 2 nd Interrupt

{
}
If no interrupt
return occurs
again.

3rd interrupt
Will hang
Since the
stack will
overflow.

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

Exercise 6. 1: Write the algorithm to generate a pulse train of period 16ms, dt=1/64s and Ton ranges from 1* dt to
64 * dt. Hints: what is the required interrupt rate? What is the size (data width) of the software counter required?

6.4.1 Experiment 61: test61.c: An example of DC motor pulse width modulation,


using the interrupt driven software counter method
Introduction:
The control of a DC motor can be achieved by the pulse width modulation method, also
known as the chopper technique. It is done by changing the on/off times of the pulses
delivered to a DC motor to achieve the goal of speed control.
For the pulse train generated by interrupt, T = Ton +Toff = 1/Frequency of the ISR. The
ratio between Ton and Toff would relate proportionally to the speed of the motor. As for
our robots DC motors, the time period T is 16ms (or frequency ~ 64Hz). This figure is
similar to the period used in the control of the servomotor to be discussed later. It is also
found that if the frequency is too slow (below 10Hz, then T is 100ms or larger) the motor
will jerk.
Now it is time to work out the details. As discussed before we cannot increase the
interrupt rate to too high since if an interrupt service routine is not finished before another
interrupt comes in, the system may crash. After some experimentation we found that
1024Hz interrupt rate is acceptable (however the details of the actual CPU utilization
needs to worked out).
In this exercise our requirements are as follows:

We choose the motor control quantized level (throttle) to be 32, that means Ton can
range from 1 unit (minimum energy delivery) to 32 units (full throttle). Said another
way, we can have 32 different motor rotation speeds. However it is found that DC
motor control and pulse width Ton are not linearly related. That means, at a certain
Ton the motor starts to move very slowly, and the increase in speed is proportional to
the increase in Ton afterwards but not linearly. It is found by experimentation that a
reasonable result can be obtained if we choose a quantized level of 32 units. However,
the first 20 units may not have any meaning at all, because the motor may not start to
move till Ton reaches 20 units. And when it reaches 32 units (all time on) it is
moving at the fastest speed. These figures are all depend on the efficiency of the
particular DC motor used.

Throttle control
Figure 6. 6 Throttle control

To avoid jerking, an interrupt rate of 1024Hz acceptable by the 8031 is chosen.

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

Now it is time to put everything into perspective. If we want to control the pulse width at
Y, where Y is any number from 0 to 31 (32 quantized levels), we can do it by the
following method.
From the requirement (interrupt rate 1024Hz and quantized levels = 32), we need a 5 bit
software counter to keep track of the operation. At each interrupt the ISR executes, which
increments the software 5-bit counter, and if the counter is less than Y we set an digital
IO bit (through one of the IO pin of the 8255 chip on the 8031RL SBC) to 1, otherwise
reset it to 0. If we reset the counter when the count reaches 32, the pulse period is
(1/1024)*32 seconds = 31.25ms, so the frequency is 1/31.25 = 32Hz. Since the interrupt
rate is 1024Hz, so the smallest Ton time we can control is dt = 1/1024=0.977ms, which
corresponds to one quantized level.

T=1/32=31.25ms

Out

dt=1/1024s=0.977ms

Ton
(When
Count1<Y)

Toff
(When
Count1=>Y)

Figure 6. 7 Tthe DC pulse width modulation output (by interrupt, software counter)

Let us relate these things mathematically, for a certain value of Y,


The % of Ton against T period = (Ton/31.25ms) *100 % = (Y* dt/31.25ms) * 100 %.

For example, for Y=32, then the % of Ton against T period is 100%.

Another example is, for Y=25, then the % of Ton against T period is 78.1%.

In our experiment we found that the motor starts to move at Y=20 and increases gradually
till it reaches the maximum at Y=32.
The relation of the 8031, 8255, real-time clock and the motor are as follows.

The 8031 RL SB
8031
/int0
(pin12)
8255 output (pb0)

Already
connected in
8031RL SBC
Motor on/off
control circuit

Pin19 of
DS1287A
Real Time Clock
Interrupt rate=
1024 Hz

DC motor

Figure 6. 8 Connections of the experiment for PWM Type I: Interrupt driven, software
counter method

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

In this particular implementation (test61.c) , getch( ) is incorporated and one can use the
keyboard to control the motor speed. See the message on the screen when you are running
the program.

6.4.2 Procedure of the experiment


If the power electronic motor driver board is not ready to be used yet, you can just
observe the pulse width modulated signal by a DSO.
Run test61.c and observe LEDS connected to both 8255, and the output at bit0 of port B
of the 8255 at address E800H by a DSO. Explain what you see.

Exercise 6. 2 Change the interrupt rate to 512 Hz and the control quantized levels to 20.

6.4.3 Program listing test61.c


/* test61.c ver3.12
**known bug, you cannot put any printf statements inside the main while-loop.
compile command:
>sdcc --main-return --code-loc 0x8000 filename.c
interrupt rate = 1024Hz
control quantized level=32, using key-board '+' , '-' keys
*/
#include <8051.h>
#include <stdio.h>
#include <serial.h>
long i,a;
char ch_in1;
unsigned char time1,foo;
unsigned char pattern,pattern_count=1, lmotor_count, lmotor_speed;
xdata unsigned char *p8255_e800_cnt=0xe803;
xdata unsigned char *p8255_e800_a=0xe800;
xdata unsigned char *p8255_e800_b=0xe801;
xdata unsigned char *p8255_e800_c=0xe802;
xdata unsigned char *p8255_e000_cnt=0xe003;
xdata unsigned char *p8255_e000_a=0xe000;
xdata unsigned char *p8255_e000_b=0xe001;
xdata unsigned char *p8255_e000_c=0xe002;
//realtime clock ds1287
xdata unsigned char *rtc_ec00_second=0xec00;
xdata unsigned char *rtc_ec01_second_alarm=0xec01;
xdata unsigned char *rtc_ec03_minute_alarm=0xec03;
xdata unsigned char *rtc_ec05_hour_alarm=0xec05;
xdata unsigned char *rtc_ec0a_rega=0xec0a;
xdata unsigned char *rtc_ec0b_regb=0xec0b;
xdata unsigned char *rtc_ec0c_regc=0xec0c;
xdata unsigned char *rtc_ec0d_regd=0xec0d;
// #include <reg51.h> //needed, ACC is the accumulator
void putchar(char cout)
{
_asm
push ACC
_endasm;
ACC=cout;
_asm
lcall 0x0030 ;
_endasm;

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

_asm
pop ACC
_endasm;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//external _getchar function expected by serial.h used in Paulmon2
// #include <reg51.h> //needed, ACC is the accumulator
char getch()
{ char cin;
_asm
push ACC
_endasm;
_asm
lcall 0x0032 ;
_endasm;
cin=ACC;
_asm
pop ACC
_endasm;
return(cin);
}
main()
{
//SETUP INTERRUPT
IE=IE | 0x85;
//ie.7 global enable interrupt set;
//ie.2 external int. 1 set;
//ie.1external int 0 set;
//set interrupt pin int1 active low (pin13 of 8031)
TCON= TCON | 0x01;
// init 8255-A,
*p8255_e800_cnt=0x80;
*p8255_e000_cnt=0x80;
*p8255_e000_a=0xff;
*p8255_e800_a=0xff;
pattern=0x0f;
//read it once to make /irq(pin19 of ds1287) return to 1
foo=*rtc_ec0c_regc;
//interrupt-case-3 periodic interrupt
//rtc registers setting
//0x20 for slower, l.s.b.-4bit =rate
//0x20 for slower, l.s.b.-4bit =rate
//0x28=>256Hz; 0x29=>128Hz; 0x2f=>2Hz; 0x21=>256Hz;
//0x26=>1.024KHz; 0x25=>2.048KHz; 0x23=>8.192KHz
*rtc_ec0a_rega= 0x26;
*rtc_ec0b_regb= 0x40;
foo=*rtc_ec0c_regc; //make sure pin19 of ds21287 /irq=1
printf("'+' to increase speed, '-' to reduce speed, 'q' to quit");
putchar(0x0a);
putchar(0x0d);

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

printf("use the DSO to look at pb0 of 8255_e800 (con6)");


lmotor_speed=1;
while (ch_in1 !='q')
{
*p8255_e000_a= 0xff-lmotor_speed;
ch_in1=getch();
if (ch_in1 == '+')
{
lmotor_speed=lmotor_speed+1;
}
if (ch_in1 == '-')
{
lmotor_speed=lmotor_speed-1;
}
}
}
// use interrupt 0 (external interrupt /int0 [pin12 of 8031]),reg.bank 2
//compile command line
//sdcc --main-return --code-loc 0x8000 filename.c
//this isr will be at 0x8003
void ext_int_isr2(void ) interrupt 0 using 2 // (register bank 2)
{
*p8255_e800_a=0xff - pattern_count;
pattern_count =pattern_count + 1;
//make sure pin19 of ds21287 /irq=1
foo=*rtc_ec0c_regc; //read it once to off interrupt
lmotor_count =(lmotor_count+1) & 0x1f; //this is to keep only lsb 5bits same as%32
//or // lmotor_count =(lmotor_count+1)%0x0f; //keep only lsb 4bits same as%16
if (lmotor_count <lmotor_speed)
{
*p8255_e800_b=0x55;
}
else
{
*p8255_e800_b=0x00;
}
}

6.5

PWM Typ2 II: Interrupt driven, hardware interval timer (8253) method:
Reason for using a timer chip instead of software counter method
It is found that in the above discussion that the interrupt rate for generating a PWM signal
of 32Hz of 32 control levels is 1024Hz. If we want to increase the PWM frequency or
control levels we have to increase the interrupt rate. In fact, 1024HZ is already a very
high interrupt rate for an 8031 processor, and increasing the interrupt rate may crash the
system because of stack overflow as described earlier. However, in practice we often
encounter requirement for high PWM frequency, such as the smooth control of DC
motors and the positional control of servomotors.

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

Figure 6. 9 A Futaba servomotor

A Futaba servomotor is a positional control system that has a strong rotating shaft that
can rotate within a range up to 200 degrees. It is controlled through a PWM signal of
around 50Hz (period=20ms) that the rotational angle corresponds to the Ton of the PWM
signal. In particular, when the pulse Ton is at about 1ms, it swings to the left most
position, and when the Ton increases to about 2ms it is at the right most position. When
Ton is around 1.5ms, it is at the neutral position.

Ton=1~2ms

20ms
At 1.5ms

dt=1ms/256=3.9s

At
1ms

At 2ms
A servomotor

Figure 6. 10 The relation of the PWM signal and servo motor rotational positions

To produce such a signal that has a resolution of less than 1 rotational degree (say divide
the 200degree range into 256 divisions = 200/256 degrees) is not easy for an interrupt
based software counter method. The reason is, unlike the previous case of controlling a
DC motor that Ton will cover the whole period, it now only ranges from 1ms to 2ms, as
compared to the whole PWM pulse period of 20ms. That means, our algorithm should be
able to increase or decrease Ton by dt = 1ms/256=3.9s, and at the same time produces a
pulse period of 20ms. Since the smallest change of a quantized level (dt) of Ton is the
time between two successive interrupts, so the interrupt rate is 1/(1ms/256) = 256KHz!
Even a Pentium V processor may result in stack overflow because of that.
So what is the solution? One way is to use an 8253 (or 8254) programmable interval
timer device together with interrupt to achieve our goal.

6.5.1 The programmable interval timer 8253 hardware


An 8253 timer [1] is a peripheral device designed to interface easily to a microprocessor.
It is actually a set of three independent counters programmable to work independently.

10

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

Figure 6. 11 From [1] 8254.pfd (8254 is the superset of the 8253 timer)

Interfacing signals of the 8253 are very similar to that of an 8255: A0,A1 are for selecting
registers, /CS is for chip select and /WR, /RD are for read/write control. If necessary, one
can add this chip to the 8031 external-memory data space. What it requires is only 4
address locations and should be easy to accommodate in a typical 8031 system.
Each of the three independent counters has one clock input (cki), one gate input (gatei)
and one output (outi), for i=1,2,3 representing the three independent counters in a chip.
On programming, there is a 16-bit counter for each counter, and a globe mode control
word for the whole chip.

6.5.2 The 8253 Timer register programming


The functions of the counters are governed by the data sent to these four registers.
A0

A1

Function of the 8-bit register

Counter 0 data

Counter 1 data

Counter 2 data

Control register
Table 6. 1 Registers of 8253/4

First we have to setup the mode of each counter, and then after the counter data are sent to
the data locations, the counters will start to count. The mode control word has the
following format:
D7
SC1

11

D0
SC0

RL1

RL0

M2

M1

M0

BCD

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

where SC1,SC0 select the counter to be programmed using the format


SC1=0,SC0=0 is for =counter0;
SC1=0,SC0=1 is for =counter1;
SC1=1,SC0=1 is for =counter2.
As for the counters initial data values, since the actual counters are 16-bit and each data
register only occupies one location, the 8253 adopts a sequential programming
mechanism to fill the 16-counter with only one address location. That is, we first send the
LSB of the 16-bit initial counting value to the address then followed by the MSB of the
value. The algorithm for programming the 8253 will look like this.
Algorithm for programming the 8253
{
send counter0 mode to address A1=1,A0=1;
send counter1 mode to address A1=1,A0=1;
send counter2 mode to address A1=1,A0=1;
send the LSB of the initial value of the 16-bit counter0 to address A1=0,A0=0;
send the MSB of the initial value of the 16-bit counter0 to address A1=0,A0=0;
send the LSB of the initial value of the 16-bit counter1 to address A1=0,A0=1;
send the MSB of the initial value of the 16-bit counter1 to address A1=0,A0=1;
send the LSB of the initial value of the 16-bit counter2 to address A1=1,A0=1;
send the MSB of the initial value of the 16-bit counter2 to address A1=1,A0=1;
}

6.5.3 Interfacing 8253 through 8255


Interfacing an 8253 to the 8031 processor should not be too difficult. However, we afraid
that the 8031 may not supply enough current to drive an extra peripheral device, because
it is already overloaded. Therefore we decided to attach the 8253 timer to the data ports of
one of the 8255 parallel interface, like an add-on card. We will discuss more about this
add-on card issue later.
Since the 8255 has 24 bits of IO pins, we can program its IO bits to perform the
read/write operations to a 8253 just like a microprocessor.
Our design even extends a bit further that one 8255 can be used to control four 8253s.
You may ask why do we need as many as four 8253 devices (totally twelve 16-bit
counters), for two counters should be enough for our two-wheeled robot. The reason is
the system can also be used for the control of a legged robot that consists of 12
servomotors. The interfacing scheme is as follows.

12

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

Connector: con6 or con7


of 8031RL board
8255

PA4(8)
PA5(9)
PA6(10)
PA7(11)

PA3(7)
PA2(6)
PA1(5)
PA0(4)
PB0-PB7

(21)/CS0_8253
/CS1_8253
/CS2_8253
/CS3_8253

ck0 (pin 9) <-1MHz


Gate0 (pin 11)<-5V
Out0 (pin 10)->servo

8253_0
Ck1(pin 15)<-1MHz
Gate1(pin14) <-5V
Out1(pin13) ->servo

(22)/RD
(23)/WR
(20)A1
(19)A0
D0-D7

8-bit data bus

Ck2(pin 18)<-1MHz
Gate1(pin 16) <-5V
Out2(pin17) ->servo

Figure 6. 12 Direct Interface four 8253s to an 8255.

(5)/E2 ->0V
(6)E3->5V

74138
(pin8)0
(pin16)5V

Connector: con7 of
8031RL board
(Pin385V
(Pin1 and pin2)0V

(1)A0 Y3(12)
(2)A1 Y2(13)
(3)A2 Y1(14)
(4)/E1 Y0(15)

8255 PA4(8)
(con7) PA5(9)
PA6(10)
PA7(11)

(21)/CS0_8253_0
8253_0
(pin 24)5V
(pin12)0V

PA3(7)
PA2(6)
PA1(5)
PA0(4)
PB0-PB7

(22)/RD
(23)/WR
(20)A1
(19)A0
D0-D7

Servo_30
Servo_31
Servo_32

(21) /cs3_8253_3

Servo_20
Servo_21
Servo_22

(21) /cs2_8253_2
(21) /cs1_8253_1

Servo_10
Servo_11
Servo_12

(pin 9)ck0 1MHz


(pin 11)Gate0 5V
(pin 10)out0servo_00
(pin 15)Ck11MHz
(pin 14)Gate15V
(pin 13)Out1 servo_01
(pin 18)Ck21MHz
(pin 16)Gate15V
(pin 17)Out2servo_02

8-bit data bus


pb0 pin 12 of con7
pb1 pin 13
pb2 pin 14
pb3 pin 15
pb4 pin 16
pb5 pin 17
pb6 pin 18
pb7 pin 19

D0 pin 8 of 8253
D1 pin 7
D2 pin 6
D3 pin 5
D4 pin 4
D5 pin 3
D6 pin 2
D7 pin 1

sig
5V
0V

Futaba
Servomotor
White
Red
Black

Figure 6. 13 Interface up to eight 8253s to the 8255 through a 74138 decoder.

13

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

1Mhz
clock
module

GND
(pin7)

(Pin 14) 5V

(Pin 8) output
1MHz clock

Figure 6. 14 The pictures and use of a 1-MHz clock module

It is shown in the interface circuit diagram that there are altogether 4 chip select signals
emulated by PA4-PA7. That means one can connect four 8253s in this system.
For connecting four (can be up to 8 in this design using the 74138) 8253s to the 8255, all
the corresponding pins of the four 8253s are connected in parallel, except that, the chip
select pin of each 8253 is connected to one of the chip select output at PA4-PA7. By
carefully setting the output pattern of PA4-PA7 by programming we can select the target
8253 as required. In other words programming the 8253 is a sequence of 8255 data
writing tasks. It is a little tedious perhaps, but rather practical.

6.5.4 Using an 8253 and interrupt for generating the PWM signal for a
servomotor.
Now lets come back to our discussion on the 8253 counting model. We found that
mode0 is useful in our PWM pulse generation. From the timing diagram of 8253 mode0
(INTERRUPT ON TERMINAL COUNT), it is like a countdown alarm. We will now use
counter 0 to illustrate our example. After we set the counter data register to a certain value
X (2 in the diagram) , it will first reset out0 to 0 and starts to decrement the counter at the
rising edge of the clock pulse at ck0. When the counter decrements (2 times in the
diagram) to 0, out0 will be set to 1.

Figure 6. 15The timing diagram of 8253 mode0 (INTERRUPT ON TERMINAL COUNT)

14

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

8255

8031

/int0

Counter0
16-bit
counter
ck0
Gate0

Interrupt clock
50Hz.
From pin19 of
the real time
clock DS1287

1MHz
Oscillator

5V

Out0
5V
GND

Futaba
Servomotor
White
Red
Black

Figure 6. 16 Showing how to connect the 8031, 8255, 8253 and the servomotor together

In order to reduce the use of chips, we have the above design and will be explained as
follows. The 1MHz clock is connected to the clock input of 8253. And out0 is connected
to the input (white line) of the servo motor On the other hand the 8031 is interrupted by a
50Hz clock from the real time clock.
With the help of this counter, our PWM ISR algorithm will look like this.
Main ()
{
:
:
}

(ISR executes
at a rate of
50Hz)

ISR_for_8253
{set the 8253 mode0,
save counter0 a 16-bit value correspond to the
required Ton
}

Using the calculation we had earlier, we need our PWM signal to have a period of 20ms
and Ton can range from 1ms to 2ms at a resolution of dt=3.9s. Since we need a
resolution of 256 divisions inside 1ms (1ms/256=3.9s).
Regular Interrupt occurs
At 50Hz
20ms
Time
Count0=0
starts

Out0

Ton

count0=X
ends

Count0=0
Starts

count0=X
ends

Toff

Figure 6. 17 Relation of interrupts and the counting of count0 in 8253

At each interrupt, the ISR will program the 8253 counter0 to work in mode 0, and saves a
value X corresponds to the desired Ton time in the 16-bit counter. Then the ISR will
return to the main program. Therefore the 8253 output out0 to the servomotor will be
reset to 0 just after each interrupt occurs. Then, the counter in 8253 will starts to
decrement at a rate of 1MHz, when reaching X, the servomotor input would be set to 1.
So what should be the value of X? The requirement is to have Ton to be ranging from 1
ms to 2 ms with the PWM period of 20ms. Then Toff would be ranging from _____ to
______ms. Therefore X can be ranging from
to
ms. Please work
out these values for your experiments.

15

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

6.5.5 Experiment 6_2: test62.c: An example of pulse width modulation for a


servomotor, using the interrupt driven, hardware interval counter 8253
method
1. The hardware shown above is already built in the robot PCB, please

look at the schematic and find out how to use and connect them.
2. Construct the circuit and write the program to drive it.
3. The requirement are:

To drive a servomotor to rotate according to the command of


the user. When the user presses the key a on the keyboard,
the servomotor rotates clockwise; when pressing s, the
servomotor rotates anti-clockwise. The PWM period is 20ms,
and the on time (Ton) should be within the working limits
between 2ms and 1ms.

To produce two independent PWM signals for the DC motors.


The period is 20ms and the number of control quantized levels
is 64. Again the control is through the keyboard :

q increase left-motor speed


w increase left-motor speed
e increase right-motor speed
r increase right-motor speed

4. Students can refer to listing test62.c for programming ideas.


5. One extra (not compulsory) exercise is to use the 8031 timer1 to replace

the interrupt signal from the DS1287 real-time clock. I dont think it is
very difficult but requires some investigation of how to use internal
timers of the 8031. No hardware connection is necessary, since the
internal timers and interrupt logic are linked internally in the 8031.

6.5.6 Listing test62.c


//test62.c ver3.12
/* the following is for an old version of the experiment hardware configuration (8253
clock is 256KHz, the output out0 of the 8253 is to the servo motor input_white_line
throughan inverter), has been changed. For the new robot pcb board: the 8253 clock is
1MHz, and the output out0 of the 8253 is connected directly to the input_white_line of
the servo motor. But the following program should just give you some idea of how to
write data into he 8253 register. */
/* This program is a little messy but should give you some ideas of how experiment6_2
should be conducted.
Sr16_servo_ok
Use isr and timer interrupt by real-time-clock-chip (DS1287A)
Hardware :
/irq (Pin19 of DS1287A) is connected to external interrupt pin (pin-12 of 8031) and adjust
interrupt at 64 (or 32) Hz.
8031 -ISR ?timer interrupt at 64Hz
|
8255
|
V
8253
Counter1 out -' inverter(7404) '(white wire) output to Futaba servo motor

16

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

^
|
(count0 out divided by 4 to ck1)
Count 0 in
^
|
1MHz clock

Futaba_servo_white_input, while red is 5V and Black is earthered.


Software: init_8253_0 is executed first and set counter 0 as a divided by 4 divider, clock0
is connected to a 1MHz clock crystal, so the output is 256KHz , it is applied to other
counters for servo pulse-width-modulation generation.
The interrupt service routine : ext_int_isr2(void ) interrupt 2 using 2, contains a timer
setting segment, it is still unknown why counter0 needed to be reprogrammed there. It is
found that if no such adjustment is placed, tcounter0 will become a large divider hence
the output frequency is much slower then 256KHz.
=================================
*/
//testing of the real-time clock Dollas DS1287A (or 12887A)
//Pin 19 of DS1287 connected to INT0 (pin0-12 of 8031)
//remember to set Interrupt pin active low
//at 8031 by TCON= TCON | 0x01;
// ----- isrmain1.c ------, blink LED of the cache 8051sbc-computer
// compile line >Sdcc footest.c --code-loc 0x8000 --main-return
//http://www.geocities.com/ResearchTriangle/Forum/1353/
// footest.ihx (intelobject file) is generated and should be download to 8031sbc
www.cachecomp.com to run
#include <8051.h>
#include <stdio.h>
#include <serial.h>
int a,temp;
long i,j;
unsigned char servo_angle_1;
unsigned char time1,foo;
unsigned char pattern,pattern_count=1;
xdata unsigned char *p8255_e800_cnt=0xe803;
xdata unsigned char *p8255_e800_a=0xe800;
xdata unsigned char *p8255_e800_b=0xe801;
xdata unsigned char *p8255_e800_c=0xe802;
xdata unsigned char *p8255_e000_cnt=0xe003;
xdata unsigned char *p8255_e000_a=0xe000;
xdata unsigned char *p8255_e000_b=0xe001;
xdata unsigned char *p8255_e000_c=0xe002;
//realtime clock ds1287
xdata unsigned char *rtc_ec00_second=0xec00;
xdata unsigned char *rtc_ec01_second_alarm=0xec01;
xdata unsigned char *rtc_ec03_minute_alarm=0xec03;
xdata unsigned char *rtc_ec05_hour_alarm=0xec05;
xdata unsigned char *rtc_ec0a_rega=0xec0a;
xdata unsigned char *rtc_ec0b_regb=0xec0b;
xdata unsigned char *rtc_ec0c_regc=0xec0c;

17

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

xdata unsigned char *rtc_ec0d_regd=0xec0d;


void init_8253_0()
{
// init 8255-A, all ports (ABC) are output ports
*p8255_e800_cnt=0x80;
*p8255_e000_cnt=0x80;
//control ports of 8253 thriu 8255 output ports B and C
//PC4 --> /CS OF 8253_0; PC5 -> /CS_8253_1; pc6->8253_2
//PC3->/RD ; PC2->/wr; PC1->A1; PC0-A0(A0=A1=1=>control)
//write control word sequence at port-C for 82530 control port is
//1111-1111,
//1110-1111,
//1110-1011,
//1111-1111,
//write (load) counter 0 sequence at port-C for 82530 is
//1111-1100,
//1110-1100,
//1110-1000,
//1111-1100
//write (load) counter 1 sequence at port-C for 82530 is
//1111-1101,
//1110-1101,
//1110-1001,
//1111-1101,
//write (load) counter 2 sequence at port-C for 82530 is
//1111-1110,
//1110-1110,
//1110-1010,
//1111-1110,
*p8255_e000_c= 0xff; //all control lines high first
servo_angle_1=0x7f;
//set counter0 mode 0write 8253 control word sequence
//A0=A1=1;
//thi1s program divids clk0(1MHZ) by 4 and output out0(256KHz)
*p8255_e000_b= 0x36; //control code
*p8255_e000_c= 0xff;
*p8255_e000_c= 0xeb; //counter 0
*p8255_e000_c= 0xff;
*p8255_e000_b= 0x04; //least sig, byte of count
*p8255_e000_c= 0xff;
*p8255_e000_c= 0xe8;
*p8255_e000_c= 0xff;
*p8255_e000_b= 0x00; //most sig, byte of count
*p8255_e000_c= 0xff;
*p8255_e000_c= 0xe8;
*p8255_e000_c= 0xff;
////////////////////////////////////////////////
}
main()
{

18

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

//DISABLE INTERRUPT FIRST


//ie.7 =0 global diable interrupt ;
IE=IE & 0x7f;
//need to disable interrupt first before init
//since isr has 8253 control routines
init_8253_0();
//SETUP INTERRUPT
IE=IE | 0x85;
//ie.7 global enable interrupt set;
//ie.2 external int. 1 set;
//ie.1external int 0 set;
//set interrupt pin int0,1 active low (pin13 of 8031)
TCON= TCON | 0x01;
// init 8255-A, ???cnt=0x89=> PA=in,low_PC=in,high_PC=input,pb=out
*p8255_e800_cnt=0x80;
*p8255_e000_cnt=0x80;
//must do these 3 instructions to make 8253 works
*p8255_e000_a=0xff;
*p8255_e000_b=0xff;
*p8255_e000_c=0xff;
pattern=0x0f;
//read it once to make /irq(pin19 of ds1287) return to 1
foo=*rtc_ec0c_regc;
/* interrupt-case-1
//set rtc alram-clock-mode
*rtc_ec0a_rega= 0x20;
*rtc_ec0b_regb= 0x20;
foo=*rtc_ec0c_regc; //make sure pin19 of ds21287 /irq=1
*rtc_ec01_second_alarm=0xff; //second don't care;interpt.every second
//*rtc_ec01_second_alarm=0x03; //int. every minures at the first 3sec
*rtc_ec03_minute_alarm=0xff; //minute is don't care
*rtc_ec05_hour_alarm=0xff; //hour is don't care
*/
/* interrupt-case-2; every-second type
//rtc registers
*rtc_ec0a_rega= 0x20;
*rtc_ec0b_regb= 0x10;
foo=*rtc_ec0c_regc; //make sure pin19 of ds21287 /irq=1
*/
//interrupt-case-3 periodic interrupt
//rtc registers setting
*rtc_ec0a_rega= 0x2a; //0x2a for 64Hz; 0x2b=32Hz;0x2f= 2Hz= slowest, l.s.b.-4bit =rate
*rtc_ec0b_regb= 0x40;
foo=*rtc_ec0c_regc; //make sure pin19 of ds21287 /irq=1
for(i=0;i<100;i++)
{
for(a=0;a<10000;a++)
{

19

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

//realtime clock testing


time1=*rtc_ec00_second;
*p8255_e000_a= (0xff-time1);
}
for(a=0;a<10000;a++)
{
*p8255_e000_a= (0xff - time1);
}
}
}
// use interrupt 2 (external interrupt 1 [pin13 of 8031]) reg. bank 1
//for the following statement 2 is interrupt number,
//using 1 means regitsre bank 1
//if you use sdcc isr5.c -code-code 0x8000 -main-return,
//this isr will be at 0x8013
//in Paulmon2 at 0x0013 long-jump lmp to 0x8013,
//address
code; jump from 0013 to 8013
// 0013
02 ;long jump ljmp
// 0014
80
// 00151
13
// it seems that if "using 1" is used, it cannot goes back to paulmon2
// it seems that if "using 2" is used, it can goes back to paulmon2
//void ext_int_isr2(void ) interrupt 2 using 1 // (register bank 1)
void ext_int_isr0(void ) interrupt 2 using 2 // (register bank 2)
{
// IE=IE & 0x7f; //disable interrupt
//I still don't understand why isr has to reinit counter 0
//if you don't do this counter 0 will change freq.
*p8255_e000_b= 0x36; //control code
*p8255_e000_c= 0xff;
*p8255_e000_c= 0xeb; //counter 0
*p8255_e000_c= 0xff;
*p8255_e000_b= 0x04; //least sig, byte of count
*p8255_e000_c= 0xff;
*p8255_e000_c= 0xe8;
*p8255_e000_c= 0xff;
*p8255_e000_b= 0x00; //most sig, byte of count
*p8255_e000_c= 0xff;
*p8255_e000_c= 0xe8;
*p8255_e000_c= 0xff;
*p8255_e000_b= 0x70; //70 counter1, mode 0-int.on.termainal-count
*p8255_e000_c= 0xff; //1111-11 11b;
*p8255_e000_c= 0xeb; //1110- 10 11b;
*p8255_e000_c= 0xff; //1111- 11 11b;
servo_angle_1=(servo_angle_1+1) % 0x7f;
*p8255_e000_b= servo_angle_1+0x7f; //least sig, byte of count
*p8255_e000_c= 0xff; // 1111 11 01b;
*p8255_e000_c= 0xe9; //1110 10 01b;
*p8255_e000_c= 0xff; //1111 11 01b;
*p8255_e000_b= 0x00; //most sig, byte of count

20

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

*p8255_e000_c= 0xff; // 1111 11 01b;


*p8255_e000_c= 0xe9; //1110 10 01b;
*p8255_e000_c= 0xff; //1111 11 01b;
/////
*p8255_e800_a=0xff - pattern_count;
pattern_count =pattern_count + 1;
//make sure pin19 of ds21287 /irq=1
foo=*rtc_ec0c_regc; //read it once to off interrupt
//SETUP INTERRUPT again
// IE=IE | 0x85;
}

6.6

Conclusion
The theory and practical issues of generating pulse width modulation signals have been
discussed. In particular, software and hardware based techniques are generating pulse
width modulated pulses have been mentioned. Experiments to illustrate these ideas have
been introduced.

6.7

References
1. 8254.pdf from Intel (http://support.intel.com/sites/support/index.htm)
2. The chapter about motors in:

ftp://cherupakha.media.mit.edu/pub/projects/6270/docs-1992/6270guide-92.pdf

21

Mobile Robot chapter 6: PWM and the use of programmable interval timers (v4.a)

3.

22

Вам также может понравиться