NRF24L01 Kullanımı

Başlatan erdogan2734, 26 Haziran 2016, 00:07:04

exper

kod paylaşırmısınız

Dtmf

#196
Ben nrf+pa ile 1,5km uzaklikta bir speeddom kamera vardi goruntu kablosuz aliyorduk fakat kontrol yoktu pic18f452 ile pelco d/pelco p protokolu yukleyip kontrol saglamistim gercekten cok hizli bir modul :)

alisumer

Alıntı yapılan: exper - 24 Mart 2020, 20:34:24kod paylaşırmısınız
Kod malesef paylaşmayacağım fakat NRF register ayarlarını paylaşmıştım ondan sonrası zaten klasık pic e ne yaptırmak istediğinle alakalı olduğu için pek bi anlam ifade etmiyor iki nrf yi haberleştirip zaten pic ile de veri gönderip okumayı bu registerler üzerinde yaptığın ayarlar ve datasında sizden istenen bekleme sürelerine riayet etmeniz ile gerçekleştiriyorsunuz sonrası size kalmış
Hep meraktan

alisumer

uçak şu an uçmuyor uçurmak için pratik gerekicek bayağı pervane eksik aldığım pervane yüksek hıza dayanamayıp resmen patladı kasığı yere bırakıyordum az kalsın fırçasız motorlara dikkat edin deli şeyler:) bir de kumandanın analog joystikleri hiç hassas değiller tüm hareketin ancak yarısına kadar olan bölümde algılama yapıyorlar çin malı hassas okuma için bağlı pot  ları kalitelileri ile değiştirmem gerekicek denemesini yaptım iyi bir pot ile çok hassas servo kontrol yapılabiliyor bu arada devre kartı kumanda kasası uçak kasası hatta metal servo kolları dahil( onları telli defterin tellerini düzleştirerrek yaptım) kendim bir idda üzerine yaptım ilk yaptığım uçağı youtube de paylaştığım belkide 10 ay oluyor o zamandan beri bununla uğraşıyorum ilk kumanda çalışmalarına  standart rf verici ile başlamıştım kontrol konusunda çok sıkıntısı olmuyor bu arada bilginiz olsun aynı işi yapıyorlar 4- 5 kanal birşey yapacaksanız iş görüyorlar kısıtlı bir menzile sahip olmaları dezavantajları ama SPI gibi bir dert açmıyorlar başınıza yönetmesi kolay ama SPI yi anlamaya başlayınca NRF çok güzel bişey.bu arada kod paylaşmamamın sebebi güvenlik falan değil bilesiniz çünkü nrf nin çalışan ARDUİNO bir ton programı ve hazır kütüphaneleri var asıl sebebi öğrenmek çabalamak inanın hazır programı kullanmak insana bir şey katsa idi arduino kullanırdım hıç uğraşmazdım 
Hep meraktan

alisumer

kendim anladığım kadarı ile NRF nin çalışması hakkında bilgimi paylaşırım ama onda sıkıntı yok
Hep meraktan

gokhan_picer

Herkese Merhaba,

Konunun başlarını takip ettim ve ben de RF modül için bir PIC kütüphanesi oluşturmak istiyorum. Arduino vb. kullanmadan kendi kütüphanemi oluşturarak logic anlamda neler olduğunu kavramak isterim. Anladığım kadarıyla özellikle nRF24L01 (bende NRF24L01 + PA + LNA SMA antenli modül var) datasheet'ini hatim etmem gerektiğini anladım.

En başta, SPI iletişimini şu aralar kavramaya çalışıyorum ve aynı zamanda bu modül hakkında da araştırma yapmaya başladım. Bende PIC16f877A var ve konu ile alakalı olarak tavsiyelerinize açığım; arduino ile haberleştir sonra pic e geç , önce datasheet oku sonra yazılıma geç gibi önerilerinizi beklerim

Herkese hayırlı günler.

ete

