33
EE25M 25th April 2002 C24 page IV 6 1. Write code to decrement a 16-bit variable and test the result for zero, branching to Bothzero if the result is zero. Can this be done using fewer lines of code and/or faster execution than simply concatenating the two routines shown previously? The concatenated routines can be made smaller by eliminating the first line from the test for zero. It is redundant, just after the decrement of countl. They can be made faster by reversing the order of the final branch so that the non-zero case branches before the non-zero case. The tutorial group proposed an alternate solution which departed early, for all cases which either borrowed from the hi-byte or had a non-zero result in the lo-byte without borrowing (see slides IV for code.) The early departure didn’t save code space, but improved average performance. 2. Why does -7/3 yield a different remainder to 7/-3? D V = Q; R D = Q × V + R -7 = (3)(-2) + (-1) 7=(-3)(-2) + 1 The sign of the remainder depends only on the sign of the dividend.

page IV 6 - Faculty of Engineering-Redirect · page IV 6 1. ... LIST p=16F877 #include ... movwf TMR0 ; Timer 0 flag will go off after 20 cycles bcf INTCON,T0IF

Embed Size (px)

Citation preview

EE25M 25th April 2002 C24

page IV 6

1. Write code to decrement a 16-bit variable and test the result for zero, branching to Bothzero

if the result is zero. Can this be done using fewer lines of code and/or faster execution thansimply concatenating the two routines shown previously?The concatenated routines can be made smaller by eliminating the first line from the test for zero.It is redundant, just after the decrement of countl. They can be made faster by reversing theorder of the final branch so that the non-zero case branches before the non-zero case.The tutorial group proposed an alternate solution which departed early, for all cases which eitherborrowed from the hi-byte or had a non-zero result in the lo-byte without borrowing (see slides IVfor code.) The early departure didn’t save code space, but improved average performance.

2. Why does -7/3 yield a different remainder to 7/-3?

DV

= Q;RD = Q× V +R

−7 = (3)(−2) + (−1)7 = (−3)(−2) + 1

The sign of the remainder depends only on the sign of the dividend.

EE25M 25th April 2002 C25

3. Design an algorithm and implement it in PIC assembly language to perform unsigned divisionof a 24-bit number by an 8-bit number and produce a 24-bit quotient and 8-bit remainder.Repeated subtraction is the simplest method. Two approaches were presented by students at thetutorial session:Jan: start from the MSB and subtract the 8 bit divisor from the current divisor byte, and theremainder of the previous divisor byte. Keep an 8 bit counter for each answer byte.Sanjay: perform 8 bit subtraction on the last byte, borrowing from the upper bytes as needed.Use a full 24 bit increment for the answer.Code for the latter approach follows:

div24by8 clrf ans_lo

clrf ans_mid

clrf ans_hi

next movf divr,W ; subtract from low byte

subwf divd_lo,F

btfsc STATUS,C ; check for borrow

goto inc_ans

movlw 1

subwf divd_mid,F

btfsc STATUS,C

goto inc_ans

subwf divd_hi,F

btfsc STATUS,C

goto inc_ans

; we are done here .... undo the last to leave

; remainder in divd_lo

movf divr,W

addwf divd_lo,F

goto good_exit

inc_ans incfsz ans_lo,F

goto next

incfsz ans_mid,F

goto next

incfsz ans_hi,F

goto next

goto error_exit; there was a problem here .....

EE25M 25th April 2002 C26

4. Design an algorithm that works more efficiently than repeated subtraction for unsigned 8-bitby 8-bit division. Implement it in PIC assembly language.Method: Shift dividend until it is large enough to subtract the divisor. (see Stallings)

movf Dividend,W

movwf Q ; final answer will be in Q

clrf A ; final remainder will be in A

movlw 8

movwf cnt

loop bcf STATUS,C

rlf Q

rlf A

movf Divisor,W

subwf A,W

btfss STATUS,C ; if we did not borrow then carry is set

goto chk ; is clear and we do not want to store A

movwf A ; is set and we need to store A and change Q_0

bsf Q,0

chk decfsz cnt ; check the count

goto loop

...

EE25M 25th April 2002 C27

5. Implement Booth’s algorithm for two signed 8 bit numbers in PIC assembly language. It ispresumed that the result will be 16 bits wide.The following does not test for invalid cases.

LIST p=16F877

#include <p16F877.inc>

A EQU 0x20

Q EQU 0x21 ; result will appear in A:Q

M EQU 0x22

count EQU 0x23

ORG 0x00 ; initialization code

nop

goto Main

Main movlw 0xB1 ; load up the numbers

movwf Q

movlw 0x80

movwf M

movlw 0x10

movwf count

clrf A

movf M,W

xorwf Q,W ; store the result sign

bthloop movf Q,W

andlw 0x01

xorwf STATUS,F ; check the pair of bits

btfss STATUS,C

goto arshft

movlw M

btfsc Q,0 ; if the Q_0 bit is 1 then subtract

sub8 subwf A,F

btfss Q,0

add8 addwf A,F

arshft bcf STATUS,C

btfsc A,7

bsf STATUS,C

rrf A,F

rrf Q,F

decfsz count,F ; check if we are done

goto bthloop

done sleep

END

EE25M 25th April 2002 C28

6. Design a Booth’s-like algorithm for the division of a signed 16 bit number by a signed 8 bitnumber, and implement it in PIC assembly language. Booth’s like division will fail in the caseswhere the divisor is 0: the invalid quotient would be ±1 (sign is opposite that of the dividend) aremainder equal to the lower byte(s) of the dividend.

LIST p=16F877

#include <p16F877.inc>

M EQU 0x20

cnt EQU 0x21

A EQU 0x22

Q_hi EQU 0x23

Q_lo EQU 0x24

sgn EQU 0x25

temp EQU 0x26

ORG 0x00

nop

init movlw 0xFF

movwf M ; load the divisor into M

clrf A

movlw 0x00

movwf Q_hi

movlw 0x01

movwf Q_lo ; load the dividend into Q (hi,lo)

