nrf_serial 库是nordic封装的比较上层的串口抽象层。可以支持多个串口,可以使用阻塞、中断、DMA三种模式。接口API比较简单,但是在使用之前需要先进行比较多的宏定义。
在sdk_config中使能如下配置
NRFX_UARTE_ENABLED
NRFX_UART_ENABLED
NRF_SERIAL_ENABLED
并把对应的c文件添加到工程中,h头文件路径包含进工程中
#define UART_TX_PIN 5
#define UART_RX_PIN 6
NRF_SERIAL_DRV_UART_CONFIG_DEF(uart_drv_config,
UART_RX_PIN, UART_TX_PIN,
NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED,
NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED,
NRF_UART_BAUDRATE_115200,
UART_DEFAULT_CONFIG_IRQ_PRIORITY);
该配置主要是用来配置串口的引脚、波特率、中断优先级等和硬件配置相关的东西。
#define SERIAL_FIFO_TX_SIZE 128
#define SERIAL_FIFO_RX_SIZE 256
NRF_SERIAL_QUEUES_DEF(serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);
#define SERIAL_BUFF_TX_SIZE 1
#define SERIAL_BUFF_RX_SIZE 1
NRF_SERIAL_BUFFERS_DEF(serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);
这两个东西很容易让人分不清,为什么既要定义queue又要定义一个buffer,是不是有点重复?
这里的BUFFER实际上就是传递给了底层,在DMA模式下当收到数据就直接把数据搬到了BUFFER里面。BUFFER定义的大小可以决定当收到几个byte以后会产生一个DMA中断,通知到上层就是一个NRF_SERIAL_EVENT_RX_DATA事件。所以为了让每接收一个byte会通知到上层来,通常就把SERIAL_BUFF_RX_SIZE设置为1了。
每一次DMA中断nrf_serial就会自动从BUFFER中取出接收到的数据,取出来的数据又会被写入到QUEUE中。应用读取接收到的数据实际上也就是从queue中提取出来了。
static void uart_evt_handler_t(struct nrf_serial_s const * p_serial,nrf_serial_event_t event)
{
if(event==NRF_SERIAL_EVENT_RX_DATA)
{
}
else if(event==NRF_SERIAL_EVENT_FIFO_ERR)
{
}
else if(event==NRF_SERIAL_EVENT_DRV_ERR)
{
}
}
前面的SERIAL_BUFF_RX_SIZE设置的是1,当接收到一个byte就会产生一个NRF_SERIAL_EVENT_RX_DATA事件。收到的数据nrf_serial自动的把数据存入到了queue中了。应用可以在接收事件中立马调用nrf_serial_read函数去读取数据,也可以放在app_scheduler中去
NRF_SERIAL_UART_DEF(serial_uarte, 0);
NRF_SERIAL_CONFIG_DEF( serial_config, NRF_SERIAL_MODE_DMA,
&serial_queues, &serial_buffs,
uart_evt_handler_t, NULL);
ret_code_t ret;
ret = nrf_serial_init(&serial_uarte, &uart_drv_config, &serial_config);
APP_ERROR_CHECK(ret);
当初始化以后就直接打开的接收功能,一旦有数据接收到就会产生事件。
ret_code_t nrf_serial_write(nrf_serial_t const * p_serial,
void const * p_data,
size_t size,
size_t * p_written,
uint32_t timeout_ms);
ret_code_t nrf_serial_read(nrf_serial_t const * p_serial,
void * p_data,
size_t size,
size_t * p_read,
uint32_t timeout_ms);
当使用DMA模式的时候,该函数需要在收到接收事件以后再调用,直接从queue取出接收到的数据。
全部0条评论
快来发表一下你的评论吧 !