임베디드시스템개론 : Arduino 활용 Lecture #10: 시리얼통신 (Serial Comm.) 2015. 5. 26 by 김영주
강의목차 시러얼통신개요 I2C 통신개요 I2C 통신실험 2
3 1. Serial Communication
아두이노통신 아두이노통신개요 아두이노 MCU 와 on-board 장치또는외부연결장치간의통신 통신프로토콜에따른데이터송수신을위해개별적인통신장치 ( 모듈 ) 을사용 외부와의통신을위해별도의통신장치가필요 MCU 내장또는외부확장통신장치등 통신모듈의지원여부에따른분류 : MCU 내장통신장치 ( 모듈 ) - I2C, SPI, UART 외부통신장치 ( 모듈 ) - USB, Ethernet, Wifi, Zigbee, Bluetooth, IR 등 4
시리얼통신 (1) 시리얼통신개요 장치간에비트단위로데이터를전송하는통신 비동기 (Asynchronous) & 동기 (Synchronous) 통신방식존재시리얼통신프로토콜 I2C(Inter-Integrated Circuit) SPI(Serial Peripheral Interface) UART(Universal Asynchronous Receive-Transmit) 5
시리얼통신 (2) 시리얼통신개요 : 비동기및동기전송비교 Asynchronous No Clock 정해진시간에맞추어전송신호를 HIGH/LOW 로설정하여데이터를표현 발신과수신을위해별도의선을사용 단지두개의장치간에통신하고자하고상호전송속도를같게설정되어있을때에유용 Synchronous With Clock clock 변화에맞추어전송신호를 HIGH/LOW 로설정하여데이터를표현 Clock 신호와전송방향별로별도의선을사용 일반적으로빠른전송속도가필요할때에유용 6
시리얼통신 (3) 시리얼통신개요 : 비동기및동기전송비교 7
8 2. UART(Universal Asynchronous Receiver/Transmitter)
UART (1) UART(Universal Asynchronous Receiver Transmitter) 대표적인비동기시리얼통신장치 정해진통신속도 (baud rate) 에맞추어병렬데이터를비트단위로직렬전송하고, 수신된직렬데이터를병렬데이터를변환하는기능을지원 기본적으로 Tx(Transmitter)/Rx(Receiver) 2 개의통신라인을사용 필요에따라 handshake 라인 (DTS/DTR) 을사용하기도함 별도의동기화메커니즘을사용하지않으므로통신하기위해서는송수신측에서동일한통신파라미터를설정하여야함. 통신속도 (Baud Rate) 9600~115200 bsp Start bit 0, 1, 2 Data bit 7, 8 Stop bit 0, 1 Parity bit none, odd, even 9
UART (2) 아두이노 UART Arduino Mega MCU(Atmega-2560) 에서는최대 4 개의 UART 장치를지원 Serial(pin0/pin1), Serial1(pin19/pin18), Serial2(pin17/pin16), Serial3(pin15/pin14) Arduino library 에서 UART 통신을위한 API 지원 Serial 내장객체 (Serial, Serial1, Serial2, Serial3) 통신메소드 begin(), end(), available(), read(), peek(), flush(), print(), println(), write(), SerialEvent() 참조 : http://arduino.cc/en/reference/serial 10
UART (3) RS-232 표준 (1) 비동기직렬통신에필요한전기적인신호특성 ( 전압, 타이밍등 ) 과기계적특성 ( 커넥터모양, 핀배치 ) 등모든사양을규정 미국 Electronic Industries Association (EIA) 에서정한표준 주로 PC 및통신장비의콘솔통신을위해사용하는직렬포트용 DB-9 커넥터의모양및핀배치표준도규정 송신신호 (TxD) 와수신신호 (RxD) 이외에도다른용도의여러신호들도정의함 데이터흐름제어 (flow control) 나반송파검출 (carrier detection) 등의다른기능은사용하지않고순수하게통신만하겠다면 TxD 와 RxD 두신호로충분 11
UART (4) RS-232 표준 (2) UART 가있으면비동기통신이가능하지만 UART 의송수신핀을 PC 의직렬포트 (RS-232 포트 ) 에바로연결할수는없다. RS-232 표준에서규정하고있는전압레벨은 TTL 호환 (TTL compatible) 이아니기때문 RS-232 표준은논리 1 에해당하는전압의범위를 -3 V ~ -15 V 로, 논리 0 에해당하는전압의범위를 +3 V ~ +15 V 로규정한다. 이런전압은일반디지털회로에서사용되는범위를벗어나기때문에 RS-232 표준을따르기위해서는 0 V ~ 3 V ( 또는 3.3 V 또는 5 V) 범위의신호를 RS-232 레벨신호로변환하고또그반대방향으로도전압을변환해주는전용회로가필요 이런역할을하는 IC 를 RS-232 트랜시버 (transceiver) 라고하며, Maxim 사의 MAX232 가대표적인예 12
13 3. I2C(IIC)
I2C (1) I2C(Inter-Integrated Circuit) Bus 데이터라인을공유하는동기시리얼통신버스하나의버스에 127 장치까지연결가능 1Mbps 전송속도까지가능간단한통신프로토콜이장점대부분의 MCU에 I2C 통신제어장치내장참조 : http://tronixstuff.files.wordpress.com/2010/10/nxp_i2c.pdf 14
I2C (2) I2C(Inter-Integrated Circuit) Bus 마이크로프로세서와저속주변장치사이의통신을위한용도로 Philips 에서개발한규격 TWI (Two Wire Interface) I2C 버스는양방향오픈드레인선인 SCL (serial clock) 과 SDA (serial data) 로이루어져있으며마스터 - 슬레이브형태로동작한다. SCL 은통신동기를위한클럭선, SDA 는데이터선 마스터는 SCL 로동기를위한클럭을출력하며, 슬레이브는 SCL 로출력되는클럭에맞추어 SDA 를통해데이터를출력하거나입력받는다. SDA 한선으로만데이터를주고받기때문에반이중 (half duplex) 통신만가능 15
I2C (3) I2C(Inter-Integrated Circuit) Bus SCL 선과 SDA 선은모두오픈드레인이므로두선에는각각풀업저항을연결해주어야한다. 16
I2C (4) I2C(Inter-Integrated Circuit) Bus 17
I2C (4) I2C(Inter-Integrated Circuit) Bus 통신프로토콜 18
19 4. I2C 통신실험
DS1307 RTC 를이용한시계 (1) 참고 Sites http://learn.adafruit.com/ds1307-real-time-clock-breakoutboard-kit tronixstuff.wordpress.com/tutorials Ch. 20 & 21 Arduino Wire Library 20
DS1307 RTC 를이용한시계 (2) DS1307 IC 21
DS1307 RTC 를이용한시계 (3) 회로도 22
DS1307 RTC 를이용한시계 (4) 회로구성 23
DS1307 RTC 를이용한시계 (5) DS1307 Pulse 출력 (1) Arduino Wire Library 사용레지스터 #07 설정하여펄스출력 24 /* DS1307 Square-wave machine Used to demonstrate the four different square-wave outputs from Maxim DS1307 See page nine of data sheet for more information John Boxall - tronixstuff.wordpress.com */ #include "Wire.h" #define DS1307_I2C_ADDRESS 0x68 // each I2C object has a unique bus address, the DS1307 is 0x68 void setup() { Wire.begin(); } void sqw1() // set to 1Hz { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0x07); // move pointer to SQW address Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary) Wire.endTransmission(); }
DS1307 RTC 를이용한시계 (6) DS1307 Pulse 출력 (2) void sqw2() // set to 4.096 khz { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0x07); // move pointer to SQW address Wire.write(0x11); // sends 0x11 (hex) 00010001 (binary) Wire.endTransmission(); } void sqw3() // set to 8.192 khz { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0x07); // move pointer to SQW address Wire.write(0x12); // sends 0x12 (hex) 00010010 (binary) Wire.endTransmission(); } 25 void sqw4() // set to 32.768 khz (the crystal frequency) { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0x07); // move pointer to SQW address Wire.write(0x13); // sends 0x13 (hex) 00010011 (binary) Wire.endTransmission(); }
DS1307 RTC 를이용한시계 (7) DS1307 Pulse 출력 (3) void sqwoff() // turns the SQW off { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0x07); // move pointer to SQW address Wire.write(0x00); // turns the SQW pin off Wire.endTransmission(); } 26 void loop() { sqw1(); delay(5000); sqw2(); delay(5000); sqw3(); delay(5000); sqw4(); delay(5000); sqwoff(); delay(5000); }
DS1307 RTC 를이용한시계 (8) DS1307 시계출력 (1) #include "Wire.h" #define DS1307_I2C_ADDRESS 0x68 // Convert normal decimal numbers to binary coded decimal byte dectobcd(byte val) { return ( (val/10*16) + (val%10) ); } // Convert binary coded decimal to normal decimal numbers byte bcdtodec(byte val) { return ( (val/16*10) + (val%16) ); } 27
DS1307 RTC 를이용한시계 (9) DS1307 시계출력 (2) 28 // 1) Sets the date and time on the ds1307 // 2) Starts the clock // 3) Sets hour mode to 24 hour clock // Assumes you're passing in valid numbers void setdateds1307(byte second, // 0-59 byte minute, // 0-59 byte hour, // 1-23 byte dayofweek, // 1-7 byte dayofmonth, // 1-28/29/30/31 byte month, // 1-12 byte year) // 0-99 { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0); Wire.write(decToBcd(second)); // 0 to bit 7 starts the clock Wire.write(decToBcd(minute)); Wire.write(decToBcd(hour)); Wire.write(decToBcd(dayOfWeek)); Wire.write(decToBcd(dayOfMonth)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.write(00010000); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave Wire.endTransmission(); }
DS1307 RTC 를이용한시계 (10) DS1307 시계출력 (3) 29 // Gets the date and time from the ds1307 void getdateds1307(byte *second, byte *minute, byte *hour, byte *dayofweek, byte *dayofmonth, byte *month, byte *year) { // Reset the register pointer Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 7); // A few of these need masks because certain bits are control bits *second = bcdtodec(wire.read() & 0x7f); *minute = bcdtodec(wire.read()); *hour = bcdtodec(wire.read() & 0x3f); // Need to change this if 12 hour am/pm *dayofweek = bcdtodec(wire.read()); *dayofmonth = bcdtodec(wire.read()); *month = bcdtodec(wire.read()); *year = bcdtodec(wire.read()); }
DS1307 RTC 를이용한시계 (11) DS1307 시계출력 (4) void setup() { byte second, minute, hour, dayofweek, dayofmonth, month, year; Wire.begin(); Serial.begin(9600); // Change these values to what you want to set your clock to. // You probably only want to set your clock once and then remove // the setdateds1307 call. second = 0; minute = 54; hour = 14; dayofweek = 4; dayofmonth = 9; month = 5; year = 10; setdateds1307(second, minute, hour, dayofweek, dayofmonth, month, year); } 30
DS1307 RTC 를이용한시계 (12) DS1307 시계출력 (5) 31 void loop() { byte second, minute, hour, dayofweek, dayofmonth, month, year; getdateds1307(&second, &minute, &hour, &dayofweek, &dayofmonth, &month, &year); Serial.print(hour, DEC);// convert the byte variable to a decimal number when being displayed Serial.print(":"); if (minute<10) { Serial.print("0"); } Serial.print(minute, DEC); Serial.print(":"); if (second<10) { Serial.print("0"); } Serial.print(second, DEC); Serial.print(" "); Serial.print(dayOfMonth, DEC); Serial.print("/"); Serial.print(month, DEC); Serial.print("/"); Serial.print(year, DEC);
DS1307 RTC 를이용한시계 (13) DS1307 시계출력 (6) Serial.print(" Day of week:"); switch(dayofweek){ case 1: Serial.println("Sunday"); break; case 2: Serial.println("Monday"); break; case 3: Serial.println("Tuesday"); break; case 4: Serial.println("Wednesday"); break; case 5: Serial.println("Thursday"); break; case 6: Serial.println("Friday"); break; case 7: Serial.println("Saturday"); break; } // Serial.println(dayOfWeek, DEC); delay(1000); } 32
DS1307 RTC 를이용한시계 (14) RTC 라이브러리설치 http://learn.adafruit.com/ds1307-real-time-clock-breakout-boardkit/overview https://github.com/adafruit/rtclib DS1307 IC 를이용한 RTC 기능을구현한라이브러리 RTClib 압축파일을다운로드하여풀고 RTClib 라는이름으로아두이노라이브러리디렉토리에설치한다. 33
DS1307 RTC 를이용한시계 (15) RTC 예제실행 LCD 출력확장 34