Here’s some PIC test code of mine that works OK:
;***************************************************************
;Test.asm
;Tx/Rx test program for MiRF V2
;MCU: PIC16F88
;uses hardware 16F88 SSP module (hardware 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, ouput (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
zzz:
bcf PORTB,CSN ;CSN low
call short_dly
movlw 0x10 ;send command (read configuration)
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
call spi_send_read
movfw RXDATA
movwf data_0
call short_dly
call spi_send_read
movfw RXDATA
movwf data_1
call spi_send_read
movfw RXDATA
movwf data_2
call spi_send_read
movfw RXDATA
movwf data_3
call spi_send_read
movfw RXDATA
movwf data_4
nop
bsf PORTB,CSN ;CSN high
nop
goto zzz
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
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 ;MS bit in 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 ;rotate RXDATA left
bsf PORTB,SPI_SCK ;SCK high to latch bit
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 0x0F
movwf scrA
short_1:
decfsz scrA, F
goto dly_2
decfsz scrB,F
return
end
Leon