NRF yi öğrenmek için SPI incelemesinden başlarsan bu işin sonunu getiremeyeceğin konusunda endişem var. Bazen komutları formatına uygun olarak direk kullanmak kafa karışıklığını önlemek açısından daha uyugundur. SPI konusunda yalnızca komut parametrelerinin kullanımına dikkat etmek bence yeterlidir. Bunun için, Kursörü, SHIFTOUT yada SHIFTIN komutlarının üzerine getir ve bu aşamada F1 butonuna bas. Böylece komutu formatı ve açıklamaları ekrana gelecektir. Burada dikkat edilecek husus yollanan bilginin en düşük değerlikli bit den mi başlanacak yokse en yüksek değerlikli bitden mi başlanacak onu tespit etmen gerekir. Bunu da MODE parametresi ayarlıyor. Diğer bir husus da iletişim sonucunda CLK HIGH da mı bekleyecek yoksa LOW da mı bekleyecek bunu belirlenmesidir. Bütün bu bilgiler haberleşilen cihaz'ın özelliklerinden tespit edilmelidir. SPI konusunda başka bir şey bilmen gerekmiyor. Bir seri iletişim metodudur. Ayrıca bazı işlemcilerde donanımsal SPI portu da bulunurki bu normal SPI komutarına göre çok daha hızlı çalışmaktadır. Dezavantajı ise standart bir CLK ve DATA pini kullanıyor olmasıdır.

Gelelim NRF ye. Data sheet veya özellikle REGISTER listesi elbette ana bilgi kaynağın olmalıdır. Her şey bu registerler üzerinden yürütülmektedir. İki NRF nin bir biri iile haberleşmebilmesi için her iki tarafta (RX ve TX) bazı ön ayarlamaların yapılması gerekir ki bu işleme Konfig diyorum ben kısaca.
Buraya örnek bir config listesi koyabilirdim. Ancak şimdilik koymayacağım. Çünki senin register listesini inceleyip kimin ne amaçla ayarlanması gerektiğini biraz incelemen ve komuya hakim olman gerekiyor. İleride gelişmelere paralel olarak gerekli ek bilgileri vereceğim.

Ete

gokhan_picer

Yanıt için teşekkür ederim öncelikle.

Genel olarak SPI konusunun nRF incelemesinden daha kolay göründüğünü düşünüyorum(umarım ;D  ). Standart olarak kullanılan pinlerle PIC16f877A ve max7219 led driver kullandım başlangıçta ve led ekrana istediğimi yazdırabildim  fakat bu max7219 modülü geri dönüş vermediği için-MISO kullanmadım- beni tatmin etmedi bu çalışma, ama yine de SPI anlamak için başlangıç oldu.

Mesela aşağıdaki gibi bir write/read fonksiyon oluşturdum ayrı ayrı. Gönderme işini sanırım çözdüm ama alma kısmında lojik olarak arka planda olan biteni merak ediyorum: Eğer ben MOSI hattını meşgul ederken SSPBUF kaydedicisini kullanıyorsam(oldu ki slave cihaza sıcaklık okuma komutu gönderdim), aynı anda nasıl oluyor da slave cevap veriyor ve yine aynı SSPBUF'a yazıyor.? Bu iş full-duplex oluyorsa aynı buffer nasıl kullanılıyor?


 -spi.c-

// ========================================
//              BYTE GÖNDERME
// ========================================
void SPI_Write(uint8_t data)
{
    SSPBUF = data;           // Veriyi buffer'a yaz, transfer başlasın
    while(!PIR1bits.SSPIF);  // Transfer bitene kadar bekle
    PIR1bits.SSPIF = 0;      // Bayrağı temizle
}

// ========================================
//              BYTE ALMA
// ========================================
uint8_t SPI_Read(void)
{
    SSPBUF = 0xFF;           // Clock üretmek için dummy byte
    while(!PIR1bits.SSPIF);  // Transfer bitene kadar bekle
    PIR1bits.SSPIF = 0;      // Bayrağı temizle
    return SSPBUF;           // Alınan byte'ı döndür
}

ete

