;
; Segon programa ASM del PIC
; Sebastia, 28 de Abril de 2008.
;
; Mostrem numeros en un 7 segments :
;
;             b
;        . _____ .
;        |          |
;     a |          | c
;        |    d    |
;        . _____ .
;        |          |
;     e |          | g
;        |    f     |
;        . _____ .       (.) h
;
; Conectar 
;
; Reg "D"    RD7  RD6  RD5  RD4  RD3  RD2  RD1  RD0
; PIC pin     30    29    28     27     22    21     20    19
; Segment   g      f       e        c       b      a       d      h 
; Pin 7 seg  9      7      6        5       4      2       1     10
;
;         0       1      1      1       1       1      1       .       1
;         1       1       .       .       1        .       .       .       0
;         2       .       1      1       1       1       .      1       1
;         3       1      1      .        1       1       .      1       0
;         4       1       .      .        1        .      1      1       1
;         5       1      1      .         .       1      1      1       0
;         6       1      1      1        .       1      1      1       1
;         7       1       .       .       1       1       .       .       0
;         8       1      1      1       1       1      1      1       1
;         9       1       .       .       1       1      1      1       0
;
; XTAL 4 MHz entre pin 13 i 14.
; 2x C (22pf) del pin 13 i 14 a massa.
;
; Versions :
;	1.1 - inici
;	1.2	- no fer servir Timer, nomes comptatge.

;	list p=16f452
	#include	<p18f452.inc>

; Configuration bits :
;
;	Oscillator mode := XT ;
;	Watch Dog Timer := off ;
;	Low Voltage Programming := on :

	config	WDT=OFF
	config	OSC=XT
	config	LVP=on

; User data

; MYDATA	UDATA
;
;DTEMP	res	1		; reserve 1 address location
;DFLAG	res	1		;

 CBLOCK		0x020
;	DTEMP			; 
	DFLAG			;
	BsrTemp		; copy of BSR
	StatusTemp		; copy of STATUS
	WregTemp		; copy of WREG
	COUNT1		; delay loop
	COUNT2		; delay loop
	COUNT3
 ENDC

DFL0	equ	0x00		; define constant : set flag bit = 0 bit of DFLAG.

; +++ code start 

MYCODE	CODE

	org		0x0000				; Reset vector
	goto	Start				; skip interrupt vectors

	org		0x0008				; High Priority Interrupt Vector

	bcf		T0CON,TMR0ON	; T0CON bit 7 off => stops timer 0
	bcf		INTCON,TMR0IF		; clear timer has overflowed flag 
	bcf		DFLAG, DFL0		; clear soft (own) flag

	retfie	FAST				; return from interrupt

	org		0x0018				; Low Priority Interrupt Vector

	goto	ISR_space

	org		0x0040

ISR_space

	movff	STATUS, StatusTemp	; save STATUS register
	movff	WREG, WregTemp		; save WREG
	movff	BSR, BsrTemp			; save BSR register

; low priority code

	movff	BsrTemp,BSR			; restore BSR
	movff	WregTemp, WREG		; restore working register
	movff	StatusTemp, STATUS	; restore STATUS register

	retfie				; return from interrupt

	org		0x0100		; Program start

Start

;	banksel CONFIG1H
;	movlw	0x21				; XT mode
;	movwf	CONFIG1H

	banksel	TRISB				; select TRIS bank
	clrf		TRISB				; clear TRISB =>set PORTB as Outputs.
	clrf		PORTB				; clear PORT B data
	clrf		TRISA				; clear TRISA => set PORTA as Output.
	clrf		PORTA				; clear PORT A (output) data => set LOW.
	clrf		TRISC				; set port C as output
	clrf		PORTC				; set low C0..C7
	clrf		TRISD				; set port D as output
	clrf		PORTD				; set low D0..D7

	banksel	INTCON				; select INTCON bank
	bsf		INTCON, GIE		; enable Global Interrupts
	bsf		INTCON, TMR0IE	; set INTCON bit 5 => enable Timer 0 interrupt

Bucle

	movlw	0xFF			;  0b11111111	; 7seg := 'all on' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0x00			;  0b00000000	; 7seg := 'all off' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0xFF			;  0b11111111	; 7seg := 'all on' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0x00			;  0b00000000	; 7seg := 'all off' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0xFD			;  0b11111101	; 7seg := '0.' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0x90			; 0b10010000	; 7seg := '1' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0x7B			; 0b01111011	; 7seg := '2.' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0xDA			; 0b11011010	; 7seg := '3' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0x97			; 0b10010111	; 7seg := '4.' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0xCE			; 0b11001110	; 7seg := '5' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0xEF			; 0b11101110	; 7seg := '6.' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0x98			; 0b10011000	; 7seg := '7' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0xFF			; 0b11111110	; 7seg := '8.' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	movlw	0x9E			; 0b10011110	; 7seg := '9' ;
	movwf	PORTD			; set port D data
	call		Delay2			; use 1 or 2 ...

	goto	Bucle

; own subroutines

Delay1

	movlw		0xF0			; set Timer0 value
	movwf		TMR0L			; 0x00 = longest, 0xFF = shortest delay.

	clrf			DFLAG			; 
	bsf			DFLAG, DFL0	; set flag bit

	movlw		0xC8			; (7) enable, (6) 8-bit, (5) internal, (4) low-to-high, (3) noprescaler, (2-1-0) prescaler value
	movwf		T0CON			; start Timer0

Tloop

	btfsc		DFLAG, DFL0	; wait for overflow (bit test, skip if clear)
	goto		Tloop			; after interrupt, DFL0  = 0.

	return						; end of Delay1
; 

Delay2

	movlw		0x06			
	movwf		COUNT3

	setf			COUNT1		; set all bits => COUNT1 := 255 ;
	setf			COUNT2

Dloop

	decfsz		COUNT1, F		; use countdown to create delay (decrement, skip if Zero)
	goto		Dloop			; end loop when DTEMP = 0

	setf			COUNT1		;
	decfsz		COUNT2,F
	goto		Dloop

	setf			COUNT2
	decfsz		COUNT3,F
	goto		Dloop

	return

szID
	DB	0x55, 0x55, 0xAA, 0xAA	; eye catcher.
	DT	"25/04/2008, v 1.2 h "		; RETLW 8-bit.
	DA	"Sebastia",0					;
	DB	0x55, 0x55, 0xAA, 0xAA	; eye catcher.

	end