Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

13/10/2014 #1


Problema con USB CDC + modulo SPI + CCS C + PIC
Hola, estoy tratando de usar un modulo de comunicación inalambrica, concretamente el nrF24L01, y a la vez tener comunicación USB CDC. Como micro, uso un 18F26J50 que lleva USB nativo. Cristal usado de 4 Mhz.

Ademas, tengo un bootloader usb cdc.

Todo lo correspondiente al bootloader, uso los códigos del compilador ccs c en su version 5.025

Si pruebo el código del modulo de comunicación sin bootloader y sin especificarle nada sobre este, funciona perfecto, pero si pongo el bootloader, añado al código lo necesario para que sea compatible con el bootloader, no va. Se me queda colgado cuando descomento las lineas correspondientes a la configuración del modulo e interrupciones.

Tampoco me funciona lo correspondiente a la RTC, si que se va a dormir, pero no despierta. Probado sin nada de usb, funciona todo bien.

Algo configuro mal, o me dejo pasos de hacer.

Adjunto el código correspondiente al programa, y la libreria del modulo nrf. Los fuses configurados en el archivo main, son los mismos que tiene el bootloader.

Programa principal:
Código:
 #include <main.h>
 #include <usb_bootloader.h>
//#include <18F26J50.h>

// Libreria modulo comunicacion NRF24L01+
#include "lib_rf2gh4_10_mod.h"



#include "string.h"

//#byte porta=0x05
//#byte portb=0x06

#byte WDTCON = 0xFC0
#byte DSCONH = 0xF4D
#byte DSCONL = 0xF4C
#byte RTCCFG = 0xF3F
#byte DSWAKEH= 0xF4B
#byte DSWAKEL= 0xF4A
#byte OSCCON = 0xFD3

#bit IDLEN =OSCCON.7      // Used to set IDLE low-power mode
#bit DSEN = DSCONH.7      // Used to set deep sleep
#bit REGSLP =WDTCON.7
#bit RELEASE = DSCONL.0
#bit RTCSYNC = RTCCFG.4
#bit DS_WAKEUP_BIT = WDTCON.3   // Bit that detects wake up from DS
#bit DSRTC = DSWAKEL.3

int8 buffer[8];  // Buffer de 8 bytes.
char buff[32];   //Buffer para el frame.
int8 ret2;
int l; //Indice para parpadeo led estado.

boolean debug = 1;

float temperatura = 0.0;

//-----------------------------------------------------
// Identificador (Nombre del dispositivo).
// Nota: Vector de 8 bytes. 7 para caracteres, 1 para vector NULL.
char ident[9] = "Mote_01 "; 
//-----------------------------------------------------


// Funcion para configurar el sleep y activarlo.

void Set_Sleep(){

//int l;
rtc_time_t SetTime;
rtc_time_t AlarmTime;
//rtc_time_t read_clock;

/*
output_low(PIN_A1);
output_low(PIN_A3);
output_high(PIN_A3); 
delay_ms(2500);
output_low(PIN_A3);
delay_ms(2500);
*/

// Release the PIC's i/o pins for normal operation
// after waking up from Deep Sleep.  Important !
//RELEASE = 0;   

/*
// Tell what caused us to start-up.
if((DS_WAKEUP_BIT == 1) && (DSRTC == 1)){
  // printf("\n\rWake-up by RTCC alarm from Deep Sleep.\n\r");
  
    //Led de estado.
       for (l=0;l<2;l++){
        output_low(PIN_A1);
        delay_ms(1000);         
        output_high(PIN_A1);
        delay_ms(10000);
        output_low(PIN_A1);}
        delay_ms(2000);
        
}
else
{
  // printf("\n\rStart-up by some other method.\n\r");
}
*/

setup_rtc(RTC_ENABLE,0);

// Set initial RTC date/time values in structure.
SetTime.tm_year = 0x11;
SetTime.tm_mon  = 3;
SetTime.tm_mday = 9;
SetTime.tm_wday = 3;
SetTime.tm_hour = 0x11;
SetTime.tm_min  = 0x47;
SetTime.tm_sec  = 0;

// Write that structure into the RTC hardware registers
// inside the 18F26J11.
rtc_write(&SetTime); 


// Set RTC alarm date/time.
AlarmTime.tm_year = 0x11;
AlarmTime.tm_mon  = 3;
AlarmTime.tm_mday = 9;
AlarmTime.tm_wday = 3;
AlarmTime.tm_hour = 0x11;
AlarmTime.tm_min  = 0x47;
AlarmTime.tm_sec  = 8;

/*
   while(1)
   {
      rtc_read(&read_clock);        //reads clock value from RTCC
      printf("\n\r%02u/%02u/20%02u %02u:%02u:%02u",read_clock.tm_mon,read_clock.tm_mday,read_clock.tm_year,read_clock.tm_hour,read_clock.tm_min,read_clock.tm_sec);
      delay_ms(1000);
   }
*/


setup_rtc_alarm(RTC_ALARM_ENABLE, RTC_ALARM_MINUTE, 0xFF);

// Configurar la alarma despues de setup_rtc_alarm si no queremos
// usar un tiempo predefinido (como el de 1 segundo, 10 segundos, 1 hora, etc).
rtc_alarm_write(&AlarmTime); 
    
    
//printf("Going to sleep.\n\r");

// Enable Deep Sleep mode.
REGSLP = 1;    // enable low-power operation in sleep mode
IDLEN = 0;
while(RTCSYNC);
#asm       // Time-critical section must be in ASM 
BSF DSEN
SLEEP
#endasm

// We should never reach the following line after a
// Deep Sleep RTCC wake-up, because it does a reset
// intentionally. It re-starts code execution at main().
//printf("Woke-up from sleep ! \r\n");

while(1);
} 

