Chapter. 11 시리얼인터페이스 HBE-MCU-Multi AVR Jaeheung, Lee
목차 1. TWI(Two Wire Serial Interface) 2. SPI(Serial Peripheral Interface) 3. TWI(I 2 C) 로 EEPROM 붙이기 4. SPI로 Serial Flash Memory 붙이기 5. TWI로온습도센서제어하기
시리얼인터페이스 패러렐 vs 시리얼인터페이스 패러렐인터페이스 (Parallel Interface) n n n 데이터및어드레스가병렬로동시에처리데이터의처리속도가빠르다 SRAM등의외부메모리및고속의주변장치들을연결하는데주로사용 n 다수의어드레스신호와데이터신호를사용칩의크기를소형화가어렵다. n ATMega128 의외부메모리인터페이스 시리얼인터페이스 (Serial Interface) n n 고속의제어가필요없는장치들을위해소수의신호를사용어드레스와데이터를순차적으로처리 n 데이터의처리속도가비교적느리다. n 필요한핀수를최소화하여칩의소형화에유리하다. n n 고속제어가필요없는소형칩들에주로사용 TWI(Two Wire Serial Interface), SPI(Serial Peripheral Interface)
TWI(Two Wire Serial Interface) TWI(Two Wire Interface) 단순하면서도강력한시리얼통신인터페이스 필립스사에서제창한 I 2 C(Inter IC Bus) 와같은방식 2 선을이용해시스템내부에서여러장치들과통신 n TWI 프로토콜은클록 (SCL) 과데이터 (SDA) 만으로양방향버스라인사용 마스터와슬레이브동작을지원하며, 다중마스터도가능하다 n TWI 의 7 비트어드레스는 128 개의다른슬레이브어드레스까지허용 버스에연결된모든디바이스는독립적인주소를가짐. n 디바이스어드레스 (Device Address) 혹은디바이스아이디 (Device ID) 라하며, 칩의구분을위해각칩마다고유의디바이스 ID 를가짐. TWI 는 400kHz 까지의데이터전송속도를가진다.
TWI(Two Wire Serial Interface) TWI(Two Wire Interface) TWI 버스연결 버스라인 (SCL, SDA) 은풀업저항을통하여 +Vcc 전압으로연결. 각디바이스들은평상시 Tri-State 상태를유지 버스를사용할때에는레벨하이 ( 1 ) 는 Tri-State 로, 레벨 Low( 0 ) 는 0 로출력.
TWI(Two Wire Serial Interface) TWI 데이터전송형식 마스터가버스에 START 조건을출력할때전송은시작되고 STOP 조건에서완료된다 START 조건, 어드레스패킷 (SLA+R/W) 와하나또는많은데이터패킷그리고 STOP 으로구성된다. ACK ( 인식비트 ) : 현재 TWI 버스내에마스터가호출한슬레이브디바이 스가존재하고있고, 정상적으로어드레스를수신했음을알게해줌.
TWI(Two Wire Serial Interface) ATMega128 TWI 레지스터 TWBR(TWI Bit Rate Register) : n TWI 비트율레지스터 TWCR(TWI Control Register) : n TWI 제어레지스터 TWSR(TWI Status Register) : n TWI 상태레지스터 TWDR(TWI Data Register) : n TWI 데이터레지스터 TWAR[TWI (Slave) Address Register] : n TWI 슬레이브어드레스레지스터
TWI(Two Wire Serial Interface) TWBR(TWI Bit Rate Register) TWI 비트율레지스터 비트율발생기에대한분주요소를선택하기위한레지스터 7 6 5 4 3 2 1 0 TWBR7 TWBR6 TWBR5 TWBR4 TWBR3 TWBR2 TWBR1 TWBR0 비트 7 0 (TWI Bit Rate Register) n 비트율발생기에대한분주요소를선택 n 비트율발진기는마스터모드에서 SCL 클록주파수를발생하는주파수 SCL 의클럭주파수
TWI(Two Wire Serial Interface) TWCR(TWI Control Register) TWI 제어레지스터 (TWI 동작제어 ) 7 6 5 4 3 2 1 0 TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE 비트 7 : TWINT(TWI Interrupt Flag) n TWI 인터럽트플래그 n TWI 가현재작업을완료하고응용소프트웨어응답을기다릴때, 하드웨어에의해세트된다. n SREG 의 I 비트와 TWCR 의 TWIE 비트가세트되면 TWI 인터럽트벡터로점프한다
TWI(Two Wire Serial Interface) TWCR(TWI Control Register) 비트 6 : TWEA(TWI Enable Acknowledge Bit) n TWI Enable 응답비트 (ACK 펄스의생성을제어 ) n 이비트에 1 을써넣은후, 다음조건을만나면 ACK 펄스가발생. n n n 디바이스에자기슬레이브어드레스가수신될경우 TWAR 의 TWGCE 비트가세트인동안일반적인호출이수신될경우 데이터바이트가마스터수신기또는슬레이브수신기모드로수신될경우 n TWEA 비트에 0 를써넣으면디바이스는 TWI 로부터일시적으로끊어짐 비트 5 : TWSTA(TWI START Condition Bit) : n TWI START 조건비트 n TWI 버스에서마스터가되고자할때이비트에 1 을써넣는다. n START 조건이전송되었을때이비트는소프트웨어에의해클리어해야한다.
TWI(Two Wire Serial Interface) TWCR(TWI Control Register) 비트 4 : TWSTO(TWI STOP Condition Bit) : n TWI STOP 조건비트 n 마스터모드에서이비트에 1 을써넣으면 TWI 버스로 STOP 조건을발생시킨다 n STOP 조건이버스에서실행될때이비트는자동적으로클리어된다. 비트 3 : TWWC(TWI Write Collision Flag) : n TWI 쓰기충돌플래그 n 이플래그비트는 TWINT 가 Low 일때 TWDR(TWI Data Register) 로써넣기를시도하면 1 로세트되고, TWINT 가 High 일때 TWDR 레지스터에써넣으면클리어된다.
TWI(Two Wire Serial Interface) TWCR(TWI Control Register) 비트 2 : TWEN(TWI Enable Bit) n TWI Enable 비트 n 이비트는 TWI 동작을 Enable시키고 TWI 인터페이스를활성화한다. n 이비트에 1을써넣으면 TWI가 Enbale되어 SCL과 SDA 핀을제어하게되고, 0을써넣으면 TWI는오프되고모든 TWI 전송은어떤행위에관계없이종료된다. 비트 0 : TWIE(TWI Interrupt Enable) n TWI 인터럽트 Enable 비트 n 이비트에 1이고, SREG의 I 비트가 1로세트되면 TWINT가 High인동안 TWI 인터럽트가활성화된다.
TWI(Two Wire Serial Interface) TWSR(TWI Status Register) TWI 상태레지스터 TWI 의상태와프리스캐일러값을보여주는레지스터 7 6 5 4 3 2 1 0 TWS7 TWS6 TWS5 TWS4 TWS3 - TWPS1 TWPS0 비트 7 3 : TWS(TWI Status) : TWI 상태 n TWI 의상태를알려주는비트
TWI(Two Wire Serial Interface) TWSR(TWI Status Register) Master Transmitter Mode 에서의 Status Code Status Code(Hex) 설명 08 Start 코드전송완료 10 Repeated START 코드전송완료 18 SLA+W 전송완료및 ACK 신호수신완료 20 SLA+W 전송완료및 ACK 신호수신불가 28 데이터바이트전송완료및 ACK 신호수신완료 30 데이터바이트전송완료및 ACK 신호수신불가 38 SLA+W 나데이터바이트전송시중재불가 ( 오류 )
TWI(Two Wire Serial Interface) TWSR(TWI Status Register) Master Receiver Mode 에서의 Status Code Status Code(Hex) 설명 08 Start 코드전송완료 10 Repeated START 코드전송완료 38 SLA+R 나 NOT ACK 비트중재불가 ( 오류 ) 40 SLA+R 전송완료및 ACK 신호수신완료 48 SLA+R 전송완료및 NOT ACK 신호수신 50 데이터바이트수신완료및 ACK 신호반송완료 58 데이터바이트수신완료및 NOT ACK 신호반송
TWI(Two Wire Serial Interface) TWSR(TWI Status Register) 비트 1 0 : TWPS(TWI Prescaler Bit) : n TWI 프리스케일러비트 n 비트율프리스케일러를제어하기위한비트 TWI Prescaler 설정표 TWPS1 TWPS0 Prescaler Value 0 0 1 0 1 4 1 0 16 1 1 64
TWI(Two Wire Serial Interface) TWDR(TWI Data Register) : TWI 데이터레지스터 n 전송모드에서 TWDR은전송될다음바이트를포함 n 수신모드에서는수신된마지막바이트를포함 7 6 5 4 3 2 1 0 TWD7 TWD6 TWD5 TWD4 TWD3 TWD2 TWD1 TWD0 비트 7 0 : TWD(TWI Data) n TWI 데이터 n 전송되는다음데이터바이트또는 2 줄직렬버스에서수신된마지막데이터바이트를포함.
TWI(Two Wire Serial Interface) TWAR[TWI (Slave) Address Register] TWI 슬레이브어드레스레지스터 슬레이브모드로사용될때슬레이브어드레스를저장하는레지스터 7 6 5 4 3 2 1 0 TWA6 TWA5 TWA4 TWA3 TWA2 TWA1 TWA0 TWGCE 비트 7 1 : TWA[TWI(Slave) Address ] n TWI 슬레이브어드레스 n 이일곱비트는 TWI 유닛의슬레이브어드레스를나타낸다. 비트 0 : TWGCE(TWI General Call Recognition Enable Bit) n TWI 일반호출인식 Enable비트 n 이비트가세트되면 TWI 버스에주어진일반호출의인식을 Enable한다.
TWI(Two Wire Serial Interface) TWI 동작 AVR TWI 는바이트단위로동작이이루어지고, 인터럽트를기본으로한다. 인터럽트는바이트의수신이나 START 조건의전송처럼모든버스의이벤트뒤에발생된다 SREG 의 I 비트와함께 TWCR 의 TWIE(TWI Interrupt Enable) 비트가 1 로세트되면 TWINT 플래그가 1 이될때인터럽트가발생한다 TWIE 비트가클리어되면, 응용소프트웨어에서 TWI 버스에서의동작상태를알기위해 TWINT 플래그를정기적으로조사 (poll) 해야한다.
TWI(Two Wire Serial Interface) TWI 를동작시키는방법 1.TWCR 의 TWINT, TWSTA, TWEN 비트를세팅하여 START Condition 을내보낸다. 2. TWCR 의 START Condition 이정상적으로출력되어 TWINT 플래그가세팅되길기다린다. 3. TWSR 을체크하여 START 상태인지확인한다. 아니면오류이다. 4. SLA+W 를 TWDR 레지스터에넣는다. TWCR 의 TWINT 플래그를클리어시킨다. 5. SLA+W 가전송되고 ACK 비트가정상적으로도착하여 TWCR 의 TWINT 가세팅되길기다린다. 6. TWSR 을체크하여 MT_SLA_ACK 상태인지확인한다. 아니면오류이다. 7. Data 를 TWDR 레지스터에넣는다. TWCR 의 TWINT 플래그를클리어시킨다. 8. Data 가전송되고 ACK 비트가정상적으로도착하여 TWCR 의 TWINT 가세팅되길기다린다. 9. TWSR 을체크하여 MT_DATA_ACK 상태인지확인한다. 아니면오류이다 10. TWCR TWINT, TWSTO, TWEN 비트를세팅하여 STOP Condition 을전송한다.
SPI(Serial Peripheral Interface) SPI(Serial Peripheral Interface) 직렬주변장치인터페이스 ( 모토로라사에서제창한방식 ) AVR 과주변장치디바이스간에, 또는여러 AVR 디바이스들간에고속동기데이터를전송하기위한인터페이스. ATmega128 에서는 SS(PB0, pin 10), SCK(PB1, pin 11), MOSI( PB2, pin 12), MISO(PB3, pin 13) 4 선을이용. 전이중 (Full-Duplex) 통신방식으로, 3 개의신호선을이용하는동기데이터전송방식을따름. 마스터와슬레이브방식으로동작 7 가지의비트율세팅 SPI 는 ATmega128 의플래쉬롬에프로그램을다운로드하는 ISP 기능제공
SPI(Serial Peripheral Interface) SPI(Serial Peripheral Interface) 동작 SPI 는반드시 1 개의마스터와 1 개의슬레이브사이에서만동작 마스터가슬레이브에게데이터를보낼때 n 여러슬레이브에서원하는슬레이브에게 SS (Slave Select) 신호를 0 레벨로출력하여선택 n 클록신호를발생하여 SCK(Serial Clock) 을통해출력 n 송신할데이터를시프트레지스터에데이터를준비하여 MOSI(Mast er Output Slave Input) 단자로출력한다. n 동시에 MISO (Master Input Slave Output) 단자를통해서는더미데이터가입력
SPI(Serial Peripheral Interface) SPI(Serial Peripheral Interface) 동작 SPI Master 와 Slave 간상호연결
SPI(Serial Peripheral Interface) SPI(Serial Peripheral Interface) 레지스터 SPCR(SPI Control Register) n SPI 제어레지스터 SPSR(SPI Status Register) n SPI 상태레지스터 SPDR(SPI Data Register) n SPI 데이터레지스터
SPI(Serial Peripheral Interface) SPCR(SPI Control Register) SPI 제어레지스터 (SPI 동작을제어하기위한레지스터 ) 인터럽트 Enable, 동작모드설정, Clock 모드설정들에사용 7 6 5 4 3 2 1 0 SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0 비트 7 (SPIE:SPi Interrupt Enable) n 1 로세트하면 SPI 전송완료인터럽트개별 Enable 비트 6 (SPE: SPi Enable) n 1 로세트하면 SPI 직렬통신을허용
SPI(Serial Peripheral Interface) SPCR(SPI Control Register) 비트 5 (DORD:Data ORDer) n 1 로설정하면 LSB 부터전송하고 0 으로하면 MSB 부터전송한다 비트 4 (MSTR:Master/Slave Select) n 1 로설정하면마스터로동작하고 0 으로하면슬레이브로동작한다. 비트 3 (CPOL:Clock POLarity) n 데이터샘플링동작이수행되는 SCK 클록의극성을설정한다 n 디폴트값인 0 이면 Leading Edge 의경우는상승에지로, Trailing Edg e 의경우에는하강에지로선정된다. n CPOL=1 이면 Leading Edge 의경우는하강에지로, Trailing Edge 의경우에는상승에지로선정된다.
SPI(Serial Peripheral Interface) SPCR(SPI Control Register) 비트 2 (CPHA:Clock PHAse) n 데이터샘플링동작이수행되는 SCK 클록의위상을설정 n 디폴트값인 0 이면 Leading Edge 의경우는샘플링이되고, Trailing Edge 의경우에는셋업된다. n CPHA=1 이면반대로된다. 비트 1~0 (SPR1~0:SPi clock Rate select 1~0) n SPSR 의비트 0(SPI2X 비트 ) 과함께 SCK 클럭신호의주파수분주비를설정 n SPSR 의비트 0 이 0 인상태에서 00 이면시스템클록의 4 분주, 01 이면 16 분주, 10 이면 64 분주, 11 이면 128 분주로설정된다. n SPSR 의비트 0 이 1 인상태에서는주파수를두배로하여분주비를반감시키는데 00 이면시스템클록의 2 분주, 01 이면 8 분주, 10 이면 32 분주, 11 이면 64 분주로설정된다.
SPI(Serial Peripheral Interface) SPSR(SPI Status Register) SPI 상태레지스터 (SPI 의동작상태를나타내는레지스터 ) 인터럽트플래그와쓰기충돌플래그등이있고, SCK 클럭주파수를 2 배로설정하는데에도사용 7 6 5 4 3 2 1 0 SPIF WCOL - - - - - SPI2X
SPI(Serial Peripheral Interface) SPSR(SPI Status Register) 비트 7 (SPIF:SPi Interrupt Flag) n 전송이완료되면 1 로세트되면서인터럽트가발생된다 n 마스터로설정하고 SS 핀이입력으로설정되어 0 레벨이입력되면 SP CR 의비트 4(MSTR) 는자동으로클리어되며슬레이브모드로되고 SP IF 가세트되면서인터럽트가발생된다. 비트 6 (WCOL:Write COLision flag) n SPI 를통해데이터를전송하고있는동안에 SPDR 레지스터를기록하려고하면 1 로세트된다. n SPSR 을읽고 SPDR 에접근하는경우에 SPIF 와함께클리어된다. 비트 0(SPI2X:SPI Double speed) n 마스터로동작할때 SCK 클록신호의주파수를 2 배로설정한다.
SPI(Serial Peripheral Interface) SPDR(SPI Data Register) SPI 데이터레지스터 SPI 의데이터전송에사용되는레지스터 7 6 5 4 3 2 1 0 SPDR7 SPDR6 SPDR5 SPDR4 SPDR3 SPDR2 SPDR1 SPDR0
SPI(Serial Peripheral Interface) SPI 제어프로그램 SPI 마스터모드로 SPI 를초기화하고, 데이터를전송하는프로그램 void SPI_MasterInit(void) { /* MOSI와 SCK 핀을출력으로, 다른핀들을입력으로선언 */ DDR_SPI = (1<<DD_MOSI) (1<<DD_SCK); /* SPI Enable, Matser 모드, clock rate fck/16 */ SPCR = (1<<SPE) (1<<MSTR) (1<<SPR0); } void SPI_MasterTransmit(char cdata) { /* 전송시작 */ SPDR = cdata; /* 전송완료까지대기 */ while(!(spsr & (1<<SPIF))) ; }
SPI(Serial Peripheral Interface) SPI 제어프로그램 SPI 슬레이브모드로 SPI 를초기화하고, 데이터를수신하는프로그램 void SPI_SlaveInit(void) { /* MISO핀을출력으로, 나머지는모두입력으로선언 */ DDR_SPI = (1<<DD_MISO); /* SPI Enable*/ SPCR = (1<<SPE); } char SPI_SlaveReceive(void) { /* 수신완료시까지대기 */ while(!(spsr & (1<<SPIF))) ; /* Data Register 값을리턴 */ return SPDR; }
실습 16 : TWI(I2C) 로 EEPROM 붙이기 실습개요 TWI(I 2 C) 로제어가되는 EEPROM 인 AT24C16 를 ATmega128 의 TWI 포트에연결하고, 여기에미리정해놓은데이터를저장했다가, 다시꺼내서 TEXT LCD 에표시한다. AT24C16 칩의 TWI 인터페이스관련라이브러리함수를 at24c16.c 에포함하고있다. 실습목표 TWI(I 2 C) 인터페이스의동작원리이해 ATmega128의 TWI 포트에대한프로그램방법을습득 TWI(I 2 C) 로제어가되는 EEPROM(AT24C16) 의동작이해
실습 16 : TWI(I2C) 로 EEPROM 붙이기 사용모듈 : MCU 모듈, TEXT-LCD 모듈, 메모리모듈 MCU 모듈 TEXT LCD 모듈 D 포트메모리모듈 TWI 연결 C,G 포트 TEXT LCD 모듈연결 Data BUS (D0~D7) Control 신호 (Rs, RW, E) SRAM I 2 C ROM SPI Flash 메모리모듈 EEPROM TWI 신호
실습 16 : TWI(I2C) 로 EEPROM 붙이기 사용모듈 메모리모듈중 I2C EEPROM 부분의회로
실습 16 : TWI(I2C) 로 EEPROM 붙이기 AT24C16 데이터읽기 / 쓰기신호흐름 Data Write Data Read
실습 16 : TWI(I2C) 로 EEPROM 붙이기 AT24C16 의디바이스어드레스의구성 AT24C16 은 2048*8 비트의메모리용량을가지는 EEPROM 칩의전체메모리에주소를할당하려면 2048 개즉 11 비트가필요 디바이스어드레스 (Device Address) 중 3 비트와워드어드레스 (W ord Address) 8 비트를묶어각메모리의주소로사용 Device Address 는 0xA 에페이지어드레스 3 비트그리고 R/W 비트로구성 7 6 5 4 3 2 1 0 1 0 1 0 P2 P1 P0 R/W AT24Cxx 칩의고유 ID Page Address R/W 비트 Write = 0 Read = 1
실습 16 : TWI(I2C) 로 EEPROM 붙이기 AT24C16 에데이터써넣기 1 START 코드를내보낸다. 2 Device Address 를내보낸다. Device Address 는 0xA + Page Address 3 비트 + 0 (R/W 비트중 Write) 이다. 3 ACK 가도착하기를기다린다. 4 Word Address 를내보낸다. Word Address 는하위 8 비트주소이다. 5 다음 ACK 가도착하길기다린다. 6 메모리에저장할데이터를내보낸다. 7 다음 ACK 가도착하길기다린다. 8 STOP 코드를내보낸다.
실습 16 : TWI(I2C) 로 EEPROM 붙이기 AT24C16 의임의의주소에서데이터읽어오기 1START 코드를내보낸다. 2Device Address 를내보낸다.( 0xA + Page Address 3 비트 + 0) : Dummy Write 3ACK 가도착하길기다린다. 4 읽어들이고싶은 Word Address 를내보낸다. 5 다음 ACK 가도착하길기다린다. 6 다시 START 코드를내보낸다. 7Device Address 를내보낸다. 여기서의 Device Address 는 0xA + Page Address 3 비트 + 1 (R/W 비트중 Read) 이다. 8 다음 ACK 가도착하길기다린다. 9 데이터를읽어들인다.( 여기서는 ACK 를기다리지않는다.) 10STOP 코드를내보낸다.
실습 16 : TWI(I2C) 로 EEPROM 붙이기 모듈결선방법 MCU 모듈포트 C의 PC0~PC7을 TEXT LCD 모듈의 D0~D7 신호에연결 MCU 모듈포트 G의 PG0~PG3은 TEXT LCD 모듈의 RS, RW, E에연결 MCU 모듈포트 D의 PD0는메모리모듈의 R_SCL에, PD1은 R_SDA에연결
실습 16 : TWI(I2C) 로 EEPROM 붙이기 구동프로그램 : 사전지식 AT24C16 칩의초기화 n TWI 포트로사용된포트 D 의하위 2 비트에대한 PORTD 레지스터를 1 로세팅하여풀업을설정 n TWBR = 28 로세팅, TWSR 의 TWPS(1:0) = 00 으로세팅 n Prescaler 를 1 분주로설정, SCL 의클럭주파수는 30.720KHz. AT24C16 칩의초기화 void AT24C16_Init(){ PORTD = 0x03; // 내부풀업 TWBR = 28; //30.720khz TWSR = 0; }
실습 16 : TWI(I2C) 로 EEPROM 붙이기 AT24C16_WRITE 함수 1바이트데이터쓰기 (Write) void AT24C16_WRITE(unsigned int address,unsigned char byte) /* write a byte */ { TWCR = 0xA4; // START condition while(((twcr & 0x80) == 0x00) ((TWSR & 0xF8)!= 0x08)); // START complete? TWDR = 0xA0 + ((address >> 7) & 0x000E); // +W TWCR = 0x84; while(((twcr & 0x80) == 0x00) ((TWSR & 0xF8)!= 0x18)); // +W complete? TWDR = (address & 0x00FF); // word address TWCR = 0x84; while(((twcr & 0x80) == 0x00) ((TWSR & 0xF8)!= 0x28)); // address complete? TWDR = byte; // write data TWCR = 0x84; while(((twcr & 0x80) == 0x00) ((TWSR & 0xF8)!= 0x28)); // data complete? TWCR = 0x94; // STOP condition ms_delay(10); // delay 10 ms for twr time }
실습 16 : TWI(I2C) 로 EEPROM 붙이기 AT24C16_READ 함수 1바이트데이터읽기 (Read) unsigned char AT24C16_READ(unsigned int address) /* read a byte */ { unsigned char byte; TWCR = 0xA4; // START condition while(((twcr & 0x80) == 0x00) ((TWSR & 0xF8)!= 0x08)); // START complete? TWDR = 0xA0 + ((address >> 7) & 0x000E); // +W TWCR = 0x84; while(((twcr & 0x80) == 0x00) ((TWSR & 0xF8)!= 0x18)); // +W complete? TWDR = (address & 0x00FF); // word address TWCR = 0x84; while(((twcr & 0x80) == 0x00) ((TWSR & 0xF8)!= 0x28)); // address complete? TWCR = 0xA4; // REPEATED START condition while(((twcr & 0x80) == 0x00) ((TWSR & 0xF8)!= 0x10)); // START complete? TWDR = 0xA0 + ((address >> 7) & 0x000E) + 0x01; // +R TWCR = 0x84;
실습 16 : TWI(I2C) 로 EEPROM 붙이기 AT24C16_READ 함수 1바이트데이터읽기 (Read) while(((twcr & 0x80) == 0x00) ((TWSR & 0xF8)!= 0x40)); // +R complete? TWCR = 0x84; // read data with no acknowledge while(((twcr & 0x80) == 0x00) ((TWSR & 0xF8)!= 0x58)); // data complete? byte = TWDR; // read data TWCR = 0x94; // STOP condition return byte; // return data }
실습 16 : TWI(I2C) 로 EEPROM 붙이기 구동프로그램 : 소스분석 Lcdconf.h #ifdef LCD_PORT_INTERFACE #ifndef LCD_CTRL_PORT #define LCD_CTRL_PORT PORTG #define LCD_CTRL_DDR DDRG #define LCD_CTRL_RS 0 #define LCD_CTRL_RW 1 #define LCD_CTRL_E 2 #endif #ifndef LCD_DATA_POUT #define LCD_DATA_POUT PORTC #define LCD_DATA_PIN PINC #define LCD_DATA_DDR DDRC #endif #endif
실습 16 : TWI(I2C) 로 EEPROM 붙이기 구동프로그램 : 소스분석 I2C_EEPROM.c 1) #include <avr/io.h> #include<util/delay.h> #include"at24c16.h" #include"lcd.h" #define DELAY_MS(x) { static unsigned int _i; \ for(_i=0;_i<x;_i++) \ _delay_ms(1); } 2) char msg1[9]="welcome!!"; char msg2[16]="hanback-world!! "; char msg3[16]="twi-eeprom Exam!"; int main(){ char i=0; 3) AT24C16_Init(); //AT24C16 초기화 lcdinit(); //TextLCD 초기화
실습 16 : TWI(I2C) 로 EEPROM 붙이기 4) for(;i<9;i++) // 각주소마다한바이트씩저장 AT24C16_WRITE(0x0100+i,msg1[i]); for(i=0;i<16;i++) AT24C16_WRITE(0x0200+i,msg2[i]); for(i=0;i<16;i++) AT24C16_WRITE(0x0300+i,msg3[i]);
실습 16 : TWI(I2C) 로 EEPROM 붙이기 5) for(i=0;i<9;i++){ // 한바이트씩읽어와서 LCD에출력 lcddatawrite(at24c16_read(0x0100+i)); DELAY_MS(100); //100ms단위의딜레이간격 } for(i=0,lcdgotoxy(0, 1);i<16;i++){ lcddatawrite(at24c16_read(0x0200+i)); DELAY_MS(100); } for(i=0;i<16;i++){ lcddatawrite(at24c16_read(0x0300+i)); DELAY_MS(100); } for(i=0;i<16;i++){ //LCD 화면을왼쪽으로쉬프트 lcdcontrolwrite(1<<lcd_move 1<<LCD_MOVE_DISP ); DELAY_MS(100); } while(1); }
실습 16 : TWI(I2C) 로 EEPROM 붙이기 실행결과
실습 17 : SPI 로 Flash Memory 붙이기 실습개요 정해진문자열을 SPI 인터페이스를이용하여 Serial Flash Memory 에저장했다가, 이를다시꺼내어 TEXT LCD 에표시하도록한다. SPI 로제어되는 Flash Memory 인 AT25F512 칩을메모리로사용 AT25F512 칩의 SPI 인터페이스관련라이브러리함수는 at25fxx.c 에포함되어있음. 실습목표 SPI 인터페이스동작원리이해 ( 레지스터설정 ) ATmega128의 SPI 포트에대한프로그램방법습득 Serial Flash Memory(AT25F512) 동작원리이해
실습 17 : SPI 로 Flash Memory 붙이기 사용모듈 : MCU 모듈, 메모리모듈, TEXT-LCD 모듈, MCU 모듈 TEXT LCD 모듈 B 포트메모리모듈 SPI 연결 C,G 포트 TEXT LCD 모듈연결 Data BUS (D0~D7) Control 신호 (Rs, RW, E) SRAM I 2 C ROM SPI Flash 메모리모듈 Flash Memory SPI 신호
실습 17 : SPI 로 Flash Memory 붙이기 사용모듈 메모리모듈의 SPI Flash 메모리부분회로 n AT25F512 n n SPI 를지원하는 64K*8(512) 비트용량의 Serial Flash memory 32K Byte 크기의섹터가 2 개내장된구조를가지고있으며, Write-Pr otect 기능을가지고있음.
실습 17 : SPI 로 Flash Memory 붙이기 사용모듈 AT25F512 를 ATMega128 에연결하는방법
실습 17 : SPI 로 Flash Memory 붙이기 사용모듈 AT25F512 핀설명
실습 17 : SPI 로 Flash Memory 붙이기 사용모듈 AT25F512 8 비트명령어세트
실습 17 : SPI 로 Flash Memory 붙이기 AT25F512 Serial Flash Memory 제어 AT25F512 칩의임의의메모리주소로부터데이터읽어오기 1) CS를 low로만든다.(chip-select active) 2) SPDR에 READ(0x03) 명령을넣어 AT25F512로전송한다. SPSR레지스터의 SPIF(SPi Interrupt Flag) 비트를관찰하면서 1로세트될때까지대기한다. 3) SPDR에 0x00을넣는다 ( 최상위어드레스 ). SPSR의 SPIF가 1로세트될때까지대기한 다. 4) SPDR에상위 8비트어드레스를넣는다. SPSR의 SPIF가 1로세트될때까지대기한다. 5) SPDR에하위 8비트어드레스를넣는다. SPSR의 SPIF가 1로세트될때까지대기한다. 6) SPDR에 0을넣는다 ( 데이터수신대기 ). SPSR의 SPIF가 1로세트될때까지대기한다. 7) SPDR에서데이터를읽어온다. 8) CS를 High로만든다.(Chip-Select inactive)
실습 17 : SPI 로 Flash Memory 붙이기 AT25F512 Serial Flash Memory 제어 AT25F512 칩의임의의메모리주소에데이터를써넣기 (Program) 1) CS 를 low 로만든다.(Chip-Select active) 2) SPDR 에 WREN(0x06) 명령을넣음으로써, AT25F512 로전송한다. SPSR 레지스터의 SPIF(SPi Interrupt Flag) 비트를관찰하면서 1 로세트될때까지대기한다. 3) SPDR 에 PROGRAM(0x00) 을넣는다 ( 쓰기선언 ). SPSR 의 SPIF 가 1 로세트될때까지대기한다. 4) SPDR 에 0x00 을넣는다 ( 최상위어드레스 ). SPSR 의 SPIF 가 1 로세트될때까지대기한다. 5) SPDR 에상위 8 비트어드레스를넣는다. SPSR 의 SPIF 가 1 로세트될때까지대기한다. 6) SPDR 에하위 8 비트어드레스를넣는다. SPSR 의 SPIF 가 1 로세트될때까지대기한다. 7) SPDR 에데이터를넣는다 ( 데이터송신 ). SPSR 의 SPIF 가 1 로세트될때까지대기한다. 8) SPDR 에 RDSR(0x05) 을넣는다 (Status Register 읽기선언 ). SPSR 의 SPIF 가 1 로세트될때까지대기한다. 9) SPDR 에 0 을넣는다 ( 레지스터내용수신대기 ). SPSR 의 SPIF 가 1 로세트될때까지대기한다. 10) SPDR 에서데이터를읽어온다.(Status Register 내용 ) 11) Status 레지스터의 RDY(0 번비트 ) 가 1 로세트될때까지 8~10 반복한다. 12) CS 를 High 로만든다.(Chip-Select inactive)
실습 17 : SPI 로 Flash Memory 붙이기 AT25F512 Serial Flash Memory 제어 AT25F512 칩의모든메모리영역을지우기 (Erase) 1) CS 를 low 로만든다.(Chip-Select active) 2) SPDR 에 WREN(0x06) 명령을넣음으로써, AT25F512 로전송한다. SPSR 레지스터의 SPIF (SPi Interrupt Flag) 비트를관찰하면서 1 로세트될때까지대기한다. 3) SPDR 에 CHIP_ERASE(0x62) 을넣는다 ( 칩지우기선언 ). SPSR 의 SPIF 가 1 로세트될때까지대기한다. 4) SPDR 에 RDSR(0x05) 을넣는다 (Status Register 읽기선언 ). SPSR 의 SPIF 가 1 로세트될때까지대기한다. 5) SPDR 에 0 을넣는다 ( 레지스터내용수신대기 ). SPSR 의 SPIF 가 1 로세트될때까지대기한다. 6) SPDR 에서데이터를읽어온다.(Status Register 내용 ) 7) Status 레지스터의 RDY(0 번비트 ) 가 1 로세트될때까지 4~6 을반복한다. 8) CS 를 High 로만든다.(Chip-Select inactive)
실습 17 : SPI 로 Flash Memory 붙이기 모듈결선방법 MCU 모듈포트 C 의 PC0~PC7 은 TEXT LCD 모듈의 D0~D7 핀에연결 MCU 모듈포트 G 의 PG0~PG3 은각각 TEXT LCD 모듈의 RS, RW, E 에연결 MCU 모듈포트 B 의 PB0(/SS) 는메모리모듈의 F_CS 에, PB1(SCK) 은 F_SCK 에, PB2(MOSI) 는 F_SI 에, PB3(MISO) 는 F_SO 핀에연결
실습 17 : SPI 로 Flash Memory 붙이기 구동프로그램 : 사전지식 (SPI 인터페이스제어 ) SPI 초기화 n SPI 신호로사용할핀들을설정하고, 입출력을결정 n ATmega128 이마스터로사용될경우, MISO 는입력으로, 나머지 MOSI, S CK, /SS 는출력으로설정 n 동작모드와클럭모드를결정 n n n SPCR 레지스터의 MSTR 비트를세팅하여, Master/ Slave 모드를결정 : 여기서는 Master 모드를사용 DORD 비트를세팅하여, 데이터전송순서를결정 : 여기서는 AT25F512 에적용하기위해, MSB 먼저보내도록설정 CPOL 과 CPHA 비트를세팅하여, 클럭의극성 (Polarity) 와위상 (Phase) 를결정 : 여기서는그냥디폴트 ( 0 ) 로설정. n 클럭의주파수를결정 : n SPCR 의 SPR(1:0) 과 SPSP 의 SPI2X 를세팅 : 여기서는 SPI2X= 0, SP R(1:0)= 00 로하여, 4 분주 (7.3728MHz/4 = 1.8432MHz) 로설정 n SPCR 의 SPE 비트를 1 로세팅하여 SPI 를 Enable
실습 17 : SPI 로 Flash Memory 붙이기 구동프로그램 : 사전지식 AT25F512 칩을위한라이브러리함수 n at25fxx_rdid(u08* data) : 제조자와칩 ID 를읽어낸다. n at25fxx_chip_erase() : 칩전체의데이터를지운다. n at25fxx_write_byte(u16 addr, u08 data) : 임의의주소에 1 바이트데이터를써넣는다. 인수로주소와써넣을 1 바이트데이터를받는다. n at25fxx_sector_erase(u16 addr) : 주어진주소가가리키는섹터의데이터를지운다. n at25fxx_read_byte(u16 addr) : 인수로주어진주소의 1 바이트데이터를읽어낸다. n at25fxx_write_arry(u16 addr, u08* BPdata, u08 size) : 인수로주어진주소로부터 size 만큼 BPData 에존재하는데이터를써넣는다. n at25fxx_read_arry(u16 addr, u08* BPbuf, u08 size) : 인수로주어진주소로부터 size 만큼의데이터를읽어 BPbuff 에넘겨준다.
실습 17 : SPI 로 Flash Memory 붙이기 구동프로그램 : AT25F512 칩을위한라이브러리함수 SPI 초기화 SPI 초기화 void SPI_Init(){ DDRB = 0x07; // 포트를설정, miso 입력설정 PORTB = 0x01; // ~cs = 1 } SPCR = 0x50; SPSR = 0x00;
실습 17 : SPI 로 Flash Memory 붙이기 구동프로그램 : AT25F512 칩을위한라이브러리함수 SPI Flash Memory 칩지우기 칩지우기 (Chip Erase) #define AT25FXX_CS_LOW (PORTB &= 0xFE) #define AT25FXX_CS_HIGH (PORTB = 0x01) void at25fxx_wren(){ } AT25FXX_CS_LOW; // 칩셀렉트 SPDR = WREN; //wren명령 while((spsr & 0x80)==0x00); // 데이타전송완료확인 AT25FXX_CS_HIGH; //cs high 가되어야다음부터쓰기실행
실습 17 : SPI 로 Flash Memory 붙이기 구동프로그램 : AT25F512 칩을위한라이브러리함수 SPI Flash Memory 칩지우기 void at25fxx_chip_erase(){ at25fxx_wren (); AT25FXX_CS_LOW; SPDR = CHIP_ERASE; while((spsr & 0x80)==0x00); AT25FXX_CS_HIGH; at25fxx_ready(); } // 칩셀렉트 //chip Erase 명령 // 데이타전송완료확인 //cs high 가되어야다음부터쓰기실행
실습 17 : SPI 로 Flash Memory 붙이기 구동프로그램 : AT25F512 칩을위한라이브러리함수 SPI Flash Memory 칩지우기 void at25fxx_ready(){ u08 data; do{ AT25FXX_CS_LOW; SPDR = RDSR; while((spsr & 0x80)==0x00); SPDR=0; while((spsr & 0x80)==0x00); data = SPDR; SPDR = 0; while((spsr & 0x80)==0x00); AT25FXX_CS_HIGH; }while((data & 1<<(RDY))); // 레지스터를읽어와준비상태가되어있을때까지루프 }
실습 17 : SPI 로 Flash Memory 붙이기 구동프로그램 : AT25F512 칩을위한라이브러리함수 SPI Flash Memory 1 바이트읽기 1 바이트읽기 u08 at25fxx_read_byte(u16 addr){ u08 data=0; AT25FXX_CS_LOW; SPDR = READ; // 읽기선언 while((spsr & 0x80)==0x00); SPDR = 0x00; while((spsr & 0x80)==0x00);
실습 17 : SPI 로 Flash Memory 붙이기 SPI Flash Memory 1 바이트읽기 1 바이트읽기 SPDR = ((addr>>8) & 0xff); while((spsr & 0x80)==0x00); SPDR = ((addr) & 0xff); while((spsr & 0x80)==0x00); // 주소 // 주소 SPDR = 0; while((spsr & 0x80)==0x00); data = SPDR; // 데이타 } AT25FXX_CS_HIGH; return data;
실습 17 : SPI 로 Flash Memory 붙이기 구동프로그램 : AT25F512 칩을위한라이브러리함수 SPI Flash Memory 1 바이트쓰기 (Program) 1 바이트쓰기 (Program) void at25fxx_write_byte(u16 addr, u08 data){ at25fxx_wren (); AT25FXX_CS_LOW; SPDR = PROGRAM; while((spsr & 0x80)==0x00); // 쓰기선언 SPDR = 0x00; //at25f512 는여기주소를사용되지않음 (16 비트주소만사용 ) while((spsr & 0x80)==0x00);
실습 17 : SPI 로 Flash Memory 붙이기 구동프로그램 : AT25F512 칩을위한라이브러리함수 SPI Flash Memory 1 바이트쓰기 1 바이트쓰기 (Program) SPDR = ((addr>>8) & 0xff); while((spsr & 0x80)==0x00); SPDR = ((addr) & 0xff); while((spsr & 0x80)==0x00); // 주소 } SPDR = data; // 데이타 while((spsr & 0x80)==0x00); AT25FXX_CS_HIGH; //cs high 가되어야입력한내용이적용 at25fxx_ready();
실습 17 : SPI 로 Flash Memory 붙이기 구동프로그램 : 소스분석 1) #include<avr/io.h> #include<util/delay.h> #include"at25fxx.h" #include"lcd.h #define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0])) #define DELAY_MS(x) {static unsigned int _i; \ for(_i=0;_i<x;_i++) \ _delay_ms(1); } 2) unsigned char msg1[]="welcome!!"; unsigned char msg2[]="hanback-world!!"; unsigned char msg3[]="spi-flash Exam"; int main(){ unsigned char i=0;
실습 17 : SPI 로 Flash Memory 붙이기 3) unsigned char buf1[20]={0}; unsigned char buf2[20]={0}; unsigned char buf3[20]={0}; 4) SPI_Init(); //SPI통신초기화 lcdinit(); //TextLCD 초기화 5) at25fxx_chip_erase(); // 모든섹터의내용을지운다. 6) at25fxx_write_arry(0x1000, msg1,array_size(msg1)); //"Welcome!!" 저장 at25fxx_write_arry(0x2000, msg2,array_size(msg2)); //"HanBack-World!!" 저장 at25fxx_write_arry(0x3000, msg3,array_size(msg3)); //"SPI-Flash Exam" 저장 at25fxx_read_arry(0x1000, buf1,array_size(msg1)); /* 각배열에플래쉬에저장한문자열을읽어온다. */ at25fxx_read_arry(0x2000, buf2,array_size(msg2)); at25fxx_read_arry(0x3000, buf3,array_size(msg3));
실습 17 : SPI 로 Flash Memory 붙이기 7) for(;i<array_size(msg1)-1;i++){ // 읽어들인문자열출력 lcddatawrite(buf1[i]); DELAY_MS(100); //100ms단위의딜레이간격 } for(i=0,lcdgotoxy(0, 1);i<ARRAY_SIZE(msg2)-1;i++){ lcddatawrite(buf2[i]); DELAY_MS(100); } for(i=0;i<array_size(msg3)-1;i++){ lcddatawrite(buf3[i]); DELAY_MS(100); } for(i=0;i<15;i++){ //LCD 화면을왼쪽으로시프트 lcdcontrolwrite(1<<lcd_move 1<<LCD_MOVE_DISP ); DELAY_MS(100); } return 0; }
실습 17 : SPI 로 Flash Memory 붙이기 실행결과
실습 18 : TWI 로온습도센서제어하기 실습개요 I 2 C 로제어되는온습도센서인 SHT11 을 ATmega128 의 TWI 포트에연결하고, 온도와습도정보를읽어들여 TEXT LCD 에표시하도록한다. GPIO 포트를이용하여, SHT11 과통신이가능한유사 TWI 버스의신호를만들어사용한다. SHT11 칩의 TWI 인터페이스관련라이브러리함수를 lib_sensor.c 에포함하고있음. 실습목표 TWI(I 2 C) 의동작원리이해 ( 레지스터설정 ) ATmega128의 GPI를통한유사 TWI(I2C) 신호제어방법습득 SHT11 온도센서제어방법습득
실습 18 : TWI 로온습도센서제어하기 사용모듈 : MCU 모듈, 센서모듈, TEXT-LCD 모듈, MCU 모듈 TEXT LCD 모듈 D 포트센서모듈 TWI 연결 C,D 포트 TEXT LCD 모듈연결 Data BUS (D0~D7) Control 신호 (Rs, RW, E) 센서모듈 온도 / 습도센서 광다이오드 조도센서 (CDS) 센서모듈온습도센서 TWI Signal
실습 18 : TWI 로온습도센서제어하기 사용모듈 센서모듈중온습도센서부분의회로 n SHT11 n n 상대습도와상대온도를측정하는칩이며, 이슬점 (Dew Point) 측정이가능함. 이칩은 SCK( 클럭 ) 과 Data, 두신호선으로 TWI(I2C) 와유사한인터페이스프로토콜을사용한다
실습 18 : TWI 로온습도센서제어하기 사용모듈 SHT11 온습도센서 SHT11 의 Serial Interface 데이터형식
실습 18 : TWI 로온습도센서제어하기 모듈결선방법 MCU 모듈포트 C의 PC0~PC7은 TEXT LCD 모듈의 D0~D7 핀에연결 MCU 모듈포트 D의 PD5~PD7은 TEXT LCD 모듈의 RS, RW, E에연결 MCU 모듈포트 D의 PD0는센서모듈의 TMP_SCK에, PD1은 TMP_SDA에연결
실습 18 : TWI 로온습도센서제어하기 구동프로그램 : 사전지식 lib_sensor.c 에서제공하는라이브러리함수 start_sht11_sensor(void) : SHT 의온습도측정기능을시작한다. get_sht11_hanback_data(u08 type) : SHT11 로부터온도와습도데이터를읽어온다. initialize_sht11_hanback(void) : SHT11 용 TWI 인터페이스와센서를초기화한다. SHT11 에서온습도데이터를읽어들이기 1) initialize_sht11_hanback(void) 를이용하여센서와 TWI 인터페이스용핀을초기화한다. 2) start_sht11_sensor(void) 를이용하여 SHT 의온습도측정기능을시작한다. 3) get_sht11_hanback_data(u08 type) 를이용하여상대습도와상대온도를읽어온다. 여기서 type 은 DEW( 이슬점 ), TEMP( 온도 ), HUMI( 습도 ) 의세가지이다.
실습 18 : TWI 로온습도센서제어하기 구동프로그램 : 소스분석 lcdconf.h n TEXT LCD 의제어포트로 D 포트를, 데이터포트는 C 포트를사용 #ifdef LCD_PORT_INTERFACE #ifndef LCD_CTRL_PORT #define LCD_CTRL_PORT PORTD #define LCD_CTRL_DDR DDRD #define LCD_CTRL_RS 5 #define LCD_CTRL_RW 6 #define LCD_CTRL_E 7 #endif #ifndef LCD_DATA_POUT #define LCD_DATA_POUT PORTC #define LCD_DATA_PIN PINC #define LCD_DATA_DDR DDRC #endif #endif
실습 18 : TWI 로온습도센서제어하기 구동프로그램 : 소스분석 Sensor_test.c 1) #include<avr/io.h> #include<util/delay.h> #include"lib_sensor.h" #include"lcd.h" #include"avr_lib.h #define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0])) #define DELAY_MS(x) { static unsigned int _i; \ for(_i=0;_i<x;_i++) \ _delay_ms(1); } 2) void printf_2dot1(u08 sense,u16 sense_temp); int main(){ volatile u16 temp,humi;
실습 18 : TWI 로온습도센서제어하기 3) initialize_sht11_hanback(); //sht11 센서초기화 start_sht11_sensor(); //sht11 센서시작 4) lcdinit(); //TextLCD 초기화 lcdprintdata("sensor_test",sizeof("sensor_test")-1); DELAY_MS(500); //500ms단위의딜레이간격 lcdclear(); while(1){ 5) temp = get_sht11_hanback_data(temp); DELAY_MS(100); //100ms단위의딜레이간격 6) humi = get_sht11_hanback_data(humi); DELAY_MS(100); //100ms단위의딜레이간격 lcdgotoxy(0,0);
실습 18 : TWI 로온습도센서제어하기 7) printf_2dot1(temp,temp); // 온도값을출력 lcdgotoxy(0,1); printf_2dot1(humi,humi); // 습도값을출력 DELAY_MS(300); //300ms단위의딜레이간격 } return 0; } void printf_2dot1(u08 sense,u16 sense_temp) { u08 s100,s10; if(sense == TEMP) lcdprintdata(" Temp: ",7); else if(sense == HUMI) lcdprintdata(" Humi: ",7); s100 = sense_temp/100; if(s100> 0) lcddatawrite(s100+'0'); else lcdprintdata(" ",1); s10 = sense_temp%100; lcddatawrite((s10/10)+'0'); lcdprintdata(".",1); lcddatawrite((s10%10)+'0'); }
실습 18 : TWI 로온습도센서제어하기 실행결과