Файл: Microcontroller Programming. Thi Micro Chip PIC (Julio Sanchez, 2007).pdf

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

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

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

Добавлен: 14.06.2025

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

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

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

268

Chapter 12

;The prescaler is assigned to Timer0 and set up so

;that the timer runs at 1:2 rate. This means that

;every time the counter reaches 128 (0x80) a total

;of 256 machine cycles have elapsed. The value 0x80

;is detected by testing bit 7 of the counter

;register.

;Note:

;The Timer0 register provides the low-order level

;of the count. Since the counter counts up from zero,

;in order to ensure that the initial low-level delay

;count is correct the value 128 - (xx/2) must be calculated

;where xx is the value in the original countL register.

;First calculate xx/2 by bit shifting

TM0delay:

bcf

STATUS,C ; Clear carry flag

rrf

countL,f ; Divide by 2

; now subtract 128 - (xx/2)

movf

countL,w ; w holds low-order byte

sublw

d’128’

; Now w has adjusted result. Store in TMR0

movwf

TMR0

;Routine tests timer overflow by testing bit 7 of

;the TMR0 register.

cycle:

btfss

TMR0,7

;

Is bit 7 set?

goto

cycle

;

Wait if not set

;At this point TMR0 bit 7 is set

;Clear the bit

bcf

TMR0,7

; All other bits are preserved

;Subtract 256 from beat counter by decrementing the

;mid-order byte

decfsz countM,f

goto

cycle

; Continue if mid-byte not

zero

;At this point the mid-order byte has overflowed.

;High-order byte must be decremented.

decfsz countH,f goto cycle

; At this point the time cycle has elapsed return

;==============================

;set register variables for

;one-half second delay ;==============================

;Procedure to initialize local variables for a

;delay of one-half second on a 16F84 at 4 Mhz.

;Timer is set up for 500,000 clock beats as

;follows: 500,000 = 0x07 0xa1 0x20


Timers and Counters

269

;500,000 = 0x07 0xa1 0x20

;—— —— ——

;

|

|

|___

countL)

;

|

|________

countM

;

|_____________

countH

onehalfSec:

movlw

0x07

movwf

countH

movlw

0xa1

movwf

countM

movlw

0x20

movwf

countL

return

end

12.5.4 The LapseTmrInt Program

;File: LapseTmrInt.ASM

;Date: May 1, 2006

;Author: Julio Sanchez

;Processor: 16F84A

;Description:

;Interrupt-driven version of the LapseTimer program.

;Using Timer0 to produce a variable-lapse delay.

;The delay is calculated based on the number of machine

;cycles necessary for the desired wait period. For

;example, a machine running at a 4 Mhz clock rate

;executes 1,000,000 instructions per second. In this

;case a 1/2 second delay requires 500,000 instructions.

;The wait period is passed to the delay routine in three

;register variables which hold the high-, middle-, and

;low-order bytes of the counter. ;===========================

;switches

;===========================

; Switches used in __config directive:

;

_CP_ON

Code protection ON/OFF

; *

_CP_OFF

;

*

_PWRTE_ON

Power-up timer ON/OFF

;_PWRTE_OFF

;

_WDT_ON

Watchdog

Timer ON/OFF

; * _WDT_OFF

;

_LP_OSC

Low power crystal

occilator

; * _XT_OSC

External

parallel

resonator/crystal oscillator

;

_HS_OSC

High speed crystal resonator (8 to 10 MHz)


; Start of block
; 3-byte auxiliary counter for delay. ; High-order byte
; Medium-order byte ; Low-order byte
; Context saving ; Idem

270

Chapter 12

;

Resonator: Murate Erie CSA8.00MG = 8 MHz

;

_RC_OSC

Resistor/capacitor oscillator

;|

;|_____ * indicates set up values

processor

16f84A

include

<p16f84A.inc>

__config

_XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

;===================================================== ; variables in PIC RAM ;===================================================== ; Local variables

cblock 0x0d

countH countM countL old_w old_STATUS endc

;========================================================

; m a i n p r o g r a m

;========================================================

org

0

; start at address 0

