STM32 + nrf24L01 1:1 Rx - Tx örneği

 



nRF24L01, 2.4 GHz frekans bandında çalışan, düşük güç tüketimli ve düşük maliyetli bir kablosuz iletişim modülüdür. antenli ve antensiz versiyonları olmak üzere 2 tip seçeneği mevcuttur. 

(açık alanda) antensiz versiyon 10 - 30 metre civarında iletim sağlıyorken, antenli versiyonu 800m - 1km mesafeye ulaşabilir.

Özellikleri:

  • Çalışma frekansı: 2.4–2.525 GHz

  • Veri hızı: 250 kbps, 1 Mbps, 2 Mbps seçenekleri

  • Güç tüketimi: Çok düşüktür (pilli projelere uygun)

  • İletişim protokolü: SPI ile kontrol edilir

  • Ekstra özellik: Otomatik acknowledgment, otomatik tekrar iletim, çoklu alıcı desteği (multi-ceiver)


  daha önce kablosuz haberleşmede LoRa örneği ile ilgili bir yazı paylaşmıştık. LoRa uzun menzil avantajı olsa da daha yüksek hız gerektiren uygulamalarda yetersiz kalmaktadır 2 mbps'ye varan hızı gerekli ihtiyaçları karşılayabilmektedir.

Bağlantı şeması: aynı anda iki st-link bağlanamadığından ötürü sırayla kod atılması daha sağlıklı olur. durum takibi için receiver olan bilgisayardan beslenirken transmitterin harici bir güç kaynağından beslenmesi daha iyi olacaktır. bu örneğimizde ben F103C8T6 ve F407-DISC kullanarak 2 stm işlemci ile gerçekleştirdim. 




Kaynak kod'u aşağıdaki linkte bulunmakta:
https://github.com/spacemonochrome/stm32_hal_nrf24l01

nrf24l01 klasöründe bulunan header (.h) ve source (.c) dosyalarının oluşturulan iki projeye de dahil olması gerekmektedir.




F103'ün ioc ekranı

F407'nin ioc ekranı






Bu örneğimizde kesme yani interrupt kullanılmamaktadır. fakat daha sonra paylaşılacak olan nrf24l01 örneklerinde interrupt kullanacağımız için bu ayarı açık bırakmakta fayda olur.   bundan ötürü her iki projede de olması gereken EXTI (interrupt) kesme pinini aktif duruma getirelim. ben her iki proje için de A2 pinini seçtim. nrf24l01 modelinde IRQ pini normalde HIGH'dır yani 1'dir olay tetiklendiğinde 0  yani LOW olur. yani yüksekten düşüğe geçişte tetiklenir. bundan ötürü yüksekten düşüğe geçiş olayında tetiklenebilmesi için  kesme pi konfigürasyonu ayarında External Interrupt mode with Falling Edge Trigger Detection seçili olmalıdır. 



ben her iki işlemcide de CE pini için A3'ü, CSN pini için de A4'ü, SPI arayüzü için de SPI1 hattını kullandım. siz farklı hat ve pinler kullanacaksanız buradan değiştirmeniz gerekmektedir.



evet. ayarlamaları yaptık kodları da projeye dahil ettik. ben bu uygulamada F103'ü Transmitter, F407'yi Receiver olarak kullandım. ikisi için de kodlar aşağıda verilmiştir.




Transmitter Kod - F103

  
  /* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include 
#include "NRF24.h"
#include "NRF24_reg_addresses.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

#define PLD_S 32

uint8_t tx_addr[5] = {0x45, 0x55, 0x67, 0x10, 0x21};

uint16_t data = 0;

uint8_t dataT[PLD_S] = "Teslanin Sovalyesi! Transmitter";

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */
  csn_high();
    ce_high();

    HAL_Delay(5);

    ce_low();

    nrf24_init();

    nrf24_stop_listen();

    nrf24_auto_ack_all(auto_ack);
    nrf24_en_ack_pld(disable);
    nrf24_dpl(disable);

    nrf24_set_crc(no_crc, _1byte);

    nrf24_tx_pwr(_0dbm);
    nrf24_data_rate(_1mbps);
    nrf24_set_channel(90);
    nrf24_set_addr_width(5);

    nrf24_set_rx_dpl(0, disable);
    nrf24_set_rx_dpl(1, disable);
    nrf24_set_rx_dpl(2, disable);
    nrf24_set_rx_dpl(3, disable);
    nrf24_set_rx_dpl(4, disable);
    nrf24_set_rx_dpl(5, disable);

    nrf24_pipe_pld_size(0, PLD_S);

    nrf24_auto_retr_delay(4);
    nrf24_auto_retr_limit(10);

    nrf24_open_tx_pipe(tx_addr);
    nrf24_open_rx_pipe(0, tx_addr);
    ce_high();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

  while (1)
  {

	    nrf24_type_to_uint8_t(data, dataT, sizeof(data));

	    uint8_t val = nrf24_transmit(dataT, sizeof(dataT));

		HAL_Delay(100);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

  





Receiver Kod - F407 tarafı


  
  /* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include 
#include "NRF24.h"
#include "NRF24_reg_addresses.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#define PLD_S 32

uint8_t tx_addr[5] = {0x45, 0x55, 0x67, 0x10, 0x21};

uint16_t data = 0;

uint8_t dataR[PLD_S];
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */
  csn_high();
    ce_high();

    HAL_Delay(5);

    ce_low();

    nrf24_init();

    nrf24_listen();

    nrf24_auto_ack_all(auto_ack);
    nrf24_en_ack_pld(disable);
    nrf24_dpl(disable);

    nrf24_set_crc(no_crc, _1byte);

    nrf24_tx_pwr(_0dbm);
    nrf24_data_rate(_1mbps);
    nrf24_set_channel(90);
    nrf24_set_addr_width(5);

    nrf24_set_rx_dpl(0, disable);
    nrf24_set_rx_dpl(1, disable);
    nrf24_set_rx_dpl(2, disable);
    nrf24_set_rx_dpl(3, disable);
    nrf24_set_rx_dpl(4, disable);
    nrf24_set_rx_dpl(5, disable);

    nrf24_pipe_pld_size(0, PLD_S);

    nrf24_auto_retr_delay(4);
    nrf24_auto_retr_limit(10);

    nrf24_open_tx_pipe(tx_addr);
    nrf24_open_rx_pipe(0, tx_addr);
    ce_high();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  nrf24_listen();

	  	if(nrf24_data_available()){
	  		nrf24_receive(dataR, sizeof(dataR));
	  	}

	      data = nrf24_uint8_t_to_type(dataR, sizeof(dataR));

	  	HAL_Delay(1);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
  
        



F103'e Transmitter tarafı kodu atıp çalıştırdıktan sonra bilgisayarla bağlantısını kesiyorum. harici bir güç kaynağı ile besliyorum. F103'ü çıkartıp F407'yi taktıktan sonra Receive kodunu atıp çalıştırıyorum. live expressions ekranından gelen değerleri takip ediyorum. bu kod şu an en temel uygulama olan 1:1 veri alma gönderme kodudur.


Referans: https://github.com/developer328/stm32_hal_nrf24_library

Diğer referanslar:
https://github.com/libdriver/nrf24l01

Yorumlar