ENGLISH 简体中文 日本語 한국어  


애플리케이션 노트  3588

MAXQ2000 마이크로컨트롤러용 소프트웨어 I²C 드라이버

개요: I²C(inter-integrated circuit)는 IC 간의 양방향 통신을 가능하게 하는 2-wire 인터페이스이다. 이 애플리케이션 노트에서는 마이크로컨트롤러의 GPIO 핀을 이용해 100kHz 또는 400kHz로 I²C 통신이 가능한 MAXQ2000 마이크로컨트롤러용 소프트웨어 I²C 드라이버에 대해 설명한다. MAXQ 마이크로컨트롤러 제품군은 높은 속도, 유연한 GPIO 모듈, 별도의 I/O 전원 전압을 특징으로 하므로 비트뱅잉(bit-banging) 애플리케이션에 적합하다.

개요

I²C(inter-integrated circuit)는 IC 간에 양방향 통신을 가능하게 하는 2-wire 인터페이스이다. 이 애플리케이션 노트에서는 MAXQ2000 마이크로컨트롤러(µC)용 소프트웨어 I²C 드라이버인 maxqi2c 라이브러리에 대해 설명한다.

maxqi2c 라이브러리는 C로 작성되었으며, MAXQ용 IAR Embedded Workbench를 이용해 컴파일하는 확장을 이용한다. 이 라이브러리는 maxqi2c.hmaxqi2c.c의 2개 파일로 구성된다. MAXQ2000 펌웨어 프로젝트에 이 파일을 포함시킴으로써, 마이크로컨트롤러의 GPIO 핀 중 어느 것이든 이용하여 100kHz 또는 400kHz로 유연한 I²C 통신이 가능하다.

MAXQ 마이크로컨트롤러 제품군은 높은 속도, 유연한 GPIO 모듈, 별도의 I/O 전원 전압을 특징으로 하므로 비트뱅잉 애플리케이션에 적합하다.

이 애플리케이션 노트에서 설명하는 프로젝트 예의 파일은 Maxim Integrated Products 웹사이트에서 다운로드할 수 있다.

maxqi2c 라이브러리의 구성

사용자는 maxqi2c 라이브러리 파일(maxqi2c.hmaxqi2c.c)을 MAXQ2000 프로젝트 디렉토리로 복사하고 이 파일을 구성해서 원하는 I²C 인터페이스를 생성해야 한다. 다음 코드(Listing 1)의 편집을 통해 모든 구성이 가능하며, maxqi2c.h 소스 파일 상단에서 이 코드를 찾을 수 있다.

Listing 1. maxi2c.h 맞춤화 코드
/* USER MUST CUSTOMIZE THE FOLLOWING DEFINE STMTS - START */
  // Enter the port used for SDA and SCL
  #define SDA_PORT               0
  #define SCL_PORT               0

  // Enter the pin used for SDA and SCL
  #define SDA_PORT_BIT           0
  #define SCL_PORT_BIT           1

  // Uncomment one of these define statements to select I²C bus speed
  #define I2C_400_KHZ
  //#define I2C_100_KHZ
  
  // Comment out the following define statement to disable clock
  // stretching in i2cRecv()
  #define I2C_CLOCK_STRETCHING
/* USER MUST CUSTOMIZE THE FOLLOWING DEFINE STMTS - END   */
참고: 맞춤화는 컴파일 때 구현되므로 런타임 때는 동작하지 않는다.

SCL 및 SDA 핀 선택

SCL 및 SDA의 이용을 위해서는 GPIO 핀 두 개가 선택되어야 한다. SCL 및 SDA를 위한 I/O를 선택한 다음에는, 바람직한 SDA 및 SCL 포트를 반영하기 위해 SDA_PORTSCL_PORT 정의문을 편집해야 한다. 또한 SDA 및 SCL에 대해 원하는 핀을 반영하기 위해 SDA_PORT_BITSCL_PORT_BIT 정의문을 편집해야 한다.

위의 Listing 1에서 소스 코드는 I/O 포트 0의 핀 0을 SDA로 동작하도록 지정하고 I/O 포트 0의 핀 1을 SCL로 동작하도록 지정했다.

통신 속도 선택

통신 속도 선택은 I2C_400_KHZI2C_100_KHZ의 2개 문의 하나를 이용해서 이루어진다.

Listing 1의 소스 코드는 400kHz I²C 버스를 이용해 maxqi2c 라이브러리를 통신으로 초기화한다. I²C 인터페이스가 비트뱅잉되므로 실제로는 이 통신이 400kHz(또는 100kHz)에 조금 못미친다. 온전히 400kHz 통신을 달성하기 위해서는 펌웨어 설계자가 maxqi2c 라이브러리를 검토하여 이 라이브러리의 고유의 유연성을 제공하는 일부 소스 코드를 제거해야 한다.

참고: maxqi2c 라이브러리에는 I²C 규격을 충족시키기 위해 지연이 발생된다. maxqi2c.c 파일 상단의 이 지연은 MAXQ2000이 20MHz 시스템 클록을 이용한다는 것을 가정하는 것이다. 이보다 낮은 클록 속도를 이용하면 이 지연을 단축할 수 있다.

클록 스트레칭 이용

maxqi2c 라이브러리의 클록 스트레칭은 i2cRecv() 함수에 대한 호출이 이루어지는 동안 전송 시작 부분에서만 허용된다(어드레스를 전송하는 경우에는 어드레스 확인응답 후에, 혹은 전송을 시작할 때). 그러므로 다음과 같은 형식을 이용해 I²C 전송에 클록 스트레칭을 이용할 수 있다.
[S] [ADDR] [R] [A] [clock stretch] [DATA0] [A] ... [DATAN-1] [A]
or
[clock stretch] [DATA0] [A] ... [DATAN-1] [N] [P]
or
[clock stretch] [DATA0] [A] ... [DATAN-1] [A]
maxqi2c 사용법 부분의 i2cRecv()에 대한 설명과 maxqi2c 라이브러리 용례 부분의 코드 예에서 이 형식을 이용해 I²C 명령을 생성하는 방법을 설명하고 있다.

클록 스트레칭을 인에이블하기 위해서는 I2C_CLOCK_STRETCHING 정의문에 주석을 기술하지 않아야 한다. 클록 스트레칭이 필요없으면 I2C_CLOCK_STRETCHING 정의문에 주석을 기술해서 클록 스트레칭을 디스에이블한다. 클록 스트레칭을 디스에이블하면 maxqi2c 라이브러리의 i2cRecv() 함수의 속도가 다소 높아진다.

위 Listing 1의 소스 코드는 클록 스트레칭을 인에이블시킨다.

maxqi2c의 이용

maxqi2c 라이브러리를 이용해 소프트웨어 I²C 드라이버로 데이터를 전송하고 수신하는 것은 i2cInit(), i2cIsAddrPresent(), i2cSend()i2cRecv()의 4개 함수에 의해 이루어진다. 이 함수에 대한 자료가 maxqi2c.h 파일 안에 포함되어 있다.

이 함수는 형식적 파라미터를 필요로 하지 않는다. 대신에 i2cData (부호 없는 문자 *), i2cDataLen (부호 없는 문자), i2cDataAddr (부호 없는 문자) 및 i2cDataTerm 부호 없는 문자)의 4개 전역 변수를 이용해 이 함수의 파라미터를 저장한다. 이 기법은 함수 호출 때 데이터를 복사하지 않음으로써 펌웨어가 더 빠르게 실행될 수 있게 해준다. maxqi2c 라이브러리에 대한 파라미터로 사용되는 4개 전역 변수는 i2cData (부호 없는 문자 *), i2cDataLen (부호 없는 문자), i2cDataAddr (부호 없는 문자) 및 i2cDataTerm (부호 없는 문자)이다.

i2cInit()

어떤 maxqi2c 함수보다도, 이 함수가 먼저 호출되어야 한다. 이 함수가 maxqi2c.h 파일의 맞춤화 코드에서 선택한 포트 핀을 초기화한다. 이 함수는 파라미터(로컬 또는 전역)를 필요로 하지 않으며 값을 리턴하지 않는다.

i2cIsAddrPresent()

이 함수는 MAXQ2000이 I²C 버스를 질의해서 특정 어드레스의 장치가 존재하는지 확인할 수 있도록 한다. 이 함수가 하나의 파라미터 전역 변수 i2cDataAddr을 이용하며, I²C 버스 상에 존재하는지 질의한 장치의 어드레스로 이 변수가 로드되어야 한다. 또한 이 함수는 값(부호 없는 문자 타입)을 리턴한다. 특정 어드레스의 장치가 식별되었으면 이 값은 I2C_XMIT_OK와 동일하고, 특정 어드레스의 장치가 식별되지 않았으면 I2C_XMIT_FAILED와 동일하다.