btfsc Q_hi,7 ; sign extend the dividend from 16 to 24 bits in A:Q_hi:Q_lo

comf A,F

movlw .16 ; load count with the number of bits in Q

movwf cnt

movf M,W ; store the result sign in bit 7 of variable

xorwf Q_hi,W

movwf sgn

; Note: division by 0 will yield an invalid answer!!

loop

bcf STATUS,C

rlf Q_lo,F ; shift A,Q left 1 bit

rlf Q_hi,F

rlf A,F

movf M,W ; put M in W

xorwf A,W

andlw 0x80 ; check if M and A have the same sign (A=A-M) or different signs (A=A+M)

btfss STATUS,Z

EE25M 25th April 2002 C29

goto diffsgn

movf M,W

subwf A,W

goto chk

diffsgn

movf M,W

addwf A,W

chk ; check if W now has same sign as A or (A=0 and Q_hi=0 and Q_lo=0)

; then set Q_0 to 1 and replace A with W

movwf temp

xorwf A,W

andlw 0x80

btfsc STATUS,Z

goto replace ; successful

movf Q_hi,W ; also succesful if this is 0 and upper bit of Q is 0.

andlw 0x80

iorwf temp,W

btfss STATUS,Z

goto next

replace ; unsuccessful but all zeros

movf temp,W

movwf A

bsf Q_lo,0

next decfsz cnt,F ; decrement count; if not zero, goto loop

goto loop

sgnchk btfss sgn,7

goto done

comf Q_hi,F ; correct for sign

comf Q_lo,F

incf Q_lo,F

btfsc STATUS,Z

incf Q_hi,F

done sleep

END

EE25M 25th April 2002 C30

7. Presuming a two’s complement 8-bit integer representation, write an algorithm and implementit in PIC assembly language to count the number of negative integers in a set of twentynumbers starting at address 30h. [Past Paper 2001, No. 1(c)]

clrf cnt

movlw 0x30

movwf FSR

loop btfsc INDF,7 ; check the sign bit

incf cnt,F ; increment the count if it is set

incf FSR,F ; move up one location

movf FSR,W ; test to see if we are at location 0x44

sublw 0x44

btfsc STATUS,Z

goto loop

... ; proceed

EE25M 25th April 2002 C31

8. Write an algorithm and implement it in PIC assembly language to subtract two 24-bit num-bers, Q 1 and Q 2, and store the result in R. Ensure that the carry flag reflects the result ofthe subtraction. [Past Paper 2001, No. 2]Note there is a bug in the Handout for 16 bit subtraction. The carry flag will be set incorrectly ifthe two hi bytes are equivalent.

movf Q_1_lo,W ; return Q_2 - Q_1

subwf Q_2_lo,W

movwf R_lo

bcf temp, mbf ; use a bit in a temporary variable as my borrow flag

btfsc STATUS,C ; carry is clear iff a borrow occurred

bsf temp, mbf ; remember to borrow from result

movf Q_1_md,W

subwf Q_2_md,W

movwf R_md

btfss temp, mbf ; do the borrow if needed

goto hi

btfsc STATUS,Z ; if R_md is zero

bsf STATUS,C ; set the carry then

decf R_md,F ; do a decrement

hi bcf temp, mbf

btfsc STATUS,C ; check for borrow from the hi byte

bsf temp, mbf

movf Q_1_hi,W

subwf Q_2_hi,W

movwf R_hi

btfss temp, mbf ; do the borrow if needed

return

btfsc STATUS,Z ; if R_hi is zero

bsf STATUS,C ; set the carry then

decf R_hi,F ; decrement

return

EE25M 25th April 2002 C32

Coursework A

Using PIC assembly, implement Booth’s algorithm for the multiplication of two 16-bit signed inte-gers. Note that Booths algorithm does not work if 0x8000 is in the multiplicand. The following sampleanswer corrects this case, and uses two’s complement addition to perform subtraction.

LIST p=16F877

#include <p16F877.inc>

A_hi EQU 0x20

A_lo EQU 0x21

Q_hi EQU 0x22

Q_lo EQU 0x23

M_hi EQU 0x24

M_lo EQU 0x25

nM_hi EQU 0x26

nM_lo EQU 0x27

count EQU 0x28

storage EQU 0x29

ORG 0x00 ; initialization code

nop

goto Main

;

; subroutine tc16 replaces the 16 bit number stored

; HI:LO at the location specified by the FSR,

; with its two’s complement.

; returns with carry flag set if there was an overflow

;

tc16 comf INDF,F ; complement hi byte

incf FSR ,F

comf INDF,F ; complement lo byte

tc16inc incf INDF,F ; now the regular increment of lo byte

btfsc STATUS,Z

bsf STATUS,C ; set the carry if we overflow

decf FSR, F

btfss STATUS,C ; if no overflow then leave

return

incfsz INDF,F ; else increment hi byte

bcf STATUS,C ; clear flag if there was no overflow

return ; all done

EE25M 25th April 2002 C33

Main movlw 0xB1 ; load up the numbers

movwf Q_hi

movlw 0x00

movwf Q_lo

movlw 0x80

movwf M_hi

movwf nM_hi

movlw 0x00

movwf M_lo

movwf nM_lo

movlw 0x10

movwf count

clrf STATUS

movlw nM_hi ; store the negative multiplier

movwf FSR

call tc16

clrf A_hi

clrf A_lo

clrf storage

clrf STATUS ; clear out the flags

movf M_hi,W

xorwf Q_hi,W ; store the result sign

movwf storage

bthloop movf Q_lo,W

andlw 0x01

xorwf STATUS,F ; check the pair of bits

btfss STATUS,C

goto ashft32

clrw

btfsc Q_lo,0 ; if the Q_lo bit is 1 then subtract

addlw 0x02

addlw M_lo

movwf FSR ; load up FSR with M or -M

add16 movf INDF,W ; addition of M (or -M) to A

addwf A_lo,F

decf FSR ,F

movf INDF,W

btfsc STATUS,C

incfsz A_hi,F

addwf A_hi,W

EE25M 25th April 2002 C34

movwf A_hi

ashft32 bcf STATUS,C ; 32 bit arithmetic shift for

btfsc A_hi,7 ; A_hi,A_lo,M_hi,M_lo

bsf STATUS,C

rrf A_hi,F

rrf A_lo,F

rrf Q_hi,F

rrf Q_lo,F

decfsz count,F ; check if we are done

goto bthloop

; fudge for the 8000 case -- check if sign is correct.

movf A_hi,W

xorwf storage,F

btfss storage,7

goto done

movlw Q_hi

movwf FSR

call tc16

comf A_lo,F

comf A_hi,F

btfss STATUS,C

goto done

incfsz A_lo,F

bcf STATUS,C

btfsc STATUS,C

incfsz A_hi,F ; note carry is not right

bcf STATUS,C ; at the end here!!

done sleep

END

EE25M 25th April 2002 C35

CourseWork B

Lab Exercise 1 – A/D settling time is 20µs and sampling time is 12 ∗ TAD. For a 4MHz clock and anA/D sampling frequency of Fosc/8, successive samples will be at least 44µs apart. The lowest prescalerthat can be used with TMR0 is 1:2. For a prescale value of 1:1 assign the prescaler to the Watchdogtimer.

LIST p=16f877

INCLUDE "p16f877.inc"

PotRead EQU 0x20

ORG 0x00

nop ; for ICD

goto Start

Start

BANKSEL PORTD

clrf PORTD

clrf PORTC

movlw B’01000001’ ;

movwf ADCON0 ; Fosc/8, A/D enabled, Sample Channel 0

BANKSEL OPTION_REG

movlw B’10001000’ ; TMR0 w/no prescaler

movwf OPTION_REG

clrf TRISD

clrf TRISC

movlw B’00001110’ ; Left justify, 1 analog channel

movwf ADCON1 ; VDD and VSS references

BANKSEL PORTD

Main movlw .236 ; 256-20=236

movwf TMR0 ; Timer 0 flag will go off after 20 cycles

bcf INTCON,T0IF

Loop btfss INTCON,T0IF

goto Loop

bsf ADCON0,GO

Wait btfss PIR1,ADIF

goto Wait

movf ADRESH,W

movwf PotRead

swapf PotRead,F

movlw 0x0F

andwf PotRead,F

movf PotRead,W

EE25M 25th April 2002 C36

call 7seg

movwf PORTC

bcf STATUS,C

rrf PotRead,W

call mbar

movwf PORTD

goto Loop

; table lists 7 seg pins as dp, g, f, e, d, c, b, a

7seg andlw 0x0F

addwf PCL,F

retlw B’00111111’ ; 0

retlw B’00000110’ ; 1

retlw B’01011011’ ; 2

retlw B’01001111’ ; 3

retlw B’01100110’ ; 4

retlw B’01101101’ ; 5

retlw B’01111101’ ; 6

retlw B’00000111’ ; 7

retlw B’01111111’ ; 8

retlw B’01100111’ ; 9

retlw B’01011111’ ; a

retlw B’01111100’ ; b

retlw B’01011000’ ; c

retlw B’01011110’ ; d

retlw B’01111011’ ; e

retlw B’01110001’ ; f

mbar andlw 0x07

addwf PCL,F

retlw B’00000001’ ; 0

retlw B’00000011’ ; 1

retlw B’00000111’ ; 2

retlw B’00001111’ ; 3

retlw B’00011111’ ; 4

retlw B’00111111’ ; 5

retlw B’01111111’ ; 6

retlw B’11111111’ ; 7

END

EE25M 25th April 2002 C37

Lab Exercise II – PWM frequency choice: For convenience with the ADRESH value between 0 and 255,choose PR2 so that 255 equals 100% duty cycle ( i.e. PR2=254) and move ADRESH directly into CCP1RLwithout modification.CCP1CON<5:4> will be 002.With a 4 MHz clock, valid prescaler values for Timer2 include 1:1, 1:4, 1:16, corresponding to PWMperiods (frequencies) of 255µs (3.92kHz), 1020µs (980Hz), 4080µs (245Hz).

When sampling two A/D channels, care must be taken to ensure that the input settles before sam-pling. With a full Timer 0 overflow (256µs)this should be ok.

LIST p=16f877

INCLUDE "p16f877.inc"

PotRead EQU 0x20

Intensity EQU 0x21

w_temp EQU 0x22

status_temp EQU 0x23

ORG 0x00

nop ; for ICD

goto Init

ORG 0x04

goto ISR

Init bcf INTCON, GIE

btfsc INTCON,GIE

goto Init

BANKSEL PORTD

clrf PORTD

clrf PORTC

movlw B’01000001’ ;

movwf ADCON0 ; Fosc/8, A/D enabled, Sample Channel 0

BANKSEL PIE1

bsf PIE1,ADIE

movlw B’10001000’ ; TMR0 w/no prescaler

movwf OPTION_REG

bsf INTCON,T0IE

clrf TRISD

bcf TRISC,2 ; setup pin for PWM output

movlw B’00000100’ ; Left justify, 3 analog channels

movwf ADCON1 ; VDD and VSS references

movlw .254

movwf PR2 ; setup PWM frequency

BANKSEL PORTD

EE25M 25th April 2002 C38

clrf CCP1RL

clrf CCP1CON

movlw B’00000100’

movwf T2CON

movlw B’00001100’

movwf CCP1CON

clrf Intensity

clrf PotRead

bsf OPTION_REG, PEIE

bsf OPTION_REG, GIE

Loop movf Intensity,W

movwf CCP1RL

movf PotRead,W

movwf PORTD

goto Loop

ISR

movwf w_temp

movf STATUS,W

movwf status_temp

Poll btfsc INTCON,T0IF ; presume we are in Bank 0

call AD_Start

btfsc PIR1, ADIF

call AD_Done

movf status_temp,W

movwf STATUS

swapf w_temp,F

swapf w_temp,W

retfie

AD_Start

bsf ADCON0,GO

bcf INTCON,T0IF

return

AD_Done

movf ADRESH,W

