아두이노 M0( SAMD21G )에서 새로운 serial 만들기

wimes·2019년 11월 20일
0

arduino

목록 보기
1/1

Arduino Uno - Arduino M0(SAMD21G) serial 통신

참고: https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports/creating-a-new-serial

참고: https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports/muxing-it-up

Uno

rx pin - D2
tx pin - D3

#include <SoftwareSerial.h>

SoftwareSerial ser(2,3);
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  ser.begin(9600);
  Serial.println("hi im uno");
}

void loop() {
  ser.write('c');
  while(ser.available() > 0){
    char temp = ser.read();
    Serial.println(temp);
  }
  delay(1000);
}

M0(SAMD21G)

rx pin - 30(PB03)
tx pin - A5(PB02)

#include <Arduino.h>
#include "wiring_private.h"
#include <LiquidCrystal_I2C.h>

Uart SerialX(&sercom5, 30, A5, SERCOM_RX_PAD_1, UART_TX_PAD_0); // rx, tx
LiquidCrystal_I2C lcd(0x38, 20, 4);

void SERCOM5_Handler(){
  //  SerialUSB.println("irq");
  SerialX.IrqHandler();
}

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.clear();
  
  SerialUSB.begin(9600);
  SerialX.begin(9600);
 
  pinPeripheral(30, PIO_SERCOM_ALT);
  pinPeripheral(A5, PIO_SERCOM_ALT);
 
  SerialUSB.println("hi im m0_serialUSB");
 
  lcd.setCursor(0,0);
  lcd.print("hi");
}

uint8_t i = 0;

void loop() {
  //  SerialUSB.println(i);
  SerialX.write('a');
  //  delay(5);
 
  while(SerialX.available()){
    //SerialUSB.print(" - > 0x");
 
    lcd.setCursor(0,0);
    char temp = SerialX.read();
    lcd.print(temp);
    SerialUSB.println(temp);
  }
  delay(1000);
}

SerialX라는 이름의 Uart객체를 생성한다. sercom은 5를 사용합니다.

Arduino M0(SAMD21G)는 총 6개의 sercom을 가지고 있으며 chip(SAMD21G)만 따로 떼어내서 사용하는 것이 아니라면 각각의 sercom은 용도에 맞게 예약되어 있습니다.

sercomN의 각각의 자주쓰는(chip만 떼어서 쓴다고하면 다른용도로도 사용할 수 있다는 것을 명심) 용도는 다음과 같습니다.

출처: https://forum.arduino.cc/index.php?topic=341054.0 에서 MartinL의 글

참고: variant.cpp

참고: variant.h

sercom0 - Uart Serial (variant.cpp (링크)에서 Serial1 그리고 Serial5으로 선언이 되어있습니다.)
sercom1 - Uart Serial
sercom2 - Uart Serial
sercom3 - I2C Wire
sercom4 - SPI
sercom5 - EDGB (variant.cpp (링크)에서 Serial로 선언이 되어있습니다.

M0에서 uart serial 생성에서 기억해야 할 코드는 다음과 같습니다.

Uart SerialX(&sercom5, 30, A5, SERCOM_RX_PAD_1, UART_TX_PAD_0);

void SERCOM5_Handler(){

SerialX.IrqHandler();

}

SerialX.begin(9600);

pinPeripheral(30, PIO_SERCOM_ALT);

pinPeripheral(A5, PIO_SERCPM_ALT);

각각 설명을 해드리면

------------------------------------------------------------------------------------------------------------------------

Uart SerialX(&sercom5, 30, A5, SERCOM_RX_PAD_1, UART_TX_PAD_0);
SerialX라는 이름의 serial 핸들링 객체를 하나 만든다.
파라미터는
Serial( sercomN의 주소값, RX pin number, TX pin number, RX_PAD number, TX_PAD number)
로 구성되어있다.

저는 sercom5를 사용했습니다.
sercom은 runtime시에 하나만 사용할 수 있습니다.

------------------------------------------------------------------------------------------------------------------------

RX는 현재 PB03를 사용하고 있습니다.
TX는 현재 PB02을 사용하고 있습니다.

windows의 경우 C:\Users\user\AppData\Local\arduino15\packages\arduino\hardware\samd\1.6.20\variants\arduino_mzero
경로에서 variant.cpp를 보면 코드에서 사용할 수 있는 pin 번호가 적혀 있습니다.

위의 캡처한 사진을 보면

PB03는 30번 핀을 사용하고 있고
PB02은 A5번 핀을 사용하고 있습니다.
따라서 2번째 3번째 파라미터는 30, A5이 되는 것입니다.

Uart SerialX(&sercom5, 30, A5, SERCOM_RX_PAD_1, UART_TX_PAD_0);

------------------------------------------------------------------------------------------------------------------------

3번째 4번째 파라미터는
PAD인데 정확한 의미와 뜻은 잘모릅니다. mux로 되어있다는 것만 알 수 있습니다.
그러나 어떻게 사용해야하는지는 알겠습니다.
SERCOM_RX_PAD_N 형태로 RX_PAD를 설정하고
UART_TX_PAD_N 형태로 TX_PAD 형태로 설정합니다.

위의 사진과 SAMD21G의 datasheet(링크)의 23페이지를 살펴보면
PB02과 PB03을 사용하려면 sercom5와 PAD[0] PAD[1]을 사용해야합니다.
PB02를 sercom5를 이용해 사용하려면 PAD[0]를 사용해야 한다는 것을 유추할 수 있습니다.
PB03은 datasheet에서 PAD[1]을 사용하라고 나와있습니다.

Uart SerialX(&sercom5, 30, A5, SERCOM_RX_PAD_1, UART_TX_PAD_0);

------------------------------------------------------------------------------------------------------------------------

void SERCOM5_Handler(){

SerialX.IrqHandler();

}

는 SerialX의 핸들러를 가져오겟다는 뜻이다. sercom을 사용하기 위해서는 반드시 정의해줘야합니다. 함수명이 SERCOMN_Handler 형태로 되어있는 것에 주목하도록합시다. 우리는 sercom5를 쓰기때문에 SERCOMN_Handler에서 N에 5가 들어갔습니다.

이 함수는 콜백메소드입니다.

------------------------------------------------------------------------------------------------------------------------

SerialX.begin(9600);

따로 설명하지 않겠습니다.

------------------------------------------------------------------------------------------------------------------------

pinPeripheral(30, PIO_SERCOM_ALT);

pinPeripheral(A5, PIO_SERCPM_ALT);

아까 선택했던 rx pin과 tx pin을 사용해줘야 합니다.
pinPeripheral함수를 이용합니다.
30번 핀을 PIO_SERCOM_ALT로 사용하겠다는 의미입니다.
아까 데이터시트를 보면 D항목의 SERCOM5-ALT항목의
위의 데이터시트 캡처화면의 PB03와 PB02에서 SERCOM5/PAD[0] 열따라 쭉 올라가보면 SERCOM5-ALT가 보입니다.

pinPeripheral의 두번째 파라미터는
PAD가 ALT인지 아닌지에 따라 달라질 수 있습니다.
여기서는 ALT이므로 PIO_SERCOM_ALT 를 사용합니다.
ALT가 아닐 시에는 PIO_SERCOM을 사용합니다.

------------------------------------------------------------------------------------------------------------------------

*결과

M0 serial monitor

Uno serial monitor

profile
iOS/Swift & Node.js Dev.

0개의 댓글