goto

main

;

;=============================

;

interrupt handler

;=============================

org

0x04

goto

IntServ

;=============================

;main program ;============================= main:

;Clear the Watchdog Timer and reset prescaler clrf TMR0

clrwdt

;Set up the OPTION register bit map

movlw

b’11011000’

;

7

6

5

4

3

2 1 0 <= OPTION bits

;

|

|

|

|

|

|__|__|_____ PS2-PS0 (prescaler bits)

;

|

|

|

|

|

Values for Timer0

;

|

|

|

|

|

000

= 1:2

001

=

1:4

;

|

|

|

|

|

010

= 1:8

011

=

1:16

;

|

|

|

|

|

100

= 1:32

101

=

1:64

;

|

|

|

|

|

110

= 1:128

*111 = 1:256


Timers and Counters

271

;

|

|

|

| |______________

PSA

(prescaler assign)

;

|

|

|

|

*1

=

to WDT

;

|

|

|

|

0

=

to Timer0

;

|

|

|

|_________________

TOSE (Timer0 edge select)

;

|

|

|

0

=

increment on low-to-high

;

|

|

|

*1

=

increment in high-to-low

;

|

|

|____________________

TOCS (TMR0 clock source)

;

|

|

*0

=

internal clock

;

|

|

1

=

RA4/TOCKI bit source

;

|

|_______________________

INTEDG (Edge select)

;

|

*0

=

falling edge

;|__________________________ RBPU (Pullup enable)

;

0

= enabled

;

*1

= disabled

option

; Set up ports

movlw

0x00

; Set Port-B to output

tris

PORTB

clrf

PORTB

; All Port-B to 0

;Port-A is not used in this program ;============================

;set up interrupts ;============================

;Clear external interrupt flag (INTF = bit 1)

bcf

INTCON,INTF

; Clear flag

;Enable global interrupts (GIE = bit 7)

;Enable RB0 interrupt (inte = bit 4)

bsf

INTCON,GIE

; Enable global int (bit 7)

bsf

INTCON,T0IE

; Enable TMR0 overflow

; interrupt

; Init count

call

onehalfSec

;============================

;do-nothing loop ;============================

;All work is performed by the interrupt handler mloop:

goto mloop ;==============================

;set register variables for

;one-half second delay ;==============================

;Procedure to initialize local variables for a

;delay of one-half second on a 16F84 at 4 Mhz.

;Timer is set up for 500,000 clock beats as

;follows: 500,000 = 0x07 0xa1 0x20

;500,000 = 0x07 0xa1 0x20

;—— —— ——


272

Chapter 12

;

|

|

|___

countL)

;

|

|________

countM

;

|_____________

countH

onehalfSec:

movlw 0x07 movwf countH movlw 0xa1 movwf countM movlw 0x20 movwf countL

;The Timer0 register provides the low-order level

;of the count. Since the counter counts up from zero,

;in order to ensure that the initial low-level delay

;count is correct the value 256 - xx must be calculated

;where xx is the value in the original countL register.

movf

countL,w ; w holds low-order byte

sublw d’255’

; Now w has adjusted result. Store in TMR0

movwf TMR0

return

;=======================================================

;Interrupt Service Routine ;=======================================================

;Service routine receives control when the timer

;register TMR0 overflows, that is, when 256 timer beats

;have elapsed

IntServ:

; First test if source is a Timer0 interrupt

btfss

INTCON,T0IF

; T0IF is Timer0 interrupt

goto

notTOIF

; Go if not RB0 origin

; If so clear the timer interrupt flag so that count continues

bcf

INTCON,T0IF

; Clear interrupt flag

; Save context

movwf

old_w

;

Save w register

swapf

STATUS,w ; STATUS to

w

movwf

old_STATUS

;

Save STATUS

;=========================

;interrupt action ;=========================

;Subtract 256 from beat counter by decrementing the

;mid-order byte

decfsz countM,f

goto

exitISR

; Continue if mid-byte not

zero

;At this point the mid-order byte has overflowed.

;High-order byte must be decremented.

decfsz countH,f

goto exitISR