Rispondi a: Problema comunicazione NRF24L01+

Home Forum FORUM ELETTRONICA MICROCONTROLLORI E CODICI Problema comunicazione NRF24L01+ Rispondi a: Problema comunicazione NRF24L01+

#4307
Led_ON
Partecipante

Ok, posto anche il ricevitore, scusate.

CODICE RICEVITORE:

 sbit RF_CS_TRIS at TRISB3_bit; //PIN CHIP SELECT sbit RF_CE_TRIS at TRISB2_bit; //PIN ENABLE sbit SCK_TRIS at TRISB1_bit; //CLK SPI sbit SDI_TRIS at TRISB0_bit; //DATA IN sbit SDO_TRIS at TRISB5_bit; //DATA OUT //----------------------------------------------------------------------------------------------------------------------------// sbit SS_pin at RB3_bit; sbit CE_pin at RB2_bit; sbit SCK_pin at RB1_bit; sbit MOSI_pin at RB5_bit; sbit MISO_pin at RB0_bit; //----------------------------------------------------------------------------------------------------------------------------// sbit Led at RB4_bit; //LED INDICAZIONE //----------------------------------------------------------------------------------------------------------------------------// #define R_REGISTER_cmd 0x00 //COMANDO DI SCRITTURA #define W_REGISTER_cmd 0x20 //COMANDO DI LETTURA #define R_RX_PL_WID_cmd 0x60 //LEGGI DIMENSIONE PAYLOAD #define R_RX_PAYLOAD_cmd 0x61 //LEGGI PAYLOAD RICEVUTO #define W_TX_PAYLOAD_cmd 0xA0 //SCRIVI PAYLOAD #define W_ACK_PAYLOAD_cmd 0xA8 //ACK DEL PAYLOAD #define W_TX_PAYLOAD_NO_ACK_cmd 0xB0 //DISABILITA AUTO ACK #define FLUSH_TX_cmd 0xE1 //SVUOTA LA FIFO DEL TX #define FLUSH_RX_cmd 0xE2 //SVUOTA LA FIFO DELL'RX #define REUSE_TX_PL_cmd 0xE3 //RIUTILIZZA ULTIMO PAYLOAD INVIATO #define NOP_cmd 0xFF //NESSUN COMANDO //----------------------------------------------------------------------------------------------------------------------------// #define CONFIG_reg 0b00000000 //INTERRUPT , CRC, ON/OFF, TX MODE SETTING #define EN_AA_reg 0x01 //AUTO ACK PIPE #define EN_RXADDR_reg 0x02 //ABILITAZIONE INDIRIZZI RX #define SETUP_AW_reg 0x03 //NUMERO DI INDIRIZZI (5) #define SETUP_RETR_reg 0x04 //SETTING TEMPO DI RITRASMISSIONE (250uS) #define RF_CH_reg 0x05 //CANALE 5 #define RF_SETUP_reg 0b00000110 //{b5-b3 => (00 1Mbps),(01 2Mbps), (10 250Kbps)} {b2:b1 => (00 -18dBm), (01 -12dBm), (10 -6dBm), (11 0dBm)} #define STATUS_reg 0x07 //REGISTRO DI STATO, INVIATO AL PIN MOSI #define OBSERVE_TX_reg 0x08 //CONTA I LOST PACKET E I RETRASMITTED PACKET #define RPD_reg 0x09 //AVVERTE SE VI è UN TRASMETTITORE ATTIVO #define RX_ADDR_P0_reg 0x0A //RICEVE L'INDIRIZZO 0 #define RX_ADDR_P1_reg 0x0B // #define RX_ADDR_P2_reg 0x0C // #define RX_ADDR_P3_reg 0x0D // #define RX_ADDR_P4_reg 0x0E // #define RX_ADDR_P5_reg 0x0F // #define TX_ADDR_reg 0x10 //TRASMISSIONE INDIRIZZI #define RX_PW_P0_reg 0x11 //NUMERO DI BYTE DEL PAYLOAD NEL DATA PIPE 0 #define RX_PW_P1_reg 0x12 // #define RX_PW_P2_reg 0x13 // #define RX_PW_P3_reg 0x14 // #define RX_PW_P4_reg 0x15 // #define RX_PW_P5_reg 0x16 // #define FIFO_STATUS_reg 0x17 //RIUTILIZZA TRASMISSIONE E STATO DELLA FIFO #define DYNPD_reg 0x1C //ENABLE DYNAMIC PAYLOAD LENGHT #define FEATURE_reg 0x1D //ABILITAZIONE MODALITà DYPLD, ACK, NO ACK //----------------------------------------------------------------------------------------------------------------------------// unsigned char x = 0; //CONTIENE IL BYTE ricevuto //----------------------------------------------------------------------------------------------------------------------------// unsigned char nRF24L01_read() //questo sottoprogramma simula una comunicazione SPI { unsigned char s = 0; //variabile per esegguire 8 esecuzioni unsigned char msg = 0; for(s = 0; s < 8; s++){ //esegue 8 volte msg <<= 1; //shifto msg SCK_pin = 1; //attivo il clock delay_us(8); //aspetto 8us (f spi 62Kbps) if(MISO_pin != 0) //se in=0 { msg |= 1; //azzero il bit di msg } SCK_pin = 0; //disattivo il clock delay_us(8); } return msg; //ritorno il valore letto } //----------------------------------------------------------------------------------------------------------------------------// void nRF24L01_write(unsigned char d){ //sottoprogramma che simula una scrittura spi unsigned char s = 0; for(s = 0; s < 8; s++) //questo for serve a trasmettere sul pin mosi bit per bit il dato d { if((d & 0x80) != 0) { MOSI_pin = 1; //se il bit scandito è 1 trasmetto 1 } else { MOSI_pin = 0; //altrimenti 0 } d <<= 1; //shifto d per inviare il prossimo bit SCK_pin = 1; //creo un clock delay_us(8); SCK_pin = 0; delay_us(8); } } //----------------------------------------------------------------------------------------------------------------------------// void register_write(unsigned char reg, unsigned char value) //sottoprogramma per scrivere i registri { SS_pin = 0; //indico che sto per inviare un comando nRF24L01_write((reg | W_REGISTER_cmd)); //maschero il registro con il comando per scrivere nRF24L01_write(value); //invio il valore che voglio scrivere nel registro SS_pin = 1; delay_us(8); } //----------------------------------------------------------------------------------------------------------------------------// unsigned char register_read(unsigned char reg) //sottoprogramma lettura registri { unsigned char value = 0; SS_pin = 0; nRF24L01_write((reg | R_REGISTER_cmd)); //indico che voglio leggere e quale registro leggere value = nRF24L01_read(); //leggo il dato che il modulo mi manda SS_pin = 1; delay_us(8); return value; } //----------------------------------------------------------------------------------------------------------------------------// void write_command(unsigned char cmd){ //sottoprogramma scrittura comandi SS_pin = 0; //indico che voglio inviare un comando nRF24L01_write(cmd); //scrivo il comando cmd SS_pin = 1; //ripristino il pin ss delay_us(8); } //----------------------------------------------------------------------------------------------------------------------------// void set_TX_RX_address(unsigned char *addr, unsigned char bytes, unsigned char reg) //sottoprogramma per scrivere gli indirizzi { unsigned char n = 0; SS_pin = 0; nRF24L01_write((reg | W_REGISTER_cmd)); //indico che voglio scrivere i registri for(n = 0; n < bytes; n++) { nRF24L01_write(addr[n]); //bytes contiene il numero di indirizzi } //scrivo gli n indirizzi SS_pin = 1; delay_us(8); } //----------------------------------------------------------------------------------------------------------------------------// void flush_TX_RX() //sottoprogramma per cancellare le FIFO { register_write(STATUS_reg, 0x70); write_command(FLUSH_TX_cmd); write_command(FLUSH_RX_cmd); } //----------------------------------------------------------------------------------------------------------------------------// void send_data(unsigned char bytes, unsigned char *value) //sottoprogramma per inviare i dati { unsigned char s = 0; flush_TX_RX(); //cancello le FIFO register_write(CONFIG_reg, 0x3A); //setto la modalità tx da CONFIG_reg e attivo il modulo SS_pin = 0; nRF24L01_write(W_TX_PAYLOAD_cmd); //scrivo nel registo di trasmissione i bit da inviare for(s = 0; s < bytes; s++) { nRF24L01_write(value[s]); } SS_pin = 1; delay_us(8); CE_pin = 1; //faccio partire l'invio, aspetto 60us e poi disattivo il modulo delay_us(60); CE_pin = 0; register_write(CONFIG_reg, 0x38); //En modo RX se quita } //----------------------------------------------------------------------------------------------------------------------------// void receive_data(unsigned char bytes, unsigned char *value) //sottoprogramma per la ricezione, indico il numero di bytes del dato { //value contiene il dato letto unsigned char s = 0; SS_pin = 0; //scrivo il comando che indica che voglio leggere nRF24L01_write(R_RX_PAYLOAD_cmd); for (s = 0; s < bytes; s++) { value[s] = nRF24L01_read(); //leggo il dato che il modlo mi sta inviando } SS_pin = 1; delay_us(8); } //----------------------------------------------------------------------------------------------------------------------------// void nrF24L01_init_TX() //sottoprogramma per settare la modalità trasmissione { unsigned char address[5] = {0x99, 0x99, 0x99, 0x99, 0x99}; //indirizzo a 5bytes con valore a piacere(devo coincidere però con il rx) CE_pin = 0; register_write(SETUP_RETR_reg, 0x00); //ritrasmissione disabilitata register_write(SETUP_AW_reg, 0x03); //setto che ho indirizzo a 5bytes register_write(RF_SETUP_reg, 0x0E); //potenza 0dbm e velocità 250Kbps register_write(RF_CH_reg, 0x09); //setto il canale di trasmissione, canale 9 in questo caso(il ricevitore deve avere uguale canale) register_write(EN_AA_reg, 0x00); //auto ack disabilitato register_write(CONFIG_reg, 0x38); //interrupt abilitati su TX_DS e MAX_RT, crc abilitato set_TX_RX_address(address, 5, TX_ADDR_reg); //inserisco gli indirizzi nell'apposito registro set_TX_RX_address(address, 5, RX_ADDR_P0_reg); flush_TX_RX(); //cancella le fifo CE_pin = 1; } //----------------------------------------------------------------------------------------------------------------------------// void nrF24L01_init_RX() //programma per settare la modalità RX { unsigned char address[5] = {0x99, 0x99, 0x99, 0x99, 0x99}; //indirizzo a 5bytes uguale a quello del TX CE_pin = 0; register_write(CONFIG_reg, 0x38); //Crc abilitato, no interrup di ricezione register_write(SETUP_RETR_reg, 0x00); //ritrasmissione non richiesta register_write(SETUP_AW_reg, 0x03); //indirizzo a 5bytes register_write(RF_SETUP_reg, 0x0E); //potenza 0dbm e velocità 250Kbps register_write(RF_CH_reg, 0x09); //canale9 register_write(EN_AA_reg, 0x00); //no ack register_write(RX_PW_P0_reg, 0x01); //dato a 1byte register_write(CONFIG_reg, 0x3B); //setto il modulo come RX set_TX_RX_address(address, 5, TX_ADDR_reg); //scrivo gli indirizzi nell'apposito registro set_TX_RX_address(address, 5, RX_ADDR_P0_reg); flush_TX_RX(); //cancello le fifo CE_pin = 1; } //----------------------------------------------------------------------------------------------------------------------------// unsigned char get_Status_Reg() //sottoprogramma per leggere lo status register che mi fornisce info sul modulo { return register_read(STATUS_reg); } //----------------------------------------------------------------------------------------------------------------------------// unsigned char val = 0; //----------------------------------------------------------------------------------------------------------------------------// void main(){ //programma principale TRISA = 0x00; //configuro inizialmente tutte le porte uscite e le setto a 0 TRISB = 0x00; TRISC = 0x00; PORTA = 0X00; PORTB = 0X00; PORTC = 0x00; //----------------------------------------------------------------------------------------------------------------------------// //configurazione I/O microprocessore per comunicare col modulo RF_CS_TRIS = 0; RF_CE_TRIS = 0; SCK_TRIS = 0; SDI_TRIS = 1; SDO_TRIS = 0; CE_pin = 0; SS_pin = 0; SCK_pin = 0; MOSI_pin = 0; LED = 1; delay_ms(100); //faccio lampeggiare una volta il led LED = 0; //----------------------------------------------------------------------------------------------------------------------------// delay_ms(10); nrF24L01_init_RX(); //inizializzo il modulo come rx delay_ms(100); //delay assestamento //----------------------------------------------------------------------------------------------------------------------------// while(1){ //ciclo infinito if(get_Status_Reg() == 0x40) //controllo nello status register se il bit di segnalazione di dato ricevuto è alto { receive_data(1, &x); //se si vado a leggere il dato PORTC = x; //e in questo caso lo visualizzo sulle portB } } 

Grazie,
Elia