interfacing nRF24L01 with PIC16F819

Hi

I am having trouble interfacing PIC16F819 with nRF24L01 using hardware SPI. My SSPSTAT = 0x40; and SSPCON = 0x20;

anyone have any idea how to fix this or point in that direction.

Many thanks

I’ve got some test code for a 16F88 which uses software SPI, if that helps. I translated the SFE C code into assembler.

Leon

okay i will try your software SPI.

what is an SFE code?

SFE: Spark Fun Electronics!

;***************************************************************
;Test.asm
;Tx/Rx test program for MiRF V2
;MCU: PIC16F88
;uses software SPI
;
;user interface
;LED		- RB5, output (pin 11)
;PB			- RA1, input (pin 18)
;
;nRF24L01 connections to 16F88
;
;IRQ		- RA0, input (pin 17)
;CE 		- RB0, output (pin 6)
;MISO/SDI	- RB1, input (pin 7)
;MOSI/SDO	- RB2, output (pin 8) 
;CSN		- RB3, output (pin 9)
;SCK		- RB4, output (pin 10)
;***************************************************************

	errorlevel -302

#define IRQ 	0
#define	MISO 	1
#define MOSI 	2
#define	SCK		4
#define	CSN		3
#define	CE		0
#define	LED		5
#define PB		1


;defines for software SPI

#define SPI_SCK 4
#define SPI_SO 2
#define SPI_SI 1

#include	<p16f88.inc>


	CBLOCK 0x20
	scrA:	1	; scratch pad	0x20
	scrB:	1
	count
	RXDATA
	TXDATA
	status
	data_0
	data_1
	data_2
	data_3
	data_4
	ENDC

	org		0

	nop

;**************************************************************
;main program
;**************************************************************
	call	init
	banksel	PORTB
	call	flash_led

	call	write
	call	read
	
	nop

stop:
	goto	stop



aaa:

	BANKSEL	SSPSTAT
LOOP: 	
	BTFSS 	SSPSTAT, BF 	;Has data been received (transmit complete)?
	GOTO 	LOOP 			;No
	BCF 	STATUS, RP0 	;Specify Bank0
	MOVF 	SSPBUF, W 		;W reg = contents of SSPBUF
	MOVWF 	RXDATA 			;Save in user RAM, if data is meaningful
	MOVF 	TXDATA, W 		;W reg = contents of TXDATA
	MOVWF 	SSPBUF 			;New data to xmit

	goto	aaa


write:
	bcf		PORTB,CSN		;CSN low
	call	short_dly
	
	movlw	0x30			;send command (write to Tx address registers)
	movwf	TXDATA			;put in TXDATA
	call	spi_send_read	;send it
	call	short_dly

	call	spi_send_read
	movfw	RXDATA			;status is first byte received
	movwf	status			;save it
	call	short_dly

	nop

	movlw	0x12
	movwf	TXDATA
	call	spi_send_read
	movfw	RXDATA
	movwf	data_0
	call	short_dly

	movlw	0x12
	movwf	TXDATA
	call	spi_send_read
	movfw	RXDATA
	movwf	data_1
	call	short_dly

	movlw	0x12
	movwf	TXDATA
	call	spi_send_read
	movfw	RXDATA
	movwf	data_2
	call	short_dly

	movlw	0x12
	movwf	TXDATA
	call	spi_send_read
	movfw	RXDATA
	movwf	data_3
	call	short_dly

	movlw	0x12
	movwf	TXDATA
	call	spi_send_read
	movfw	RXDATA
	movwf	data_4
	call	short_dly

	nop
	bsf		PORTB,CSN		;CSN high
	call	short_dly
	nop
	return


read:
	bcf		PORTB,CSN		;CSN low
	call	short_dly
	
	movlw	0x10			;send command (read from Tx address registers)
	movwf	TXDATA			;put in TXDATA
	call	spi_send_read	;send it
	call	short_dly

	call	spi_send_read
	movfw	RXDATA			;status is first byte received
	movwf	status			;save it
	call	short_dly

	nop

	call	spi_send_read
	movfw	RXDATA
	movwf	data_0
	call	short_dly

	call	spi_send_read
	movfw	RXDATA
	movwf	data_1
	call	short_dly

	call	spi_send_read
	movfw	RXDATA
	movwf	data_2
	call	short_dly

	call	spi_send_read
	movfw	RXDATA
	movwf	data_3
	call	short_dly

	call	spi_send_read
	movfw	RXDATA
	movwf	data_4
	call	short_dly

	nop
	bsf		PORTB,CSN		;CSN high
	call	short_dly
	nop
	return

