RF4432 – PIC16F877A Demo Uygulama

schema_picRF4432 – PIC16F877A Demo Uygulama

Bu uygulamada, RF4432 kablosuz modülü için, sağlayıcısı tarafından yayınlanmış demo yazılımının pic16f877a mikrodenetleyicisine uyarlanmış versiyonunu edinebileceksiniz.

Kablosuz modülün görseli:

rf4432_gorsel

/********************************************************************
* Language:        C
* Compiler:         XC8 (v1.21)
* Version:           1.00
* IDE:                MPLABX (2.30)
* Schematic:      Proteus (7.10)
* Device:            PIC16F877A
* Crystal:           20Mhz
*
* Company:       hasankara.info
********************************************************************/

Şematik tasarım olabildiğince basite indirgenmiştir. Önemli bir uyarı; Mikrodenetleyici bu uygulamada 3,3 volt ile beslenmektedir. Çünkü rf4432 modülü 3,3 volt ile çalışmaktadır. Modül 5 volt ile beslendiğinde kısa bir süre içerisinde bozulacaktır. Bu hususta şunu da söylemeliyim; mikrodenetleyiciyi 3,3 volt ile beslerken pickit2 programlayıcısı ile sağlıklı programlama işlemi gerçekleştiremeyebilirsiniz. Böyle bir durumda mikrodenetleyiciyi devreden bağımsız 5 volt beslemeli iken (zif soket olabilir) programladıktan sonra devre ile bağlantısı sağlanabilir.

Uygulamaya dair;

Alıcı ve verici şematik tasarımları aynıdır ve içerilerinde ki yazılıma göre alıcı veya verici özelliğini taşıyabilirler. Bilgisayar üzerinde isis simülasyonu çalışmamaktadır.

Verici modül 10 byte lık bir dizi gönderir. Gönderme işlemi Timer1 kesmesi ile rutin bir şekilde yapılmaktadır. Kesme sayısı 150 e ulaştığı zaman özel bir bayrak set edilir. Bu bayrak ana döngüde ki sonsuz döngü içerisinde kontrol edilir ve bayrak kesme içinde her set edildiğinde bu bayrak sonsuz döngü içerisinde temizlenip dizi gönderme işlemine gidilir. Yaklaşık 1 sn gibi bir süre ile tekrarlı olarak aynı dizi gönderilmektedir. Veri gönderme süresini kısaltmak için firmware c kodlarında ki açıklamalardan faydalanılabilinir.

Çalışmaya hazır hale getirilmiş olan alıcı modüle ulaşan 10 byte lık dizi, modül üzerinde ki nIRQ pininde kesme (seviye değişimi) meydana getirir. Sonsuz döngü içerisinde durumu kontrol edilen nIRQ pini seviye değiştiği zaman verinin geldiği kabul edilir. Modül kesme temizlemesi yapılır. Ardından, gelen dizinin boyutu okunur ve boyut uzunluğu kadar, modül fifo hafızası içerisinde saklanan dizi, modülün aynı adresinin defalarca okunması ile mikrodenetleyici hafızasına alınır. Aynı hafızayı okuyor olsak da fifo yapısı her okuma işleminden sonra sırasıyla çözüleceği için sırası ile diziyi okumuş olmaktayız.

10 byte lık dizi mikrodenetleyiciye alındıktan sonra her byte checksum hesaplama işlemine tabi tutulur ve 10. byte ile karşılaştırılır. Eğer 10 byte lık dizi hatasız gelmiş ise karşılaştırma sonucu olumlu olacaktır ve alıcı devrenin rx ledi (RB7) konum değiştirerek bilgiyi sağlıklı bir şekilde aldığını kullanıcıya bildirmiş olacaktır.

Aynı masa üzerinde çalışıyor iken iletişimin sorunsuz sağlanması olağan, ancak verici modül ile alıcı modül mesafesi arttırıldığında anten pinleri boşta iken belirli bir uzaklıktan sonra iletişim sağlanamayacaktır. 10 cm boylarında ki kabloyu diğer ucu boşta olacak şekilde anten pinine bağlanabilir. Böylece iletişim menzili hatırı sayılır derecede artacaktır. Daha verimli sonuç almak için 433mhz helical bir anten kullanılabilir.

