EE/Embedded Systems

Nordic nRF52 UART 통신

esmJK 2020. 12. 23. 14:50

Introduction 

Universal Asyncronous Receiver / Transmitter (UART) 는 데이터 통신에 널리 쓰이는 통식 방식중 하나이다.

 

Asynchronous인 이유는 두 디바이스 간 통신 시 Clock 이 비동기 이기 때문이다. 각 디바이스는 고유한 Clock 을 발생시킨다. 같은 Clock Source로 통신을 동기화시킬 경우 Universal Synchronous Asynchronous Transmitter/Receiver (USART) 로 볼 수 있다. 

 

하나의 Packet은 다음과 같이 구성된다. 

 

Baud Rate는 보통 9600 b/s 또는 115200 b/s 로 설정된다. 

 

마이크로컨트롤러끼리 UART로 통신할 경우 한 Device의 Tx Pin 이 반대쪽의 Rx 로 연결되고, 반대쪽의 Tx 는 Device의 Rx 로 연결된다. Serial Communication 방식이므로 8개 bit 를 동시에 다루는 Parallel Communication 보다 시간이 약 8배정도 더 걸릴 수밖에 없다. 

 

높은 Baud Rate를 사용할 때는 Hardware Flow Control이 필요하다. 

그러나 이번 예시에서는 필요가 없기 때문에 API에 있는 값으로 Disable 시켜준다. 

#define UART_HWFC APP_UART_FLOW_CONTROL_DISABLED

 

Error Handling

UART 통신에러 발생 시 전환되는 루틴을 미리 설정해주어야 한다. 다음과 같이 에러 코드 변수를 선언하고, 함수가 실행될 때 error code 에 할당해주면 에러가 발생했을 때 발생 내용을 변수에 저장한다.

uint32_t err_code;
err_code = someFunctions();
APP_ERROR_CHECK(err_code);

 

 

Controlling MCU via UART

아래는 키보드 입력을 UART로 받아 MCU의 LED를 켜고 끄는 방법이다.  

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "app_uart.h"
#include "app_error.h"
#include "nrf_delay.h"
#include "nrf.h"
#include "bsp.h"
#include "nrf_uart.h"

#define UART_TX_BUFF_SIZE 128 
#define UART_RX_BUFF_SIZE 128
#define UART_HWFC APP_UART_FLOW_CONTROL_DISABLED

void uart_err_handle(app_uart_evt_type_t * p)
{
  
}


int main(void)
{
  uint32_t err_code;
  bsp_board_init(BSP_INIT_LEDS); // initialize all leds 

  
  // UART Pin Configuration
  const app_uart_comm_params_t com_params =
  {
    RX_PIN_NUMBER, 
    TX_PIN_NUMBER,
    RTS_PIN_NUMBER,
    CTS_PIN_NUMBER, 
    UART_HWFC,
    false, 
    NRF_UART_BAUDRATE_115200
  }; // end of definition : to be passed into a function 


  APP_UART_FIFO_INIT(&com_params, UART_RX_BUFF_SIZE, UART_TX_BUFF_SIZE, uart_err_handle, APP_IRQ_PRIORITY_LOWEST, err_code);
  
  APP_ERROR_CHECK(err_code);

  printf("Hello PC from nordic Device\r\n"); 
  while(true)
  {
    uint8_t cr;
    while(app_uart_get(&cr) != NRF_SUCCESS); // wait here until it receives a char from pc

    if(cr == 't')
    {
      bsp_board_leds_on();
      printf("Leds Turned On\r\n");
    }

    if(cr == 'k')
    {
      bsp_board_leds_off(); 
      printf("Leds Turned off\r\n"); 
    }
  }

}

 

이후 Putty Program을 받고 제어판 - 장치관리자에서 MCU가 COM 포트 몇 번에 입력되어있는지 확인 후 Connecting Type: Serial, Serial Line 과 Speed 설정 후 Open 해준다. 

 

처음에 버퍼에 무엇이 쌓였을 지 모르기 때문에 프로그램을 MCU로 다운로드 하고서 보드의 Reset 버튼을 누른다. 

 

t 를 누르면 LED가 켜지고 

k 를 누르면 LED가 꺼지는 것을 볼 수 있다.