;-----------------------------------------------------------------
;spi_send_read
;sends byte in TXDATA and returns with received byte in RXDATA

spi_send_read:
	banksel	PORTB
	bcf		PORTB,SPI_SCK	;SCK low
	movfw	TXDATA
	movlw	8				;8 bits to send
	movwf	count
sp1_1:
	rlf		TXDATA,f		;bit 7 -> C
	btfss	STATUS,C		;C = 0?		
	goto	spi_2			;no, jump
	bsf		PORTB,SPI_SO	;yes, output one
	goto	spi_3
spi_2:
	bcf		PORTB,SPI_SO	;output zero
spi_3:
	btfsc	PORTB,SPI_SI	;SPI_SI input low?
	goto	spi_4			;no, jump
	bcf		STATUS,C		;yes, clear carry bit
	goto	spi_5
spi_4:
	bsf		STATUS,C		;set carry bit
spi_5:
	rlf		RXDATA,f		;bit 0 <- C
	bsf		PORTB,SPI_SCK	;SCK high to latch bit
	call	short_dly
	bcf		PORTB,SPI_SCK	;SCK low
	decfsz	count,f			;count = 0?
	goto	sp1_1			;no, loop back
	return					;yes, return


;***************************************************************
;initialisation
;***************************************************************
init:

	;oscillator setup
	BANKSEL	OSCCON
	MOVLW	0x70		; 8 MHz int. RC osc.
	MOVWF	OSCCON

WAIT1:
	BTFSS	OSCCON,2	; wait until freq. is stable
	GOTO	WAIT1

	;I/O setup
	BANKSEL PORTA 		; select bank of PORTA
	CLRF 	PORTA 		; Initialize ports by
	CLRF	PORTB		; clearing output data latches
	BANKSEL	ANSEL 		; Select Bank of ANSEL
	MOVLW	0x00 		; Configure all pins
	MOVWF	ANSEL 		; as digital
	BANKSEL TRISB
	MOVLW	0x02		; configure PORTB I/O (00000010)
	MOVWF	TRISB	
	MOVLW	0x01		;configure PORTA I/O (00000001)
	MOVWF	TRISA
	banksel	PORTB
	bsf		PORTB,CSN	;CSN high
	bcf		PORTB,CE	;CE low

	return

	;SPI setup
	BANKSEL	SSPSTAT
	MOVLW	0x40		;SPI master mode (01000000)
	MOVWF	SSPSTAT
	MOVLW	0x32		;enable SSP for SPI master mode, clock = OSC/64 (00110010)
	MOVWF	SSPCON

	RETURN


;******************************************************************
;flash LED five times
;******************************************************************
flash_led
	movlw	5
	movwf	count
flash1:
	BSF		PORTB,LED	;toggle LED
	call	dly
	BCF		PORTB,LED
	call	dly
	decfsz	count,f
	goto	flash1
	return

;****************************************************************
;transmit configuration
;****************************************************************
Tx_config:
	banksel	PORTA
	clrf	PORTA
	movlw	0x38
	movwf	TRISA
	bcf	PORTA,CE	;set config mode (CE = 0, CSN = 1)
	nop
	bsf	PORTA,CSN
	call	dly
	;send 24 bit configuration word 001000110100111000000100 (0x234E04) MS bit first
	movlw	0x23
	call	put_byte
	movlw	0x4E
	call	put_byte
	movlw	0x04
	call	put_byte
	call	dly
	banksel	PORTA
	bcf	PORTA,CE
	nop
	bsf	PORTA,CSN	;configuration enabled on falling edge of CSN
	return

;******************************************************************
;receive configuration
;******************************************************************
Rx_config:
	banksel	PORTA
	clrw
	movfw	PORTA		;all bits low
	movlw	0x38		;DATA1, DR1 output
	movfw	TRISA
	banksel	PORTA
	bcf	PORTA,CE	;set config mode (CE = 0. CS = 1)
	bsf	PORTA,CSN
	call	dly
	;send 24 bit configuration word 001000110100111000000101 (0x234E05) MS bit first
	movlw	0x23
	call	put_byte
	movlw	0x4E
	call	put_byte
	movlw	0x05
	call	put_byte
	banksel	PORTA
	bcf	PORTA,CE
	nop
	bcf	PORTA,CSN
	clrw
	movwf	PORTA
	movlw	0x3A		;DATA1 muse be input
	movwf	TRISA
	bcf	PORTA,CE
	nop
	bsf	PORTA,CSN
	return