I²C 버스 상에 특정 장치가 존재하는지 확인하기 위해 i2cIsAddrPresent()가 다음 형식으로 I²C 명령을 전송한다.
[S] [ADDR] [W] [A] [P]

i2cSend()

이 함수는 MAXQ2000이 소프트웨어 I²C 드라이버를 이용해 특정 장치로 데이터를 전송할 수 있도록 한다. i2cSend()가 초기화되려면 다음과 같은 4개 파라미터(모두 전역 변수)를 필요로 한다.
  • i2cData (부호 없는 문자 *): 전송하려는 바이트 어레이의 첫 번째 바이트 포인터
  • i2cDataLen (부호 없는 문자): I²C 버스로 전송하려는 바이트 수 (장치 어드레스 포함하지 않음)
  • i2cDataAddr (부호 없는 문자): 데이터를 전송하려는 장치의 어드레스. 이 변수가 0으로 설정되면 I²C 데이터가 어드레스를 포함하지 않고 전송된다.
  • i2cDataTerm (부호 없는 문자): I²C 전송이 어떻게 종료되는지를 나타낸다. 이 변수가 i2cSend(): I2C_TERM_NONE이나 I2C_TERM_STOP을 호출해서 2가지 값을 취할 수 있다.
I²C 버스 상의 장치로 데이터를 전송하기 위해 이용되는 형식은 파라미터로 이용되는 4개 전역 변수 값에 따라 결정된다. 표 1은 이 전역 변수의 값에 따른 I²C 명령 형식이다.

표 1. i2cSend()가 전송하는 I²C 명령
i2cDataLen(hex) i2cDataAddr(hex) i2cDataTerm I²C Command Format
0x0002 0x7E I2C_TERM_STOP [S] [ADDR] [W] [A] [DATA0] [A] [DATA1] [P]
0x0002 0x7E I2C_TERM_NONE [S] [ADDR] [W] [A] [DATA0] [A] [DATA1] [A]
0x0002 0x00 I2C_TERM_NONE [DATA0] [A] [DATA1] [A]
0x0002 0x00 I2C_TERM_STOP [DATA0] [A] [DATA1] [A] [P]

참고: 표 1의 마지막 3개 형식은 i2cSend()가 어떻게 I²C 버스 상의 동일 장치로 연속적으로 데이터를 전송하는지 보여준다.

지정된 어드레스의 장치가 모든 바이트를 확인응답하면 i2cSend() 함수가 I2C_XMIT_OK에 해당되는 값(부호 없는 문자 타입)을 리턴하고, 지정된 어드레스의 장치가 바이트를 확인응답하지 않으면 I2C_XMIT_FAILED에 해당되는 값을 리턴한다. 한 바이트라도 확인응답되지 않으면 이 함수가 곧바로 값을 리턴한다.

i2cRecv()

이 함수는 MAXQ2000이 소프트웨어 I²C 드라이버를 이용해 특정 장치로부터 데이터를 수신할 수 있도록 한다. i2cRecv() 함수는 초기화를 위해 다음 4개 파라미터(모두 전역 변수)를 필요로 한다.
  • i2cData (부호 없는 문자 *): 수신한 값을 저장하려는 바이트 어레이의 첫 번째 바이트 포인터
  • i2cDataLen (부호 없는 문자): I²C 버스에서 수신하려는 바이트 수 (장치 어드레스 포함하지 않음)
  • i2cDataAddr (부호 없는 문자): 데이터를 수신할 장치의 어드레스. 이 변수를 0으로 설정하면 어드레스를 전송하지 않고 I²C 데이터가 수신된다.
  • i2cDataTerm (부호 없는 문자): I²C 전송이 어떻게 종료되는지를 나타낸다. 이 변수는 i2cRecv(): I2C_TERM_NONE, I2C_TERM_ACK 또는 I2C_TERM_NACK_AND_STOP을 호출해서 3가지 값을 취할 수 있다.
I²C 버스 상의 장치로부터 데이터를 수신하기 위해 이용되는 형식은 파라미터로 이용하는 4개 전역 변수의 값에 따라 결정된다. 표 2는 이 전역 변수의 값에 따른 I²C 명령 형식이다.

표 2. 클록 스트레칭이 디스에이블되었을 때 i2cRecv()가 전송하는 I²C 명령
i2cDataLen(hex) i2cDataAddr(hex) i2cDataTerm I²C Command Format
0x0002 0x7E I2C_TERM_NACK_AND_STOP [S] [ADDR] [R] [A] [DATA0] [A] [DATA1] [N] [P]
0x0002 0x7E I2C_TERM_ACK [S] [ADDR] [R] [A] [DATA0] [A] [DATA1] [A]
0x0002 0x00 I2C_TERM_ACK [DATA0] [A] [DATA1] [A]
0x0002 0x00 I2C_TERM_NACK_AND_STOP [DATA0] [A] [DATA1] [N] [P]