///////////////////////////////////////////////////////////////////////////////


// Funcion envio del frame en 4 bloques de 8 bits.
void Send_frame(){
   int i;
   int fc;
   for (fc=0;fc<32;fc++){

       for (i=0;i<8;i++){
          RF_DATA[i] = Buff[fc];
          fc++;         
       }
       fc--; //Restamos 1 para no saltarnos un byte en el siguiente bucle, pues
             //se lo suma antes de ejecutar las instrucciones.
      // RF_DATA[0] = Buff[0];      
       RF_DIR=0x08;           // Dirección del receptor.
       ret2=RF_SEND();        // Enviar datos.
       delay_ms(100);  
   }
}

// Interrupcion. Lee el paquete recibido.
#int_ext
void int_RB0()
{
   int8 ret1;

   
   ret1 = RF_RECEIVE();
   if ( (ret1 == 0) || (ret1 == 1) )
   {
      do
      { 
        //Asigno los 8 bytes de entrada a un buffer secundario.
        buffer[0] = RF_DATA[0];
        buffer[1] = RF_DATA[1];
        buffer[2] = RF_DATA[2];
        buffer[3] = RF_DATA[3];
        buffer[4] = RF_DATA[4]; 
        buffer[5] = RF_DATA[5]; 
        buffer[6] = RF_DATA[6]; 
        buffer[7] = RF_DATA[7]; 
        ret1 = RF_RECEIVE(); 
        
      }  while ( (ret1 == 0) || (ret1 == 1) );
   }  
}

///////////////////////////////////////////////////////////////////////////////
// Empieza el programa principal.
///////////////////////////////////////////////////////////////////////////////

