Professional Documents
Culture Documents
1.1 The PCA 16-bit Timer/Counter serves as the time base of all PCA operations.
It consists of two 8-bit counters PCA0H and PCA0L.
Reading the PCA0L register automatically latches the value of PCA0H into a
snapshot register, the following read of PCA0H accesses this snapshot register.
This ensures an accurate reading of the entire 16-bit timer.
The rollover of PCA0 timer from 0xFFFF to 0x0000 sets the CF flag.
The operation of the PCA timer is controlled by the PCA0CN (enables timer to
count, keeps track of the capture/compare flags of all PCA channels), and
PCA0MD register (selects clock source, enables/disables PCA interrupts,
enable/disable PCA module when CPU is in the idle state.)
Example 8.8 Configure PCA module 0 of the C8051F040 to capture the rising edge of
the signal applied to the CEX0 pin. Use SYSCLK 12 as the clock source of the timer.
Solution:
Three registers need to be programmed:
PCA0CN register:
The PCA counter must be enabled (CR = 1) and all flags should be cleared at the
beginning.
PCA0MD register:
This application does not care about watchdog function, nor counter idle control; Disable
both. Bits 3, 2, and 1 of the PCA0MD register should be set to 000 to select SYSCLK/12
as the PCA clock source. PCA overflow interrupt is not needed; Set the bit 0 to 0.
PCA0CPM register:
For module 0,
Bit PWM160 (bit 7): set to 0 (this bit is dont care)
Bit ECOM0 (bit 6): set to 0 to disable the comparator.
Bit CAPP0 (bit 5): set to 1 to capture the rising edge.
Bit CAPN0 (bit 4): set to 0 to disable falling edge capture.
Bit MAT0 (bit 3): set to 0 to disable module 0 comparator.
Bit TOG0 (bit 2): set to 0 so that CEX0 pin will not toggle when PCA counter
matches the compare/capture registers of module 0
Bit PWM0 (bit 1): set to 0 to disable pulse modulation output.
Bit ECCF0 (bit 0): cleared to disable CCF interrupt.
Therefore, the value 20H should be written into the PCA0CPM0 register. The following
instructions accomplish the intended configuration:
PCA0CN
= 0x40;
PCA0MD
= 0;
PCA0CPM0
= 0x20;
1.3 Edge-Triggered Capture Mode
The PCA copies the 16-bit timer into the capture register at the moment that the
selected edge on the CEXn pin is detected.
This action can be used to measure period, pulse width, duty cycle, and phase
difference of signals.
The signal edge that triggers the capture action is selected by setting or clearing
the CAPPn and CAPNn bits in the PCA mode register.
Let
ovcnt
edge1
edge2
diff
Then the pulse width can be calculated using the following equations:
Case 1: edge2 edge 1
Pulse width = ovcnt 216 + diff
-- (8-7)
Case 2: edge2 < edge1
Pulse width = (ovcnt 1) 216 + diff -- (8-8)
Example 8.9 Suppose an unknown signal is connected to the CEX0 pin. Write a program
to measure the pulse width of this signal assuming that the system clock is generated by a
24-MHz external crystal oscillator.
Solution:
The settings of PCA0CN, PCA0MD, and PCA0CPM0 are as follows:
Configuration of PCA0CN:
Clear all the flags and enable PCA timer to run. Write the value 40H into PCA0CN.
Configuration of PCA0MD:
Choose SYSCLK 12 as the clock source of the PCA timer and enable PCA timer
overflow interrupt. Disable watchdog timer and choose to gate off the PCA timer
during idle mode. Write the value 81H into PCA0MD.
Configuration of PCA0CPM0:
Disable the comparator function, capture rising edge, disable match, disable toggling,
disable pulse width modulation, and disable capture interrupt. Write the value 20H into
the PCA0CPM0 register. Falling edge capture must be enabled after the rising edge has
been captured.
#include <c8051F040.h>
void pcaISR (void);
void sysInit (void);
unsigned char pwH, pwL,tovCnt;
unsigned long PulseWidth;
void main (void)
{
unsigned short t1,t2,t3;
sysInit();
SFRPAGE = 0;
tovCnt
= 0;
PCA0CN
= 0x00;
PCA0MD
= 0x81;
PCA0CPM0= 0x20;
IE
= 0;
CR
= 1;
while (!CCF0);
pwH
= PCA0CPH0;
pwL
= PCA0CPL0;
PCA0CPM0 = 0x10;
// prepare to capture CEX0's falling edge
CCF0
= 0;
// clear flags
CF
= 0;
EIE1
= 0x08;
// enable PCA0 timer overflow interrupt
EA
= 1;
// enable interrupt globally
while (!CCF0);
// wait for the arrival of the falling edge
EIE1
= 0;
// disable PCA interrupts
t1
= 256 * (unsigned short)pwH + (unsigned short)pwL;
t2
= 256 * (unsigned short) PCA0CPH0 + (unsigned short) PCA0CPL0;
t3
= t2 t1;
if (t2 < t1)
tovCnt--;
PulseWidth = (unsigned long) tovCnt * 65536 + (unsigned long)t3;
}
void sysInit (void)
{
SFRPAGE = 0x0F;
WDTCN = 0xDE;
WDTCN = 0xAD;
OSCXCN = 0x67;
// delay about 1 ms
// wait for oscillator to stabilize
// switch to external oscillator
XBR0
= 0xF7;
// assign all peripheral function pins to port pins
XBR1
= 0xFF;
//
"
XBR2
= 0x5D;
//
"
XBR3
= 0x8F;
//
"
SFRPAGE = 0;
// switch to SFR page 0
SPI0CN
= 0x01; // enable 3-wire SPI
}
void pcaISR (void) interrupt 9
{
CF = 0;
// clear the CF flag
tovCnt++;
// increment PCA timer overflow count
}
SFRPAGE = temp;
}
Example 8.11 Assume that there is a C8051F040 demo board running with a 24-MHz
crystal oscillator. Write a program that enables the PCA module 0 to generate a 1-kHz
digital waveform with 40% duty cycle.
Solution: A 1-kHz digital waveform with 40% duty cycle is shown in Figure 8.20.
<C8051F040.h>
HThi 0x03 // high interval delay count (800)
HTlo 0x20 //
"
LThi 0x04 // low interval delay count (1200)
LTlo 0xB0 //
"
HI 1
LO 0
10
else {
PCA0CPH0 += LThi;
PCA0CPL0 += LTlo;
if (temp > PCA0CPL0)
PCA0CPH0++;
hiORlo
= HI;
}
}
Example 8.12 Use the CEX0s frequency output mode to generate a 10-kHz signal
assuming that the C8051F040 is running with a 24-MHz external crystal oscillator.
Solution:
#include <C8051F040.h>
void sysInit(void);
void main (void)
{
sysInit();
SFRPAGE = PCA0_PAGE;
PCA0CN = 0;
PCA0CPM0
= 0x46;
PCA0MD = 0x80;
PCA0CPL0 = 0x64;
PCA0CPH0= 0x64;
PCA0L
= 0;
PCA0CN = 0x40;
while(1);
11
}
void sysInit(void)
{
unsigned char cx;
SFRPAGE = SPI0_PAGE; // switch to SFR page where the SPI registers reside
SPI0CN
= 1;
// select 3-wire SPI (just to fixed I/O pin assignment)
SFRPAGE = CONFIG_PAGE;
WDTCN = 0xDE;
// disable watchdog interrupt
WDTCN = 0xAD;
//
"
OSCXCN = 0x67;
// start external crystal oscillator
for (cx = 0; cx < 255; cx++);
while(!(OSCXCN & 0x80)); // wait for crystal oscillator to stabilize
CLKSEL |= 1;
// switch to external crystal oscillator as clock source
XBR2
= 0x5D;
// enable crossbar decoder, and assign I/O pins to all
XBR0
= 0xF7;
// peripheral signals
XBR1
= 0xFF;
// "
XBR3
= 0x8F;
// "
P1MDOUT
= 0x07;
// enable CEX0 pin as output
}
12
Example 8.13 Write a C program to generate a PWM waveform with 60% duty cycle
assuming that the program is to be run on a C8051F040 demo board.
Solution:
Load the value 102 (256*(1-60%)) into the PCA0CPH0, thus the logic 1 time for the
PWM output will be 154 clock cycles and the resultant PWM waveform will have about
a 60% duty cycle.
#include <C8051F040.h>
void sysInit(void);
void main (void)
{
sysInit();
PCA0MD
= 0x80;
PCA0L = 0;
PCA0H = 0;
PCA0CPM0 = 0x42;
PCA0CPL0 = 102;
PCA0CPH0 = 102;
PCA0CN
= 0x40;
while(1);
}
void sysInit(void)
{
.
}
13
Load the value 26214 (65536*(1-60%)) into the PCA0CPH0, thus the logic 1 time for the
PWM output will be 39322 clock cycles and the resultant PWM waveform will have
about a 60% duty cycle.
#include <C8051F040.h>
void sysInit(void);
void main (void)
{
sysInit();
PCA0MD = 0x80;
// choose OSC/12 as clock input to PCA timer
PCA0L
= 0;
// let PCA0 counter counts from 0
PCA0H
= 0;
//
*
PCA0CPM0
= 0xC2;
// configure module for 16-bit PWM mode
PCA0CPL0 = 0x66;
// set duty cycle to 60%
PCA0CPH0= 0x66;
// (reload value is 26,214 = 0x6666)
PCA0CN = 0x40;
// enable the PCA timer and clear all PCA flags
while(1);
}
void sysInit(void)
{
SFRPAGE = 0;
// switch to SFR page 0
SPI0CN
= 0x01;
// enable 3-wire SPI
SFRPAGE = 0x0F;
WDTCN = 0xDE; // disable watchdog timer
WDTCN = 0xAD;
CLKSEL = 0;
// select internal oscillator as SYSCLK
OSCICN = 0x83;
// set SYSCLK frequency to 24.5 MHz
XBR0
= 0xF7;
// assign port pins to all peripheral signals
XBR1
= 0xFF;
XBR2
= 0x5D;
XBR3
= 0x8F;
P1MDOUT
|= 0x02;
// enable CEX0 output (P1.1 pin)
}
14
2. DC Motor Control
DC motors are used in control systems as positioning devices
Both the speed and torque of the DC motor can be precisely controlled over a
wide range.
A DC motor consists of a stator and a rotor (also called armature).
The stator of the DC motor is a permanent magnet whereas the armature consists
of coils.
When current flows into the armature, the motor starts to rotate.
The speed of the DC motor is determined by the voltage applied to the armature
coils.
PWM function is often used to control the DC motor speed.
MCU can not drive the motor directly and needs a driver chip to provide the
needed current levels.
15
16
In Figure 8.27,
The PWM output (CEX0) is connected to one end of the motor voltage input
whereas the P4.0 pin provides the direction control (shown in Figure 8.28).
Due to its mass, a DC motor cannot reach final speed instantaneously.
Example 8.15 For the circuit connection shown in Figure 8.27, write a C function to
measure the motor speed (in rpm) assuming that the C8051F040 is running with a 24MHz external oscillator.
Solution: To measure the motor speed, we need to capture two consecutive falling (or
rising) edges. Let the difference of two consecutive edges be diff and the period of the
timer be set to 0.5 s (set the clock prescaler of the PCA0 timer to 12), then the motor
speed (rpm- revolutions per minute) is
Speed = 60(s) (1/( 0.5 10-6 diff 2)) = 60 106 /diff
The C function that measures the motor speed is as follows:
17
Electrical Braking
Turning off the voltage to the motor does not make it stop immediately because
the momentum will keep it rotating.
An abrupt stop may be required by certain applications in which the motor must
run a few turns and stop quickly at a predetermined point. This is called electrical
braking.
Electrical braking is done by reversing the voltage applied to the motor.
In Figure 8.28, the motor can be braked by (1) reducing the duty cycle of PWM
output (at CEX0) to 0.4% and (2) setting the port pin P4.0 output to high for an
appropriate amount of time.
18