Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

8x8 leds with 74hc595n and pic

Status
Not open for further replies.

jay543_uk

New Member
hi all, I am trying to change nigels code at WinPicProg Page for displaying numbers on a 8x8 led square so i can have more than one 8x8 square. I am trying to use 2 74hc595n shift latchs and a 16f876a to do it.
i can get it to display a number if i just shift the bytes into the SSPBUF one at a time so im shore the wiring of my circuit is right but when i try to use the tmr2 interrupt to send the byte to the SSPBUF the 8x8 led square just has random lights on.

Can i use the SPI SSPBUF while using the tmr2 interrupt.

i am a newbie to all this so sorry if it dosnt make sence.

i will try and post code later

thanks for any help

jason
 
I am using porta 1 and 4 to communicate with a ds1337 RTC to get the time and then i want to display it on a 8x8 led square.Can any one tell me why i carnt make it work using two 74hc595n and the SPI on the 16f876a



Code:
	LIST	p=16F876		;tell assembler what chip we are using
	include "P16F876a.inc"		;include the defaults for the chip
	ERRORLEVEL	0,	-302	;suppress bank selection messages
	__config 0x3939			;sets the configuration settings (oscillator type etc.)


#define	SCL	PORTA,1		; bus clock line I2C
#define	SDA	PORTA,4		; bus data line	I2C
#define	ENABLE PORTA,2	;ENABLE LED 74HC595N


		cblock	0x20			;start of general purpose registers
			count			;used in looping routines
			count1			;used in delay routine
			counta			;used in delay routine
			countb			;used in delay routine
			tmp1			;temporary storage
			tmp2
			p_temp			;save register
			s_temp			;save register
			w_temp			;save register
						
						;registers for display

			row_pos			;position on row

			zero			;zero storage
			one			;one storage
			two			;two storage
			three			;three storage
			four			;four storage
			five			;five storage
			six			;six storage
			seven			;seven storage

			zero1			;zero storage
			one1			;one storage
			two1			;two storage
			three1			;three storage
			four1			;four storage
			five1			;five storage
			six1			;six storage
			seven1			;seven storage
			TEN				;CONVERT CLOCK RESULT TENS TO SINGLE UNIT
			UNITS			;CONVERT CLOCK	RESULT UNITS TO SINGLE UNIT
			TEMPCLOCK		;HOLDS TEMP CLOCK RESULT FOR TENSANDUNITS
			SCRATCH			; 1 by general-purpose scratchpad
			TMP				; temp register
			TMP2				; temp register
			COUNT		
			YRS		
			MON	
			DOW		
			DAYS		
			HRS		
			MINS		
			SEC	
		endc

ROW_PORT	Equ	PORTB			;row port
ROW_TRIS	Equ	TRISB

COL_PORT	Equ	PORTC			;column port
COL_TRIS	Equ	TRISC






	org	0x0000
	goto	START

;**************************************************************************	
;			     	Interrupt routine
;**************************************************************************



; 	Interrupt routine handles TMR2 which generates a 1ms tick

;	Interrupt vector

		ORG	0x0004


INT
		movwf	w_temp		; Save W register
		swapf	STATUS,W	; Swap status to be saved into W
		movwf	s_temp		; Save STATUS register
		movf	PCLATH,w
		movwf	p_temp		; Save PCLATH 
	
		btfss	PIR1,TMR2IF	; Flag set if TMR2 interrupt
		goto	INTX		; Jump if not timed out

		; Timer (TMR2) timeout
	

		bcf	PIR1,TMR2IF	; Clear the calling flag


		btfss	row_pos, 0	;check which ROW was last
		goto	Do_One
		btfss	row_pos, 1	;check which ROW was last
		goto	Do_Two
		btfss	row_pos, 2	;check which ROW was last
		goto	Do_Three
		btfss	row_pos, 3	;check which ROW was last
		goto	Do_Four
		btfss	row_pos, 4	;check which ROW was last
		goto	Do_Five
		btfss	row_pos, 5	;check which ROW was last
		goto	Do_Six
		btfss	row_pos, 6	;check which ROW was last
		goto	Do_Seven

Do_Zero	
		movlw	0xFF
		movwf	row_pos
		movf	zero,	w
		CALL	SEND_OUT
		bcf		row_pos, 0
		MOVLW	b'11111110'
		CALL	SEND_OUT
		call	DISPLAYON
		goto	INTX

Do_One	
		movlw	0xFF
		movwf	row_pos
		movf	one,	w
		CALL	SEND_OUT
		bcf		row_pos, 1
		MOVLW	b'11111101'
		CALL	SEND_OUT
		call	DISPLAYON
		goto	INTX

