Hola compañeros del foro, después de casi 2 semanas de romperme la cabeza y gastar mucha plata en analgésicos. Decidí consultar con ustedes que tal vez alguno tuvo alguna vez algo parecido por lo general puedo arreglármelas solo pero esto ya se me va de las manos. Nunca me paso algo igual, Por lo general mis problemas con el puerto SPI suelen darse en el hardware.
Bueno sin más rodeos Les cuento que estoy trabajando en un proyecto de transmisión y recepción de datos al PC via RF con el NRF24L01 de nordic cosa que me parece una herramienta fantástica y muy muy al alcance de cualquier desarrollador. Todo andaba bien en un principio, tenía algunas fallas intermitentes pero no les di mucha importancia. Pero ahora que tengo que cerrar el proyectito este, me encuentro con cosas extremadamente raras como el hecho de voltajes escalonados en las entradas y salidas del bus SPI, mi único periférico es este transmisorcito SPI. Para resumir les muestro las fotos que estuve sacando, este escalonamiento es continuo no es intermitente, siempre esta ahí a veces anda el transmisor a veces no. Primero desconfiando de los Chinos que encargue 50 pics 16F887 tqfp44 a casi 50 centavos de dólar cada uno, me dirigí a elemon y lo único que conseguí en tqfp44 fue el pic16F1937, pero ho sorpresa! me pasa exactamente lo mismo! la interface digital sigue escalonada. Ya tome en cuenta capacitores de desacoplo y demás. Pero nada de lo que modifique en hardware y software dan resultado
Libreria NRF24L01+
Programa PIC
Bueno basicamente es compartir y ver si no soy el unico al que le pasa esto, Pero de todos modos cualquier ayuda o sugerencia viene bien, cuanyo ya se agotan las posibilidades otras cabezas pueden tener diferentes ideas a las mias. Saludos ...
desgraciadamente no me dejo subir las fotos soy muy nuevo para poner links.
aca pude poner las fotos !
Bueno sin más rodeos Les cuento que estoy trabajando en un proyecto de transmisión y recepción de datos al PC via RF con el NRF24L01 de nordic cosa que me parece una herramienta fantástica y muy muy al alcance de cualquier desarrollador. Todo andaba bien en un principio, tenía algunas fallas intermitentes pero no les di mucha importancia. Pero ahora que tengo que cerrar el proyectito este, me encuentro con cosas extremadamente raras como el hecho de voltajes escalonados en las entradas y salidas del bus SPI, mi único periférico es este transmisorcito SPI. Para resumir les muestro las fotos que estuve sacando, este escalonamiento es continuo no es intermitente, siempre esta ahí a veces anda el transmisor a veces no. Primero desconfiando de los Chinos que encargue 50 pics 16F887 tqfp44 a casi 50 centavos de dólar cada uno, me dirigí a elemon y lo único que conseguí en tqfp44 fue el pic16F1937, pero ho sorpresa! me pasa exactamente lo mismo! la interface digital sigue escalonada. Ya tome en cuenta capacitores de desacoplo y demás. Pero nada de lo que modifique en hardware y software dan resultado
Libreria NRF24L01+
Código:
//********************************************************************************
//* lib_rf2gh4_10.h *
//* version: 1.0 *
//* Esta librería contiene las funciones necesarias para gestionar el módulo *
//* RF2GH4 con programas del compilador CCS *
//* Copyright (C) 2007 Bizintek Innova S.L. *
//********************************************************************************
//* This program is free software; you can redistribute it and/or modify *
//* it under the terms of the GNU General Public License as published by *
//* the Free Software Foundation; either version 2 of the License, or *
//* (at your option) any later version. *
//* *
//* This program is distributed in the hope that it will be useful, *
//* but WITHOUT ANY WARRANTY; without even the implied warranty of *
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
//* GNU General Public License for more details. *
//* *
//* You should have received a copy of the GNU General Public License along *
//* with this program; if not, write to the Free Software Foundation, Inc., *
//* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
//********************************************************************************
//********************
//* DEFINICIONES *
//********************
// PORTB
#define RF_IRQ PIN_B0
#define RF_IRQ_TRIS TRISB,0
// PORTC
#define RF_CS PIN_D3//PIN_C2
#define RF_CE PIN_D0//PIN_C1
#define SCK PIN_C3
#define SDI PIN_C4
#define SDO PIN_C5
#define RF_CS_TRIS TRISD,3
#define RF_CE_TRIS TRISD,0
#define SCK_TRIS TRISC,3
#define SDI_TRIS TRISC,4
#define SDO_TRIS TRISC,5
//*****************
//* VARIABLES *
//*****************
#BYTE TRISA = 0x85
#BYTE TRISB = 0x86
#BYTE TRISC = 0x87
#BYTE TRISD = 0x88
#BYTE TRISE = 0x89
#BYTE INTCON = 0x0B
//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 envio aleatoria.
//En la función de enviar se configura la direccion
//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);
spi_write(0x00);
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);
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);
}
//*****************************************************
Programa PIC
Código:
#include <16F1937.h>
#device ADC = 10
//#FUSES XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD
#FUSES NOWDT, INTRC_IO, NOPUT, NOPROTECT, NODEBUG, noBROWNOUT, NOLVP, NOCPD, NOWRT,NOMCLR,IESO,FCMEN
//#FUSES INTRC, NOMCLR
//#use i2c(MASTER, sda=PIN_A1, scl=PIN_A2, stream=I2CM)
#use delay(clock=4000000)
#include "lib_rf2gh4_10.h"
//#byte porta=0x00
//#byte portb=0x06
#bit T1GSEL = 285.3
//#define MPU6050_W 0b11010010
//#define MPU6050_R 0b11010011
//#define MPU6050_RA_WHO_AM_I 0x75 //quien soy
#define TRIS_A7 TRISA,7
#define TRIS_A6 TRISA,6
#define TRIS_A5 TRISA,5
#define TRIS_A4 TRISA,4
#define TRIS_A3 TRISA,3
#define TRIS_E0 TRISE,0
#define TRIS_E1 TRISE,1
//unsigned int temp[14];
// unsigned int Ax_raw, Ay_raw, Az_raw;
// char salida1[7];
LONG I ;
LONG D ;
int8 ret1;
int8 ret2;
#int_ext
void ISR()
{
//ret1 = RF_RECEIVE();
// } while ( (ret1 == 0) || (ret1 == 1) );
// }
}
void main()
{
setup_oscillator(OSC_8MHZ|OSC_PLL_OFF);
setup_dac(DAC_OFF);
setup_vref(VREF_OFF);
setup_WDT(WDT_OFF);
setup_ccp1(CCP_OFF); // Configure CCP1
setup_ccp2(CCP_OFF);
T1GSEL=0;
//Delay_us(100);
//RF_INT_EN(); // Habilitar interrupción RB0/INT.
//Delay_us(100);
RF_CONFIG_SPI(); // Configurar módulo SPI del PIC.
//Delay_us(100);
RF_CONFIG(0x40,0x01); // Configurar módulo RF canal y dirección.
//Delay_us(100);
RF_ON();// Activar el módulo RF.
//Delay_ms(100);
while(true)
{
//ret1 = RF_RECEIVE();
RF_DIR=0x08; // Dirección del receptor.
ret2=RF_SEND(); // Enviar datos.
}
}
Bueno basicamente es compartir y ver si no soy el unico al que le pasa esto, Pero de todos modos cualquier ayuda o sugerencia viene bien, cuanyo ya se agotan las posibilidades otras cabezas pueden tener diferentes ideas a las mias. Saludos ...
desgraciadamente no me dejo subir las fotos soy muy nuevo para poner links.
aca pude poner las fotos !
Adjuntos
Última edición: