LIST p=16F88 ; list directive to define processor
#INCLUDE <P16F88.INC> ; processor specific variable definitions
;------------------------------------------------------------------------------
;
; CONFIGURATION WORD SETUP
;
; The 'CONFIG' directive is used to embed the configuration word within the
; .asm file. The lables following the directive are located in the respective
; .inc file. See the data sheet for additional information on configuration
; word settings.
;
;------------------------------------------------------------------------------
__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
;------------------------------------------------------------------------------
;
; VARIABLE DEFINITIONS
;
; Available Data Memory divided into Bank 0 through Bank 3. Each Bank contains
; Special Function Registers and General Purpose Registers at the locations
; below:
;
; SFR GPR SHARED GPR's
; Bank 0 0x00-0x1F 0x20-0x6F 0x70-0x7F
; Bank 1 0x80-0x9F 0xA0-0xEF 0xF0-0xFF
; Bank 2 0x100-0x10F 0x110-0x16F 0x170-0x17F
; Bank 3 0x180-0x18F 0x190-0x1EF 0x1F0-0x1FF
;
;------------------------------------------------------------------------------
CBLOCK 0x20 ; Sample GPR variable registers allocated contiguously
MYVAR1 ; User variable
MYVAR2 ; User variable
MYVAR3 ; User variable
DY1
DY2
DY3
ENDC
Ctr0 EQU 0x20 ; Counter variable - sent to SPI
Dly0 EQU 0x21 ; Delay Variable (low byte)
Dly1 EQU 0x22 ; Delay Variable (high byte)
#define CS 0x02 ; PORTA,2
W_TEMP EQU 0x7D ; w register for context saving (ACCESS)
STATUS_TEMP EQU 0x7E ; status used for context saving (ACCESS)
PCLATH_TEMP EQU 0x7F ; variable used for context saving
;------------------------------------------------------------------------------
; EEPROM INITIALIZATION
;
; The 16F88 has 256 bytes of non-volatile EEPROM, starting at address 0x2100
;
;------------------------------------------------------------------------------
DATAEE ORG 0x2100
DE "MCHP" ; Place 'M' 'C' 'H' 'P' at address 0,1,2,3
;------------------------------------------------------------------------------
; RESET VECTOR
;------------------------------------------------------------------------------
RESET ORG 0x0000 ; processor reset vector
PAGESEL START
GOTO START ; go to beginning of program
;------------------------------------------------------------------------------
; INTERRUPT SERVICE ROUTINE
;------------------------------------------------------------------------------
ISR ORG 0x0004 ; interrupt vector location
; Context saving for ISR
MOVWF W_TEMP ; save off current W register contents
MOVF STATUS,W ; move status register into W register
MOVWF STATUS_TEMP ; save off contents of STATUS register
MOVF PCLATH,W ; move pclath register into W register
MOVWF PCLATH_TEMP ; save off contents of PCLATH register
;------------------------------------------------------------------------------
; USER INTERRUPT SERVICE ROUTINE GOES HERE
;------------------------------------------------------------------------------
; Restore context before returning from interrupt
MOVF PCLATH_TEMP,W ; retrieve copy of PCLATH register
MOVWF PCLATH ; restore pre-isr PCLATH register contents
MOVF STATUS_TEMP,W ; retrieve copy of STATUS register
MOVWF STATUS ; restore pre-isr STATUS register contents
SWAPF W_TEMP,F
SWAPF W_TEMP,W ; restore pre-isr W register contents
RETFIE ; return from interrupt
;------------------------------------------------------------------------------
; MAIN PROGRAM
;------------------------------------------------------------------------------
START ; Set up the SPI Support
BANKSEL TRISA ; BANK 1
movlw 0x00 ; Set PORTA as
movwf TRISA ; all Outputs
movlw 0x01 ; Turn off A/D
movwf ADCON0 ; so PORTA can be used
; Set up the SPI Port
BANKSEL TRISB ; BANK 1
movlw 0x02 ; SCK is output (Master), SDI is input,
movwf TRISB ; SDO is output, all others output
movlw 0x40 ; Mode 1,1 SPI, middle of output
movwf SSPSTAT ; time sampling
BANKSEL SSPCON ; BANK 0
movlw 0x31 ; Mode 1,1 SPI Master Mode, 1/16 Tosc bit
time
movwf SSPCON ; SSP is on
Send_DT
bcf PORTA,CS ; Enable Chip Select Output (low)
CALL RUTINE
movlw 0x0F
movwf SSPBUF ; put in SSPBUF
BANKSEL SSPSTAT ; BANK 1
Char1 btfss SSPSTAT,BF ; Data transfer complete? (Buffer Full?)
goto Char1 ; if not, check again
BANKSEL SSPBUF ; BANK0
movf SSPBUF,W ; Get Data from SSPBUF
; ; Throw it away
bsf PORTA,CS ; Disable Chip Select Output (high)
Update_Test_Counter
incf Ctr0,F ; Increment counter variable
Delay movlw 0x01 ; Simple Delay loop
movwf Dly1 ; |
movlw 0x0F ; |
movwf Dly0 ; |
DlyLoop decfsz Dly0,F ; |
goto DlyLoop ; |
decfsz Dly1,F ; |
goto DlyLoop
DoAgain goto Send_DT ; Done, Send Next Byte.
RUTINE
return
;------------------------------------------------------------------------------
; PLACE USER PROGRAM HERE
;------------------------------------------------------------------------------
GOTO $
END
LIST p=16F88 ; list directive to define processor
#INCLUDE <P16F88.INC> ; processor specific variable definitions
;------------------------------------------------------------------------------
;
; CONFIGURATION WORD SETUP
;
; The 'CONFIG' directive is used to embed the configuration word within the
; .asm file. The lables following the directive are located in the respective
; .inc file. See the data sheet for additional information on configuration
; word settings.
;
;------------------------------------------------------------------------------
__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC & _FOSC_XT
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
;------------------------------------------------------------------------------
;
; VARIABLE DEFINITIONS
;
; Available Data Memory divided into Bank 0 through Bank 3. Each Bank contains
; Special Function Registers and General Purpose Registers at the locations
; below:
;
; SFR GPR SHARED GPR's
; Bank 0 0x00-0x1F 0x20-0x6F 0x70-0x7F
; Bank 1 0x80-0x9F 0xA0-0xEF 0xF0-0xFF
; Bank 2 0x100-0x10F 0x110-0x16F 0x170-0x17F
; Bank 3 0x180-0x18F 0x190-0x1EF 0x1F0-0x1FF
;
;------------------------------------------------------------------------------
CBLOCK 0x20 ; Sample GPR variable registers allocated contiguously
MYVAR1 ; User variable
MYVAR2 ; User variable
MYVAR3 ; User variable
DY1
DY2
DY3
ENDC
#define CS 0x20 ; PORTA,5 (HW SS pin)
W_TEMP EQU 0x7D ; w register for context saving (ACCESS)
STATUS_TEMP EQU 0x7E ; status used for context saving (ACCESS)
PCLATH_TEMP EQU 0x7F ; variable used for context saving
;------------------------------------------------------------------------------
; EEPROM INITIALIZATION
;
; The 16F88 has 256 bytes of non-volatile EEPROM, starting at address 0x2100
;
;------------------------------------------------------------------------------
DATAEE ORG 0x2100
DE "MCHP" ; Place 'M' 'C' 'H' 'P' at address 0,1,2,3
;------------------------------------------------------------------------------
; RESET VECTOR
;------------------------------------------------------------------------------
RESET ORG 0x0000 ; processor reset vector
PAGESEL START
GOTO START ; go to beginning of program
; MAIN PROGRAM
;------------------------------------------------------------------------------
START
clrf PORTB
CLRF PORTA
; Set up the SPI Support
BANKSEL TRISA ; BANK 1
movlw CS ; Chip Select pin
movwf TRISA ; is in input mode
movlw 0x06 ; Turn Off A/D mode for at least the
movwf ADCON1 ; Chip Select pin (all Digital mode)
; Set up output port
BANKSEL TRISB ; BANK 1
movlw b'00110010' ; Configure all PORTB pins
movwf TRISB ; to be in output mode
BANKSEL PORTA
CLRF PORTA
BANKSEL TRISB
; Set up the SPI
movlw 0x40 ; Mode 1,1 SPI with
movwf SSPSTAT ; middle of output time sampling
BANKSEL SSPCON ; BANK 0
movlw 0x34 ; Mode 1,1 SPI Slave Mode, /SS Required
movwf SSPCON ; SSP is on
Chk4Dat
btfss SSPSTAT,BF ; Here is the test
goto Chk4Dat ; New data, do a transfer (below
Recibed
BANKSEL SSPBUF
movf SSPBUF,W
MOVWF MYVAR2 ; put in SSPBUF into W
UNOS2 CALL UNOS
DOS1 CALL DOS
tres2 CALL TRES
CUATRO2 CALL CUATRO
BANKSEL PORTB ; BANK 0
movwf PORTB ; Show the results on PORTB
CALL ENVIOSLAVE
DoAgain
; Optional customer code can go here
goto Chk4Dat ; Receive Next Byte
UNOS BTFSS MYVAR2,0
CALL UNO1
BSF PORTA,1
CALL DELAY
RETURN
UNO1 BCF PORTA,1
GOTO UNOS2
DOS BTFSS MYVAR2,1
CALL DOS2
BSF PORTB,5
CALL DELAY
RETURN
DOS2 BCF PORTB,5
GOTO DOS1
TRES BTFSS MYVAR2,2
CALL TRES1
BSF PORTB,6
CALL DELAY
RETURN
TRES1 BCF PORTB,6
GOTO tres2
CUATRO BTFSS MYVAR2,3
CALL CUATRO1
BSF PORTB,7
CALL DELAY
RETURN
CUATRO1 BCF PORTB,7
GOTO CUATRO2
ENVIOSLAVE
MOVLW 0XFF
MOVWF MYVAR1
MOVLW MYVAR1
MOVWF SSPBUF
RETURN
DELAY CLRF DY1
CLRF DY2
clrf DY3
ITER DECFSZ DY1
GOTO ITER
DECFSZ DY2
GOTO ITER
DECFSZ DY3
GOTO ITER
RETURN
;------------------------------------------------------------------------------
; PLACE USER PROGRAM HERE
;------------------------------------------------------------------------------
GOTO $
END
Hola, yo tambien estuve batallando todo un fin de semana, al final pude comunicarme, y no estoy del todo satisfecho pues solo logre transmitir con un NRF24L01 de los que tienen un amplificador integrado y antena, y recibo en uno como el tuyo, tambien puedo recibir en uno con antena, pero no he podido transmitir con uno sencillo, no se a que se deba y eso que probe con 6 diferentes para descartar que estuvieran dañados pero dudo que sea asi por que todos ellos reciben perfectamente
Si sabes de algo por favor hazmelo saber
Claro, no tengo problema en pasartelo cuando llegue a mi casa te lo envio, estoy usando CCS, y tu?
Y como te das cuenta que estas emitiendo datos por RF?
Pd. estoy usando Dos pics 16f877
aqui esta mi codigo me base a esta pagina:
https://sites.google.com/site/proyectosroboticos/nrf24l01/16f876-nrf24l01
pero lo modifique para que al presionar un boton que conecte en B1 enviara un dato al receptor y encendiera un led conectado en A1, y al soltar el boton se apagara
si puedes mandame tu codigo para ver que puedo hacer con el
Saludos
#include <16F88.h>
#fuses XT //Oscilador a cristal standar
#fuses NOWDT //sin WatchDog Timer
#fuses NOPROTECT //sin proteccion de memoria de programa
#fuses NOPUT //sin PowerUp Timer
#fuses NOBROWNOUT //sin brownout
#fuses NOLVP //sin programación en baja tensión
#use delay(clock=4000000)
#include "lib_rf2gh4_10_4550.h" // Librería modificada para el el nRF24L01 con el PIC 18F4550.
#byte porta=0x05 // Dirección de los puertos A, B, C, D y E.
#byte portb=0x06
int8 cont=0XFF;
int8 ret2;
void main()
{
RF_CONFIG_SPI(); // Configurar módulo SPI del PIC.
RF_CONFIG(0x40,0x01); // Configurar módulo RF canal y dirección de recepción de datos para este PIC.
RF_ON(); // Activar el módulo RF.
delay_ms(5); // Dejamos como mínimo 2.5ms antes de comenzar a enviar.
set_tris_a(0b111011); // Dejo RA5 como salida para evitar poner la resistencia de polarización.
set_tris_b(0b00000010);
while(true)
{
#asm
btfss PORTA,0
bcf cont,0
BTFSC PORTA,0
BSF cont,0
btfss PORTA,1
bcf cont,1
BTFSC PORTA,1
BSF cont,1
btfss PORTA,3
bcf cont,2
BTFSC PORTA,3
BSF cont,2
#endasm
RF_DATA[0] = cont; // El contenido del contador lo cargo en RF_DATA[0] para ser enviado., se pueden enviar hasta 8 bytes desde data 0 hasta data 7
RF_DIR=0x08; // Dirección del receptor.
ret2=RF_SEND(); // Envía el dato.Ret 2 nos devuelve el estado del proceso (envio)
delay_ms(50); // Una pausa en cada incremento.
}
}
// PORTB
#define RF_IRQ PIN_A4
#define RF_IRQ_TRIS TRISA,4
// PORTC
#define RF_CS PIN_A2
#define RF_CE PIN_B3
#define SCK PIN_B4
#define SDI PIN_B1
#define SDO PIN_B2
#define RF_CS_TRIS TRISA,2
#define RF_CE_TRIS TRISB,3
#define SCK_TRIS TRISB,4
#define SDI_TRIS TRISB,1
#define SDO_TRIS TRISB,2
//*****************
//* VARIABLES *
//*****************
#BYTE TRISA = 0x85 // Dirección de los TRIS.
#BYTE TRISB = 0x86
#BYTE INTCON = 0x10B // Registro de interrupciones. Sólo es importante el bit 7, GIE=interrupciones globales.
//Variables internas
static int1 interRF;
static int16 noRF;
static int1 RCVNW=0;
static int8 DATA_N_SND=0;
static int8 DATA_N_RCV=0;
//Variables configurables
static int8 RF_DATA[8];
static int8 RF_DIR;
//**************
//* CÓDIGO *
//**************
//*****************************************************
//* RF_CONFIG_SPI() *
//*****************************************************
//*Descripción: La función configura el módulo SPI del*
//*microcontrolador.En ella se especifica como salida *
//*SDO y como entrada SDI entre otros parámetros del *
//*protocolo SPI. *
//*****************************************************
//*Variables de entrada: *
//*Variables de salida: *
//*****************************************************
void RF_CONFIG_SPI()
{
//Configuración I/O.
bit_clear(SCK_TRIS);
bit_set(SDI_TRIS);
bit_clear(SDO_TRIS);
//Configuración módulo comunicaciones.
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_4|SPI_SAMPLE_AT_END);
}
//*****************************************************
//*****************************************************
//* RF_CONFIG(int canal, int dir) *
//*****************************************************
//*Descripción:Esta función se encarga de configurar *
//*el transceptor habilitando su propia dirección de *
//*escucha y el canal entre otros parámetros. *
//*****************************************************
//*Variables de entrada:- Canal *
//* - Direccion *
//*Variables de salida: *
//*****************************************************
void RF_CONFIG(int canal, int dir)
{
bit_clear(RF_CS_TRIS);
bit_set(RF_IRQ_TRIS);
bit_clear(RF_CE_TRIS);
output_low(RF_CE);
// TX_ADDR (0xFF)
//Configuración de la dirección de envío aleatoria.
//En la función de enviar se configura la dirección
//deseada por el usuario.
output_low(RF_CS);
spi_write(0x30);
spi_write(0xFF);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
output_high(RF_CS);
// RX_ADDR_P0 (0xFF) ACK
//Configuración de la direccióndel Pipe0 para la
//recepción de ACK.
output_low(RF_CS);
spi_write(0x2A);
spi_write(0xFF);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
output_high(RF_CS);
// RX_ADDR_P1 (dir)
//Configuración de la direccióndel Pipe1 para la
//recepción de tramas.
output_low(RF_CS);
spi_write(0x2B);
spi_write(dir);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
output_high(RF_CS);
// RX_ADDR_P2 (0x00) BROADCAST
//Configuración de la direccióndel Pipe2 para la
//recepción de tramas
output_low(RF_CS);
spi_write(0x2C);
spi_write(0x00);
output_high(RF_CS);
// EN_AA
//Habilitar AutoAck en los Pipe0,Pipe1 y Pipe2.
output_low(RF_CS);
spi_write(0x21);
spi_write(0x07);
output_high(RF_CS);
// EN_RXADDR
//Habilitar los Pipe0,Pipe1 y Pipe2.
output_low(RF_CS);
spi_write(0x22);
spi_write(0x07);
output_high(RF_CS);
// SETUP_AW
//Configuración de la longitud de las direcciones.
//Direcciones de 5 bytes.
output_low(RF_CS);
spi_write(0x23);
spi_write(0x03);
output_high(RF_CS);
//SETUP_RETR
//Configuración de las retrasmisiones en la transmisión.
//Diez retransmisiones cada 336us.
output_low(RF_CS);
spi_write(0x24);
spi_write(0x0A);
output_high(RF_CS);
//RF_CH
//Configuración del canal.
//Canal elegido por el usuario (0x01 - 0x7F).
output_low(RF_CS);
spi_write(0x25);
spi_write(canal);
output_high(RF_CS);
//RF_SETUP
//Configuración aspectos RF. *******************************************************************************************
//Ganancia máxima de LNA, 0dBm potencia de salida y 1Mbps de velocidad. ************************************************
output_low(RF_CS);
spi_write(0x26);
spi_write(0x07); // Lo he cambiado a 1Mbps. Originalmente era "0x0F" ----> (2Mbps).
output_high(RF_CS);
//STATUS
//Reseteo del registro STATUS
output_low(RF_CS);
spi_write(0x27);
spi_write(0x70);
output_high(RF_CS);
//RX_PW_P0
//Nº de bytes en Pipe0.
//1 byte (ACK).
output_low(RF_CS);
spi_write(0x31);
spi_write(0x01);
output_high(RF_CS);
//RX_PW_P1
//Nº de bytes en Pipe1.
//10 byte (Direccion emisor y trama).
output_low(RF_CS);
spi_write(0x32);
spi_write(0x0A);
output_high(RF_CS);
//RX_PW_P2
//Nº de bytes en Pipe2.
//10 byte (Direccion emisor y trama).
output_low(RF_CS);
spi_write(0x33);
spi_write(0x0A);
output_high(RF_CS);
}
//*****************************************************
//*****************************************************
//* RF_ON() *
//*****************************************************
//*Descripción:Esta rutina activa el módulo de *
//*radiofrecuencia en modo escucha para poder recibir *
//*datos enviados a su dirección. *
//*****************************************************
//*Variables de entrada: *
//*Variables de salida: *
//*****************************************************
void RF_ON()
{
output_low(RF_CE);
// CONFIG
//Se activa el modulo, se pone en recepción,
//se activa el CRC para que utilice 2 bytes.
output_low(RF_CS);
spi_write(0x20);
spi_write(0x0F);
output_high(RF_CS);
delay_ms(2);
output_high(RF_CE);
delay_us(150);
}
//*****************************************************
//*****************************************************
//* RF_OFF() *
//*****************************************************
//*Descripción:Este procedimiento desactiva el módulo *
//*de radiofrecuencia. *
//*****************************************************
//*Variables de entrada: *
//*Variables de salida: *
//*****************************************************
void RF_OFF()
{
output_low(RF_CE);
// CONFIG
//Se desactiva el modulo
output_low(RF_CS);
spi_write(0x20);
spi_write(0x0C);
output_high(RF_CS);
}
//*****************************************************
//*****************************************************
//* RF_SEND() *
//*****************************************************
//*Descripción:Esta función envía 8 Bytes de datos a *
//*la dirección indicada informando de la correcta *
//*recepción en el destinatario. *
//*****************************************************
//*Variables de entrada:- RF_DATA[] *
//* - RF_DIR
//*Variables de salida: - *
//*Salida: - 0: Envío correcto (ACK OK) *
//* - 1: No recepcibido (NO ACK) *
//* - 2: No enviado *
//*****************************************************
int RF_SEND()
{
int i;
int estado;
if(bit_test(INTCON,7))
interRF=1;
else
interRF=0;
disable_interrupts(GLOBAL);
// INICIO
output_low(RF_CE);
//STATUS
//Reseteo del registro STATUS
output_low(RF_CS);
spi_write(0x27);
spi_write(0x70);
output_high(RF_CS);
// EN_RXADDR
//Se habilita el Pipe0 para la recepción del ACK
output_low(RF_CS);
spi_write(0x22);
spi_write(0x01);
output_high(RF_CS);
// TX_ADDR
//Se configura la dirección de transmisión=RF_DIR
output_low(RF_CS);
spi_write(0x30);
spi_write(RF_DIR);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
output_high(RF_CS);
// RX_ADDR_P0
//Para la recepción del ACK se debe configurar el Pipe0 con
//la misma dirección a trasmitir.
output_low(RF_CS);
spi_write(0x2A);
spi_write(RF_DIR);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
output_high(RF_CS);
// RX_ADDR_P1
//Se mete en RF_DIR la direccion propia.
//De esta manera el receptor sabe la dirección
//del transmisor.
output_low(RF_CS);
spi_write(0x0B);
RF_DIR=spi_read(0);
spi_read(0);
spi_read(0);
spi_read(0);
spi_read(0);
output_high(RF_CS);
// W_TX_PAYLOAD
//Se manda los datos al transductor
output_low(RF_CS);
spi_write(0xA0);
DATA_N_SND++;
spi_write(DATA_N_SND);
spi_write(RF_DIR);
for (i=0;i<8;i++)
{
spi_write(RF_DATA[i]);
}
output_high(RF_CS);
// CONFIG
//Se pasa a modo transmisión.
output_low(RF_CS);
spi_write(0x20);
spi_write(0x0E);
output_high(RF_CS);
// Pulso de comienzo de envío
output_high(RF_CE);
delay_us(15);
output_low(RF_CE);
noRF=0;
while (input(RF_IRQ)==1) {
noRF++;
//Si no da respuesta en 7ms, no se ha enviado.
if(noRF==500) { break; }
}
// STATUS
//Lectura del estado en el registro estatus.
output_low(RF_CS);
estado=spi_read(0x27);
spi_write(0x70);
output_high(RF_CS);
// EN_RXADDR
//Habilitar los Pipe0,Pipe1 y Pipe2.
output_low(RF_CS);
spi_write(0x22);
spi_write(0x07);
output_high(RF_CS);
// TX_FLUSH
//Limpieza de la FIFO de salida
output_low(RF_CS);
spi_write(0xE1);
output_high(RF_CS);
// CONFIG
//Paso a modo recepción
output_low(RF_CS);
spi_write(0x20);
spi_write(0x0F);
output_high(RF_CS);
// FIN
output_high(RF_CE);
delay_us(150);
//Si no da respuesta en 7ms, no se ha enviado.
if(noRF==500)
{
if(interRF==1)
enable_interrupts(GLOBAL);
clear_interrupt(int_ext);
return(2);
}
//estado
//Chequeo de los bit del registro STATUS que indican si se ha recibido
//ACK y si se ha terminado las retrasmisiones sin ningun ACK.
if ((bit_test(estado,4)==0) && (bit_test(estado,5)==1)){
if(interRF==1)
enable_interrupts(GLOBAL);
clear_interrupt(int_ext);
return(0);
}
else{
if(interRF==1)
enable_interrupts(GLOBAL);
clear_interrupt(int_ext);
return(1);
}
}
//*****************************************************
//*****************************************************
//* RF_RECEIVE() *
//*****************************************************
//*Descripción: Esta rutina se encarga de comprobar si*
//*se ha producido una recepción y de ser así, *
//*devuelve la trama recibida. *
//*****************************************************
//*Variables de entrada:- *
//*Variables de salida: - RF_DATA[] *
//* - RF_DIR *
//*Salida: - 0: Recepción correcta y única *
//* - 1: Recepción correcta y múltiple *
//* - 2: No se ha producido recepción *
//* - 3: No se ha producido recepción *
//*****************************************************
int RF_RECEIVE()
{
int i;
int mas;
int estado;
if (input(RF_IRQ)==1 && RCVNW==0){
return (2);
}
//STATUS
//Lectura y reseteo del registro STATUS
output_low(RF_CS);
estado=spi_read(0x27);
spi_write(0x70);
output_high(RF_CS);
//estado
//Chequeo de la interrupción de recepción.
if (bit_test(estado,6)==0 && RCVNW==0){
return(3);
}
//R_RX_PAYLOAD
//Lectura de los datos recibidos.
output_low(RF_CS);
spi_write(0x61);
DATA_N_RCV=spi_read(0);
RF_DIR=spi_read(0);
for (i=0;i<8;i++)
{
RF_DATA[i]=spi_read(0);
}
output_high(RF_CS);
//FIFO_STATUS
//Comprobación del estado de la FIFO de
//recepción para comprobar si hay más datos
output_low(RF_CS);
spi_write(0x17);
mas=spi_read(0);
output_high(RF_CS);
if (bit_test(mas,0)==0){
RCVNW=1;
return(1);
}
RCVNW=0;
return(0);
}
//*****************************************************
#include <16F88.h>
#fuses XT //Oscilador a cristal standar
#fuses NOWDT //sin WatchDog Timer
#fuses NOPROTECT //sin proteccion de memoria de programa
#fuses NOPUT //sin PowerUp Timer
#fuses NOBROWNOUT //sin brownout
#fuses NOLVP //sin programación en baja tensión
#use delay(clock=4000000)
#include "lib_rf2gh4_10.h" // Librería para manejar el módulo SPI con el nRF24L01.
#byte porta=0x05 // Dirección del puerto A.
#byte portb=0x06 // Dirección del puerto B.
int8 ret1, data;
void main() //Programa principal
{
set_tris_a(0b100101); // RA0 sustituye a RB0 y se pone un LED en RA0.
set_tris_b(0b11000010); // RB0 es para la interrupción, el resto son LEDs.
RF_CONFIG_SPI(); // Configurar módulos SPI del PIC.
RF_CONFIG(0x40,0x08); // Configurar módulo RF (canal y dirección).
RF_ON(); // Activar el módulo RF.
}
void RF_CE ()
{
ret1 = RF_RECEIVE();
if ( (ret1 == 0) || (ret1 == 1) )
{
do
{
data=RF_DATA[0]; // Data contendrá el valor que le llege del emisor, a través de RF_DATA[0].
ret1 = RF_RECEIVE();
#asm
btfss data,0
bcf PORTA,4
BTFSC data,0
BSF PORTA,4
btfss data,1
bcf PORTB,0
BTFSC data,1
BSF PORTB,0
btfss data,2
bcf PORTB,3
BTFSC data,2
BSF PORTB,3
#endasm
} while ( (ret1 == 0) || (ret1 == 1) ); // Tanto si existe entrada múltiple o simple de datos los lee.
}
}
// PORTB
#define RF_IRQ PIN_A2
#define RF_IRQ_TRIS TRISA,2
// PORTC
#define RF_CS PIN_B5
#define RF_CE PIN_A3
#define SCK PIN_B4
#define SDI PIN_B1
#define SDO PIN_B2
#define RF_CS_TRIS TRISB,5
#define RF_CE_TRIS TRISA,3
#define SCK_TRIS TRISB,4
#define SDI_TRIS TRISB,1
#define SDO_TRIS TRISB,2
//*****************
//* VARIABLES *
//*****************
#BYTE TRISA = 0x85
#BYTE TRISB = 0x86
#BYTE INTCON = 0x10B // Registro de interrupciones. Sólo es importante el bit 7, GIE=interrupciones globales.
//Variables internas
static int1 interRF;
static int16 noRF;
static int1 RCVNW=0;
static int8 DATA_N_SND=0;
static int8 DATA_N_RCV=0;
//Variables configurables
static int8 RF_DATA[8];
static int8 RF_DIR;
//**************
//* CÓDIGO *
//**************
//*****************************************************
//* RF_CONFIG_SPI() *
//*****************************************************
//*Descripción: La función configura el módulo SPI del*
//*microcontrolador.En ella se especifica como salida *
//*SDO y como entrada SDI entre otros parámetros del *
//*protocolo SPI. *
//*****************************************************
//*Variables de entrada: *
//*Variables de salida: *
//*****************************************************
void RF_CONFIG_SPI()
{
//Configuración I/O.
bit_clear(SCK_TRIS);
bit_set(SDI_TRIS);
bit_clear(SDO_TRIS);
//Configuración módulo comunicaciones.
setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_4|SPI_SAMPLE_AT_END);
}
//*****************************************************
//*****************************************************
//* RF_INT_EN() *
//*****************************************************
//*Descripción:Se encarga de habilitar la interrupción*
//*externa (RB0) utilizada por el módulo de RF en la *
//*recepción de datos. *
//*****************************************************
//*Variables de entrada: *
//*Variables de salida: *
//*****************************************************
void RF_INT_EN()
{
//Habilitar interrupciones externas con flanco de
//bajada.
disable_interrupts(global);
enable_interrupts(int_ext);
ext_int_edge( H_TO_L );
bit_set(RF_IRQ_TRIS);
enable_interrupts(global);
}
//*****************************************************
//*****************************************************
//* RF_CONFIG(int canal, int dir) *
//*****************************************************
//*Descripción:Esta función se encarga de configurar *
//*el transceptor habilitando su propia dirección de *
//*escucha y el canal entre otros parámetros. *
//*****************************************************
//*Variables de entrada:- Canal *
//* - Direccion *
//*Variables de salida: *
//*****************************************************
void RF_CONFIG(int canal, int dir)
{
bit_clear(RF_CS_TRIS);
bit_set(RF_IRQ_TRIS);
bit_clear(RF_CE_TRIS);
output_low(RF_CE);
// TX_ADDR (0xFF)
//Configuración de la dirección de envío aleatoria.
//En la función de enviar se configura la dirección
//deseada por el usuario.
output_low(RF_CS);
spi_write(0x30);
spi_write(0xFF);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
output_high(RF_CS);
// RX_ADDR_P0 (0xFF) ACK
//Configuración de la direccióndel Pipe0 para la
//recepción de ACK.
output_low(RF_CS);
spi_write(0x2A);
spi_write(0xFF);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
output_high(RF_CS);
// RX_ADDR_P1 (dir)
//Configuración de la direccióndel Pipe1 para la
//recepción de tramas.
output_low(RF_CS);
spi_write(0x2B);
spi_write(dir);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
output_high(RF_CS);
// RX_ADDR_P2 (0x00) BROADCAST
//Configuración de la direccióndel Pipe2 para la
//recepción de tramas
output_low(RF_CS);
spi_write(0x2C);
spi_write(0x00);
output_high(RF_CS);
// EN_AA
//Habilitar AutoAck en los Pipe0,Pipe1 y Pipe2.
output_low(RF_CS);
spi_write(0x21);
spi_write(0x07);
output_high(RF_CS);
// EN_RXADDR
//Habilitar los Pipe0,Pipe1 y Pipe2.
output_low(RF_CS);
spi_write(0x22);
spi_write(0x07);
output_high(RF_CS);
// SETUP_AW
//Configuración de la longitud de las direcciones.
//Direcciones de 5 bytes.
output_low(RF_CS);
spi_write(0x23);
spi_write(0x03);
output_high(RF_CS);
//SETUP_RETR
//Configuración de las retrasmisiones en la transmisión.
//Diez retransmisiones cada 336us.
output_low(RF_CS);
spi_write(0x24);
spi_write(0x0A);
output_high(RF_CS);
//RF_CH
//Configuración del canal.
//Canal elegido por el usuario (0x01 - 0x7F).
output_low(RF_CS);
spi_write(0x25);
spi_write(canal);
output_high(RF_CS);
//RF_SETUP
//Configuración aspectos RF. *******************************************************************************************
//Ganancia máxima de LNA, 0dBm potencia de salida y 2Mbps de velocidad. ************************************************
output_low(RF_CS);
spi_write(0x26);
spi_write(0x07); // Lo he cambiado a 1Mbps. Originalmente era 0x0F.
output_high(RF_CS);
//STATUS
//Reseteo del registro STATUS
output_low(RF_CS);
spi_write(0x27);
spi_write(0x70);
output_high(RF_CS);
//RX_PW_P0
//Nº de bytes en Pipe0.
//1 byte (ACK).
output_low(RF_CS);
spi_write(0x31);
spi_write(0x01);
output_high(RF_CS);
//RX_PW_P1
//Nº de bytes en Pipe1.
//10 byte (Direccion emisor y trama).
output_low(RF_CS);
spi_write(0x32);
spi_write(0x0A);
output_high(RF_CS);
//RX_PW_P2
//Nº de bytes en Pipe2.
//10 byte (Direccion emisor y trama).
output_low(RF_CS);
spi_write(0x33);
spi_write(0x0A);
output_high(RF_CS);
}
//*****************************************************
//*****************************************************
//* RF_ON() *
//*****************************************************
//*Descripción:Esta rutina activa el módulo de *
//*radiofrecuencia en modo escucha para poder recibir *
//*datos enviados a su dirección. *
//*****************************************************
//*Variables de entrada: *
//*Variables de salida: *
//*****************************************************
void RF_ON()
{
output_low(RF_CE);
// CONFIG
//Se activa el modulo, se pone en recepción,
//se activa el CRC para que utilice 2 bytes.
output_low(RF_CS);
spi_write(0x20);
spi_write(0x0F);
output_high(RF_CS);
delay_ms(2);
output_high(RF_CE);
delay_us(150);
}
//*****************************************************
//*****************************************************
//* RF_OFF() *
//*****************************************************
//*Descripción:Este procedimiento desactiva el módulo *
//*de radiofrecuencia. *
//*****************************************************
//*Variables de entrada: *
//*Variables de salida: *
//*****************************************************
void RF_OFF()
{
output_low(RF_CE);
// CONFIG
//Se desactiva el modulo
output_low(RF_CS);
spi_write(0x20);
spi_write(0x0C);
output_high(RF_CS);
}
//*****************************************************
//*****************************************************
//* RF_SEND() *
//*****************************************************
//*Descripción:Esta función envía 8 Bytes de datos a *
//*la dirección indicada informando de la correcta *
//*recepción en el destinatario. *
//*****************************************************
//*Variables de entrada:- RF_DATA[] *
//* - RF_DIR
//*Variables de salida: - *
//*Salida: - 0: Envío correcto (ACK OK) *
//* - 1: No recepcibido (NO ACK) *
//* - 2: No enviado *
//*****************************************************
int RF_SEND()
{
int i;
int estado;
if(bit_test(INTCON,7))
interRF=1;
else
interRF=0;
disable_interrupts(GLOBAL);
// INICIO
output_low(RF_CE);
//STATUS
//Reseteo del registro STATUS
output_low(RF_CS);
spi_write(0x27);
spi_write(0x70);
output_high(RF_CS);
// EN_RXADDR
//Se habilita el Pipe0 para la recepción del ACK
output_low(RF_CS);
spi_write(0x22);
spi_write(0x01);
output_high(RF_CS);
// TX_ADDR
//Se configura la dirección de transmisión=RF_DIR
output_low(RF_CS);
spi_write(0x30);
spi_write(RF_DIR);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
output_high(RF_CS);
// RX_ADDR_P0
//Para la recepción del ACK se debe configurar el Pipe0 con
//la misma dirección a trasmitir.
output_low(RF_CS);
spi_write(0x2A);
spi_write(RF_DIR);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
spi_write(0xC2);
output_high(RF_CS);
// RX_ADDR_P1
//Se mete en RF_DIR la direccion propia.
//De esta manera el receptor sabe la dirección
//del transmisor.
output_low(RF_CS);
spi_write(0x0B);
RF_DIR=spi_read(0);
spi_read(0);
spi_read(0);
spi_read(0);
spi_read(0);
output_high(RF_CS);
// W_TX_PAYLOAD
//Se manda los datos al transductor
output_low(RF_CS);
spi_write(0xA0);
DATA_N_SND++;
spi_write(DATA_N_SND);
spi_write(RF_DIR);
for (i=0;i<8;i++)
{
spi_write(RF_DATA[i]);
}
output_high(RF_CS);
// CONFIG
//Se pasa a modo transmisión.
output_low(RF_CS);
spi_write(0x20);
spi_write(0x0E);
output_high(RF_CS);
// Pulso de comienzo de envío
output_high(RF_CE);
delay_us(15);
output_low(RF_CE);
noRF=0;
while (input(RF_IRQ)==1) {
noRF++;
//Si no da respuesta en 7ms, no se ha enviado.
if(noRF==500) { break; }
}
// STATUS
//Lectura del estado en el registro estatus.
output_low(RF_CS);
estado=spi_read(0x27);
spi_write(0x70);
output_high(RF_CS);
// EN_RXADDR
//Habilitar los Pipe0,Pipe1 y Pipe2.
output_low(RF_CS);
spi_write(0x22);
spi_write(0x07);
output_high(RF_CS);
// TX_FLUSH
//Limpieza de la FIFO de salida
output_low(RF_CS);
spi_write(0xE1);
output_high(RF_CS);
// CONFIG
//Paso a modo recepción
output_low(RF_CS);
spi_write(0x20);
spi_write(0x0F);
output_high(RF_CS);
// FIN
output_high(RF_CE);
delay_us(150);
//Si no da respuesta en 7ms, no se ha enviado.
if(noRF==500)
{
if(interRF==1)
enable_interrupts(GLOBAL);
clear_interrupt(int_ext);
return(2);
}
//estado
//Chequeo de los bit del registro STATUS que indican si se ha recibido
//ACK y si se ha terminado las retrasmisiones sin ningun ACK.
if ((bit_test(estado,4)==0) && (bit_test(estado,5)==1)){
if(interRF==1)
enable_interrupts(GLOBAL);
clear_interrupt(int_ext);
return(0);
}
else{
if(interRF==1)
enable_interrupts(GLOBAL);
clear_interrupt(int_ext);
return(1);
}
}
//*****************************************************
//*****************************************************
//* RF_RECEIVE() *
//*****************************************************
//*Descripción: Esta rutina se encarga de comprobar si*
//*se ha producido una recepción y de ser así, *
//*devuelve la trama recibida. *
//*****************************************************
//*Variables de entrada:- *
//*Variables de salida: - RF_DATA[] *
//* - RF_DIR *
//*Salida: - 0: Recepción correcta y única *
//* - 1: Recepción correcta y múltiple *
//* - 2: No se ha producido recepción *
//* - 3: No se ha producido recepción *
//*****************************************************
int RF_RECEIVE()
{
int i;
int mas;
int estado;
if (input(RF_IRQ)==1 && RCVNW==0){
return (2);
}
//STATUS
//Lectura y reseteo del registro STATUS
output_low(RF_CS);
estado=spi_read(0x27);
spi_write(0x70);
output_high(RF_CS);
//estado
//Chequeo de la interrupción de recepción.
if (bit_test(estado,6)==0 && RCVNW==0){
return(3);
}
//R_RX_PAYLOAD
//Lectura de los datos recibidos.
output_low(RF_CS);
spi_write(0x61);
DATA_N_RCV=spi_read(0);
RF_DIR=spi_read(0);
for (i=0;i<8;i++)
{
RF_DATA[i]=spi_read(0);
}
output_high(RF_CS);
//FIFO_STATUS
//Comprobación del estado de la FIFO de
//recepción para comprobar si hay más datos
output_low(RF_CS);
spi_write(0x17);
mas=spi_read(0);
output_high(RF_CS);
if (bit_test(mas,0)==0){
RCVNW=1;
return(1);
}
RCVNW=0;
return(0);
}
//*****************************************************
En tu tercer código mostrado, luego del main defines una funciónCódigo: C
void RF_CE ()
Pero RF_CE también es una definición que tienes en la librería... Tal vez ello esté generando un conflicto
Correcto, el problema es lo que menciona AngelGris, llama tu funcion con otro nombre aunque otro problema que tambien veo es que nunca mandas llamar esa funcion, o me equivoco
Suerte!
y como recomendacion primero modifica solo la libreria que adjunte algunos mensajes arriba, solo eso lo demas solo adaptalo a tu micro y prueba, para que veas que funciona, posteriormente ve haciendo tus cambios y modificaciones especificas, yo te puedo asegurar que el programa funciona perfectamente bien incluso ahorita acabo de realizar envio y recepcion de 8 bytes por paquete y funciona perfectamente
Suerte!