Verici taraf C kodları “tx” :

/********************************************************************
 * FileName: "si4432_tx_main.c"
 * Language: C
 * Compiler: XC8(v1.21)
 * Version: 1.00
 * Dependencies: "pic16f877a.h"
 * Device: PIC16F877A
 * Crystal: 20Mhz
 *
 * Created on: 18 OCAK 2015 Pazar, 13:18
 * Company: hasankara.info
 ********************************************************************/

/*
 * Aciklama:
 * Daha hizli veri yollamak icin;
 * void interrupt ISR_timer(void) {} fonksiyonu icerisinde
 * if (count_50hz == 150) kontrolundeki 150 sayisi azaltilabilir.
 */

//This Demo code suit fo7r RF4431, RF4432,RF4432Pro, RF4432F27,
// this code run in the transmitter and Tx the fixed data packet every 1s
// The parameter is £º FSK£¬ 433.5MHz£¬ 1.2KBPS£¬ +/-10PPM, Deviation£º30KHz£¬ Bandwidth£º61.2KHz
// enable AFC£¬enable CRC£¬ PH + FIFO
// The payload for tx and Rx: 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x6d,
// checksum( 0x6d ) = (0x41 +0x42 +0x43 +0x44 +0x45 +0x46 +0x47 + 0x48 +0x49)
// MCU : Microchip high performance 8 bit MCU 

#include<pic16f877a.h>
//_/__/___/____/_____/______/_______/________/_________/__________/
#define SI4432_PWRSTATE_READY 01 // define ready mode
#define SI4432_PWRSTATE_TX 0x09 // define Tx mode
#define SI4432_PACKET_SENT_INTERRUPT 04 // Packet sent interrupt

#define TX1_RX0 spi_rw(0x0e|0x80, 0x01) // antenna state for Tx
#define TX0_RX0 spi_rw(0x0e|0x80, 0x00) // antenna state for ready mode ,standby mode, power down mode

#define INPUT 1
#define OUTPUT 0
//_/__/___/____/_____/______/_______/________/_________/__________/
// PORTB KULLANIMI
#define SDN PORTBbits.RB0 // MCU output
#define nIRQ PORTBbits.RB1 // MCU input
#define nSEL PORTBbits.RB2 // MCU output
#define SCK PORTBbits.RB3 // MCU output
#define SDI PORTBbits.RB4 // MCU output
#define SDO PORTBbits.RB5 // MCU input
#define LED_TX PORTBbits.RB6
#define LED_RX PORTBbits.RB7

#define SDN_set TRISBbits.TRISB0 // register to set input/output
#define nIRQ_set TRISBbits.TRISB1 // register to set input/output
#define nSEL_set TRISBbits.TRISB2 // register to set input/output
#define SCK_set TRISBbits.TRISB3 // register to set input/output
#define SDI_set TRISBbits.TRISB4 // register to set input/output
#define SDO_set TRISBbits.TRISB5 // register to set input/output
#define LED_TX_set TRISBbits.TRISB6
#define LED_RX_set TRISBbits.TRISB7
//_/__/___/____/_____/______/_______/________/_________/__________/
// Tx fixed paylaod every 1 second£¬ the 10th data is the checksum
static unsigned char tx_test_data[10] = {0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x6d};

unsigned char count_50hz;

unsigned char ItStatus1, ItStatus2;
unsigned char rf_timeout;

typedef struct {
 unsigned char reach_1s : 1;
 unsigned char rf_reach_timeout : 1;
 unsigned char is_tx : 1;
} FlagType;
FlagType Flag;
//_/__/___/____/_____/______/_______/________/_________/__________/
void tx_data(void);

unsigned char spi_byte(unsigned char data);
unsigned char spi_rw(unsigned char addr, unsigned char data);
void SI4432_init(void);

void delay_1ms(unsigned char time);

void port_init(void);
void timer_init(void);
//_/__/___/____/_____/______/_______/________/_________/__________/
// CONFIG 16f877a
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
//_/__/___/____/_____/______/_______/________/_________/__________/

