Lect05 Prog Dev
Lect05 Prog Dev
Lect05 Prog Dev
TAB4333
Timer 0 will be used as example in program development. PIC18F452 has four 16-bit timers: Timer 0, Timer 1, Timer 2, and Timer 3. All counters are count-up type. Timers 1-3 can be paired capture / compare / pulse-width modulation (CCP) circuitry for external time control and measurement. Since Timer 0 can not be paired with CCP it is usually used for internal Looptime timing. Timer 0 can count pulses of either the internal program clock or on pin RA4. Throughout the slides it is assumed that the internal clock is used. The notation RA4 means that it is pin 4 (of pins 0-7) on I/O port A. The RA4 pin is also labeled T0CKI to show that it can be used as Timer 0 clock input or as a general-purpose input/output pin.
Timer 0
TAB4333
Timer 0 Features
Freq < internal clock N = 1,2,4,8, , 256 TMR0H (8-bit) TMR0L (8-bit) prescaler ( N)
synchronizer
If only on internal clock: What time interval TMR0IF overflow? How many counts need to be deducted from the counter for overflow interval of 10ms?
TAB4333
Timer 0
The two 8-bit halves of the 16-bit Timer 0 are special function registers (SFRs). The most-significant byte (MSB) of the timer has symbolic name TMR0H and is register 0xFD7. The LSB of the timer is called TMR0L and is register 0xFD6. All of the SFRs are listed in Appendix A8 of the book and defined in 18F452 header file. The Timer 0 control (T0CON) - special function register sets up the way Timer 0 functions. Four bits of T0CON are important for internal-clock Timer 0 operation: 1) TMR0ON Timer 0 on/off 2) T08BIT Timer 0 8-bit/16-bit 3) T0CS Timer 0 clock select 4) PSA Prescaler use/bypass
TAB4333 4
Timer 0 On/Off
TMR0ON is a symbolic name (defined in P18F452.inc) equal to the value 7. The bit that turns Timer 0 on or off happens to be the most-significant bit (MSB) of T0CON (a symbolic name defined in P18F452.inc as 0xFD5). To turn Timer 0 on, we could use: bsf T0CON, TMR0ON ; [bsf 0xFD5,7]
Timer 0 8-bit/16-bit
Timer 0 is the only timer that can be used as an 8-bit or 16-bit timer. Probably the only reason to use 8-bit mode is for porting code from older PIC C (which only had an 8-bit Timer 0). To set Timer 0 to 16-bit mode we could use: bcf T0CON, T08BIT
TAB4333
TAB4333
TAB4333
TAB4333
10
Timer 0 Rollover
All PIC timers count up (increment) only and never down (decrement). Timer 0 sets the TMR0IF (Timer 0 interrupt flag) bit of the INTCONT (interrupt control) SFR when the timer counts from 0xFFFF to 0x0000 (regardless of whether interrupts are used or not). We can skip the next instruction on Timer 0 rollover using: btfss INTCON, TMR0IF
TAB4333
11
Looptime Subroutine
Using a 10 MHz crystal (like the QwikFlash board has) and not using the PICs internal PLL results in an internal clock frequency of 2.5 MHz. Bypassing the Timer 0 prescaler for maximum timing resolution allows for no more than 65,536 clock cycles between Timer 0 rollovers. Using 25,000 counts at 2.5 MHz gives a nice round number of 10 milliseconds per rollover. To get 25,000 counts per rollover, we must skip the remaining 65,536 25,000 = 40,536 of the maximum counts between rollovers. Since the code to add a value to the running counter causes 14 counts to be missed, we actually need to add 40,536 + 14 = 40,550 to the timer value.
TAB4333
13
Symbolic Constants
The equ directive can be used to assign a symbolic name to a constant:
Bignum
If the default radix has been set to hex, the above results in the symbolic name ValueToAdd being equated with 0x9E66. The MSB or LSB of a symbolic constant can be obtained with the high or low directive: high ValueToAdd ; gets 0x9E low ValueToAdd ; gets 0x66
TAB4333 14
TAB4333
15
Macros
Macros are used to create single-line pseudo-instructions that expand to commonly-used multi-instruction sequences. Macro definitions have the form: <macro name> macro <parameters> <macro body> endm
TAB4333
16
Macros
A macro can be defined to move a literal into a specified register (with the side effect of trashing the W value): movlf macro literal, dest movlw literal movwf dest endm
The macro MOVLF defined above can be invoked by using it like an instruction: movlf 17, NUM On assembly, the macro will be expanded to act as if we had written: movlw 17 movwf NUM
TAB4333
17
BlinkAlive Subroutine
It is often useful during development to have an LED that does nothing but blink regularly when the code is running. Toggling the LED every 10 ms would be too fast for the eye to see. To make the LED come on every 1 second requires the BlinkAlive subroutine to maintain a count variable that counts from 100 downto 0.
Why 100?
BlinkAlive
invoke macro
PORTA, RA4 ;off LED ALIVECNT, F ;counter 1 BAend ;counter != 0 100, ALIVECNT ;reset counter PORTA, RA4 ;on LED
TAB4333
18
Using $
The $ symbol refers to the program address of the current instruction. An infinite loop can be generated using: goto $ The previous instruction is equivalent to: Loop goto Loop
TAB4333
19
Org Directive
The org assembler directive says to locate the following code in program memory starting at the address specified:
org 0x1000 ; assemble starting at 0x1000 btg PORTC, RC2 ; the program address of this instruction is 0x1000
TAB4333 21
Configuration Bits
The desired configuration bits can be included in the HEX file output using the __CONFIG command (note that it starts with a double underscore): __CONFIG <config_word>, <bit> & <bit>
Only those bits that need to be different than the default need to be specifed.
TAB4333
22
Oscillator Configuration
The high speed oscillator is selected using the _HS_OSC_1H bit of the _CONFIG1H configuration word __CONFIG _CONFIG1H, _HS_OSC_1H This oscillator will result in a program clock that is as fast as the crystal input.
TAB4333
23
Vector Addresses
Reset vector (address executed at reset): 0x0000 High priority interrupt vector: 0x0008 Low priority interrupt vector: 0x0018
TAB4333 24
TAB4333
25
repeat
TAB4333
26
HERE
DELAY AGAIN
TAB4333
27