btfsc ADCON0,CHS0 ; if channel 1 put it in Intensity

movwf Intensity

btfss ADCON0,CHS0 ; if channel 0 put it in PotRead

movwf PotRead

bcf PIR1,ADIF

return

END

EE25M 25th April 2002 C39

page IV 10

1. Many CPU’s provide logic for performing arithmetic on packed decimal numbers. Althoughthe rules for decimal arithmetic are similar to those for binary operations, the decimal resultsmay require some corrections to the individual digits if binary logic is used. Consider thedecimal addition of two unsigned numbers. If each number consists of N digits, then thereare 4N bits in each number. The two numbers are to be added using a binary adder. Suggesta simple rule for correcting the result.Add 6 to each nibble of the addition result. If the nibble overflows into the next nibble, thenit was not a valid BCD nibble previously, and it is now correct. The next nibble up should beincremented. If the nibble did not overflow into the next nibble, then it was valid, and should berestored.

Perform addition in this fashion on the numbers 1698 and 1786. [Sta00, 9.1]The decimal numbers 169810 and 178610 are represented as the packed BCD hex numbers: 169816and 178616. Standard binary addition will yield the result 2E1E16. Starting with the leastsignificant nibble, add 6 to each nibble, test for overflow, and reverse if not. 2E1E16 +000616 =2E2416 – overflow so is ok2E2416 + 006016 = 2E8416 – no overflow so undo2E2416 + 060016 = 342416 – overflow so is ok342416 + 600016 = 942416 – no overflow so undoFinal answer is 342410.

2. The tens complement of the decimal number X is defined to be 10N − X, where N is thenumber of digits in the number. Describe the use of tens complement representation toperform decimal subtraction.To perform decimal subtraction, take the ten’s complement of the subtrahend (number below)and add it to the minuend(number above).

Illustrate the procedure by subtracting (0326)10 from (0736)10. [Sta00, 9.2]073610 − 032610 = 073610 + (104 − 032610) = 073610 + 9674(10) = 1041010Uppermost digit will not fit in the 4 digit result. Remaining digits give the correct answer.

What purpose does ten’s complement arithmetic serve in BCD arithmetic?BCD represents individual decimal digits separately. BCD subtraction can therefore be done byusing the BCD ten’s complement of the subtrahend and adding it to the BCD minuend usingstandard BCD addition.

3. BCD is not the only means of representing decimal numbers. The ASCII character setdefines a representation of characters as 7 bit numbers. The digit characters 0 through 9 arerepresented as 011 0000 thru 011 1001. Using this information write routines to correctlyadd and subtract two ASCII digits. (Note: The carry flag should be set for overflow, or noborrow respectively)

Ascii_add movf A,W ; perform A+B where A and B

addwf B,W ; are ASCII encoded digits

andlw 0x0F ; clear the upper bits

iorlw 0x30 ; set the upper bits

bcf STATUS,C ; set the CARRY flag if the

btfsc STATUS,DC ; add generated a digit carry

bsf STATUS,C

bcf STATUS,DC

return

EE25M 25th April 2002 C40

page IV 12

1. Show how the following floating point calculations are performed (where significands aretruncated to 4 decimal digits) [Sta00, 8.25–8.27]

(a) 0.5566× 103 + 0.7777× 103

(0.5566 + 0.7777)× 103 = 1.3343× 103 = 0.1334× 102

(b) 0.3344× 102 + 0.8877× 10−1

(0.3344 + 0.8877× 10−1−2=−3)× 102 = 0.3352× 102

(c) 0.7744× 10−2 − 0.6666× 10−2

(0.7744− 0.6666)× 10−2 = 0.1078× 10−2

(d) 0.8844× 10−2 − 0.2233× 100