void main() {
 unsigned char i, j, chksum;

 port_init(); // initial io port

 SDN = 1;
 delay_1ms(10); // reset RF module
 SDN = 0;
 delay_1ms(200); // delay 200ms then enter normal mode

 SI4432_init(); // initail RF module
 TX0_RX0; // set antenna

 timer_init();

 count_50hz = 0;
 Flag.reach_1s = 0;

 INTCON = 0xc0; // enable interrupt

 while (1) {
 if (Flag.reach_1s) {

 Flag.reach_1s = 0;
 tx_data(); // tx 1 packet every 1 second
 }
 }
}
//_/__/___/____/_____/______/_______/________/_________/__________/

void delay_1ms(unsigned char time) {
 unsigned char i, k;
 for (k = 0; k < time; k++) {
 for (i = 0; i < 130; i++) {
 asm("NOP");
 }
 }
}
//_/__/___/____/_____/______/_______/________/_________/__________/

void timer_init(void) {
 T1CON = 0x31;

 TMR1IE = 1;
 TMR1L = 0x78; //intial timer
 TMR1H = 0xec;
}
//_/__/___/____/_____/______/_______/________/_________/__________/

void interrupt ISR_timer(void) {
 unsigned char i;
 if (TMR1IF) {
 TMR1L = 0x78; // timer = 20ms
 TMR1H = 0xec;

 rf_timeout++;
 if (rf_timeout > 50) {
 Flag.rf_reach_timeout = 1; // tx timeout or Rx timeout
 }
 count_50hz++;
 if (count_50hz > 150) // <<
 {
 count_50hz = 0;
 Flag.reach_1s = 1; //timer for 1s
 }

 TMR1IF = 0;
 }
}
//_/__/___/____/_____/______/_______/________/_________/__________/

void port_init(void) {
 SDN_set = OUTPUT;
 nIRQ_set = INPUT;
 nSEL_set = OUTPUT;
 SCK_set = OUTPUT;
 SDI_set = OUTPUT;
 SDO_set = INPUT;

 LED_TX_set = OUTPUT;
 LED_RX_set = OUTPUT;
}
//_/__/___/____/_____/______/_______/________/_________/__________/

void SI4432_init(void) {
 ItStatus1 = spi_rw(0x03, 0x00); // clr RF interrupt factor
 ItStatus2 = spi_rw(0x04, 0x00);

 spi_rw(0x06 | 0x80, 0x00); // Set RF interrupt

 spi_rw(0x07 | 0x80, SI4432_PWRSTATE_READY); // enter ready mode

 spi_rw(0x09 | 0x80, 0x7f); // load cap = 12P

 spi_rw(0x0a | 0x80, 0x05); // output clk set
 spi_rw(0x0b | 0x80, 0xea); // GPIO 0 digital output
 spi_rw(0x0c | 0x80, 0xea); // GPIO 1 digital output

 spi_rw(0x0d | 0x80, 0xf4); // /GPIO 2 = rx data

 spi_rw(0x70 | 0x80, 0x2c);
 spi_rw(0x1d | 0x80, 0x40); // enable afc

 // 1.2K bps setting
 spi_rw(0x1c | 0x80, 0x16); // according to Silabs's excel
 spi_rw(0x20 | 0x80, 0x83);
 spi_rw(0x21 | 0x80, 0xc0);
 spi_rw(0x22 | 0x80, 0x13);
 spi_rw(0x23 | 0x80, 0xa9);
 spi_rw(0x24 | 0x80, 0x00);
 spi_rw(0x25 | 0x80, 0x04);
 spi_rw(0x2a | 0x80, 0x14);
 spi_rw(0x6e | 0x80, 0x09);
 spi_rw(0x6f | 0x80, 0xd5);
 //1.2K bps setting end

 spi_rw(0x30 | 0x80, 0x8c); // enable PH+ FIFO, enable crc, msb
 spi_rw(0x32 | 0x80, 0xff); // head = byte0, 1, 2, 3
 spi_rw(0x33 | 0x80, 0x42); // header = byte 0,1,2,3, sync = byte 3, 2

 spi_rw(0x34 | 0x80, 16); // preamble = 16 nibbles
 spi_rw(0x35 | 0x80, 0x20); // preamble detection = 20bit
 spi_rw(0x36 | 0x80, 0x2d); // sync word = 0x2dd4
 spi_rw(0x37 | 0x80, 0xd4);
 spi_rw(0x38 | 0x80, 0x00);
 spi_rw(0x39 | 0x80, 0x00);
 spi_rw(0x3a | 0x80, 's'); // header for tx ����swwx"
 spi_rw(0x3b | 0x80, 'w');
 spi_rw(0x3c | 0x80, 'w');
 spi_rw(0x3d | 0x80, 'x');
 spi_rw(0x3e | 0x80, 10); // length of payload = 10
 spi_rw(0x3f | 0x80, 's'); // head check ����swwx"
 spi_rw(0x40 | 0x80, 'w');
 spi_rw(0x41 | 0x80, 'w');
 spi_rw(0x42 | 0x80, 'x');
 spi_rw(0x43 | 0x80, 0xff); // all bit to be checked
 spi_rw(0x44 | 0x80, 0xff);
 spi_rw(0x45 | 0x80, 0xff);
 spi_rw(0x46 | 0x80, 0xff);
 spi_rw(0x6d | 0x80, 0x07); // maximum ouput power

 spi_rw(0x79 | 0x80, 0x0); // non hop
 spi_rw(0x7a | 0x80, 0x0); // non hop

 spi_rw(0x71 | 0x80, 0x22); // FiFo, FSK , not need clk
 spi_rw(0x72 | 0x80, 0x20); // deviation: 20KHz

 spi_rw(0x73 | 0x80, 0x0); // no frequency offset
 spi_rw(0x74 | 0x80, 0x0); // no frequency offset

 spi_rw(0x75 | 0x80, 0x53); // frequency: 433.5
 spi_rw(0x76 | 0x80, 0x57);
 spi_rw(0x77 | 0x80, 0x80);
}
//_/__/___/____/_____/______/_______/________/_________/__________/

