// Make sure to include all these headers otherwise you might receive some compilation errors
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "nrf.h"
#include "nrf_drv_clock.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_drv_power.h"
#include "nrf_serial.h"
#include "app_timer.h"
#include "app_error.h"
#include "app_util.h"
#include "boards.h"
// define a vairable for the queue size
#define OP_QUEUES_SIZE 3
// A sleep handler which will be called when there is no communication taking place
void sleep_handler(void)
{
__WFE();
__SEV();
__WFE();
}
// Declare an event handler function which will be called when the device transmits or receives the data.
void uart_event_handler(struct nrf_serial_s const *p_serial, nrf_serial_event_t event);
// define the configurations for uart, we can define custom pin numbers and then assign them here in this step as well
NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uart0_drv_config,
RX_PIN_NUMBER, TX_PIN_NUMBER, // TX pin and rx pin
RTS_PIN_NUMBER, CTS_PIN_NUMBER, // RTS and CTS pin
NRF_UART_HWFC_ENABLED, NRF_UART_PARITY_EXCLUDED, // Hardware flow control is disabled because we are not using a very high baud rate
NRF_UARTE_BAUDRATE_115200, // UART baud rate is defined using this constant
UART_DEFAULT_CONFIG_IRQ_PRIORITY); // default interrupt priority is set to 7 which is the lowest and will be processed once higher priority interrupts are executed
// Now we need to define the size of fifo, if this is too small then receiving more data then this size will cause the fifo overflow so adjust it according to your application
#define SERIAL_FIFO_TX_SIZE 32 // Fifo for TX
#define SERIAL_FIFO_RX_SIZE 32// FIFO for RX
// Create a queue and assign it the fifo sizes
NRF_SERIAL_QUEUES_DEF(serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);
// This is the minimum buffer size and interrupts will depend on its size, for e.g if the rx buffer size is 1, then upon receiving every one character an interrupt will be generated
// Adjust it according to your requirements
#define SERIAL_BUFF_TX_SIZE 1
#define SERIAL_BUFF_RX_SIZE 4
// Now create a buffer and assign it size of RX buffer and TX buffer
NRF_SERIAL_BUFFERS_DEF(serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);
// Create a main configuration handle and pass it all the configurations created above
// Parameters are: name of configuration, Mode of operation i.e blocking - non-blocking or - DMA mode,
// serial queue configuration address, serial buffers address, event handler which will be called on interrupts,
// Sleep handler which will be called if the device is not using serial comm so it can go into sleep mode, we can pass it NULL value as well
NRF_SERIAL_CONFIG_DEF(serial_config, NRF_SERIAL_MODE_DMA,
&serial_queues, &serial_buffs, uart_event_handler, sleep_handler);
//
// Create a UART handle and assign it the hardware UART, 0 for nrf52832 and it can be 0 or 1 for nrf52840
NRF_SERIAL_UART_DEF(serial_uart, 0);
//**************************************************************************************************
// This event handler will be called whenever an interrupt is triggered by the UART module
void uart_event_handler(struct nrf_serial_s const *p_serial, nrf_serial_event_t event)
{
ret_code_t err_code; // A variable to hold the error code value
uint8_t c[4]; // defined an array of 4 char type values
// check which event was generated by the interrupt
switch(event)
{
// if this event occured then it means the transmission of data is succesfully completed and we
// can now update our user or perform something else
case NRF_SERIAL_EVENT_TX_DONE:
bsp_board_led_invert(0);// a function to toggle the led 1
break;
// if this event occured it means that some data is available to be read, its size depends on the buffer size as mentioned above.
case NRF_SERIAL_EVENT_RX_DATA:
bsp_board_led_invert(3); //toggle the LED 4 on the board showing some data is received
// Read the data from the serial port and save it into the array
err_code = nrf_serial_read(&serial_uart, &c, sizeof(c), NULL, 100);
APP_ERROR_CHECK(err_code); // check if some error occured during reading
// We can also use type casting to drop the error code like i did below by using (void) before the function
(void)nrf_serial_write(&serial_uart, &c, sizeof(c), NULL, 100); // a function to transmit the data over uart
(void)nrf_serial_flush(&serial_uart, 0); // call this function to clear the buffers from the last received data
break;
default:
// do nothing if none of the above event is occured
break;
}
}
// main function
int main(void)
{
ret_code_t err_code; // a variable to hold the error value
// Initialize the clock to use the timers and bsp board package
err_code = nrf_drv_clock_init();
APP_ERROR_CHECK(err_code);
// initialize the power management so that the sleep handler function is not automatically called but it is managed by
// power management... more on power management will be covered in future tutorial. for now this line is enough
err_code = nrf_drv_power_init(NULL);
APP_ERROR_CHECK(err_code);
// request the low frequency clock to not to generate the events
nrf_drv_clock_lfclk_request(NULL);
// Initialize the timers which can be used by the BSP package. I am not using the BSP but its necessary see the tutorial on BSP revisited for more information
err_code = app_timer_init();
APP_ERROR_CHECK(err_code);
// Initialize the LEDs so that they can be toggled
bsp_board_init(BSP_INIT_LEDS);
// This is the main function and it initialzies the serial Port so after all the configurations are done as we did above,
// we call this function and pass it all the configurations
err_code = nrf_serial_init(&serial_uart, &m_uart0_drv_config, &serial_config);
APP_ERROR_CHECK(err_code);
// Create a simple char array and assign it some string data along with the line ending sequence i.e. \r\n
static char tx_msg[] = "This is some data from nrf device. \r\n";
// Infinite loop
// Transmit a simple message every second
while (true)
{
// wait for 1 Second
nrf_delay_ms(1000);
// A function to write data(transmit data) to serial port
// Parameters are:
// 1: serial uart handle
// 2: char array or a single char
// 3: lenght of the array here we use strlen function which calculates the length of the array
// 4: Time out value, here we tell it the max timeout so it will wait until the transmission succesfully completes
err_code = nrf_serial_write(&serial_uart, tx_msg, strlen(tx_msg), NULL, NRF_SERIAL_MAX_TIMEOUT);
APP_ERROR_CHECK(err_code);
}
}
/** @} */
NRF52832学习笔记 (uart communication)
最新推荐文章于 2024-03-12 16:49:34 发布