Файл: The quintessential PIC microcontroller (S. Katzen, 2000).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 15.06.2025

Просмотров: 5307

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

374 The Quintessential PIC Microcontroller

Program 13.3 Generating a 15 minute data logger timebase.

include "p16C74b.inc" __config _WDT_OFF & _CP_OFF

cblock

20h

_work:1, _status:1, JIFFY:1

endc

org

0

goto

MAIN

org

4

goto

ISR

MAIN

movlw

b’00011011’

; Timer on, external clock, synched

movwf

T1CON

; Oscillator enabled, PS ratio 2:1

clrf

JIFFY

; Zero Jiffy count

bsf

STATUS,RP0

; To Bank1

bsf

PIE1,TMR1IE

; Enable the Timer1 interrupt

bcf

STATUS,RP0

; Back to Bank0

DOOZE

sleep

; Remember, the 1st instruction

movlw

d’225’

; Check, 225 Jiffies = 15 minutes?

subwf

JIFFY,w

btfss

STATUS,Z

goto

DOOZE

; IF not THEN go back to sleep

clrf

JIFFY

; ELSE reset Jiffy count

call

SAMPLE

; Sample temperature and transmit

goto

DOOZE

; and go back to sleep

;*************************************************************

;First save context in usual way

ISR

movwf

_work

;

Put

away W

swapf

STATUS,w

;

and

the Status register

movwf

_status

;************************************************************

;The core code

btfss

PIR1,TMR1IF

; Was it

a Timer1

interrupt?

goto

ISR_EXIT

; IF no

THEN

false alarm

incf

JIFFY,f

;

Record

one

more

Jiffy

bcf

PIR1,TMR1IF

;

Reset

interrupt

flag

; ************************************************************

ISR_EXIT swapf

_status,w

; Untwist

the original Status reg

movwf

STATUS

swapf

_work,f

; Get

the

original W reg back

swapf

_work,w

;

leaving

STATUS unchanged

retfie

;

and

return from interrupt


13. Time is of the Essence 375

oscillator with a prescale ratio of 2:1, giving our 4 s ji y. In addition, both TMR1IE, PEIE and GIE mask bits are set to enable the interrupt on Timer 1 overflow.

The ISR simply adds one onto the Ji y count. This is tested for 225 in the background program after sleep and if equal it is zeroed, the temperature taken and transmitted to base.

Timer 1 can be reset to zero by any Compare/Compare/PWM CCP module. Some PIC devices have two CCP modules sharing the same timer, such as the PIC16C74, and in such cases the second module CCP2 is virtually identical to CCP1 and can share the same timer. With this in mind we will look just at CCP1 for convenience, pointing out any di erences at the relevant point. All CCP operations require Timer 1 to be configured in its synchronous mode; that is SYNCH = 0.

Each CCP module has an associated control register. For CCP1 this is CCP1CON at File 1Dh in which the lower four bits CCP1M[3:0] set the module mode. A setting of 0000, the reset value, disables the CCP module, resets the CCP output latch and clears the Capture mode prescaler. Modes 1000 – 1011 listed in Fig. 13.6 give four Compare modes. Here an equality comparator detects when the 16-bit Timer 1 datum equals the setting in the 16-bit CCPR1H:L (CCP Register 1) at File 15:16h respectively. When an equality match occurs the CCP1IF interrupt flag in PIR1[2] will be set and this can cause an interrupt if the corresponding CCP1IE mask bit in PIE1[2] is set.

Besides setting CCP1IF and depending on the setting of the CCP1M[3:0] mode bits, one of four actions are possible on Timer 1 matching CCPR1:

0000

CCP1 off

3

2

1

0

CCP1CON

1000

CCP1 pin high on match

CCP1M3

CCP1M2

CCP1M1

CCP1M0

File 17h

File 0Ch

1001

CCP1 pin low on match

1010

CCP1 pin unchanged on match

0

1011

Reset Timer 1 on match

TMR1IF

PIR1

CCP latch

RC2

R

O/P

CCP1

Overflow

1R TMR1H

1RTMR1L

logic

S

C1

File 0Fh

File 0Eh

TRISC[2]

Timer 1

PIR1

Comparator

Match

2 CCP1IF

=

CCP Register 1

CCPR1H

CCPR1L

File 16h

File 15h

Fig. 13.6 The CCP1 module set to Compare mode.


376 The Quintessential PIC Microcontroller

1000:

Pin RC2/CCP1 is forced high.

1001:

Pin RC2/CCP1 is forced low.

1010:

Pin RC2/CCP1 unchanged, but CCP1IF still set.

1011:

Timer 1 is cleared and with CCP2 only7 an analog module conversion is initialized by setting GO/DONE – see Fig. 14.8 on page 404.

Where RC2/CPP1 or RC1/CCP2 are to be used as CCP outputs then the appropriate TRISC bit(s) should be cleared to set the pin direction to output. There is no way to directly reset or set the CCP latch other than zeroing the CCPCON register which resets the latch and disables the CCP module. In this case the state of the RC2/CCP1 pin will be that of PORTC[2] until the module is set to an appropriate mode, in which case the pin will reflect the state specified above when the match occurs.

As an example consider that we wish to set up Timer 1 as configured in the last example to generate an interrupt each 10 seconds. To do this we need set the timer to time-out after 16 s (prescale ratio 8:1) and then shorten the cycle. This is implemented by loading the CCPR1 register with the fraction 1016 −1, which translates to 9FFFh. Whenever Timer 1 reaches this value it will automatically be reset on the next clock input (that would have normally incremented the timer to A000h) and an interrupt will occur if the CCP1IE mask bit (and global PEIE and GIE masks) are set.