void tx_data(void) {
 unsigned char i;

 Flag.is_tx = 1;

 spi_rw(0x07 | 0x80, SI4432_PWRSTATE_READY); // enter ready mode
 TX1_RX0; // set antenna switch to Tx mode
 delay_1ms(5); // delay 5ms for warmup

 spi_rw(0x08 | 0x80, 0x03);
 spi_rw(0x08 | 0x80, 0x00); // clr tx ,rx fifo

 spi_rw(0x34 | 0x80, 40); // preamble for Tx = 40 nibbles
 spi_rw(0x3e | 0x80, 10); // TX packet length = 10 bytes
 for (i = 0; i < 10; i++) {
 spi_rw(0x7f | 0x80, tx_test_data[i]); // fill data into fifo
 }
 spi_rw(0x05 | 0x80, SI4432_PACKET_SENT_INTERRUPT); // enable packet sent interrupt
 ItStatus1 = spi_rw(0x03, 0x00); // clr rf interrupt factor
 ItStatus2 = spi_rw(0x04, 0x00); // clr rf interrupt factor
 spi_rw(0x07 | 0x80, SI4432_PWRSTATE_TX); // enter tx mode

 LED_TX = LED_TX^1; // for TX LED flash

 rf_timeout = 0; // initial tx 500ms timeout
 Flag.rf_reach_timeout = 0;
 while (nIRQ) // wait for interrupt
 {
 if (Flag.rf_reach_timeout) {
 SDN = 1; //reset the RF module when not find the interrutp for 500ms
 delay_1ms(10);
 SDN = 0;
 delay_1ms(200);

 SI4432_init();
 break; // exit
 }
 }

 TX0_RX0; // set antenna switch to Tx mode
 ItStatus1 = spi_rw(0x03, 0x00); // clr rf interrupt factor
 ItStatus2 = spi_rw(0x04, 0x00); // clr rf interrupt factor
 spi_rw(0x07 | 0x80, SI4432_PWRSTATE_READY); // enter ready mode
}
//_/__/___/____/_____/______/_______/________/_________/_____/

