Lab #3 Narrative

;***************************************************************************
;  RTC_18F8722.asm
;  Real-time clock program for the 18F8722 on a PIC TRAINER REV-1.28;
;   this version uses the LCD.asm library.
;
;  CTEC1904/2016W Lab #3
;
;  Ported by Mike Boldin <mboldin@niagaracollege.ca>
;  Niagara College Canada
;  2013.03.19
;***************************************************************************
;  Uses code from the "Timer1 Module Data Sheet Errata",
;  Document# DS80329B, (c) 2010 Microchip Technology Inc.
;
;***************************************************************************
;  Uses code from the "PIC18F8722 Family Data Sheet",
;  Document #DS39646C, (c) 2008 Microchip Technology Inc.
;
;***************************************************************************
;  Portions originally written by Professor Mark Csele 2006/09
;  as LCD Test program for the 18F452 on a PICPROTO-II (up to 20MHz)
;***************************************************************************
;  Hardware:
;  --------
;  PIC18F8722 MCU
;  CLK = 4.9196 MHz (f_osc)
;  T1CLK = 32.768 kHz (TMR1 osc)
;  RH0-7 - LCD Data Lines (to D0-D7)
;  RE2   - LCD R/W Line
;  RE1   - LCD Enable Line
;  RE0   - LCD RS (register select) Line
;***************************************************************************

	cblock	0x000
	Hours	; current hour: 0-23
	Mins	; current minute: 0-59
	Secs	; current second: 0-59
	DM10Q	; DM10 subroutine return register (WREG / 10)
	DM10R	; DM10 subroutine return register (WREG % 10)
	endc



;***************************************************************************
; Reset
;***************************************************************************

	org	0x000000	; Reset vector

Reset_V
	; Skip interrupt handler


;***************************************************************************
; Interrupts
;***************************************************************************

	org	0x000008	; High-priority interrupt vector

HIntVector
	; jump to high priority ISR code

End_IntH
	retfie	FAST


;***************************************************************************
; Main Program Begins
;***************************************************************************

Main
	; Ensure BSR register points to first block

	; Initialize LCD

	; REGISTER 4-1: RCON: RESET CONTROL REGISTER
	; IPEN SBOREN — RI TO PD POR BOR
	; bit 7 			bit 0

	; bit 7 IPEN: Interrupt Priority Enable bit
	; 1 = Enable priority levels on interrupts
	; 0 = Disable priority levels on interrupts
	;      (PIC16CXXX Compatibility mode)

	; All interrupts vectored to 0x000008



	; Initialize real time clock

	; Enable peripheral interrupts
	; Enable interrupts

End_Main
	; Clock handled by interrupt


;***************************************************************************
;***************************************************************************
; Subroutines
;***************************************************************************
;***************************************************************************


;***************************************************************************
; Interrupt Service Routines
;***************************************************************************


HighISR
	; TMR1 overflow?
	; No, check another interrupt source

RTCisr
  	; wait for TMR1L<0> to become clear
  	; may already be clear (loops for 0 to 30.5us)
  	; wait for TMR1L<0> to become set
  	; (loops for 30.5us)

  	; If TMR1 update can be completed before clock pulse
  	; goes low, start update here
Update
	; Preload for 1 sec overflow
	; Clear interrupt flag

	; Increment seconds
	; 60 seconds elapsed?
	; No, done

	; Clear seconds
	; Increment minutes
	; 60 minutes elapsed?
	; No, done

	; Clear minutes
	; Increment hours
	; 24 hours elapsed?
	; No, done

	; Reset hours (new day)

End_RTCisr
	; Display clock
	; Done


NextISR 			; Another interrupt source...
  	; .... 			; code for other interrupts, if needed

  	; Done handling all high-priority interrupts



;***************************************************************************
; Real Time Clock initialization
;***************************************************************************


	; REGISTER 13-1: T1CON: TIMER1 CONTROL REGISTER
	; RD16 T1RUN T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON
	; bit 7 						bit 0

	; bit 7 RD16: 16-Bit Read/Write Mode Enable bit
	;  1 = Enables register read/write of Timer1 in one 16-bit operation
	;  0 = Enables register read/write of Timer1 in two 8-bit operations

	; bit 6 T1RUN: Timer1 System Clock Status bit
	;  1 = Device clock is derived from Timer1 oscillator
	;  0 = Device clock is derived from another source

	; bit 5-4 T1CKPS<1:0>: Timer1 Input Clock Prescale Select bits
	;  11 = 1:8 Prescale value
	;  10 = 1:4 Prescale value
	;  01 = 1:2 Prescale value
	;  00 = 1:1 Prescale value

	; bit 3 T1OSCEN: Timer1 Oscillator Enable bit
	;  1 = Timer1 oscillator is enabled
	;  0 = Timer1 oscillator is shut off
	;
	;  The oscillator inverter and feedback resistor are turned off
	;   to eliminate power drain.

	; bit 2 T1SYNC: Timer1 External Clock Input Synchronization Select bit
	;  When TMR1CS = 1:
	;   1 = Do not synchronize external clock input
	;   0 = Synchronize external clock input
	;  When TMR1CS = 0:
	;   This bit is ignored. Timer1 uses the internal clock when
	;    TMR1CS = 0.

	; bit 1 TMR1CS: Timer1 Clock Source Select bit
	;  1 = External clock from pin RC0/T1OSO/T13CKI (on the rising edge)
	;  0 = Internal clock (FOSC/4)

	; bit 0 TMR1ON: Timer1 On bit
	;  1 = Enables Timer1
	;  0 = Stops Timer1

RTCinit
	; Preload TMR1 register pair
	;  for 1 second overflow
	; Configure for external clock,
	; Asynchronous operation, external oscillator

	; Initialize timekeeping registers
	; (Hard-coded to 12:00:00 ... sync with Display code below)

	; Display initial clock (hard-coded)

	; Enable Timer1 interrupt
End_RTCinit
	return


;*****************************************************************************
; DM10:  n is in WREG -- integer divide by 10:
;        quotient return in DM10Q, remainder returned in DM10R;
;
; Uses successive subtraction.
;*****************************************************************************

DM10
	movwf	DM10R		; Store n in remainder reg
	clrf	DM10Q		; Clear quotient reg
	movlw	.10		; Load divisor

DM10_Check
	cpfslt	DM10R		; Is remainder less than 10?
	bra	DM10_Divide	; No, keep dividing
	bra	DM10_Done	; Yes, stop

DM10_Divide
	subwf	DM10R, f	; Subtract divisor and store new remainder
	incf	DM10Q, f	; Count it
	bra	DM10_Check	; Continue

DM10_Done
	return


;***************************************************************************
; Output clock to LCD
;***************************************************************************

LCD_Sep
	movlw	':'		; Time separator: colon
	call	LCD_Char
End_LCD_Sep
	return

LCD_Dig
	addlw	0x30		; Output a decimal digit (0-9) to the LCD
	call	LCD_Char	; Output ASCII version
End_LCD_Dig
	return


ClockLCD			; Display clock as hh:mm:ss on LCD
	call	LCD_Home

	; Display hours
	; 10's place
	; 1's place
	; Display minutes
	; 10's place
	; 1's place
	; Display seconds
	; 10's place
	; 1's place

End_ClockLCD
	return


;***************************************************************************
; LCD Library
;***************************************************************************

#include "LCD.asm"		; Include LCD library


	END

Back to CTEC1904