Anladığım kadarı ile C dili kullanıyorsun.
Yine anladığım kadarı ile donanımsal SPI portunu anlamaya çalışıyorsun.
Bu olay işlemcinin kendi içindeki bir prosedür.Benim bildiğim her şeyin buffer aracılığı ile yürütüldüğü. Olay, senin yazdığın programdan bağımsız geri planda çalıştığı için neler olup bittiğini anlamak zor diye düşünüyorum. Hem data yollarken hemde alırken aynı buffer kullanıldığına göre sistem aynı anda hem alma hem gönderme yapamaz diye düşünüyorum. Alma verme süreleri çok kısa olduğu için bize aynı anda yapılıyormuş gibi gelsede en azından SSBUF boşa düşünceye kadar birinin beklemesi kaçınılmaz bana kalırsa. Açıkçası ben bu kadar derinlere hiç girmedim. Girme ihtiyacı da duymadım.
Sana kolay gelsin.
Ete

alisumer

#204
bufer kaydırmalı yazmaç slaveye okumak istediğin adresi gönderdikten sonra sana o adresin kullanımını açıyor sonrasında sahte byte gönderiyorsun ya sen ff göndermişsin her saat darbesinde (iki cihazda aynı saati kullanıyor) bufer sola doğru kayıp sdo dan dışarı tek tek  çıkarken slave cıhazın içindeki veri de masterin sdi pininden eş zamanlı olarak bufere sağ taraftan tek tek giriyor 8 darbe sonunda veriler yer değiştirmiş oluyor. tren yapıyorlar :P asm de rrf komutu gibi kaydırınca status c kayan bit ne ise onun değeri oluyor tekrar kaydırırsan diğer taraftan geri giriyor registere onun gibi .
Hep meraktan

gokhan_picer

Alıntı yapılan: alisumer - 26 Kasım 2025, 05:28:15bufer kaydırmalı yazmaç slaveye okumak istediğin adresi gönderdikten sonra sana o adresin kullanımını açıyor sonrasında sahte byte gönderiyorsun ya sen ff göndermişsin her saat darbesinde (iki cihazda aynı saati kullanıyor) bufer sola doğru kayıp sdo dan dışarı tek tek  çıkarken slave cıhazın içindeki veri de masterin sdi pininden eş zamanlı olarak bufere sağ taraftan tek tek giriyor 8 darbe sonunda veriler yer değiştirmiş oluyor. tren yapıyorlar :P asm de rrf komutu gibi kaydırınca status c kayan bit ne ise onun değeri oluyor tekrar kaydırırsan diğer taraftan geri giriyor registere onun gibi .

Teşekkürler yanıt için. Bir nevi üzerine yazma oluyor diyebiliriz sanırım. Konuyu araştırdım ve üzerine sizin yorumunuzla kafamda oturmuş oldu aslında. SSPSR kaydedicisi aslında ara görev aldığı için bir nevi Dout gibi görev alıyor MOSI tarafında.



Alıntı yapılan: ete - 25 Kasım 2025, 20:09:23Anladığım kadarı ile C dili kullanıyorsun.
Yine anladığım kadarı ile donanımsal SPI portunu anlamaya çalışıyorsun.
Bu olay işlemcinin kendi içindeki bir prosedür.Benim bildiğim her şeyin buffer aracılığı ile yürütüldüğü. Olay, senin yazdığın programdan bağımsız geri planda çalıştığı için neler olup bittiğini anlamak zor diye düşünüyorum. Hem data yollarken hemde alırken aynı buffer kullanıldığına göre sistem aynı anda hem alma hem gönderme yapamaz diye düşünüyorum. Alma verme süreleri çok kısa olduğu için bize aynı anda yapılıyormuş gibi gelsede en azından SSBUF boşa düşünceye kadar birinin beklemesi kaçınılmaz bana kalırsa. Açıkçası ben bu kadar derinlere hiç girmedim. Girme ihtiyacı da duymadım.
Sana kolay gelsin.
Ete


Evet hocam C dili ile PIC programlamaya çalışıyorum. Ayrıca donanımsal SPI pinlerini kullanmaya çalıştığım için biraz arka plandaki donanımsal otomatik işlemlere kafam takıldı, ama anladığımı düşünüyorum artık.