unsigned char spi_byte(unsigned char data) {
 unsigned char i, j;

 for (i = 0; i < 8; i++) // spi simulation with normal IO
 { // read data at rising edge and wite data at falling edge of the sck
 if (data & 0x80)
 SDI = 1;
 else
 SDI = 0;
 asm("NOP");
 data <<= 1;

 SCK = 1;
 if (SDO)
 data |= 0x01;
 else
 data &= 0xfe;
 SCK = 0;
 }
 return (data);
}
//_/__/___/____/_____/______/_______/________/_________/_____/

unsigned char spi_rw(unsigned char addr, unsigned char data) {
 unsigned char i, j;

 SCK = 0;
 asm("NOP");
 nSEL = 0;
 for (i = 0; i < 8; i++) {
 if (addr & 0x80)
 SDI = 1;
 else
 SDI = 0;
 addr <<= 1;
 asm("NOP");
 SCK = 1;
 SCK = 0;
 }

 for (i = 0; i < 8; i++) {
 if (data & 0x80)
 SDI = 1;
 else
 SDI = 0;
 data <<= 1;
 asm("NOP");
 SCK = 1;
 if (SDO) data |= 0x01;
 else data &= 0xfe;
 SCK = 0;
 }
 nSEL = 1;
 asm("NOP");
 SCK = 1;
 return (data);
}

//_/__/___/____/_____/______/_______/________/_________/_____/

Alıcı taraf C kodları “rx” :

/********************************************************************
 * FileName: "si4432_rx_main.c"
 * Language: C
 * Compiler: XC8(v1.21)
 * Version: 1.00
 * Dependencies: "pic16f877a.h"
 * Device: PIC16F877A
 * Crystal: 20Mhz
 *
 * Created on: 18 OCAK 2015 Pazar, 13:18
 * Company: hasankara.info
 ********************************************************************/

//This Demo code suit for RF4431, RF4432,RF4432Pro, RF4432F27,
// This code run in the receiver mode
// The parameter is £º FSK£¬ 433.5MHz£¬ 1.2KBPS£¬ +/-10PPM, Deviation£º30KHz£¬ Bandwidth£º61.2KHz
// enable AFC£¬enable CRC£¬ PH + FIFO
// The payload for tx and Rx: 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x6d,
// checksum( 0x6d ) = (0x41 +0x42 +0x43 +0x44 +0x45 +0x46 +0x47 + 0x48 +0x49)
// MCU : Microchip high performance 8 bit MCU 

#include<pic16f877a.h>
//_/__/___/____/_____/______/_______/________/_________/__________/
#define SI4432_PWRSTATE_READY 01 // define ready mode
#define SI4432_PWRSTATE_RX 05 // define Rx mode
#define SI4432_Rx_packet_received_interrupt 0x02 // Packet received interrupt
#define EZRADIOPRO_RECEIVED_PACKET_LENGTH 0x4B // received packet length

#define TX0_RX1 spi_rw(0x0e|0x80, 0x02) // antenna state for Rx
#define TX0_RX0 spi_rw(0x0e|0x80, 0x00) // antenna state for ready mode ,standby mode, power down mode

#define INPUT 1
#define OUTPUT 0
//_/__/___/____/_____/______/_______/________/_________/__________/
// PORTB KULLANIMI
#define SDN PORTBbits.RB0 // MCU output
#define nIRQ PORTBbits.RB1 // MCU input
#define nSEL PORTBbits.RB2 // MCU output
#define SCK PORTBbits.RB3 // MCU output
#define SDI PORTBbits.RB4 // MCU output
#define SDO PORTBbits.RB5 // MCU input
#define LED_TX PORTBbits.RB6
#define LED_RX PORTBbits.RB7

#define SDN_set TRISBbits.TRISB0 // register to set input/output
#define nIRQ_set TRISBbits.TRISB1 // register to set input/output
#define nSEL_set TRISBbits.TRISB2 // register to set input/output
#define SCK_set TRISBbits.TRISB3 // register to set input/output
#define SDI_set TRISBbits.TRISB4 // register to set input/output
#define SDO_set TRISBbits.TRISB5 // register to set input/output
#define LED_TX_set TRISBbits.TRISB6
#define LED_RX_set TRISBbits.TRISB7
//_/__/___/____/_____/______/_______/________/_________/__________/
unsigned char count_50hz;

unsigned char ItStatus1, ItStatus2;

