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
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.