Asıl konuya gelecek olursak PIC-nRF nihai bağlantısı ile çalıştığım yerde RF bağlantılı CAN hattını izleme işini yapmaya çalışıyorum. İlk olarak SPI ve nRF modülünü çözmem gerekiyor. Şimdi nRF modülü ile ilgili araştırmamda takıldığım yerlerde tekrar buraya geleceğim, hayırlı günler.

gokhan_picer

Herkese iyi haftalar, nRF24L01' e ait datasheet' e bir süredir bakıyordum ve 21/74 sayfaya kadar ilerledim. Operasyonel modlara kadar gelmişken konunun uzmanı hocalardan tavsiye ve bilgi almak istiyorum.

İlk olarak doğru anladığımı düşündüğüm kısımları madde madde anlatarak başlamak istiyorum. Yanlış olduğum yerlere müdahale ediniz lütfen.

SPI

1- SPI için konuşursak; MCU ve nrf arasındaki bağlantı senkron olmak zorunda-SCK- ama nrf' in kendi içindeki işleyişinde(mesela tekrar tekrar paket göndermeye çalışmasında) SCK gerekliliği bulunmuyor. Bu tamamen nrf içindeki kendi işleyişi ile(bit tanımlamalarına bağlı) alakalı.

2- Fakat master node eğer birden fazla paket alacaksa SCK pinini aktif etmek için dummmy mesajla clock generate işini aktif tutar ve her komutta ilk aldığı mesaj STATUS kaydedicisidir. Yani her gönderilen 1 byte'a karşılık 1 byte veri gelir(master-slave arasında).
----------------------------------------------------------------------------------------------------------------------
NRF

1- NRF'DE bir adresi okumak için göndereceğimiz verinin ilk 3 byte'ı 0 olmalı ve okumak istediğimiz yer TX_ADDR ise buranın adresi 0x10 olduğundan gönderilecek paket 0b0001 0000 oluyor. Diğer yandan TX_ADDR kaydedicisi 5 byte yer kapladığı için ilk gönderilen mesajdan-oku- sonra 5 kez dummy mesaj göndermemiz gerekiyor SCK hattını aktif tutmamız için.

2- Ayrıca STATUS register'ı alınan/gönderilen paketle ilgili durumların bilgisini tutar(NRF tarafında).

3- Donanımsal olarak bu nrf modülünün 3.3 V ile beslenebileceğini öğrendim. 5 V kesinlikle çipi yakıyormuş, ama SPI ve dijital pinlerini 5 v ile sürebiliyoruz(MOSI, SCK, CE, CS).

4- RX mode: Bu moda girmek için en başta PWR_UP biti 1 olmalı ve PRIM_RX biti 1 ve CE pini high olmalı. Ayrıca master paket gönderecekse önceden nrf'deki rx fifoyu okuması gerekir. Eğer bu buffer doluysa gelmesi gereken paket slave tarafından alınmaz. Ama paket gelirse demodüle edilerek RX_FIFO'ya aktarılır.

p5- PWR_UP: 1 ve PRIM_RX:0 ve tabi ki CE:1 olmalı. NRF, paket gönderildikten sonra CE:0 yapılırsa standby1 konumuna geçer ve CE:1 yapılırsa standby2 konumunda kalır. Ayrıca, CE:1 ise ve TX FIFO boş değilse gönderilmesi gereken paketi gönderene kadar bunu dener.

Bundan sonra sorularım olacak. Öncelikle izlediğim yolla alakalı yorumlarınızı bekliyorum. Bu şekilde ilerleme kaydetmem sizce mümkün mü? Olduğum konumu özetlersem;

- Alıcı ve verici devreleri donanımsal olarak kurdum( 2x PIC16F877A kullandım).
- nRF24L01 SMA antenli modül kullanıyorum.

Sorularım;

-ACK ve interrupt bilgisi almadan sadece STATUS veya FIFO bitlerine bakarak alma verme işlemlerinin kontrolünü yapabilir miyim.

-SPI protokolünde SCK olmazsa olmaz durumken. nRF modüllerin haberleşmesinde buna ihtiyaç duyulmuyor. Bu çip göndermesi gereken paketi karşı modül alana kadar deniyor. Bu esnada mesela 5 paket veri gönderildiğinde alıcı modül bunu saklıyor mu ilgili kayıtta. Eğer öyleyse alıcı MCU bunu okuyup silene kadar bu alınan paket orada mı kalır.