(0.8844− 0.2233× 100−(−2)=2 × 10−2 = −21.4467× 10−2 = −0.2145× 100

(e) (0.2255× 102)× (0.1234× 101)(0.2255× 0.1234)× 102+1=3 = 0.02782× 103 = 0.2782× 102

(f) (0.8833× 103)÷ (0.5555× 105)(0.8833÷ 0.5555)× 103−5=−2 = 1.5901× 10−2 = 0.1590× 10−1

2. Any floating point representation used in a computer can represent only certain real numbersexactly; all others must be approximated. If A’ is the stored value approximating the realvalue A then the relative error r is expressed as: r = A−A′

A.[Sta00, 8.21–8.24]

(a) Represent the decimal quantity +0.4 in the following floating point format: base = 2;exponent: biased 4 bits; significand 7 bits.This is a recurring decimal in base 2: 0.410 = 0.011001100110....2Truncating we get: 0.110011002 × 21

In floating point format, the sign bit is 0, the significand is 1001100 and the biased exponentis 1001 (presumed that the bias is 7 for the 4 bit exponent).What is the relative error?The stored truncated value is equivalent to 0.398437510. The relative error is therefore:0.0039062510 or approximately 0.4%.

(b) If A = 1.427, find the relative error if A is truncated to 1.42 and if it is rounded to 1.43.For truncation: 0.49% For rounding: -0.21%

(c) Numerical values A and B are stored in the computer as approximations A′ and B′.Neglecting any further truncation or roundoff errors, show that the relative error of theproduct is approximately the sum of the relative errors in the factors.Rearranging the equation we get: A′ = A(1 − r). Therefore the product A′B′ = AB(1 −rA)(1 − rB) = AB(1 − (rA + rB − rArB)) If the relative errors were small (i.e. much lessthan 1), the product term is negligible and rAB ≈ rA + rB

(d) One of the most serious errors in computer calculations occurs when two nearly equalnumbers are subtracted. Consider A = 0.22288 and B = 0.2221. The computer trun-cates all values to four decimal digits. Thus A′ = 0.2228 and B′ = 0.2221.

i. What are the relative errors for A′ and B′? rA = 0.036%,rB = 0%

ii. What is the relative error for C ′ = A′ −B′? C = 0.00078, C ′ = 0.0007, rC = 10%

EE25M 25th April 2002 C41

3. Typically floating point numbers are represented using a minimum of 32 bits.

The IEEE standard 754 standard defines a ”single” format 32 bit floating point number as asign bit followed by an 8 bit biased exponent, followed by a 23 bit significand (representingthe normalised 24 bit binary fraction 0.1xxx xxxx xxxx xxxx xxxx xxxx).

Floating point numbers in the CCS compiler for the PIC16F877, place a biased 8 bit exponentfirst, followed by the sign bit and then a 23 bit significand (representing the normalised 24bit binary fraction 0.1xxx xxxx xxxx xxxx xxxx xxxx).

The difference is in the location of the sign bit. Suggest possible advantages/disadvantagesof placing the sign bit in either position.If the sign bit is at the beginning, then floating point numbers can easily be tested for relativemagnitude, by considering the front bits for sign and biased exponent as a two’s complementinteger. Sorting by these bits will group numbers of similar value.If the sign bit is placed after the exponent, then the initial byte, can easily be extracted for use inexponent manipulation.

page IV 13

1. (a) For the following data structures, draw the big-endian and little-endian layouts, using the formatof Figure 9.18 (see handout) and comment on the results. [Sta00, 9.17]

i. struct {

double i; // 0x1112131415161718

} s1;00 01 02 03 04 05 06 07

Big 11 12 13 14 15 16 17 18Little 18 17 16 15 14 13 12 11

ii. struct {

int i; // 0x11121314

int j; // 0x15161718

} s2;00 01 02 03 04 05 06 07

Big 11 12 13 14 15 16 17 18Little 14 13 12 11 18 17 16 15

iii. struct {

short i; // 0x1112

short j; // 0x1314

short k; // 0x1516

short l; // 0x1718

} s3;00 01 02 03 04 05 06 07

Big 11 12 13 14 15 16 17 18Little 12 11 14 13 16 15 18 17

In Big-endian layout, all the data structures appear identical, however in the little endian layoutthe data order depends on the type of data being stored.

EE25M 25th April 2002 C42

(b) Based on the above, write a small C program which determines the endianness of a machine andreports the results. [Sta00, 9.19]

#include <stdio.h>

void main()

{

int i; // i is a 32 bit integer

BYTE *b; // b is a single byte pointer

i=1;

b=&i;

// now test to see which of the four bytes is non-zero,

// and which end of the byte the

// bit is set at ...

if ((b[0]==0x00) && (b[3]!=0x00))

{

if (b[3]==0x01)

printf("Big endian, LSB at bit 0");

else if (b[3]==0x80)

printf("Big endian, LSB at bit 7");

else

printf("Big endian");

}

else if ((b[0]!=0x00) &&(b[3]==0x00))

{

if (b[0]==0x01)

printf("Little endian, LSB at bit 0");

else if (b[0]==0x80)

printf("Little endian, LSB at bit 7");

else

printf("Little endian");

}

else

{

printf("Something went wrong in the test ....");

}

}

EE25M 25th April 2002 C43

page IV 16

1. The notes contain example code for a lookup table using the DT directive, which presumesthat there was no need to switch banks within the table. Write similar code which will operatecorrectly even when the table spans a program bank boundary.The following code is from PIC Microcontroller Pocket Reference by M. Predko. HIGH and LOWare assembler directives which will return the high and low bytes of the following program address.The code operates by determining if the value we want to lookup is in this bank, or the nextbank.

Table ; return table value of contents of "w"

movwf Temp ; save the table index

movlw HIGH TableEntries ; get the current 256 instruction block

movwf PCLATH ; store it so that the next jump is correct

movf Temp,w

addlw LOW TableEntries

btfsc STATUS,C

incf PCLATH,F ; if our entry is in the next bank, increment PCLATH

movwf PCL ; writes the correct address to the Program counter

TableEntries

DT "Table",0 ; now declare data as normal.

2. Write a program containing a lookup table for multiplication by 7 in the data EEPROM. Thelookup table should be accessed with a subroutine called mul7 which will take the value inthe working register as it’s argument, and return the answer in the working register. Assumethat mul7 is only called with inputs from 0 to 15.

; note that this routine changes bank .. the main code should be careful!!

mul7 addlw 0x60 ; find offset from table start

BANKSEL EEADR

movwf EEADR

BANKSEL EECON1

bcf EECON1, EEPGD ;Point to Data memory

bsf EECON1, RD ;Start read operation

BANKSEL EEDATA

movf EEDATA, W ;W = EEDATA

return

ORG 2160 ; Table starts at data EEPROM location 0x60

DE .0,.7,.14,.21,.28,.35,.42,.49,.56,.63,.70,.77,.84,.91,.98,.105

3. (a) It is possible to store a data structure which is either wider or narrower than the dataword size, by simply storing the bits of the data structure consecutively. What are theimplications for retrieving data from memory?Where a data structure consists of multiple parts which need to be accessed individually,storing the structure in consecutive bits, may mean that multiple data-words have to beretrieved, and artificially ”joined” in order to access the part.

EE25M 25th April 2002 C44

(b) Boundary alignment is the practice of starting new blocks of data in a new data-wordblock, regardless of the space remaining in the previous data-word block. What possibleadvantage does such a scheme offer?The advantage is that a new part will always start at the beginnning of a dataword andfetching the part will require a mininal number of datawords.

(c) A particular data structure contains an 10 bit unsigned integer, two 7 bit characters,and two status flags. Write some sample code for the PIC which retrieves the specified26-bit data structure from the program memory, and stores it in 5 registers using:The variables are presumed to be stored in Int hi, Int lo, char a, char b, and Flags a, Flags b.To retrieve a dataword from the program memory we use the following procedures:

GetPWord BANKSEL ADDRL

movf ADDRL, W ;Write the

BANKSEL EEADR

movwf EEADR ;address bytes

BANKSEL ADDRH

movf ADDRH,W ;for the desired

BANKSEL EEADRH

movwf EEADRH ;address to read

BANKSEL EECON1

bsf EECON1, EEPGD ;Point to Program memory

bsf EECON1, RD ;Start read operation

nop ;Required two NOPs

nop ;

BANKSEL EEDATA

movf EEDATA, W ;DATAL = EEDATA

BANKSEL DATAL

movwf DATAL

BANKSEL EEDATH

movf EEDATH,W ;DATAH = EEDATH

BANKSEL DATAH

movwf DATAH

return

GetNextPWord ; note this does not check for bad increments/addresses

incf ADDRL,F

btfsc STATUS,Z

incf ADDRH,F

call GetPWord

return

EE25M 25th April 2002 C45

i. packing with boundary alignment (i.e. 2 data words per structure)In this case, the entire structure has been aligned to the dataword boundary. In thiscase we just need two datawords, and we need to extract the relevant bits.

13 12 11 10 9 8 7 6 5 4 3 2 1 0 13 12 11 10 9 8 7 6 5 4 3 2 1 0

address address+1

int char char flag flag N/U

Inthi < 1 : 0 >,Intlo < 7 : 0 > Chara < 6 : 0 > Charb < 6 : 0 > Flaga < 0 > Flagb < 0 >

; presume that the starting address was already loaded into ADDRL, ADDRH

call GetPWord

swapf DATAH,W

andlw 0x0F

movwf Int_hi

swapf DATAH,W

andlw 0xF0

movwf Int_lo

swapf DATAL,W

andlw 0x0F

iorwf Int_lo,F

swapf DATAL,W

andlw 0xF0

movwf Char_a

bcf STATUS,C

rrf Char_a

call GetNextPWord

movf DATAH,W

movwf tmp

rlf tmp,F

swapf tmp,W

andlw B’00000111’

iorwf Char_a,F

movf DATAH,W

movwf tmp

swapf tmp,W

andlw B’01110000’

movwf Char_b

swapf DATAL,W

andlw 0x0F

iorwf Char_b,F

clrf Flag_a

btfsc DATAL,3

bsf Flag_a,0

clrf Flag_b

btfsc DATAL,2

bsf Flag_b,0

return

EE25M 25th April 2002 C46

ii. packing with no boundary alignment (i.e. overlapping datawords)In this case because neither the structure nor the data is boundary aligned, then thedata is packed in consecutive bits. We cannot use the same extraction code for eachstructure. The structure is 26 bits wide, and the data word size is 14 bits. The spare twobits will make a complete structure after 13 iterations. Therefore, the pattern will repeatitself every 14 structures. We could write code to extract a block of 14 structures, or wecould use a buffer and shift data in and out, if we know which bit the structure starts at.

13 12 11 10 9 8 7 6 5 4 3 2 1 0 13 12 11 10 9 8 7 6 5 4 3 2 1 0

address address+1

int char char flag flag int(uppermost)

Inthi < 1 : 0 >,Intlo < 7 : 0 > Chara < 6 : 0 > Charb < 6 : 0 > Fa Fb Inthi < 1 : 0 >

address+2 address+3

int char char flag flag int(uppermost)

Intlo < 7 : 0 > Chara < 6 : 0 > Charb < 6 : 0 > Fa Fb Inthi < 1 : 0 >,Intlo < 7 : 6 >

address+4 address+5

int char char flag flag int(uppermost)

Intlo < 5 : 0 > Chara < 6 : 0 > Charb < 6 : 0 > Fa Fb Inthi < 1 : 0 >, Intlo < 7 : 4 >

; presume structure starts n bits from the MSB in ADDRH,ADDRL dataword

; with an end of buffer pointer b

call InitBuff ; do GetPWord, and shift until data bit n is first

clrf Int_lo

clrf Int_hi

movlw .10

movwf cnt

Fill_int

call GetBuffBit ; shift uppermost bit into the CARRY -- refill using GetNextPWord

rlf Int_lo,F

rlf Int_hi,F

decfsz cnt,F

goto Fill_int

clrf Char_a

movlw .7

movwf cnt

Fill_ca

call GetBuffBit

rlf Char_a,F

decfsz cnt,F

goto Fill_ca

clrf Char_b

movlw .7

movwf cnt

Fill_cb

call GetBuffBit

rlf Char_b,F

decfsz cnt,F

goto Fill_cb

clrf Flag_a

call GetBuffBit

rlf Flag_a,F

clrf Flag_b

call GetBuffBit

EE25M 25th April 2002 C47

rlf Flag_b,F

return

InitBuff

call GetPWord

movlw .16

movwf b ; initialise end of buffer

call ShiftBuff ; get rid of two blanks

call ShiftBuff

movf n,F

tst btfsc STATUS,Z

return

call ShiftBuff

decf n,F

goto tst

GetBuffBit

ShiftBuff

movf b,F

btfsc STATUS,Z

call RefillBuff

bcf STATUS,C

rlf DATAL

rlf DATAH

decf b,F

return

RefillBuff

call GetNextPWord

movlw .16

movlw b

call ShiftBuff

call ShiftBuff

return

EE25M 25th April 2002 C48

iii. individual program words for each structure element (i.e. 5 data words per structure)This is relatively simple, each element is retrieved, one at a time; if necessary, bit maskingcould be used to ensure that invalid bits were not set.

call GetPWord

movf DATAH,W

movwf Int_hi

movf DATAL,W

movwf Int_lo

call GetNextPWord

movf DATAL,W

movwf Char_a

call GetNextPWord

movf DATAL,W

movwf Char_b

call GetNextPWord

movf DATAL,W

movwf Flag_a

call GetNextPWord

movf DATAL,W

movwf Flag_b

return

From the preceding examples (i)-(iii) we can see that boundary alignment reduces the ex-traction code, but makes memory usage less efficient. One compromise as in (i) is to alignthe structure instead of individual elements.

page V6

1. The MPASM assembler has the BANKSEL preprocessor directive, which switches banks tothe bank of the specified register. Write code to configure PortB for all inputs using theBANKSEL directive.

BANKSEL TRISB

movlw .255

movwf TRISB ; set for all inputs

BANKSEL PORTB

movf PORTB,W ; now we can read in data

EE25M 25th April 2002 C49

2. Write an assembly language routine which will

• initialize PORTB<5> as an input, and PORTB<4> as an output.

• within a loop: read PORTB<5> and set PORTB<4> to the value read.

BANKSEL TRISB

movlw B’11101111’

movwf TRISB ; set for all inputs except <4>

BANKSEL PORTB

Loop btfss PORTB,5

bcf PORTB,4 ; clear <4> if not <5>

btfsc PORTB,5

bsf PORTB,4 ; set <4> if <5>

goto Loop

page V12

1. For the example on page V 8, calculate the percentage error caused by the neglected overhead,and the extra cycle on return for delays of 1 ms, 100 ms and 255 ms.The overhead on this routine is

Load value into W 1 cycle

Call the subroutine 2 cycles

Store W 1 cycle

Return 1 extra cycle

An error of 5µs is incurred on each call of this routine. The percentage errors will be: 0.5%,0.005% and 0.002% respectively.

2. For the example on page V11, the code timed 250 cycles, with the prescaler set to 128. Fora 4MHz clock, what is the delay in ms?Clock tick: 0.25µsInstruction tick: 1µsPre-scaler tick: 128µsDelay: 250 ∗ 128 = 32000µs = 32ms

EE25M 25th April 2002 C52

page V16

1. In a typical ISR, part of the initialization saves the W and STATUS registers, however thisassumes that the main code that will be interrupted will never be in Bank 1 at the time ofthe interrupt. If the ISR ever switches banks then the values of W and STATUS that arerestored would be incorrect27. In processors where the Bank 0 addresses are different fromthe Bank 1 addresses several things can be done to relax this assumption.

(a) Interrupts can be disabled before switching to Bank 1 and re-enabled after switchingback to Bank 0.

(b) Use two addresses, one in each bank, to hold the temporary value of W, i.e. W_TEMP. Forexample,

W_TEMP equ 0x20 W_TEMP_ equ 0xA0

Now when W is stored in W_TEMP using direct addressing at the beginning of the ISR itwill go in either of two locations: 0x20 or 0xA0, depending on which bank is active atthe moment the interrupt occurs.

i. Rewrite the initialization of the ISR that saves W and STATUS in this case, switch-ing to Bank 0 for the duration of the ISR. There would be need only for one locationfor STATUS_TEMP defined in Bank 0.

movwf W_TEMP

movf STATUS,W

bcf STATUS,RP0; switch to bank zero

bcf STATUS,RP1

movwf STATUS_TEMP

ii. Rewrite the ending of the ISR to restore the STATUS and W.

bcf STATUS,RP0

bcf STATUS,RP1; back to bank zero

movf STATUS_TEMP,W

movwf STATUS ; back to original bank so w restore ok

swapf W_TEMP,F

swapf W_TEMP,W

2. (a) What is the reason of having the interrupt sources in a particular order?For priority servicing.

(b) When the ISR is entered in response to one specific interrupt, is it possible that adifferent source might be serviced first? Discuss your answer.Yes. If a higher priority interrupt occurs after the ISR has been entered, but before the higherpriority flag has been polled/re-polled, it will be serviced before the original interrupt source.

(c) If while one interrupt source is being serviced, a second interrupt source requests service,will the second source be serviced before the retfie instruction at the end of the ISR?Discuss your answer.Possibly. This depends on the ISR structure. If the ”call” structure is used, the ISR will exit,and then re-enter to service the later interrupt. If the ”goto” structure is used, the secondsource will be service before exit.

27In the PIC16F8x, Bank 1’s General purpose registers are mapped to Bank 0, so that this argument does not hold

EE25M 25th April 2002 C62

page V 32

1. List features of simulators, and debuggers using MPLAB as an example.Simulator:Debugger:What are some of the disadvantages of using simulators to develop application code?a) Instruction level simulation, cannot handle events occurring between instructions in the sameway as the hardware would. This may lead to different results on the simulator and hardware.b) Microprocessor assembly programming is highly dependent on the connected hardware, and theresultant currents/voltages cannot be simulated, except as binary 1/0’s. This may be inadequate.(e.g. An output pin is loaded so that it’s voltage drops sufficiently that it cannot trigger theinput Schmidt trigger. The program may be written to ignore this effect, if it is observed prior toloading on the hardware.)

