Upload
hoangtuyen
View
215
Download
0
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.