Do_Two	
		movlw	0xFF
		movwf	row_pos
		movf	two,	w
		CALL	SEND_OUT
		bcf		row_pos, 2
		MOVLW	b'11111011'
		CALL	SEND_OUT
		call	DISPLAYON
		goto	INTX

Do_Three	
		movlw	0xFF
		movwf	row_pos
		movf	three,	w
		CALL	SEND_OUT
		bcf		row_pos, 3
		MOVLW	b'11110111'
		CALL	SEND_OUT
		call	DISPLAYON
		goto	INTX

Do_Four	
		movlw	0xFF
		movwf	row_pos
		movf	four,	w
		CALL	SEND_OUT
		bcf		row_pos, 4
		MOVLW	b'11101111'
		CALL	SEND_OUT
		call	DISPLAYON
		goto	INTX

Do_Five	
		movlw	0xFF
		movwf	row_pos
		movf	five,	w
		CALL	SEND_OUT
		bcf		row_pos, 4
		MOVLW	b'11011111'
		CALL	SEND_OUT
		call	DISPLAYON
		goto	INTX

Do_Six	
		movlw	0xFF
		movwf	row_pos
		movf	six,	w
		CALL	SEND_OUT
		bcf		row_pos, 4
		MOVLW	b'10111111'
		CALL	SEND_OUT
		call	DISPLAYON
		goto	INTX

Do_Seven	
		movlw	0xFF
		movwf	row_pos
		movf	seven,	w
		CALL	SEND_OUT
		bcf		row_pos, 4
		MOVLW	b'01111111'
		CALL	SEND_OUT
		call	DISPLAYON
		goto	INTX

INTX
		movf	p_temp,W
		movwf	PCLATH		; Restore PCLATH
		swapf	s_temp,W
		movwf	STATUS		; Restore STATUS register - restores bank
		swapf	w_temp,F
		swapf	w_temp,W	; Restore W register
		retfie

;program initialisation
START		
		
		
		BANKSEL ADCON1			;disable analogue inputs
		movlw 	0x06			;turn off a/d
		movwf 	ADCON1
		BANKSEL PORTA
		bsf 	STATUS,		RP0	;select bank 1
		movlw	b'00000000'		;Set port data directions, data output
		movwf	ROW_TRIS
		movwf	COL_TRIS

		MOVLW	0XC0
		MOVWF	SSPSTAT

		MOVLW	B'00000111'
		MOVWF	OPTION_REG
		bcf 	STATUS,		RP0	;select bank 0
		clrf	COL_PORT		;turn OFF all LED's
		movlw	0xFF
		movwf	ROW_PORT	

		MOVLW 	0X20
		MOVWF	SSPCON		

		movlw	0x01
		movwf	row_pos

		call	Clear			;clear display registers

		
		movlw	b'00000110'		; Post scale /4, pre scale /16, TMR2 ON
		movwf	T2CON

		bsf 	STATUS,		RP0	;select bank 1

		movlw	.249			; Set up comparator
		movwf	PR2

		bsf	PIE1,TMR2IE		; Enable TMR2 interrupt

		bcf 	STATUS,		RP0	;select bank 0

		


;main program loop

		
Main	
		bcf		INTCON,PEIE		; disable all peripheral interrupts
		bcf		INTCON,GIE		; Global interrupt disable
	
		bsf 	STATUS,		RP0	;select bank 1
		bcf		PIE1,TMR2IE		; disable TMR2 interrupt
		bcf 	STATUS,		RP0	;select bank 0

		call	RTC_brst_rd

		bsf 	STATUS,		RP0	;select bank 1
		bsf		PIE1,TMR2IE		; Enable TMR2 interrupt
		bcf 	STATUS,		RP0	;select bank 

		bsf		INTCON,PEIE		; Enable all peripheral interrupts
		bsf		INTCON,GIE		; Global interrupt enable
		
		

		MOVF	HRS,W
		CALL	TENSANDUNITS
		clrf	TEN
		MOVF	TEN,W
		CALL	NUMBERTABLE
		CALL	ScrollL8
		MOVF	UNITS,W
		CALL	NUMBERTABLE
		CALL	ScrollL8

		CALL	DOUBLEDOT
		CALL	ScrollL8

		MOVF	MINS,W
		CALL	TENSANDUNITS
		MOVF	TEN,W
		CALL	NUMBERTABLE
		CALL	ScrollL8
		MOVF	UNITS,W
		CALL	NUMBERTABLE
		CALL	ScrollL8

		CALL	DOT
		CALL	ScrollL8
		
		MOVF	SEC,W
		CALL	TENSANDUNITS
		MOVF	TEN,W
		CALL	NUMBERTABLE
		CALL	ScrollL8
		MOVF	UNITS,W
		CALL	NUMBERTABLE
		CALL	ScrollL8
		CALL	Delay255
		CALL	Clear


		goto	Main			;endless loop



