NRF51822——串口学习笔记

前言:

为了方便查看博客,特意申请了一个公众号,附上二维码,有兴趣的朋友可以关注,和我一起讨论学习,一起享受技术,一起成长。

NRF51822——串口学习笔记_第1张图片


1.概述

nRF51822 没有固定的串口引脚 RX 和 TX,与UART相关的信号RXD、CTS、RTS和TXD可根据寄存器:PSELRXD、PSELCTS、PSELRTS和PSELTXD独立配置映射到相应的物理引脚。

RTS (Require ToSend,发送请求:为输出信号,用于指示本设备准备好可接收数据,低电平有效,低电平说明本设备可以接收数据。

CTS (Clear ToSend,发送允许:为输入信号,用于判断是否可以向对方发送数据,低电平有效,低电平说明本设备可以向对方发送数据。

NRF51822——串口学习笔记_第2张图片

2.配置

2.1 IO口方向配置:

NRF51822——串口学习笔记_第3张图片

2. 2 串口相关存器:

NRF51822——串口学习笔记_第4张图片

在 nrf51.h中已有相关定义:


typedef struct {                                    /*!< UART Structure                                                        */
  __O  uint32_t  TASKS_STARTRX;                     /*!< Start UART receiver.                                                  */
  __O  uint32_t  TASKS_STOPRX;                      /*!< Stop UART receiver.                                                   */
  __O  uint32_t  TASKS_STARTTX;                     /*!< Start UART transmitter.                                               */
  __O  uint32_t  TASKS_STOPTX;                      /*!< Stop UART transmitter.                                                */
  __I  uint32_t  RESERVED0[3];
  __O  uint32_t  TASKS_SUSPEND;                     /*!< Suspend UART.                                                         */
  __I  uint32_t  RESERVED1[56];
  __IO uint32_t  EVENTS_CTS;                        /*!< CTS activated.                                                        */
  __IO uint32_t  EVENTS_NCTS;                       /*!< CTS deactivated.                                                      */
  __IO uint32_t  EVENTS_RXDRDY;                     /*!< Data received in RXD.                                                 */
  __I  uint32_t  RESERVED2[4];
  __IO uint32_t  EVENTS_TXDRDY;                     /*!< Data sent from TXD.                                                   */
  __I  uint32_t  RESERVED3;
  __IO uint32_t  EVENTS_ERROR;                      /*!< Error detected.                                                       */
  __I  uint32_t  RESERVED4[7];
  __IO uint32_t  EVENTS_RXTO;                       /*!< Receiver timeout.                                                     */
  __I  uint32_t  RESERVED5[46];
  __IO uint32_t  SHORTS;                            /*!< Shortcuts for UART.                                                   */
  __I  uint32_t  RESERVED6[64];
  __IO uint32_t  INTENSET;                          /*!< Interrupt enable set register.                                        */
  __IO uint32_t  INTENCLR;                          /*!< Interrupt enable clear register.                                      */
  __I  uint32_t  RESERVED7[93];
  __IO uint32_t  ERRORSRC;                          /*!< Error source. Write error field to 1 to clear error.                  */
  __I  uint32_t  RESERVED8[31];
  __IO uint32_t  ENABLE;                            /*!< Enable UART and acquire IOs.                                          */
  __I  uint32_t  RESERVED9;
  __IO uint32_t  PSELRTS;                           /*!< Pin select for RTS.                                                   */
  __IO uint32_t  PSELTXD;                           /*!< Pin select for TXD.                                                   */
  __IO uint32_t  PSELCTS;                           /*!< Pin select for CTS.                                                   */
  __IO uint32_t  PSELRXD;                           /*!< Pin select for RXD.                                                   */
  __I  uint32_t  RXD;                               /*!< RXD register. On read action the buffer pointer is displaced.
                                                         Once read the character is consumed. If read when no character
                                                          available, the UART will stop working.                               */
  __O  uint32_t  TXD;                               /*!< TXD register.                                                         */
  __I  uint32_t  RESERVED10;
  __IO uint32_t  BAUDRATE;                          /*!< UART Baudrate.                                                        */
  __I  uint32_t  RESERVED11[17];
  __IO uint32_t  CONFIG;                            /*!< Configuration of parity and hardware flow control register.           */
  __I  uint32_t  RESERVED12[675];
  __IO uint32_t  POWER;                             /*!< Peripheral power control.                                             */
} NRF_UART_Type;

2.3 波特率

波特率 对应参数 备注
Baud1200 0x0004F000 1200 baud
Baud2400 0x0009D000 2400 baud
Baud4800 0x0013B000 4800 baud
Baud9600 0x00275000 9600 baud
Baud14400 0x003B0000 14400 baud
Baud19200 0x004EA000 19200 baud
Baud28800 0x0075F000 28800 baud
Baud38400 0x009D5000 38400 baud
Baud57600 0x00EBF000 57600 baud
Baud76800 0x013A9000 76800 baud
Baud115200 0x01D7E000 115200 baud
Baud230400 0x03AFB000 230400 baud
Baud250000 0x04000000 250000 baud
Baud460800 0x075F7000 460800 baud
Baud921600 0x0EBEDFA4 921600 baud
Baud1M 0x10000000 1Mega baud

2.4 串口收发

开启串口发送:

当触发STARTTX任务时,UART传输时序启动。通过写TXD寄存器可以实现字节的发送。当一个字节成功发送的候,UART会产生一个TXDRDY事件,于是新的字节也可以写到TXD寄存器。通过触发STOPTX任务,UART传输时序将会关闭。

开启串口接收:

当触发STARTRX任务时,UART接收时序启动。接收到的字节会被移动到CPU能够提取的RXD寄存器中。RXD寄存器时双缓冲的,当第一个字节被CPU从RXD寄存器中提取走的同时第二个字节可以被接收。每当一个新字节被移入RXD寄存器时UART会产生一个RXDRDY事件。当第一个字节被从RXD寄存器中提取走的时候,第二个字节会被从RXD-1移到RXD寄存器。通过触发STOPRX任务,UART接收时序将会关闭。

**在程序最后,通过触发STARTTX任务和STARTRX任务,开启UART发送和接收。**为了避免因为以前接收到数据而产生的RXDRDY事件导致接收到错误的数据,在最后也需要对EVENTS_RXDRDY清零。但是由于是在字节发送成功之后自动产生TXDRDY事件,对其清不清零并不影响将来的数据发送。

3.软件实现

3.1 寄存器方式实现
//初始化
void Usart_Init(uint32_t bound)
{
	nrf_gpio_cfg_input(USART_RX, NRF_GPIO_PIN_NOPULL);
	nrf_gpio_cfg_output( USART_TX);
	
	NRF_UART0->PSELRXD = USART_RX;
	NRF_UART0->PSELTXD = USART_TX;
	NRF_UART0->PSELRTS = 0XFFFFFFFF;//关闭流控
	NRF_UART0->PSELCTS = 0XFFFFFFFF;

	NRF_UART0->BAUDRATE = bound;
	NRF_UART0->CONFIG = 0;	//不使用流控,不校验

	NRF_UART0->EVENTS_RXDRDY = 0;
	NRF_UART0->EVENTS_TXDRDY = 0;

	NRF_UART0->ENABLE = 4;	//使能串口
	NRF_UART0->TASKS_STARTRX  = 1;
	NRF_UART0->TASKS_STARTTX = 1;
}

//发送数据
void Usart_Send_Byte(uint8_t dat)
{ 
	
	NRF_UART0->EVENTS_TXDRDY = 0;
	NRF_UART0->TXD = dat;
	while(NRF_UART0->EVENTS_TXDRDY == 0);
}

//接收数据
uint8_t Usart_Recive_Byte(void)
{
	
	while(NRF_UART0->EVENTS_RXDRDY == 0);
	NRF_UART0->EVENTS_RXDRDY = 0;	//清零事件

	return (uint8_t)NRF_UART0->RXD;	
}

//发送字符串
void Usart_Send_String(uint8_t *str)
{
	uint8_t i=0;
	
	while(str[i]!= '\0')
	{
		Usart_Send_Byte(str[i]);
		i++;
	}
}

测试现象:

NRF51822——串口学习笔记_第5张图片

3.2 中断方式实现:

需在初始化中加入中断初始化:

//中断方式
	NVIC_SetPriority(UART0_IRQn, 1);
	NVIC_ClearPendingIRQ(UART0_IRQn);
	NVIC_EnableIRQ(UART0_IRQn);

中断服务程序:

void UART0_IRQHandler(void)
{
	//接收
	if(NRF_UART0->EVENTS_RXDRDY != 0)
	{
		NRF_UART0->EVENTS_RXDRDY = 0;
		uart_buf[rx_index++] = (uint8_t)NRF_UART0->RXD;
	}

	//发送
	if(NRF_UART0->EVENTS_TXDRDY != 0)
	{
		NRF_UART0->EVENTS_TXDRDY = 0;
		if(tx_index != 0)
		{
			NRF_UART0->TXD = uart_buf[tx_index++];
		}
		
	}
}


参考:

1.nrf51822裸机教程-UART

2.nRF51822 UART引脚配置

你可能感兴趣的:(NRF51822专栏)