ete

NRF de adres değeri konusundaki açıklamanı anlamadım.
"1- NRF'DE bir adresi okumak için göndereceğimiz verinin ilk 3 byte'ı 0 olmalı ve okumak istediğimiz yer TX_ADDR ise buranın adresi 0x10 olduğundan gönderilecek paket 0b0001 0000 oluyor. Diğer yandan TX_ADDR kaydedicisi 5 byte yer kapladığı için ilk gönderilen mesajdan-oku- sonra 5 kez dummy mesaj göndermemiz gerekiyor SCK hattını aktif tutmamız için. "

NRF data sheet'ini inceleyeli epeyce zaman oldu.Böyle bir şart olduğunu hatırlamıyorum.  Ama sanki bir kelime hatası var gibi. İlk 3 byte'mı sıfır olmalı ilk 3 Bit'imi sıfır olmalı. Sanki byte'lar ile Bitler karışmış gibi duruyor bu açıklamanda. Tekrar kontrol et lütfen.

ACK ve interrupt konusundaki soruna gelince. Özellikle  Interrupt kullanmadan bu işleri elbette yönetirsin ama sürekli gecikmeye uğrarsın. Daha açık bir deyişle sana bilgi gelir NRF de kesme pini set edilir ama sen başka işlerle uğraşacağın için aklına estiği bvir zaman aralığında bilgi gelmişmi diye bakarsın. Bu gecikmeler çok fazla bilgi ile çalışıyor isen sana sıkıntı çıkartabilir. Çünki Fifo denilen ara hafızanın düzenli şekilde boşaltılması gerekir. Bence bu sorunun cevabı "yapamazsın" olmalıdır.

CLK konusundaki açıklamana da katılmıyorum. Mademki bu modül SPI ile haberleşiyor. O halde CLK her zaman gereklidir. CLK sinyali her zaman veren tarafından üretilir. Yani ortada bir alan bir veren olunca veren CLK sinyalini üreteceği için alanın ayrıca CLK sinyali üretmesi gerekmez hatta hiç gerekmez.

NRF içinde bir fifo (İlk giren ilk çıkar) hafızası bulunuyor. Gelen giden oraya kayıt ediliyor. Tamamı yanlış hatırlamıyor isem 32 Byte bilgi alıyor idi. Sen zamanında bu hafızayı boşaltmaz isen anında dolar ve yeni gelenler eskisinin üzerine yazılır (diye hatırlıyorum). Bu nedenle kesme pini burada önem kazanıyor. Kesme pininden ikaz gelince anında haberdar olup fifo yu boşlatman gerekir.

Ete

gokhan_picer

Alıntı yapılan: ete - 08 Aralık 2025, 15:38:10NRF data sheet'ini inceleyeli epeyce zaman oldu.Böyle bir şart olduğunu hatırlamıyorum.  Ama sanki bir kelime hatası var gibi. İlk 3 byte'mı sıfır olmalı ilk 3 Bit'imi sıfır olmalı. Sanki byte'lar ile Bitler karışmış gibi duruyor bu açıklamanda. Tekrar kontrol et lütfen.

Evet bit yazacakken byte yazmışım orada haklısınız. Okuma komutu ile ilgili 0x10 ve 0x1F arasında olması gerekir diye bir bilgi var.

First, you would bring CSN low and then send the command byte '00010000' to
the 24L01. This instructs the 24L01 that you want to read register 0x10, which is the
TX_ADDR register. Then you would send five dummy data bytes (it makes absolutely
no difference what the data bytes contain), and the 24L01 will send back to you the
contents of the TX_ADDR register. Finally, you would bring the CSN pin back high.

Şeklinde bir paragraf okudum bir tutorial yazısında. Ayrıca aşağıdaki gibi bir tablo var datasheet 46. sayfasında.