2. One useful feature of the PIC16F877 microcontroller is the fact that it can report whatcondition caused it to re-start: Power-on, Brown-out, Watchdog timer reset or Physical reset(MCLR pin). Are these features supported in the simulator? Yes.Can the simulator be used to generate each of these conditions, in order to test any associatedcode? Yes.For details of the actual menu options/buttons, refer to the MPLAB SIM/IDE manual.

EE25M 25th April 2002 C63

page VI9

1. Consider a PIC application that has four interrupt sources, with T1 =10 cycles, T2 =20 cycles,T3 =40 cycles and, T4 =80 cycles

(a) Using the inequality

T1 + T2 + · · ·+ Tn +On ≤ worst case time < T1 + T2 + · · ·+ Tn + 2On, (3)

determine the worst-case response of the CPU to any of these interrupts given the pollingscheme where subroutine calls are used for each handler.

On = 12 + 8 = 20 T1 + T2 + t3 + T4 = 150 170 ≤ worst case time < 190

(b) What does this mean for the minimum period between any of these interrupts? Ifinterrupts arrive more frequently than the period dictated by the worst case execution time,the priority ordering of the interrupts will not be correct, and a new interrupt may arrivebefore the previous one has been serviced.

2. Consider the timing diagrams from Figures (8), (9) and (10) in the notes titled Input/Output.