참고: 표 2의 마지막 3개 형식은 i2cRecv()가 어떻게 I²C 버스 상의 동일 장치로부터 데이터를 수신하는지를 보여준다.

어드레스가 I²C 명령에 포함되어 전송되고 확인응답되지 않으면 i2cRecv() 함수가 I2C_XMIT_FAILED에 해당되는 값(부호 없는 문자 타입)을 리턴하고, 그렇지 않으면 I2C_XMIT_OK를 리턴한다.

클록 스트레칭이 가능한 maxqi2c 라이브러리 용례

다음 예에서는 maxqi2c 라이브러리를 이용해 MAX1169 ADC로부터 16비트 샘플을 수신하고, 이를 MAXQ의 RS-232 포트를 이용해 PC로 전송하는 것을 설명하고 있다.

회로도

이 예는 MAX1169 ADC EV 킷MAXQ2000 EV 킷(Rev B)을 이용해 구현되었다. 그림 1은 두 EV 킷이 어떻게 연결되었는지를 보여준다. MAXQ2000의 I/O 포트 0의 핀 0 및 핀 1(각각 J2-30 및 J2-28에서 이용 가능)이 I²C 버스 상의 마스터 SDA 및 SCL 라인으로 동작한다.

그림 1. MAX1169 EV 킷과 MAXQ2000 EV 킷(Rev B)이 어떻게 연결되고 maxqi2c 라이브러리가 이용할 수 있도록 준비되었는지 보여준다.
그림 1. MAX1169 EV 킷과 MAXQ2000 EV 킷(Rev B)이 어떻게 연결되고 maxqi2c 라이브러리가 이용할 수 있도록 준비되었는지 보여준다.

참고: MAXQ2000 EV 킷의 MAXQ2000 고주파 크리스털(Y1)을 20MHz 크리스털로 대체했다. MAX1169 EV 킷의 점퍼 설정과 MAXQ2000 EV 킷의 스위치 설정이 표 3표 4와 같아야 한다.

표 3. MAX1169 EV 킷의 점퍼 설정
Jumper Shunt Position
JU1 Shunt on pins 1 and 2
JU2 Shunt on pins 1 and 2
JU3 Shunt on pins 1 and 2
JU4 No shunt
JU5 No shunt

표 4. MAXQ2000 EV 킷(Rev B)의 스위치 설정
Switch Position
SW1-1 OFF
SW1-2 OFF
SW1-3 OFF
SW1-4 ON
SW1-5 OFF
SW1-6 OFF
SW1-7 ON
SW1-8 OFF
SW6-1 OFF
SW6-2 OFF
SW6-3 OFF
SW6-4 OFF
SW6-5 OFF
SW6-6 OFF
SW6-7 OFF
SW6-8 ON

펌웨어

이 예의 펌웨어 파일(max1169.c)은 부록 A와 같다. Maxim MAXQ2000 웹페이지에서 전체 프로젝트를 다운로드할 수 있으며 MAXQ용 IAR Embedded Workbench를 이용해 컴파일할 수 있다. 이 예에서는 maxqi2c 라이브러리의 코드 맞춤화(maxqi2c.h 파일 상단)가 Listing 1의 소스 코드와 동일하다.

max1169.c 파일은 iomaxq200x.hmaxqi2c.h의 2개 헤더 파일을 포함한다. 이 예의 iomaxq200x.h 파일이 MAXQ include 패스에서 IAR Embedded Workbench의 iomaxq200x.h 파일을 오버라이드한다. iomaxq200x.h 파일은 maxqi2c 라이브러리에 필요한 모든 포트의 모든 핀에 대한 정의를 생성한다. maxqi2c.h 파일을 포함시킴으로써 펌웨어는 maxqi2c 라이브러리의 함수를 호출할 수 있다.

이 펌웨어는 max1169.c 파일에서 표기한 5단계로 구성된다(부록 A 참조).

1단계는 UART0을 초기화해서 19200bps로 비동기 통신한다. MAXQ2000 시스템 클록이 20MHz가 아니면 레지스터 PR0에 대한 지정을 변경해서 원하는 보(Baud) 속도를 획득하도록 해야 한다.

