Embedded Multi-Function Timer with 8051 Microcontroller

Duration: Jul-Aug 2016. With: Prof. Taikang Ning, Trinity College, CT.

Summary

  • Designed, implemented and tested a multi-function timer after studying 8051 embedded systems.
  • 8051 Microcontroller Embedded Multi-Function Timer
  • Applied knowledge learned to implement a power amplifier to run earphone jack signals on a 20W speaker.

Results Demo

Circuit Design and Wire Wrapping

Code for programming 2k EEPROM link

		BaseN   EQU 30h	; set the base addr for normal display
		BaseS   EQU 34h	; set the base addr for stopwatch display
; Program initialization  
		org 0000h
		ajmp MainProg
		
		org 0003h; jump address for the ET0 interrupt
		ajmp ISRIE0; ]ump to the starting location of interrupt service routine ISRIE0
	
		org 000bh   ; jump address for timer0 overflow interrupt
		ajmp ISRTF0 ; ]ump to the starting location of interrupt service routine ISRTF0
		
		org 0030h; starting address of the main 
MainProg
		;mov TMOD, #11h ;initialize Timer0
		setb TR0 ; enable Timer0 to start counting
		setb ET0 ; enable TF0 interrupt
		setb IT0; enable IT0
		mov TH0, #0ECh
		mov TL0, #7Fh
		
		; initialize each digit in normal mode
		mov 30h, #00h 
		mov 31h, #10h
		mov 32h, #20h
		mov 33h, #30h
	
		; initialize each digit in stop-watch mode
		mov 34h, #00h 
		mov 35h, #10h
		mov 36h, #20h
		mov 37h, #30h
		
		mov 40h, #00h  ; set addr 40h for one second-count in normal mode
		mov 41h, #00h  ; set addr 41h for ten msec-count in stop watch mode 
		mov 42h, #02h  ; set addr 42h to count the times of External Interrupt
		mov 43h, #00h  ; set addr to save how many 5-msec required for per carry unit e.g. 200 for a second and 2 for ten msec
		mov 45h, #00h  ; set addr 45h to mark if we need background update
		setb EA        ; enable all interrupts
		mov SP, #60h   ; set pointer to avoid overlap
		
		; in this program Nmode means normal mode and Smode means StopWatchMode
		;set the variables for Nmode
		mov R7, #baseN   ; move the base addr of normal display to R7
		mov R0, #baseN   ; move the base addr into R0 for display
		mov 43h, #200	;number check for one sec
		mov R1,  #40h    ; move addr 40h into R1 for counting 5 msec in persec in Nmode
waitHere 
 		nop
		sjmp waitHere
		
ISRIE0 
		inc  42h; inc addr 42h to count the times of External Interrupt
		;after inc if addr 42h = 4       = reset and go back to Nmode   
				;			   = 1 3     = freeze display in baseS
				;			   = 2       = start counting in Smode
		; set the variables for Smode
		mov  R6, 42h          	 ;for the syntax of cjne in the next line of code
		cjne R6, #4h, nextStepBridge   ;distinguish which mode to go depending on the times external interrupt had happened
  								 ;if not go to nextStep
								 ;if 4 times restart
		mov R7, #baseN;reset the display base addr for Nmode
		mov R0, #baseN;move the base addr into R0 for display
		mov P1, @R0   ;move the base addr of normal display to P1 before going back to normal mode
		mov 43h, #200 ;reset to one second for normal mode
		mov R1,  #40h ; move addr 40h into R1 for counting 5 msec per second in Nmode
		ajmp nextStep		  ;return so it would go back to the normal mode after the next interrrput
		
ISRTF0	
		clr EA
		mov TH0, #0ECh   ; reset every 5 msec
		mov TL0, #80h 
		setb EA   
		mov  R6, 42h         ; for the syntax of cjne in the next line of code  
		cjne R6, #0, modeHub ; distinguish which mode to go by the times external interrupt had happened
							 ; update in Nmode if R6 equals to 0 
		ajmp carryUnit
		