(a) Why does the worst-case time for source 1 begin at the end of the time labeled P1 insteadat the time before this when the CPU actually stops execution of the main program?In the worst case, the interrupt for source 1 arrives just after it has been polled for in an ISRtriggered by another source.

(b) Why does the worst-case time for source 2 begin at the end of the time labeled P2 insteadat the time before this when the CPU actually stops execution of the main program?In the worst case, the interrupt for source 2 arrives just after it has been polled for in an ISRtriggered by source 3 and on re-poll source 1 is serviced first.

(c) Why does the worst-case time for source 3, the lowest priority interrupt, begin when theCPU actually stops execution of the main program rather at the end of P3 or P1?In the worst case, source 3 triggers the ISR, and then services the other sources first.

3. Using the new polling structure for ISRs i.e. using goto for the handlers instead of call, con-sider an application with four interrupt sources having times exactly like those in Problem 1and priority T1, T2, T3, and T4.

Draw the worst-case timing diagram for the response of the CPU to interrupts from source 1.Worst case timing is from just after the poll (P1) through the execution of the longest otherhandler (T4) i.e. Tw1 = O4 + (2× 4− 1 + T4) + (2× 1− 1 + T1)− P1

Also determine the time TP1, the minimum time between source 1 interrupts such that theCPU will assuredly execute source 1’s handler and be ready to handle another source 1interrupt.This is the same as the worst case timing except we do not need to exit the routine, so the returnand the remaining polls are removed from the overhead, i.e. TP1 = Tw1 − 6− (2× 3)