;*****************************************************************************
;transmit data
;*****************************************************************************
Tx_data:
	banksel	PORTA
	bsf	PORTA,CE	;power up RF front end (CE = 1)
	call	dly
	movlw	0xE7		;RF address 11100111 (0xE7)
	call	put_byte	;clock in address
	movlw	0x11		;send four data bytes (0x11223344)
	call	put_byte
	movlw	0x22
	call	put_byte
	movlw	0x33
	call	put_byte
	movlw	0x44
	call	put_byte
	bcf	PORTA,CE	;start transmission (CE = 0)
	return


;****************************************************************************
;receive data
;****************************************************************************
Rx_data:
	banksel	PORTA
	bcf	PORTA,CE	;power down RF front end
	clrf	data_0		;zero buffers so that we can ensure that
	clrf	data_1		;correct date is being received
	clrf	data_2
	clrf	data_3
	call	get_byte	;receive four bytes and save in buffer
	movwf	data_0
	call	get_byte
	movwf	data_1
	call	get_byte
	movwf	data_2
	call	get_byte
	movwf	data_3
	bsf		PORTA,CE	;power up RF front end
	return

;***************************************************************************
;send byte to nRF24L01 (MS bit first)
;byte in  WREG
;***************************************************************************
put_byte:
	banksel	PORTA
	movwf	scrA	;save byte
	movlw	8	;initialise bit counter
	movwf	count
put_1:
	btfsc	scrA,7	;bit 7 = 0?
	goto	put_2	;no, jump
	bcf		PORTA,MOSI	;clear DATA
	nop
	bsf		PORTA,SCK	;clock it
	nop
	bcf		PORTA,SCK
	goto	put_3
put_2:
	bsf		PORTA,MOSI	;set DATA
	nop
	bsf		PORTA,SCK	;clock it
	nop
	bcf		PORTA,SCK
put_3:
	rlf		scrA,f		;left shift for next bit
	decfsz	count,f		;more bits?
	goto	put_1		;yes, loop back
	return				;no, return			


;***************************************************************************
;get byte from nRF24L01 (MS bit first) by clocking in data from MISO
;byte returned in WREG
;***************************************************************************
get_byte:
	banksel	PORTA
	movlw	8		;initialise bit counter
	movwf	count
get_1:
	btfsc	PORTA,MISO	;data = 1?
	goto	get_2		
	bcf		scrA,0		;no, clear MS bit
	goto	get_3
get_2:
	bsf		scrA,0		;Yes, set MS bit
get_3:
	bsf		PORTA,SCK
	nop
	bcf		PORTA,SCK
	rlf		scrA,f		;left shift for next bit
	decfsz	count,f		;more bits?
	goto	get_1		;no, loop back
	movfw	scrA		;return with byte in WREG
	return


;**************************************************************************
;delay routine
;**************************************************************************
dly:
	movlw	0xFF
	movwf	scrB
dly_1
	movlw	0xFF                        
	movwf	scrA                          
dly_2:	
	decfsz	scrA, F                    
	goto	dly_2
	decfsz	scrB,F
	goto	dly_1                          
	return
	

short_dly:
	movlw	0x05                        
	movwf	scrA                          
short_1:	
	decfsz	scrA, F                    
	goto	dly_2
	decfsz	scrB,F
	return

	end

Leon

I shall try this out,

thanks a lot.

I have a few routines with the 24L01 and PICs in PBP basic code too.

thanks everyone for your help.

I managed to solve my interfacing problem and able communicate now on SPI with the NORDIC chip. It was mostly to do with my CCS compiler.

Thanks

A

RonnyM:
I have a few routines with the 24L01 and PICs in PBP basic code too.

hi I’ll be interesting with pbp code, I’ll free lot of time could you post or send me them ?

for everyone’s help, I thought I would post my working code for the Hardware SPI configuration using CCS compiler.

Using C with CCS compiler, i was unable to get the exact combination for SSPSTAT and SSPCON. So I chose the nearest combination and then wrote to one bit directly into the register.

I came to the conclusion that what my compiler was setting, mismatched to what I need by comparing the SPI timing diagram of the NORDIC chip and PIC microcontroller.

My C file had the following:

/*Enable HWSPI Configuration*/ 
	setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4);
	CKE = 1;

To write to bit CKE you need to have the following in header file.

#bit CKE = 0x94.6  //this is the location of CKE in PIC16F819

Hope this helps

A.