modeHub	
		cjne R6, #2, Display  ; distinguish which mode to go by the times external interrupt had happened
		ajmp carryUnit		  ; update in Smode if R6 equals to 2 	

Display
		mov  R6, 45h;  for the syntax of cjne in the next line of code  
		cjne R6, #01, Display1  ; check if it is not a backgroundupdate, if it is not(R6=00), go to display1 to display						
							 ; if it is(R6=01), reset to Smode and leave
		mov  R7, #baseS      ; move the base addr of stopWatch display to R7 for furthur use
		mov  R0, #baseS      ; move the base addr into R0 for display
		mov  43h,#2          ; set the ten-msec carry unit 
		mov  R1, #41h 		 ; move addr 41h into R1 for counting 5 mesc per 10 mesec in Smode 
		mov  45h,#00h  		 ; reset 45h=0 for background update next time 
		ajmp nextStep
Display1
		mov  A, R7;            ; put R7 in a for arithmetic
		add  A, #4h;           ; add four to A
		mov  44h,A;            ; save the result of R7(the base display addr)+4 into 44h 
		mov  P1, @R0           ; display digit
		inc  R0		           ; inc R0 to point to the next digit
		mov  A, R0			   ; for the syntax of cjne in the next line of code 
		cjne A, 44h, nextStep  ; display and go to nextStep if @R0 not equal to base addr +4
							   ; in other words got to nextStep if haven't displayed all four digits
		mov  B, R7             ; this and the next line resets the value of R0 by the value of R7
		mov  R0, B			   ; if equal reset to display digit 1 agian 
		mov  R6, 42h 
		cjne R6, #0h, backGroundUpdate
		ajmp nextStep

backGroundUpdate
		mov  R7, #baseN      ; move the base addr of stopWatch display to R7 for furthur use
		mov  R0, #baseN      ; move the base addr into R0 for display
		mov  43h,#200          ; set the ten-msec carry unit 
		mov  R1, #40h 		 ; move addr 41h into R1 for counting 5 mesc per 10 mesec in Smode 
		mov  45h,#01h  		 ; when 45h=1 to say that this is background update
nextStepBridge
		ajmp nextStep

carryUnit
		inc  @R1					; inc the content of the addr R1 is pointing to(the content of 40h if Nmode and 41 if Smode) 
		
		mov  A,@R1                  ; for the syntax of cjne in the next line of code  
		cjne A,43h, Display         ; if A, count of 5 msec, doesn't reach the carry unit, go to Display
		mov  @R1, #00h				; if did reach the carry unit, reset @R1 and 
		ajmp updateDig 			    ; jump to update
		
updateDig
		mov  B, R7      ; move R7(30h if Nmode and 34h if Smode)into R0
		mov  R0, B
		
		inc  @R0		; update value              
		cjne @R0, #0Ah, Display; got to display if digit 1 is not 10 
		mov  @R0, #00h; reset digit one 
		
		inc  R0; inc R0 to the addr of digit 2
	
		inc  @R0 ; update value 
		cjne R7 , #baseS, radixSix ; go to radixSix if the if is Nmode
		cjne @R0, #1Ah, Display;got to display  if digit 2 is not 10 
		sjmp backToDig3
radixSix	
		cjne @R0, #16h, Display; got to display if digit 2 is not 6
backToDig3
		mov  @R1, #10h; reset digit 2
		
		inc  R0; inc R0 to the addr of digit 3

		inc  @R0; update the value 
		cjne @R0, #2Ah, Display; got to display  if digit 3 is not 10 
		mov  @R0, #20h; 
		
		inc  R0 ; inc R0 to the addr value of digit 4
		
		inc  @R0; update the value 
		cjne @R0, #36h, Display; got to display if digit 4 is not 6
		mov  @R0, #30h 
		ajmp nextStep
nextStep
		reti
				
		END