;start of subroutines

TENSANDUNITS
	movwf	TEMPCLOCK
	andlw   b'00001111'
	movwf	UNITS
	swapf	TEMPCLOCK,w
	andlw	b'00001111'
	movwf	TEN
	RETURN

NUMBERTABLE
	ADDWF	PCL
		goto	Load_Zero
		goto 	Load_One
		goto 	Load_Two
		goto 	Load_Three
		goto 	Load_Four
		goto 	Load_Five
		goto 	Load_Six
		goto 	Load_Seven
		goto 	Load_Eight
		goto 	Load_Nine

Clear		clrf	zero			;clear display storage
		clrf	one
		clrf	two
		clrf	three
		clrf	four
		clrf	five
		clrf	six
		clrf	seven
		return

DOUBLEDOT
	movlw	0x00
		movwf	zero1
		movlw	0X18
		movwf	one1
		movlw	0x18
		movwf	two1
		movlw	0x00
		movwf	three1
		movlw	0x00
		movwf	four1
		movlw	0x18
		movwf	five1
		movlw	0x18
		movwf	six1
		movlw	0x00
		movwf	seven1
		
		return

DOT
	movlw	0x00
		movwf	zero1
		movlw	0X18
		movwf	one1
		movlw	0x18
		movwf	two1
		movlw	0x00
		movwf	three1
		movlw	0x00
		movwf	four1
		movlw	0x00
		movwf	five1
		movlw	0x00
		movwf	six1
		movlw	0x00
		movwf	seven1
		return



Load_Zero	movlw	0x00
		movwf	zero1
		movlw	0x38
		movwf	one1
		movlw	0x44
		movwf	two1
		movlw	0x4C
		movwf	three1
		movlw	0x54
		movwf	four1
		movlw	0x64
		movwf	five1
		movlw	0x44
		movwf	six1
		movlw	0x38
		movwf	seven1
		return

Load_One	movlw	0x00
		movwf	zero1
		movlw	0x38
		movwf	one1
		movlw	0x10
		movwf	two1
		movlw	0x10
		movwf	three1
		movlw	0x10
		movwf	four1
		movlw	0x10
		movwf	five1
		movlw	0x30
		movwf	six1
		movlw	0x10
		movwf	seven1
		return

Load_Two	movlw	0x00
		movwf	zero1
		movlw	0x7C
		movwf	one1
		movlw	0x20
		movwf	two1
		movlw	0x10
		movwf	three1
		movlw	0x08
		movwf	four1
		movlw	0x04
		movwf	five1
		movlw	0x44
		movwf	six1
		movlw	0x38
		movwf	seven1
	return

Load_Three	movlw	0x00
		movwf	zero1
		movlw	0x38
		movwf	one1
		movlw	0x44
		movwf	two1
		movlw	0x04
		movwf	three1
		movlw	0x08
		movwf	four1
		movlw	0x10
		movwf	five1
		movlw	0x08
		movwf	six1
		movlw	0x7C
		movwf	seven1
		
		return
Load_Four	movlw	0x00
		movwf	zero1
		movlw	0x08
		movwf	one1
		movlw	0x08
		movwf	two1
		movlw	0x7C
		movwf	three1
		movlw	0x48
		movwf	four1
		movlw	0x28
		movwf	five1
		movlw	0x18
		movwf	six1
		movlw	0x08
		movwf	seven1
	
		return

Load_Five	movlw	0x00
		movwf	zero1
		movlw	0x38
		movwf	one1
		movlw	0x44
		movwf	two1
		movlw	0x04
		movwf	three1
		movlw	0x04
		movwf	four1
		movlw	0x78
		movwf	five1
		movlw	0x40
		movwf	six1
		movlw	0x7C
		movwf	seven1
		
		return

Load_Six	movlw	0x00
		movwf	zero1
		movlw	0x38
		movwf	one1
		movlw	0x44
		movwf	two1
		movlw	0x44
		movwf	three1
		movlw	0x78
		movwf	four1
		movlw	0x40
		movwf	five1
		movlw	0x20
		movwf	six1
		movlw	0x18
		movwf	seven1
		
		return

Load_Seven	movlw	0x00
		movwf	zero1
		movlw	0x20
		movwf	one1
		movlw	0x20
		movwf	two1
		movlw	0x20
		movwf	three1
		movlw	0x10
		movwf	four1
		movlw	0x08
		movwf	five1
		movlw	0x04
		movwf	six1
		movlw	0x7C
		movwf	seven1
		
		return

Load_Eight	movlw	0x00
		movwf	zero1
		movlw	0x38
		movwf	one1
		movlw	0x44
		movwf	two1
		movlw	0x44
		movwf	three1
		movlw	0x38
		movwf	four1
		movlw	0x44
		movwf	five1
		movlw	0x44
		movwf	six1
		movlw	0x38
		movwf	seven1
	
		return

Load_Nine	movlw	0x00
		movwf	zero1
		movlw	0x30
		movwf	one1
		movlw	0x08
		movwf	two1
		movlw	0x04
		movwf	three1
		movlw	0x3C
		movwf	four1
		movlw	0x44
		movwf	five1
		movlw	0x44
		movwf	six1
		movlw	0x38
		movwf	seven1
	
		return


ScrollL8	call	ScrollL
		call	Delay20	
		call	ScrollL
		call	Delay20	
		call	ScrollL
		call	Delay20	
		call	ScrollL
		call	Delay20	
		call	ScrollL
		call	Delay20	
		call	ScrollL
		call	Delay20	
		call	ScrollL
		call	Delay20	
		call	ScrollL
		call	Delay20
		return






ScrollL		bcf	STATUS, C
		rlf	zero1, f
		rlf	zero, f
		bcf	STATUS, C
		rlf	one1, f
		rlf	one, f
		bcf	STATUS, C
		rlf	two1, f
		rlf	two, f
		bcf	STATUS, C
		rlf	three1, f
		rlf	three, f
		bcf	STATUS, C
		rlf	four1, f
		rlf	four, f
		bcf	STATUS, C
		rlf	five1, f
		rlf	five, f
		bcf	STATUS, C
		rlf	six1, f
		rlf	six, f
		bcf	STATUS, C
		rlf	seven1, f
		rlf	seven, f
		return





Delay1Sec	call	Delay250
		call	Delay250
		call	Delay250
		call	Delay250
		Return


Delay255	movlw	0xff	;delay 255mS
		goto	d0
Delay250	movlw	d'250'	;delay 250mS
		goto	d0
Delay100	movlw	d'100'	;delay 100mS
		goto	d0
Delay50		movlw	d'50'	;delay 50mS
		goto	d0
Delay20		movlw	d'20'	;delay 20mS
		goto	d0
Delay10		movlw	d'10'	;delay 10mS
		goto	d0
Delay1		movlw	d'1'	;delay 1mS
		goto	d0
Delay5		movlw	0x05	;delay 5ms
d0		movwf	count1
d1		movlw	0xE7
		movwf	counta
		movlw	0x04
		movwf	countb
Delay_0		decfsz	counta, f
		goto	$+2
		decfsz	countb, f
		goto	Delay_0
		decfsz	count1	,f
		goto	d1
		retlw	0x00


;-----------------------------------------
;--           RTC routines              --
;-----------------------------------------

RTC_brst_wr:
	call I2CSTART
	movlw	0D0h			; slave address + write
	call	write_RTC
	movlw	0			; set word address to seconds register
	call	write_RTC
	movf	SEC, W
	call	write_RTC
	movf	MINS, W
	call	write_RTC
	movf	HRS, W
	call	write_RTC
	movf	DOW, W
	call	write_RTC
	movf	DAYS, W
	call	write_RTC
	movf	MON, W
	call	write_RTC
	movf	YRS, W
	call	write_RTC
	call I2CSTOP

	return


RTC_brst_rd:
	call I2CSTART
	movlw	0D0h			; slave address + write
	call	write_RTC
	movlw	0X00			; set word address to seconds register
	call	write_RTC
	call I2CSTART
	movlw	0D1h			; slave address + read
	call	write_RTC
	call	read_RTC		; read the seconds data
	movwf	SEC			; save it
	call	ack;
	call	read_RTC		; and so on
	movwf	MINS
	call	ack;
	call	read_RTC
	movwf	HRS
	call	ack;
	call	read_RTC
	movwf	DOW
	call	ack;
	call	read_RTC
	movwf	DAYS
	call	ack;
	call	read_RTC
	movwf	MON
	call	ack;
	call	read_RTC
	movwf	YRS
	call	nack;
	call I2CSTOP
	return