unsigned char rx_buf[64];

typedef struct {
 unsigned char reach_1s : 1;
 unsigned char rf_reach_timeout : 1;
 unsigned char is_tx : 1;
} FlagType;

FlagType Flag;
//_/__/___/____/_____/______/_______/________/_________/__________/
void rx_data(void);

unsigned char spi_byte(unsigned char data);
unsigned char spi_rw(unsigned char addr, unsigned char data);

void SI4432_init(void);

void delay_1ms(unsigned char time);

void port_init(void);

void timer_init(void);
//_/__/___/____/_____/______/_______/________/_________/__________/
// CONFIG 16f877a
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
//_/__/___/____/_____/______/_______/________/_________/__________/

void main() {
 unsigned char i, j, rxlen, chksum;

 port_init(); // initial io port

 SDN = 1;
 delay_1ms(10); // reset RF module
 SDN = 0;
 delay_1ms(200); // delay 200ms then enter normal mode

 SI4432_init(); // initail RF module
 rx_data(); // enter RX mode

 timer_init();

 count_50hz = 0;
 Flag.reach_1s = 0;

 INTCON = 0xc0; // enable interrupt

 while (1) {

 if (!nIRQ) {
 ItStatus1 = spi_rw(0x03, 0x00); // clr interrupt //read the Interrupt Status1 register
 ItStatus2 = spi_rw(0x04, 0x00); // clr interrupt

 if (ItStatus1 & 0x02) {
 rxlen = spi_rw(EZRADIOPRO_RECEIVED_PACKET_LENGTH, 0x00); // read packet length

 SCK = 0;
 nSEL = 0;
 spi_byte(0x7f); // read data from FiFo

 for (i = 0; i < rxlen; i++) {
 rx_buf[i] = spi_byte(0x00);
 }
 nSEL = 1;

 spi_rw(0x07 | 0x80, SI4432_PWRSTATE_RX); // back to receive mode after received data

 if (rxlen == 10) {
 chksum = 0;
 for (i = 0; i < 9; i++) // cal Checksum
 chksum += rx_buf[i];

 if ((chksum == rx_buf[9]) && (rx_buf[0] == 0x41)) // check the checksum and packet
 {
 LED_RX = LED_RX^1; // data is correct then flash the LED
 } else {
 rx_data(); // restart Rx when data is not correct.
 }
 }
 }
 }
 }
}
//_/__/___/____/_____/______/_______/________/_________/__________/

void delay_1ms(unsigned char time) {
 unsigned short i, k;
 for (k = 0; k < time; k++) {
 for (i = 0; i < 130; i++) {
 asm("NOP");
 }
 }
}
//_/__/___/____/_____/______/_______/________/_________/__________/

void timer_init(void) {
 T1CON = 0x31;

 TMR1IE = 1;
 TMR1L = 0x78; //intial timer
 TMR1H = 0xec;

}
//_/__/___/____/_____/______/_______/________/_________/__________/

void interrupt ISR_timer(void) {
 static unsigned char i, rf_timeout = 0;

 if (TMR1IF) {
 TMR1L = 0x78; // timer = 20ms
 TMR1H = 0xec;

 rf_timeout++;
 if (rf_timeout == 50) {
 Flag.rf_reach_timeout = 1; // tx timeout or Rx timeout
 rf_timeout = 0;
 }
 count_50hz++;
 if (count_50hz == 150) //
 {
 count_50hz = 0;
 Flag.reach_1s = 1; //timer for 1s
 }
 TMR1IF = 0;
 }
}
//_/__/___/____/_____/______/_______/________/_________/__________/

void port_init(void) {
 SDN_set = OUTPUT;
 nIRQ_set = INPUT;
 nSEL_set = OUTPUT;
 SCK_set = OUTPUT;
 SDI_set = OUTPUT;
 SDO_set = INPUT;

 LED_TX_set = OUTPUT;
 LED_RX_set = OUTPUT;
}
//_/__/___/____/_____/______/_______/________/_________/__________/