Initialization code for this is:

movlw

9Fh

; Set up CCPR1 to 9FFFh

movwf

CCPR1H

movlw

FFh

movwf

CCPR1L

movlw

b’00001011’

; CCP Compare mode 1011

movwf

CCP1CON

movlw

b’00111011’

; Timer1 on (1), external clock (1)

movwf

T1CON

; Synched (0), oscillator (1) 8:1 (111)

bsf

STATUS,RP0

; Change to Bank 1

bsf

PIE1,CCP1IE

; Enable CCP1 interrupts

bcf

STATUS,RP0

; Change back to Bank 0

bsf

INTCON,PEIE

; Enable Timer/CCP interrupts

bsf

INTCON,GIE

; Enable all interrupts

The PIC will then automatically be interrupted every ten seconds.

As CCP1 is not changed by Compare mode 1011 this pin can be used as a normal Port C input/output independently of the CCP1 module.

Where there are two CCP modules they can work in tandem using di erent modes, but the timebase will be common – see Example 13.3.

7This is the only functional di erence between CCP1 and CCP2.


13. Time is of the Essence 377

Modes 0100 – 0111 configure the appropriate CCP module to capture the state of Timer 1 when an ‘event’ occurs at the appropriate CCP pin. We can see from Fig. 13.7 that an event can be a falling or rising edge on the RC2/CCP1 pin or every 4th or 16th rising edge according to the CCP1M[3:0] mode bits. This Event prescaler is cleared when the mode bits are set to 0000.

Once a defined event has taken place the 16-bit state of Timer 1 is parallel loaded into the CCP register 1 and CCP1IF set. The processor can then subsequently read this frozen value – that is the time. If Timer 1 is reset after each capture then the sampled datum is the time since the last event. Alternatively, as Timer 1 continues to increment, its captured value can be subtracted from the previous reading to give the di erence. As the mode may be altered on the fly, the time between rising and falling edge on CCP1 can be measured by toggling CCP1M[0] between captures. This may cause the CCP1IF flag to be set. To prevent false interrupts, CCP1IE should be cleared before the change-over and CCP1IF after the change-over. Alternatively, the CCP1 module can be used to capture the rising edge and CCP2 the falling edge – see Example 13.3. There is no room for the CCP2IF and the associated interrupt mask CCP2IE mask bit in PIR1/PIE1. Instead bit 0 of PIR2/PIE2 are pressed into service and in many mid-range processors is the only occupant of these registers.

As our example, consider that we wish to measure the period of our ECG signal with the peak detector connected to pin CCP1. If we assume Timer 1 is clocked by its own 32.768 kHz watch crystal, our set up code is something like this:

File

PIR1 h0C

CCP1IF

2

TMR2IF

1

TMR1IF

0

CCP1CON

File 17h

3

2

1

0

0100

Every falling edge

CCP1M3 CCP1M2 CCP1M1 CCP1M0

0101

Every rising edge

0110

Every 4th rising edge

CCP1 Control register

0111

Every 16th rising edge

Prescaler

CCP Register 1

÷1, ÷4, ÷16

File 16h

File 15h

C CCPR1H

C CCPR1L

Timer 1

CCP1

TMR1H

TMR1L

File 0Fh

File 0Eh

Fig. 13.7 Capturing the time of an event.


378 The Quintessential PIC Microcontroller

movlw

b’00001011’

; Timer on, external clock, synched

movwf

T1CON

; Oscillator enabled, PS ratio 1:1

movlw

b’00000100’

; Capture mode, event = falling edge

movwf

CCP1CON

clrf

NEW

; Zero NEW flag

bsf

STATUS,RP0

; To Bank1

bsf

PIE1,CCP1IE

; Enable the CCP1 interrupt

bcf

STATUS,RP0

; Back to Bank0

bsf

INTCON,PEIE

; Enable Timer/CCP interrupts

bsf

INTCON,GIE

; Global interrupts enabled

The ISR simply reads the contents of the CCP register and stores it away in two temporary locations, setting the file register NEW to indicate to background program that a new time datum exists. Timer 1 is then reset ready for the next event.

With a crystal of 32.768 kHz the time resolution of the captured datum is 30.5 µs with our 1:1 prescale setting. Timer 1 will overflow in 2 s, which is su cient to record a heart rate of 30 beats per minute.

Program 13.4 Capturing the instant of time an ECG R-point occurs.

;*************************************************************

;First save context in usual way

ISR

movwf

_work

;

Put

away W

swapf

STATUS,w

;

and

the Status register

movwf

_status

;************************************************************

;The core code

btfss

PIR1,CCP1IF

; Was it a CCP1 interrupt?

goto

ISR_EXIT

; IF no THEN false alarm

incf

NEW,f

; Signal a new capture

bcf

PIR1,CCP1IF

; Reset interrupt flag

movf

CCPR1L,w

; Get captured low byte

movwf

TEMP+1

; Store away

movf

CCPR1H,w

; Get captured high byte

movwf

TEMP

; Store away

clrf

TMR1L

; Zero Timer1

clrf

TMR1H

; ************************************************************

ISR_EXIT swapf

_status,w

; Untwist

the original Status reg

movwf

STATUS

swapf

_work,f

; Get

the

original W reg back

swapf

_work,w

;

leaving

STATUS unchanged

retfie

;

and

return from interrupt