;---- Read RTC into W  ----
read_RTC:
	call SET_BANK1
	bsf	TRISA,4		; set SDA for input
	call SET_BANK0

	movlw	08h			; send 8 bits
	movwf	COUNT

	bcf	SCL			; clock data out
	call SET_BANK1
	bcf	TRISA, 1		; SCL low (output)
	call SET_BANK0

	clrf	TMP			; clear var
	rlf	TMP, 1			; rotate carry in
	clrf	TMP			; clear var again

I2C_read_loop:
	rlf	TMP, 1

	call SET_BANK1
	bsf	TRISA, 1		; SCL high (input)
	call SET_BANK0

	btfsc	SDA
	bsf	TMP, 0			; if data out = 1, set bit

	bcf	SCL
	call SET_BANK1
	bcf	TRISA, 1		; SCL low (output)
	call SET_BANK0
	decfsz	COUNT, 1
	goto	I2C_read_loop

	movf	TMP, W

	return

;---- ACK read (assumes SCL=0 on entry) ----
ack:
	bcf		SDA

	call SET_BANK1
	bcf	TRISA,4		; set SDA for output
	call SET_BANK0

	call SET_BANK1
	bsf	TRISA, 1		; SCL high (input)
	call SET_BANK0
	nop
	bcf	SCL
	call SET_BANK1
	bcf	TRISA, 1		; SCL low (output)
	call SET_BANK0

	return

;---- NACK read (assumes SCL = 0 on entry) ----
nack:
	bsf	SDA

	call SET_BANK1
	bcf	TRISA,4		; set SDA for output
	call SET_BANK0

	call SET_BANK1
	bsf	TRISA, 1		; SCL high (input)
	call SET_BANK0

	bcf	SCL
	call SET_BANK1
	bcf	TRISA, 1		; SCL low (output)
	call SET_BANK0

	return

;--- Write the byte in W to RTC ---
;---- assumes CE is asserted ----
write_RTC:
	movwf	TMP			;Save the data
;
;--- Do a I2C bus write of byte in 'TMP' ---
;
I2C_write:

	call SET_BANK1
	bcf	TRISA, 4		; set SDA for output
	call SET_BANK0

	movlw	08h			; send 8 bits
	movwf	COUNT

	bcf	SCL
	call SET_BANK1
	bcf	TRISA, 1		; SCL low (output)
	call SET_BANK0

I2C_w_loop:
	bcf	SDA			; assume data out is low
	btfsc	TMP, 7
	bsf	SDA			; if data out = 1, set bit
	; nop

	call SET_BANK1
	bsf	TRISA, 1		; SCL high (input)
	call SET_BANK0
	rlf	TMP, 1
	bcf	SCL			; clock it in
	call SET_BANK1
	bcf	TRISA, 1		; SCL low (output)
	call SET_BANK0
	decfsz	COUNT, 1
	goto	I2C_w_loop

	call SET_BANK1
	bsf	TRISA,4		; set SDA for input
	call SET_BANK0

	bcf	SCL
	call SET_BANK1
	bcf	TRISA, 1		; SCL low (output)
	call SET_BANK0
	; nop
	call SET_BANK1
	bsf	TRISA, 1		; SCL high (input)
	call SET_BANK0
	; if(sda) printf("Ack bit missing  %02X\n",(unsigned int)d);
	bcf		SCL
	call SET_BANK1
	bcf	TRISA, 1		; SCL low (output)
	call SET_BANK0

	return

I2CSTART 
	bsf	SDA			; SDA high
	nop
	call SET_BANK1
	bsf	TRISA, 1		; SCL high (input)
	call SET_BANK0
	bcf	SDA			; SDA low (start)
	return

I2CSTOP			; assumes SCL is high on entry
	bcf	SDA			; SDA low
	nop
	nop
	call SET_BANK1
	bsf	TRISA, 1		; SCL high (input)
	call SET_BANK0
	bsf	SDA			; SDA high
	return

SET_BANK0
	bcf STATUS, RP0
	bcf STATUS, RP1
	return

SET_BANK1
	bsf	STATUS, RP0
	bcf	STATUS, RP1
	return

;******************************************************
;****************SPI ROUTE*****************************
;******************************************************

SEND_OUT
		
		BCF	PIR1,SSPIF
		MOVWF	SSPBUF
		
	
TEST_BF
		BTFSS	PIR1,SSPIF	
		GOTO	TEST_BF
		RETLW	0

DISPLAYON
		BCf	ENABLE
		BSf	ENABLE
		RETURN

	END
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top