{"id":870,"date":"2022-04-11T13:04:56","date_gmt":"2022-04-11T13:04:56","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=870"},"modified":"2022-04-11T13:05:39","modified_gmt":"2022-04-11T13:05:39","slug":"working-with-stm32-and-nrf24l01-wireless-rf-part1-configuration","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=870","title":{"rendered":"Working with STM32 and NRF24L01 Wireless RF Part1: Configuration"},"content":{"rendered":"\n<p>NRF24L01 is one of the legal RF communicators for modern applications. NRF24L01 is the cheapest one and it comes with great features. A single module communicates at 2.4 GHz frequency which makes it legal. It can transmit and receive data by a single module. Transreceiving is not its only ability, it can communicate with a total of 6 other same NRF24L01 modules at a single time. The device interfaces with the Arduino application and covers all kinds of remote-control applications. This wireless module uses SPI communication protocol and offers 10MBs data rate with 125 address range which makes it reliable the most reliable RF module. The RF module uses the GFSK module to transceiver the data.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"600\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module.png\" alt=\"\" class=\"wp-image-871\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module.png 600w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-300x300.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-150x150.png 150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-400x400.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-250x250.png 250w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>nRF24L01<\/li><li>Connection with STM32.<\/li><li>Configuring the required peripheral.<\/li><li>Configuring nRF24L01.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. nRF24L01:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>In NRF24L01 there aren\u2019t any special pins, all pins it offers to communicate are present in all microcontrollers and board. The device will interface with an external microcontroller\/Arduino through these pins to operate. It consists of 8 pins. All available pins are:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"616\" height=\"400\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-Pin-configuration-e1579096008632.png\" alt=\"\" class=\"wp-image-872\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-Pin-configuration-e1579096008632.png 616w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-Pin-configuration-e1579096008632-300x195.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-Pin-configuration-e1579096008632-400x260.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-Pin-configuration-e1579096008632-250x162.png 250w\" sizes=\"(max-width: 616px) 100vw, 616px\" \/><\/figure><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Power supply pins<\/h3>\n\n\n\n<p>VCC<\/p>\n\n\n\n<p>The power pin of the module is VCC, which connects itself with the power supply.<\/p>\n\n\n\n<p>GND<\/p>\n\n\n\n<p>nRF24L01 operates with another microcontroller and it will need a common ground to operate with it. GND pin will solve the requirement of the common ground.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Communication Pins<\/h3>\n\n\n\n<p>CE<\/p>\n\n\n\n<p>CE is an enable pin, which activates the transmission\/receiving of the module. It will only activate the device when there is a HIGH state on itself.<\/p>\n\n\n\n<p>CSN<\/p>\n\n\n\n<p>This pin is for activating the data listening and processing from the microcontroller. To keep the data communication between the microcontroller and the module it should be HIGH.<\/p>\n\n\n\n<p>SCK<\/p>\n\n\n\n<p>It is the clock pulse pin of&nbsp;SPI communication&nbsp;in nRF24L01. The data will move between the module and the microcontroller according to the clock pulse on the SCK pin.<\/p>\n\n\n\n<p>MOSI<\/p>\n\n\n\n<p>The data transmitted from the microcontroller through SPI pins are going to receive by nRF24L01 at the MOSI pin.<\/p>\n\n\n\n<p>MISO<\/p>\n\n\n\n<p>The instructions transmitted from the nRF24L01 using SPI pins are going to receive by the microcontroller at the MISO pin.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">IRQ Interrupt Pin<\/h3>\n\n\n\n<p>IRQ is an interrupt pin, which generates the event whenever a new data is available for SPI pins. It helps to send feedback to the transmitter.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">NRF24L01 RF Module Feature<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>It works at 2.4GHz frequency which makes it legal in almost every country.<\/li><li>A single module can act as both a transmitter or receiver.<\/li><li>A built-in antenna can send the data up to 100 meters.<\/li><li>A module nRF24L01 can communicate with a maximum of 6 other modules at a time.<\/li><li>It requires 3.3 volts to operate but voltages can only extend up to 3.6V otherwise it won\u2019t take much time to heat up and burn.<\/li><li>The device has a built-in oscillator of 16MHz.<\/li><li>The transmission speed of nRF24L01 is 256kbps to 2Mbps.<\/li><li>The device has 125 channel range which gives the feature of operating 125 different networks at a single place.<\/li><li>The channel frequencies variate from 2400MHz to 2525MHz.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">NRF24L01 Applications<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>In the creation of a small mesh network, nRF24L01 is the best choice to use.<\/li><li>Remote control applications at developing and commercial works wonderfully with nRF24L01.<\/li><li>Most&nbsp;IoT&nbsp;applications at home level have this wireless module but at a small level only.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">How to use the NRF24L01 Communication Module<\/h2>\n\n\n\n<p>nRF24L01 is usable with all the microcontrollers and smart boards but to use it, some pins and data information should be understood. To use the module connect it with another microcontroller with SPI protocol. First, give the power input to the devices and then attach their SPI pins according to the given circuit.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"776\" height=\"553\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-circuit-e1579096747126.png\" alt=\"\" class=\"wp-image-873\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-circuit-e1579096747126.png 776w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-circuit-e1579096747126-300x214.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-circuit-e1579096747126-768x547.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-circuit-e1579096747126-750x534.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-circuit-e1579096747126-400x285.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/nRF24L01-RF-module-circuit-e1579096747126-250x178.png 250w\" sizes=\"(max-width: 776px) 100vw, 776px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Connection with STM32:<\/h2>\n\n\n\n<p>In this guide, we need the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>2x STM32F boards<\/li><li>2x LEDs<\/li><li>2x nRF24L01<\/li><li>Hookup wires.<\/li><\/ul>\n\n\n\n<p>The connection shall be as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"823\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/Screen-Shot-2022-04-11-at-3.29.17-PM-1024x823.png\" alt=\"\" class=\"wp-image-874\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/Screen-Shot-2022-04-11-at-3.29.17-PM-1024x823.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/Screen-Shot-2022-04-11-at-3.29.17-PM-300x241.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/Screen-Shot-2022-04-11-at-3.29.17-PM-768x617.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/Screen-Shot-2022-04-11-at-3.29.17-PM-1536x1234.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/Screen-Shot-2022-04-11-at-3.29.17-PM-2048x1645.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/Screen-Shot-2022-04-11-at-3.29.17-PM-1150x924.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/Screen-Shot-2022-04-11-at-3.29.17-PM-750x603.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/Screen-Shot-2022-04-11-at-3.29.17-PM-400x321.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/04\/Screen-Shot-2022-04-11-at-3.29.17-PM-250x201.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-table is-style-regular\"><table><tbody><tr><td>STM32<\/td><td>nRF24L01<\/td><\/tr><tr><td>PA5<\/td><td>SCK<\/td><\/tr><tr><td>PA6<\/td><td>MISO<\/td><\/tr><tr><td>PA7<\/td><td>MOSI<\/td><\/tr><tr><td>PA0<\/td><td>nCS<\/td><\/tr><tr><td>PA1<\/td><td>CE<\/td><\/tr><tr><td>PA4<\/td><td>Anode of the LED<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Configuring the peripheral:<\/h2>\n\n\n\n<p>Since the module is using SPI, we shall use SPI1 of STM32F4 to communicate with the module.<\/p>\n\n\n\n<p>We start off by configuring the SPI as following:<\/p>\n\n\n\n<p>In spi.h file:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef SPI_H_\n#define SPI_H_\n#include &quot;stdint.h&quot;\nvoid spi_init();\nvoid spi1_transmit(uint8_t *data,uint32_t size);\nvoid spi1_receive(uint8_t *data,uint32_t size);\n#endif \/* SPI_H_ *\/\n<\/pre><\/div>\n\n\n\n<p>for the spi.c source file:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;spi.h&quot;\n#include &quot;stm32f4xx.h&quot;\n\nvoid spi_init()\n\t{\n\n\t#define AF05  (0x05)\n\t\/\/enable clock for GPIOA\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\n\t\/\/set PA5, PA6 and PA7 to alternate function mode\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE5_1|GPIO_MODER_MODE6_1|GPIO_MODER_MODE7_1;\n\t\/\/set which type of alternate function is\n\tGPIOA-&gt;AFR[0]|=(AF05&lt;&lt;20)|(AF05&lt;&lt;24)|(AF05&lt;&lt;28);\n\t\/\/enable clock access to SPI1\n\tRCC-&gt;APB2ENR|=RCC_APB2ENR_SPI1EN;\n\t\/\/set software slave managment\n\tSPI1-&gt;CR1|=SPI_CR1_SSM|SPI_CR1_SSI;\n\t\/\/set SPI in master mode\n\tSPI1-&gt;CR1|=SPI_CR1_MSTR;\n\t\/\/SPI1-&gt;CR1|=SPI_CR1_BR_0;\n\tSPI1-&gt;CR1|=SPI_CR1_SPE;\n\t}\n\nvoid spi1_transmit(uint8_t *data,uint32_t size)\n{\n\tuint32_t i=0;\n\tuint8_t temp;\n\n\twhile(i&lt;size)\n\t{\n\t\t\/*Wait until TXE is set*\/\n\t\twhile(!(SPI1-&gt;SR &amp; (SPI_SR_TXE))){}\n\n\t\t\/*Write the data to the data register*\/\n\t\tSPI1-&gt;DR = data[i];\n\t\ti++;\n\t}\n\t\/*Wait until TXE is set*\/\n\twhile(!(SPI1-&gt;SR &amp; (SPI_SR_TXE))){}\n\n\t\/*Wait for BUSY flag to reset*\/\n\twhile((SPI1-&gt;SR &amp; (SPI_SR_BSY))){}\n\n\t\/*Clear OVR flag*\/\n\ttemp = SPI1-&gt;DR;\n\ttemp = SPI1-&gt;SR;\n}\n\nvoid spi1_receive(uint8_t *data,uint32_t size)\n{\n\twhile(size)\n\t{\n\t\t\/*Send dummy data*\/\n\t\tSPI1-&gt;DR =0;\n\n\t\t\/*Wait for RXNE flag to be set*\/\n\t\twhile(!(SPI1-&gt;SR &amp; (SPI_SR_RXNE))){}\n\n\t\t\/*Read data from data register*\/\n\t\t*data++ = (SPI1-&gt;DR);\n\t\tsize--;\n\t}\n}<\/pre><\/div>\n\n\n\n<p>Since we are using LED for notification, we need to create two files, led.c and led.h<\/p>\n\n\n\n<p>For the led.h:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\n#ifndef LED_H_\n#define LED_H_\n\nvoid led_init();\nvoid led_off();\nvoid toggle_led();\n\n\n#endif \/* LED_H_ *\/\n<\/pre><\/div>\n\n\n\n<p>For led.c<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;led.h&quot;\n#include &quot;stm32f4xx.h&quot;\n\nvoid led_init()\n\t{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE4_0;\n\tGPIOA-&gt;MODER&amp;=~GPIO_MODER_MODE4_1;\n\t}\n\nvoid led_on()\n\t{\n\tGPIOA-&gt;BSRR=GPIO_BSRR_BS4;\n\t}\n\nvoid led_off()\n\t{\n\tGPIOA-&gt;BSRR=GPIO_BSRR_BR4;\n\t}\n\nvoid toggle_led()\n\t{\n\tGPIOA-&gt;ODR^=GPIO_ODR_OD4;\n\t}\n<\/pre><\/div>\n\n\n\n<p>Also, we need to delay in milliseconds, in this case, we shall use systick to generate interrupt each 1 milliseconds as following:<\/p>\n\n\n\n<p>For delay.h:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\n#ifndef DELAY_H_\n#define DELAY_H_\n\n#include &quot;stdint.h&quot;\nvoid delay_init(uint32_t freq);\nuint64_t millis();\nvoid delay(uint32_t time);\n#endif \/* DELAY_H_ *\/\n<\/pre><\/div>\n\n\n\n<p>and delay.c<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;delay.h&quot;\n#include &quot;stm32f4xx.h&quot;\n\n#define\tCTRL_ENABLE\t\t\t\t\t(1U&lt;&lt;0)\n#define CTRL_CLKSRC\t\t\t\t\t(1U&lt;&lt;2)\n#define CTRL_COUNTFLAG\t\t\t\t(1U&lt;&lt;16)\n#define CTRL_TICKINT\t\t\t\t(1U&lt;&lt;1)\n\n\nvolatile uint64_t mil;\n\nvoid delay_init(uint32_t freq){\n\n\tSysTick-&gt;LOAD  = (freq\/1000) - 1;\n\n\t\/*Clear systick current value register *\/\n\tSysTick-&gt;VAL = 0;\n\n\t\/*Enable systick and select internal clk src*\/\n\tSysTick-&gt;CTRL = CTRL_ENABLE | CTRL_CLKSRC ;\n\n\t\/*Enable systick interrupt*\/\n\tSysTick-&gt;CTRL  |= CTRL_TICKINT;\n\n}\n\n\n\nuint64_t millis()\n\t{\n\t__disable_irq();\n\tuint64_t ml=mil;\n\t__enable_irq();\n\treturn ml;\n\t}\n\n\n\nvoid delay(uint32_t time)\n\t{\n\n\tuint64_t start=millis();\n\twhile((millis() - start) &lt; time);\n\n\t}\n\nvoid SysTick_Handler(void)\n{\n\tmil++;\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Configuring nRF24L01:<\/h2>\n\n\n\n<p>Before we start configuring the module, we need to create functions that allow us to perform the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Chip select and chip enable<\/li><li>Write to register.<\/li><li>Multiple bytes write.<\/li><li>Read a register.<\/li><li>Read multiple bytes from a register.<\/li><li>Write a command.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>For those functions:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\n\nvoid CS_Select (void)\n{\nGPIOA-&gt;BSRR=GPIO_BSRR_BR1;\n}\n\nvoid CS_UnSelect (void)\n{\nGPIOA-&gt;BSRR=GPIO_BSRR_BS1;\n}\n\n\nvoid CE_Enable (void)\n{\n\tGPIOA-&gt;BSRR=GPIO_BSRR_BS0;\n\n}\n\nvoid CE_Disable (void)\n{\n\tGPIOA-&gt;BSRR=GPIO_BSRR_BR0;\n\n}\n\n\n\/\/ write a single byte to the particular register\nvoid nrf24_WriteReg (uint8_t Reg, uint8_t Data)\n{\n\tuint8_t buf[2];\n\tbuf[0] = Reg|1&lt;&lt;5;\n\tbuf[1] = Data;\n\n\t\/\/ Pull the CS Pin LOW to select the device\n\tCS_Select();\n\n\tspi1_transmit(buf, 2);\n\n\t\/\/ Pull the CS HIGH to release the device\n\tCS_UnSelect();\n}\n\n\/\/write multiple bytes starting from a particular register\nvoid nrf24_WriteRegMulti (uint8_t Reg, uint8_t *data, int size)\n{\n\tuint8_t buf[2];\n\tbuf[0] = Reg|1&lt;&lt;5;\n\/\/\tbuf[1] = Data;\n\n\t\/\/ Pull the CS Pin LOW to select the device\n\tCS_Select();\n\n\tspi1_transmit(buf,1);\n\tspi1_transmit(data, size);\n\n\t\/\/ Pull the CS HIGH to release the device\n\tCS_UnSelect();\n}\n\n\nuint8_t nrf24_ReadReg (uint8_t Reg)\n{\n\tuint8_t data=0;\n\n\t\/\/ Pull the CS Pin LOW to select the device\n\tCS_Select();\n\n\tspi1_transmit(&amp;Reg, 1);\n\tspi1_receive(&amp;data,1);\n\n\t\/\/ Pull the CS HIGH to release the device\n\tCS_UnSelect();\n\n\treturn data;\n}\n\n\n\/* Read multiple bytes from the register *\/\nvoid nrf24_ReadReg_Multi (uint8_t Reg, uint8_t *data, int size)\n{\n\t\/\/ Pull the CS Pin LOW to select the device\n\tCS_Select();\n\n\tspi1_transmit(&amp;Reg, 1);\n\tspi1_receive(data, size);\n\t\/\/ Pull the CS HIGH to release the device\n\tCS_UnSelect();\n}\n\n\n\/\/ send the command to the NRF\nvoid nrfsendCmd (uint8_t cmd)\n{\n\t\/\/ Pull the CS Pin LOW to select the device\n\tCS_Select();\n\n\tspi1_transmit( &amp;cmd, 1);\n\n\t\/\/ Pull the CS HIGH to release the device\n\tCS_UnSelect();\n}\n<\/pre><\/div>\n\n\n\n<p>Then we need to configure the CE and nCS as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\nvoid ncs_cs_init()\n\t{\n  \t\/*enable clock access ti GPI)A*\/\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\n  \t\/*Set PA0 and PA1 as output*\/\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODER0_0|GPIO_MODER_MODER1_0;\n\tGPIOA-&gt;MODER&amp;=~(GPIO_MODER_MODER0_1|GPIO_MODER_MODER1_1);\n\n\t}\n<\/pre><\/div>\n\n\n\n<p>For initializing the nRF24L01:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\nvoid NRF24_Init (void)\n{\n\tspi_init();\n\tncs_cs_init();\n\t\/\/ disable the chip before configuring the device\n\tCE_Disable();\n\n\n\t\/\/ reset everything\n\tnrf24_reset (0);\n\n\tnrf24_WriteReg(CONFIG, 0);  \/\/ will be configured later\n\n\tnrf24_WriteReg(EN_AA, 0);  \/\/ No Auto ACK\n\n\tnrf24_WriteReg (EN_RXADDR, 0);  \/\/ Not Enabling any data pipe right now\n\n\tnrf24_WriteReg (SETUP_AW, 0x03);  \/\/ 5 Bytes for the TX\/RX address\n\n\tnrf24_WriteReg (SETUP_RETR, 0);   \/\/ No retransmission\n\n\tnrf24_WriteReg (RF_CH, 0);  \/\/ will be setup during Tx or RX\n\n\tnrf24_WriteReg (RF_SETUP, 0x0E);   \/\/ Power= 0db, data rate = 2Mbps\n\n\t\/\/ Enable the chip after configuring the device\n\tCE_Enable();\n\n}<\/pre><\/div>\n\n\n\n<p>For the header file:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef NRF_H_\n#define NRF_H_\n\n#include &quot;stdint.h&quot;\n\nvoid NRF24_Init (void);\n\n\/* Memory Map *\/\n#define CONFIG      0x00\n#define EN_AA       0x01\n#define EN_RXADDR   0x02\n#define SETUP_AW    0x03\n#define SETUP_RETR  0x04\n#define RF_CH       0x05\n#define RF_SETUP    0x06\n#define STATUS      0x07\n#define OBSERVE_TX  0x08\n#define CD          0x09\n#define RX_ADDR_P0  0x0A\n#define RX_ADDR_P1  0x0B\n#define RX_ADDR_P2  0x0C\n#define RX_ADDR_P3  0x0D\n#define RX_ADDR_P4  0x0E\n#define RX_ADDR_P5  0x0F\n#define TX_ADDR     0x10\n#define RX_PW_P0    0x11\n#define RX_PW_P1    0x12\n#define RX_PW_P2    0x13\n#define RX_PW_P3    0x14\n#define RX_PW_P4    0x15\n#define RX_PW_P5    0x16\n#define FIFO_STATUS 0x17\n#define DYNPD\t    0x1C\n#define FEATURE\t    0x1D\n\n\/* Instruction Mnemonics *\/\n#define R_REGISTER    0x00\n#define W_REGISTER    0x20\n#define REGISTER_MASK 0x1F\n#define ACTIVATE      0x50\n#define R_RX_PL_WID   0x60\n#define R_RX_PAYLOAD  0x61\n#define W_TX_PAYLOAD  0xA0\n#define W_ACK_PAYLOAD 0xA8\n#define FLUSH_TX      0xE1\n#define FLUSH_RX      0xE2\n#define REUSE_TX_PL   0xE3\n#define NOP           0xFF\n\n\n\n#endif \/* NRF_H_ *\/\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>In part 2, we shall configure the module to transmit data<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude42 <\/p>\n","protected":false},"excerpt":{"rendered":"<p>NRF24L01 is one of the legal RF communicators for modern applications. NRF24L01 is the cheapest one and it comes with great features. A single module communicates at 2.4 GHz frequency which makes it legal. It can transmit and receive data by a single module. Transreceiving is not its only ability, it can communicate with a [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-870","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/870"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=870"}],"version-history":[{"count":3,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/870\/revisions"}],"predecessor-version":[{"id":877,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/870\/revisions\/877"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=870"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=870"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=870"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}