Repeat this exercise for source 3.For source 3, worst case is when it is just missed on a source 4, and then sources 1 and 2 are bothserviced. i.e. Tw3 = O4+(2×4−1+T4)+(2×3−1)+T1+T2+T3−P3 TP1 = Tw3−6−(2×1)

EE25M 25th April 2002 C64

4. When an interrupt occurs, the global interrupt enable bit, GIE, is automatically cleared bythe CPU. Sometimes it is necessary to disable interrupts for a short time in the main programin order to execute a short sequence that can give an incorrect result if interrupted and thenre-enable the interrupt after the sequence.

A problem could arise if the instruction to disable the interrupts is being executed at theexact moment that an interrupt occurs. Describe the effect if the instruction to disable theinterrupts is indeed executed, but the interrupt is acknowledged and handled by the CPUbefore the program instruction is able to take effect.If the interrupt occurs when the instruction to disable interrupts is being fetched, the interrupthandler will be activated, just after the GIE bit has been cleared by the instruction. On leaving theinterrupt handler, the system will set the GIE bit (automatic). The main program will thereforeproceed as though the GIE bit had never been cleared.

EE25M 25th April 2002 C65

page VI 15

1. Using the code developed for the Rotary Pulse Generator, modify it to increment a 2-bytevariable, Amplitude if the RPG has been rotated CW and to decrement it if the rotation isCCW. Do not increment past 65,535 or decrement past zero.

2. Modify the solution to Problem (1) to change the variable Amplitude by one-eighth of itsvalue or by one count, whichever is larger when fast turning of the RPG is detected.

Using the same interrupt structure, we can simply write the subroutines decrease voltage smalletc...

decrease_voltage_small

movf Amplitude_lo,F

btfss STATUS,Z ; check if lo byte is zero

goto dvsok

movf Amplitude_hi,F

btfsc STATUS,Z

return ; both bytes zero then leave

decf Amplitude_hi,F

dvsok decf Amplitude_lo,F

return

increase_voltage_small

incf Amplitude_lo,F

btfss STATUS,Z

return ; increment didn’t overflow low byte

incf Amplitude_hi,F

btfss STATUS,Z

return ; increment didn’t overflow upper byte

max_out movlw 0xFF

movwf Amplitude_hi

movwf Amplitude_lo

return

decrease_voltage_large

call find_eighth

; do 16 bit subtraction -- if overflow set to 0

movf Temp_lo,W

subwf Amplitude_lo,F

movf STATUS,W

movwf LoSubFlags

movf Temp_hi,W

subwf Amplitude_hi,W

btfss LoSubFlags,C

addlw 0xFF

movwf Amplitude_hi

btfsc STATUS,C

return

zero clrf Amplitude_hi

clrf Amplitude_lo

return

EE25M 25th April 2002 C66

increase_voltage_large

call find_eighth

; do 16 bit addition -- if overflow set to max.

movf Temp_lo,W

addwf Amplitude_lo,F

movf Temp_hi,W

btfsc STATUS,C

incf Amplitude_hi,F

addwf Amplitude_hi

btfsc STATUS,C

goto max_out

return

find_eighth

; find one-eighth of value and place in the variable Eighth

; minimum value should be 1.

movf Amplitude_lo,W

movwf Eighth_lo

movf Amplitude_hi,W

movwf Eighth_hi

bcf STATUS,C

rrf Eighth_hi

rrf Eighth_lo

movf Eighth_lo,F

btfss STATUS,Z

return

movf Eighth_hi,F

btfsc STATUS,Z

incf Eighth_lo,F

return

EE25M 25th April 2002 C67

page VI 18

1. The code presented should produce a 16-bit estimate for the switching frequency of the signalconnected to Timer0. Comment on the accuracy of this measurement. Hints: Check theminimum duration change detected on the Timer0 input, and the ISR execution time.We make the following observations:

• The latency between the external interrupt, and the clearing of TMR0 at the beginningof measurement is 3-4 cycles (response time) + 10 cycles (counting instructions) + saveoverhead.

• The latency between the external interrupt, and the storage of TMR0 is 3-4 cycles (responsetime) + 11 cycles (counting instructions) + save overhead.

• In the worst case, if INTF arrives while T0IF is being serviced, there will be an additional 10cycles while T0IF is serviced.

• If INTF arrives during register restore, the time will be the total overhead plus the ISR re-turn/call overhead.

It follows that the accuracy of the timebase for the frequency estimate will be off by 1cycle at best, and up to twice 10 (or overhead if larger)+1 cycles at worst.

• The transition count may have overflowed, just prior to the timebase interrrupt, in whichcase Ncycles will be unincremented even though the count in TMR0 has rest to a smallervalue. This will lead to an occasional error in the transition count of 255*prescale.

• Transitions must occur with at least 2 T OSC between them. Therefore frequencies morethan 2MHZ cannot be measured.

• In two registers, we can express frequencies up to 131072 (using carry) Hz with a resolutionof 1 Hz.

• When sampling, there is always the problem of starting late in the cycle, and not getting alltransitions for another point. This adds inaccuracy of ±1 transition.