Alıntı yapılan: ete - 08 Aralık 2025, 15:38:10ACK ve interrupt konusundaki soruna gelince. Özellikle  Interrupt kullanmadan bu işleri elbette yönetirsin ama sürekli gecikmeye uğrarsın. Daha açık bir deyişle sana bilgi gelir NRF de kesme pini set edilir ama sen başka işlerle uğraşacağın için aklına estiği bvir zaman aralığında bilgi gelmişmi diye bakarsın. Bu gecikmeler çok fazla bilgi ile çalışıyor isen sana sıkıntı çıkartabilir. Çünki Fifo denilen ara hafızanın düzenli şekilde boşaltılması gerekir. Bence bu sorunun cevabı "yapamazsın" olmalıdır.

Bu cevaptan durumu daha iyi anladım.
Alıntı yapılan: ete - 08 Aralık 2025, 15:38:10CLK konusundaki açıklamana da katılmıyorum. Mademki bu modül SPI ile haberleşiyor. O halde CLK her zaman gereklidir. CLK sinyali her zaman veren tarafından üretilir. Yani ortada bir alan bir veren olunca veren CLK sinyalini üreteceği için alanın ayrıca CLK sinyali üretmesi gerekmez hatta hiç gerekmez.

Bu kısmı açıklamaya çalıştım ama tam anlaşılmama ihtimali var veya ben anlatamadım.
Anladığım kısmı tekrar açıklamak istiyorum. Tabi ki yanlış anlamış da olabilirim.
Şimdi verici MCU nrf modülüne paketi gönderdikten sonra SCK ile işi bitiyor, çünkü nrf24 artık RF ile veri göndereceği için alıcı nrf24'e, artık senkronizasyona ihtiyacı yok. Zaten verici MCU son paketi gönderdikten sonra clock vermiyor. Benim bahsetmek istediğim nrf24 çipinin bu aşamadan sonra yaptığı işlem. Bu kısımda nrf24 donanımsal olarak otomatik şekilde veriyi modüle edip gönderiyor. İşte bu kısımda SCK'ya ihtiyacı yok şeklinde anladım. Yanlışım varsa düzeltiniz.

gokhan_picer

#209
Merhaba, uzun zamandır bakamıyordum. Şimdi direkt olarak kodu paylaşacağım. Senaryo şu: Gönderici devre bir analog sinyal okur ve 500 ms aralıklar sürekli bunu RF gönderir . Alıcı taraf ise sürekli dinler ve bilgi geldiğinde bunu bir değişkene kaydeder. Sinyal güvenliği açısından yapılacak frekans değişikliğini kodda işlemedim henüz ama daha profesyonel olması için yapılması şart. Şimdi iki sorum var; alıcının sürekli enable kalması problem olur mu ve kod doğru mu bu senaryoda.

Tranceiver PIC:

/*
* gonderici devre
* Created on 29 Aral?k 2025 Pazartesi, 13:18
*/

#include <xc.h>

// CONFIGURATION BITS
#pragma config FOSC = HS        // HS Oscillator (High-speed crystal)
#pragma config WDTE = OFF      // Watchdog Timer Disable
#pragma config PWRTE = ON      // Power-up Timer Enable
#pragma config BOREN = ON      // Brown-out Reset Enable
#pragma config LVP = OFF        // Low Voltage Programming Disable
#pragma config CPD = OFF        // Data EEPROM Code Protection Disable
#pragma config WRT = OFF        // Flash Program Memory Write Protection Disable
#pragma config CP = OFF        // Flash Program Memory Code Protection Disable

#define _XTAL_FREQ 8000000      // 8MHz Kristal

#define CSN RC2
#define CE  RC1

void SPI_Init() {
    TRISC3 = 0; //SCK
    TRISC5 = 0; //MOSI
    TRISC4 = 1; //MISO
    SSPSTAT = 0x40; // CKE=1
    SSPCON = 0x20;  // Master mode, Fosc/4, SSPEN=1
}

uint8_t SPI_Write(uint8_t data) {
    SSPBUF = data;
    while(!BF);
    return SSPBUF;
}

void NRF_Command(uint8_t reg, uint8_t value) {
    CSN = 0;
    SPI_Write(0x20 | reg); // Yazma komutu + Register adresi
    SPI_Write(value);
    CSN = 1;
}