void main()
{  
   usb_init_cs();
   
   char s[7];  //Variable string para el dato de la temperatura.
   char frase[14] = "Temperatura: ";
   //Variables para el frame de pruebas.
   int g;
   int gg;
   
      
   output_high(PIN_B3); // LED RGB APAGADO.
   output_high(PIN_B1); // LED RGB APAGADO.
  // output_high(PIN_C6); // LED RGB APAGADO.
   
   /*
   RF_ON();
   delay_ms(500);
   //RF_INT_EN();              // Habilitar interrupción RB0/INT. ** Aqui se cuelga
   delay_ms(500);
   RF_CONFIG_SPI();          // Configurar módulo SPI del PIC. ** Aqui se cuelga.
   delay_ms(500);
   RF_CONFIG(0x40,0x01);     // Configurar módulo RF canal y dirección.
   delay_ms(500);
   RF_OFF();                 // Modulo RF off.
   */
   delay_ms(100);
   
  // set_tris_a(0b000001);     // Todo el puerto A como entradas.
   
    
   //
   output_low(PIN_A3);       //Led de estado apagado.
  // output_high(PIN_A1);       // Sensor humedad OFF.
   
   // Configurar ADC.
   setup_adc_ports(sAN4,sAN2);//Definimos las entradas analógicas.
   //setup_adc_ports(ALL_ANALOG|VSS_VDD); 
   delay_us (20);
   setup_adc (ADC_CLOCK_INTERNAL);//Configuramos el modo del convertidor.
   delay_ms (20);
   
   while(true)
   {  
      usb_task();
      
      if (usb_enumerated() ) {   
     // delay_ms(2000);
      printf(usb_cdc_putc, "\r\n\ -- Programa Test nrF24L01 --\r\n");
      }
      
     // output_low(PIN_B3);
     // delay_ms(1000);
     
      // Release the PIC's i/o pins for normal operation
      // after waking up from Deep Sleep.  Important !
   //   RELEASE = 0;  
      
      int t; //Indice para varias medidas de temperatura.
      
     // output_low(PIN_C6);
  
    //  delay_ms(2000);
      //Led de estado.
      
       for (l=0;l<2;l++){
       
        output_low(PIN_B3);
        output_low(PIN_B1); // LED RGB APAGADO.
      //  output_low(PIN_C6); // LED RGB APAGADO.
        delay_ms(500);         
       
        output_high(PIN_B3); // LED RGB APAGADO.
       output_high(PIN_B1); // LED RGB APAGADO.
      // output_high(PIN_C6); // LED RGB APAGADO.
        delay_ms(500);
       
      
       if (usb_enumerated() ) {   
      //delay_ms(2000);
      printf(usb_cdc_putc, " +\r\n");
      }
        }
       
        
        delay_ms(200);
      
      //LECTURA DE SENSORES.      
        set_adc_channel(4); //Selección del canal analógico.
        delay_us (20);
        temperatura=0.0;
        
        //Varias medidas para sacar una media de la temperatura.
        for (t=0;t<2;t++){
         temperatura += read_adc();
         delay_ms(10);        
        }
        temperatura = (temperatura/2);       
        delay_ms(1);
        
       
       
     //Calculo de la temperatura dada por el sensor MCP9700. 
     //ADC configurado a 10 bits. Vcc = 3.3v.
     temperatura = (temperatura*(3.3/1024.0));
  
     
     //temperatura = 105;     
    
     //Conversion float to string.
     sprintf(s,"%3.2f",temperatura);
    if (usb_enumerated() ) {           
      printf(usb_cdc_putc, "Temperatura: %3.2f --\r\n", temperatura);      
      }
        
     // Cargo informacion al frame para ser enviada.
     
     gg = 0;
     for (g=0;g<9;g++){
          Buff[gg] = ident[g];
          gg++;
     }
     
     for (g=0;g<13;g++)
         {         
            Buff[gg] = frase[g];
            gg++;
         }
         
      for (g=0;g<5;g++)
         {         
            Buff[gg] = s[g];
            gg++;
         }
         
      for (g=0;g<5;g++)
         {            
            Buff[gg] = " ";
            gg++;
         }    
      
      /*
      //AZUL
      if (temperatura > 500){
       //  Buff[0] = 0x30;
         output_low(PIN_B1);
      }
      //ROJO
      if (temperatura < 200){
        // Buff[0] = 0x10;
         output_low(PIN_C6);      
      }
      //VERDE
      if ((temperatura > 200) && (temperatura < 500)){
        // Buff[0] = 0x20;
         output_low(PIN_B3);
      }
      */
     
      delay_ms(10);

    //  RF_ON();                  // Activar el módulo RF.
      delay_ms(500);
      //Led de estado.
      
       for (l=0;l<3;l++){
       // output_low(PIN_A3);
        output_low(PIN_B1);
        delay_ms(500);         
      //  output_high(PIN_A3);
        output_high(PIN_B1);
        delay_ms(500);
     //   output_low(PIN_A3);
      if (usb_enumerated() ) {   
     // delay_ms(2000);
      printf(usb_cdc_putc, " +\r\n");
      }
         }
         
     
   //   Send_frame(); //Envio el frame por RF.
      delay_ms(500);

    //  RF_OFF();                  // Apagar el módulo RF.
      
      //Tiempo de espera.
      Delay_ms(200);
      
       
          
      output_high(PIN_B3); // LED RGB APAGADO.
      output_high(PIN_B1); // LED RGB APAGADO.
    //  output_high(PIN_C6); // LED RGB APAGADO.
      
     // Set_Sleep();
      
   }
}
Archivo main

Código:
#include <18F26J50.h>
#device ADC=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES T1DIG                    //Secondary Oscillator Source may be select regardless of T1CON.3 state
#FUSES NOLPT1OSC                //Timer1 configured for higher power operation
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES DSWDTOSC_INT             //DSWDT uses INTRC as reference clock
#FUSES RTCOSC_T1                //RTCC uses Secondary Oscillator as reference source
#FUSES DSBOR                    //BOR enabled in Deep Sleep
#FUSES DSWDT                    //Deep Sleep Watchdog Timer enabled
#FUSES DSWDT2147483648          //DSWDT uses 1:2147483648 Postscale
#FUSES IOL1WAY                  //Allows only one reconfiguration of peripheral pins
#FUSES MSSPMSK7                 //MSSP uses 7 bit Masking mode
#FUSES WPFP                     //Write/Erase Protect Page Start/End Location, set to last page or use WPFP=x to set page
#FUSES WPEND                    //Flash pages WPFP to Configuration Words page are write/erase protected
#FUSES NOWPCFG                  //Configuration Words page is not erase/write-protected
#FUSES WPDIS                    //All Flash memory may be erased or written

#use delay(clock=48000000,crystal=4000000,USB_FULL)

#include <usb_cdc.h>
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_B2
#define   RF_CE       PIN_C2
#define   SCK         PIN_B4
#define   SDI         PIN_B5
#define   SDO         PIN_B0
                      
#define   RF_CS_TRIS  TRISB,2
#define   RF_CE_TRIS  TRISC,2
#define   SCK_TRIS    TRISB,4
#define   SDI_TRIS    TRISB,5
#define   SDO_TRIS    TRISB,0



//*****************
//*   VARIABLES   *
//*****************
#BYTE TRISA     =  0xF92
#BYTE TRISB     =  0xF93
#BYTE TRISC     =  0xF94
#BYTE INTCON    =  0xFF2

//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);
   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);
}
//*****************************************************
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.