CSE466 Assignment 1: Due Monday 10/2

This assignment is a little longer than a typical 3-pointer, so it will be worth 5-points and it is due on Monday 10/2

A. Describe a strategy, using the hardware resources of the 8051, to measure the fan speed and detect errors as in the introductory example. Hint: consider the use of timers and interrupts, see the AT89 Series Hardware Description for ideas. 

Answer. I forgot to list it here, but the example presented in class had a clock speed of 4Mhz. At that oscillator speed the maximum count on timer zero at a 30Hz fan speed is (4M/12)/30 = ~11K. Setup timer-2 in capture mode and enable T2EX interrupts so that the timer will stop on the falling edge of T2EX. After we read the timer value in the external interrupt routine, we clear and restart the timer. 

B. What factors might affect with the accuracy of your measurement?

As long as no interrupts are missed due to processor occupation with other tasks, the solution is accurate to a single machine cycle. 

C. Write the 8051 assembly program including reset code, interrupt routine(s), hardware initialization and main execution loop to implement to perform fan speed measurement and verification. I don't mean for you to worry too much about syntax for 8051 assembly programs.

In my version, I went ahead and added the code to check for the case that the fan is moving too slow. There are at least three ways that this code can fail in real operation. Identify at least two of these failure modes and make any changes or additions necessary to catch them. Note: I am not looking for bugs in my code, If I made an obvious programming error, please fix it, but it won't count against the two items!

NAME HW1

maxH equ  2BH;  maximum period at 30Hz is 11K
maxL equ  67H;

PROG SEGMENT CODE
VAR1 SEGMENT DATA
BITVAR SEGMENT BIT
STACK SEGMENT IDATA
RSEG  BITVAR     ; relocatable segment
first: DBIT  1           ; single bit variables

RSEG VAR1
periodH:  DS  1
periodL:  DS  1
thenL:     DS 1
thenH:    DS 1

RSEG  STACK  ; relocatable segment

DS    10H  ; 16 Bytes
CSEG  AT   0 ; absolute segment        
JMP   START  ; Execution starts here on reset.

CSEG AT 2BH  ; location for EX2 interrupt
PUSH  ACC;
PUSH  PSW;
PUSH  R3;
JMP    MYT2;

RSEG  PROG
MYT2:
CLR C;
MOV  A,RCAP2L ; get low byte
MOV  R3,A           ; save for later
SUBB thenL        ; subtract "then" low byte
MOV  thenL,R3  ; save now as then
MOV  periodL,A     ; store difference in low byte  
MOV  A,RCAP2H; get high byte
MOV  R3,A       ; save for later    
SUBB A, thenH   ; subtract high byte
MOV  thenH,R3  ; save now as then
MOV  periodH,A ; store high byte difference
MOV  T2CON, #0D;  clear the interrupt flags
POP   R3;
POP   PSW;
POP   ACC;
RTI

 

RSEG  PROG      ; relocatable segment

START:
MOV  SP,#STACK-1 ; first set Stack Pointer
MOV  PSW,#00  ; use register bank 0
MOV  T2CON, #0D;    setup timer 2 for internal clock, capture, external interrupt
MOV  IE, #C0        ;     enable global interrupts and T2EX interrupt
MOV  periodH,#00;
MOV  periodL,#00;
LOOP:
MOV  A,periodH;
CLR    C;
SUBB A,#maxH;
JC       OKAY;   maxH is greater than periodH so no error
JNZ    ERR;        maxH is less than periodH so error  
; maxH equals periodH so check the low byte
MOV  A,periodL;
CLR   C;
SUBB A,#maxL
JC      OKAY;   maxL is greater than periodL so okay
JZ       OKAY;  maxL is equal to periodL so okay
ERR: SET   P1.1    ; set error bit
JMP  LOOP;
OKAY: CLR P1.1
JMP LOOP