void ADC_Init() {
    ADCON1 = 0x80; // Sa? dayal?, tümü analog
    ADCON0 = 0x41; // Fosc/8, Channel 0, ADC On
}

uint8_t ADC_Read() {
    __delay_us(30);
    GO_nDONE = 1;
    while(GO_nDONE);
    return ADRESH; // 8-bit sonuç (ADCON1 ayar?na göre üst bitler)
}

void main() {
    TRISA0 = 1; // ANALOG input
    SPI_Init(); 
    ADC_Init(); 
    TRISC1 = 0; 
    TRISC2 = 0;
    
    // NRF Ayarlar? (0x7A: IRQ kapal?, CRC 1-byte, PWR_UP=1, PTX)
    NRF_Command(0x00, 0x7A); 
    NRF_Command(0x11, 1);    // Payload boyutu: 1 Byte gondermek icin
    
    while(1) {
        uint8_t sensor_data = ADC_Read();
        
        CSN = 0;
        SPI_Write(0xA0);        // W_TX_PAYLOAD komutu
        SPI_Write(sensor_data); // Analog veriyi gönder
        CSN = 1;
        
        CE = 1; __delay_us(15); CE = 0; // Gönderim teti?i
        
        __delay_ms(500); // 500ms aral?klarla gönder
    }
}



Receiver PIC

/*
* analog sinyalin alindigi vericiden okundugu, yani alici devrenin kodu
* Created on 29.12.2025 monday, 13:41
*/

#include <xc.h>

// CONFIGURATION BITS
#pragma config FOSC = HS        // HS Oscillator (High-speed crystal)
#pragma config WDTE = OFF      // Watchdog Timer Disable
#pragma config PWRTE = ON      // Power-up Timer Enable
#pragma config BOREN = ON      // Brown-out Reset Enable
#pragma config LVP = OFF        // Low Voltage Programming Disable
#pragma config CPD = OFF        // Data EEPROM Code Protection Disable
#pragma config WRT = OFF        // Flash Program Memory Write Protection Disable
#pragma config CP = OFF        // Flash Program Memory Code Protection Disable

#define _XTAL_FREQ 8000000      // 8MHz Kristal

#define CSN RC2
#define CE  RC1

void SPI_Init() // SPI pin yapilandirma
{
    TRISC3 = 0; // SCK
    TRISC5 = 0; // MOSI
    TRISC4 = 1; // MISO
    SSPSTAT = 0x40; // CKE=1
    SSPCON = 0x20;  // Master mode, Fosc/4, SSPEN=1
}

uint8_t SPI_Write(uint8_t data) // tek komutlar icin
{
    SSPBUF = data;
    while(!BF);
    return SSPBUF;
}

void NRF_Command(uint8_t reg, uint8_t value) // yazma/okuma
{
    CSN = 0;
    SPI_Write(0x20 | reg); // Yazma komutu + Register adresi
    SPI_Write(value);
    CSN = 1;
}

uint8_t saved_data = 0;

void main() {
    SPI_Init();
    TRISC1 = 0; 
    TRISC2 = 0;
    
    // NRF Ayarlar? (0x7B: IRQ kapal?, CRC 1-byte, PWR_UP=1, PRX)
    NRF_Command(0x00, 0x7B); // bekleyen taraf oldugu icin RX modda ayarl?
    NRF_Command(0x11, 1);    // 1 Byte bekliyoruz -payload length-
    
    CE = 1; // Sürekli dinleme modu aktif
    
    while(1) {
        // STATUS register'?n? oku (0x07)
        CSN = 0;
        uint8_t status = SPI_Write(0x07); // status register'?n? okumak için
        CSN = 1;
        
        if(status & 0x40) // RX_DR biti (6. bit) 1 mi? Veri geldi mi?
        { 
            CSN = 0;
            SPI_Write(0x61);        // R_RX_PAYLOAD komutu
            saved_data = SPI_Write(0xFF); // Gelen veriyi oku ve kaydet
            CSN = 1;
            
            // Kesme bayra??n? temizle (6. biti 1 yazarak temizlenir)
            NRF_Command(0x07, 0x40); 
        }
        __delay_ms(10); // loop data rate
    }
}

Powered by EzPortal
▲