void SI4432_init(void) {
 ItStatus1 = spi_rw(0x03, 0x00); // clr RF interrupt factor
 ItStatus2 = spi_rw(0x04, 0x00);

 spi_rw(0x06 | 0x80, 0x00); // Set RF interrupt

 spi_rw(0x07 | 0x80, SI4432_PWRSTATE_READY); // enter ready mode

 spi_rw(0x09 | 0x80, 0x7f); // load cap = 12P

 spi_rw(0x0a | 0x80, 0x05); // output clk set
 spi_rw(0x0b | 0x80, 0xea); // GPIO 0 digital output
 spi_rw(0x0c | 0x80, 0xea); // GPIO 1 digital output

 spi_rw(0x0d | 0x80, 0xf4); // /GPIO 2 = rx data

 spi_rw(0x70 | 0x80, 0x2c);
 spi_rw(0x1d | 0x80, 0x40); // enable afc

 // 1.2K bps setting
 spi_rw(0x1c | 0x80, 0x16); // according to Silabs's excel
 spi_rw(0x20 | 0x80, 0x83);
 spi_rw(0x21 | 0x80, 0xc0);
 spi_rw(0x22 | 0x80, 0x13);
 spi_rw(0x23 | 0x80, 0xa9);
 spi_rw(0x24 | 0x80, 0x00);
 spi_rw(0x25 | 0x80, 0x04);
 spi_rw(0x2a | 0x80, 0x14);
 spi_rw(0x6e | 0x80, 0x09);
 spi_rw(0x6f | 0x80, 0xd5);
 //1.2K bps setting end

 spi_rw(0x30 | 0x80, 0x8c); // enable PH+ FIFO, enable crc, msb
 spi_rw(0x32 | 0x80, 0xff); // head = byte0, 1, 2, 3
 spi_rw(0x33 | 0x80, 0x42); // header = byte 0,1,2,3, sync = byte 3, 2

 spi_rw(0x34 | 0x80, 16); // preamble = 16 nibbles
 spi_rw(0x35 | 0x80, 0x20); // preamble detection = 20bit
 spi_rw(0x36 | 0x80, 0x2d); // sync word = 0x2dd4
 spi_rw(0x37 | 0x80, 0xd4);
 spi_rw(0x38 | 0x80, 0x00);
 spi_rw(0x39 | 0x80, 0x00);
 spi_rw(0x3a | 0x80, 's'); // header for tx ����swwx"
 spi_rw(0x3b | 0x80, 'w');
 spi_rw(0x3c | 0x80, 'w');
 spi_rw(0x3d | 0x80, 'x');
 spi_rw(0x3e | 0x80, 10); // length of payload = 10
 spi_rw(0x3f | 0x80, 's'); // head check ����swwx"
 spi_rw(0x40 | 0x80, 'w');
 spi_rw(0x41 | 0x80, 'w');
 spi_rw(0x42 | 0x80, 'x');
 spi_rw(0x43 | 0x80, 0xff); // all bit to be checked
 spi_rw(0x44 | 0x80, 0xff);
 spi_rw(0x45 | 0x80, 0xff);
 spi_rw(0x46 | 0x80, 0xff);
 spi_rw(0x6d | 0x80, 0x07); // maximum ouput power

 spi_rw(0x79 | 0x80, 0x0); // non hop
 spi_rw(0x7a | 0x80, 0x0); // non hop

 spi_rw(0x71 | 0x80, 0x22); // FiFo, FSK , not need clk
 spi_rw(0x72 | 0x80, 0x20); // deviation: 20KHz

 spi_rw(0x73 | 0x80, 0x0); // no frequency offset
 spi_rw(0x74 | 0x80, 0x0); // no frequency offset

 spi_rw(0x75 | 0x80, 0x53); // frequency: 433.5
 spi_rw(0x76 | 0x80, 0x57);
 spi_rw(0x77 | 0x80, 0x80);
}
//_/__/___/____/_____/______/_______/________/_________/__________/