단계는 MAXQ2000에서 I²C 버스에 이용되는 핀의 초기화를 담당한 i2cInit() 함수를 호출한다.

3단계는 파라미터를 초기화하고 i2cRecv() 함수를 호출한다. 그러면 파라미터가 초기화되고 다음과 같은 형식으로 I²C 명령을 전송한다.
[S] [ADDR] [R] [A] [clock stretch] [DATA0] [A] [DATA1] [A (termination)] 
4단계는 어드레스 파라미터를 0으로 설정한다. 그러면 i2cRecv() 함수가 다음과 같은 형식으로 I²C 명령을 전송한다.

[clock stretch] [DATA0] [A] [DATA1] [A (termination)] 
5단계는 무한 반복하는 루프이다. 이 루프가 i2cRecv()를 호출하고 (4단계의 형식으로) MAX1169로부터 16비트 샘플을 수신한다. 이 16비트 샘플이 UART0을 이용해 PC로 전송된다 (MSB 먼저). 종료 파라미터 i2cDataTerm은 언제나 I2C_TERM_ACK와 동일하므로, 루프는 무한 반복하며 MAX1169는 정지 조건을 만나지 않는다.

부록 A: max1169.c
/*
 * DEMO of maxqi2c Software I²C Driver
 * (uses evkits for the MAX1169 and MAXQ2000)
 *
 * by: Paul Holden - MAXIM INTEGRATED PRODUCTS
 *
 * 
 * DESC: Test program for the maxqi2c.c/maxqi2c.h I²C
 *       driver for the MAXQ2000. The program reads
 *       16-bit samples from the MAX1169 (running in 
 *       continuous conversion mode) and transmits them
 *       using the UART0 port.
 *
 * NOTE - THE FOLLOWING CODE ASSUMES THE MAXQ2000 HAS
 *        A Fsysclk=20MHz.
 */

#include "iomaxq200x.h"
#include "maxqi2c.h"

void main()
{
   unsigned char data[2];

   // 1. Init UART0
   PD7_bit.bit0 = 1;      // Set TX0 pin as output
   SCON0        = 0x42;
   SMD0         = 0x02;
   PR0          = 0x07DD; // 19200bps

   // 2. Init bit-banged I²C port
   i2cInit();

   // 3. Send initial I²C request
   // [S] [ADDR+R] [A] [clock_stretch] [DATA0] [A] [DATA1] [A (termination)] 
   i2cData     = (unsigned char *)(&data); // cast needed!
   i2cDataAddr = 0x7E;
   i2cDataLen  = 0x0002;
   i2cDataTerm = I2C_TERM_ACK;
   i2cRecv();

   // 4. Init continuous conversion
   // [clock_stretch] [DATA0] [A] [DATA1] [A (termination)]
   i2cDataAddr = 0x00;

   // 5. Receive a 16-bit sample and transfer it to the UART0 port
   //    one byte at a time. Repeat forever...
   while (1)
   {
      i2cRecv();
      
      while(!SCON0_bit.TI);   // Wait for UART0 Buffer to be empty
      SCON0_bit.TI = 0;       // Reset TI flag
      SBUF0        = data[0]; // Send data byte 0
      while(!SCON0_bit.TI);   // Wait for UART0 Buffer to be empty
      SCON0_bit.TI = 0;       // reset TI flag
      SBUF0        = data[1]; // Send data byte 1
   }
}


의견을 보내주세요!
위 내용이 도움이 되셨나요?
여러분의 의견을 기다립니다 — Maxim은 보내주신 정정이나 제안사항을 반영하고 있습니다. 이 페이지를 평가하고 의견을 보내주십시오.


자동 업데이트
관심있는 분야의 애플리케이션 노트가 나올 때 자동으로 업데이트 받고 싶으세요? 그렇다면 EE-Mail™을 신청하십시오.



추가 정보  APP 3588: Jul 12, 2006
MAX1169 14핀 TSSOP 패키지로 제공되는 58.6ksps, 16비트, 2-Wire 직렬 ADC 전체 데이터 시트
(PDF, 456kB)
무료 샘플
MAXQ2000 저전력 LCD 마이크로컨트롤러 전체 데이터 시트
(PDF, 480kB)
무료 샘플
 

다운로드, PDF 형식다운로드, PDF 형식 (42kB)
 AN3588, AN 3588, APP3588, Appnote3588, Appnote 3588



         


      개인정보보호 정책    법적 고지

      Copyright © 2008 by Maxim Integrated Products, Dallas Semiconductor