void rx_data(void) {
 unsigned char i, chksum;
 Flag.is_tx = 0;

 spi_rw(0x07 | 0x80, SI4432_PWRSTATE_READY); //enter ready mode
 TX0_RX1; // antenna switch set
 delay_1ms(5); //

 spi_rw(0x08 | 0x80, 0x03); //clr tx, Rx fifo
 spi_rw(0x08 | 0x80, 0x00); //clr tx, Rx fifo

 spi_rw(0x07 | 0x80, SI4432_PWRSTATE_RX); // enter rx mode

 spi_rw(0x05 | 0x80, SI4432_Rx_packet_received_interrupt); // set rf module packet receive interrupt

 ItStatus1 = spi_rw(0x03, 0x00); //clr interrupt factor
 ItStatus2 = spi_rw(0x04, 0x00); //clr interrupt factor
}
//_/__/___/____/_____/______/_______/________/_________/__________/

unsigned char spi_byte(unsigned char data) {
 unsigned char i, j;

 for (i = 0; i < 8; i++) // spi simulation with normal IO
 { // read data at rising edge and wite data at falling edge of the sck
 if (data & 0x80)
 SDI = 1;
 else
 SDI = 0;

 data <<= 1;

 asm("NOP");
 SCK = 1;
 if (SDO)
 data |= 0x01;
 else
 data &= 0xfe;
 SCK = 0;
 }
 return (data);
}
//_/__/___/____/_____/______/_______/________/_________/__________/

unsigned char spi_rw(unsigned char addr, unsigned char data) {
 unsigned char i, j;

 SCK = 0;
 asm("NOP");
 nSEL = 0;
 for (i = 0; i < 8; i++) {
 if (addr & 0x80)
 SDI = 1;
 else
 SDI = 0;
 addr <<= 1;
 asm("NOP");
 SCK = 1;
 SCK = 0;
 }

 for (i = 0; i < 8; i++) {
 if (data & 0x80)
 SDI = 1;
 else
 SDI = 0;
 data <<= 1;
 asm("NOP");
 SCK = 1;
 if (SDO) data |= 0x01;
 else data &= 0xfe;
 SCK = 0;
 }
 nSEL = 1;
 asm("NOP");
 SCK = 1;
 return (data);
}
//_/__/___/____/_____/______/_______/________/_________/__________/

Tüm dosyalar için buraya tıklayın.

“RF4432 – PIC16F877A Demo Uygulama” için 6 yorum

  1. Dosyaları indirmenin dışında sayfanın en altına birde kodları koysanız çok hoş olur hocam.

  2. Önerin için teşekkürler Berat. Dikkate alıp kodları da tek tıklamayla görünür kıldım.

  3. Verdiğiniz kodları denedim ancak devreyi bir türlü çalıştıramadım. Alıcı tarafında kod asla
    if(ItStatus1&0x02)
    bloğunun içine girmiyor. Modül ItStatus1 için 0x20 ve ItStatus2 için 0x02 yolluyor.
    Kodlar üzerinde sadece LED_RX ve LED_TX in yerlerini değiştirmek için ufak bi dğeişiklik yaptım, devreyi de şemadaki gibi kurdum. En azından alıcı mı yoksa verici tarafında mı hata yaşıyorum onu öğrensem yeter.
    Birde fifoya veri yazarken burst modunda yazmamız gerektiği yazıyor datasheette. nSEL 0 olduktan sonra bir kere adresi girmemiz sonra da sırayla bütün datayı yollayıp nSEL’i 1 yapmamız gerek. Ancak sizin kodunuzda her defasında nSEL resetleniyor ve her defasında datanın başına 0xFF adresi ekleniyor. Bu sıkıntı olabilir mi?

  4. Verdiğiniz kodları ve devre şemasını aynen uyguladım ancak sistemi çalıştıramadım. (Sadece LED_TX ve LED_RX bacaklarını değiştirdim.) Alıcı tarafında modül ItStatus1 değeri için 0x20 değeri döndürüyor. Datasheet’teki açıklamaya göre bu değer fifo’daki bilgilerin tamamen gönderildiği anlamına geliyor ama alıcı tarafında gönderme işlemi yapmıyorum.
    Birde datasheette fifo için burst okuma ve yazma uygulanması gerektiği yazıyor. Ancak sizin kodunuzda fifoya yazarken nSEL değerini her defasında 1’e çekiliyor ve her 8 bitlik verinin önünde 0xFF adresi ekleniyor. Hata burda olabilir mi yada kontrol etmem gereken başka bir yer var mı?

Bir Cevap Yazın

Or

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir