ENGLISH 简体中文 日本語 한국어  


APPLICATION NOTE  3315

C를 이용한 병렬 포트 2-Wire 소프트웨어 제작

개요: 본 고에서는 애플리케이션 노트 AN3230에서 설명된 병렬 포트 하드웨어와 함께 사용하는 병렬 포트 2-wire 소프트웨어 제작을 위한 안내와 소스 코드를 제공한다.

참조: 애플리케이션 노트 3317: Adding Windows NT/2000/XP Support to the AN3315 Parallel-Port 2-Wire Software

개요

본 애플리케이션 노트는 AN3230에서 설명한 병렬 포트 하드웨어용 2-wire 소프트웨어 개발에 관심이 있는 고객들을 위해 제공되어 있는 C 소스를 살펴보고자 한다. 이 소스 코드는 Dallas Semiconductor 사의 FTP 사이트에서 무료로 공급되고 있으며 Windows® 95 또는 Windows 98 운영체계를 사용하고 있는 모든 PC에서 구동될 수 있다. 또한 단순 평가 및 병렬 포트 하드웨어 디버깅 용으로 사용될 수 있는 기본적인 2-wire 통신 소프트웨어를 제공하는 FTP 사이트에서 간단한 프로그램을 공급하고 있다. 하드웨어에 관한 보다 자세한 정보는 AN3230 AN3230를 참조한다.

본 애플리케이션 노트에 제시된 소프트웨어는 현재로서는 당사의 고객들에게 무료로 공급되고 있다. Dallas Semiconductor 사는 본 소프트웨어가 일으킬 수도 있는 모든 손상에 대해 책임을 지지 않는다. 소프트웨어 사용상의 모든 위험은 사용자의 책임이다.

소프트웨어 요구조건

서언에서 언급한 바와 같이 본 프로그램은 Windows 95 또는 Windows 98 운영 체계를 사용하는 PC에서 구동되어야 한다. 본 소프트웨어는 직접 병렬 포트에 액세스하며 Windows NT 기반 운영체계는 본 작업 완료를 위해 드라이버를 필요로 한다. Windows NT/2000/XP 용 병렬 포트 액세스를 위한 드라이버 사용에 관해서는 앞으로 제공될 애플리케이션 노트를 참고 한다.

또한 운영에 필요한 다중 병렬 포트 동작 모드가 있어야 하며, 몇몇 소프트웨어와는 호환되지 않는다. 성공적으로 사용된 두 종류의 모드는 EPP와 ECP이다. 대부분의 PC 병렬 포트 모드는 BIOS 설정에서 변경 가능하다.

소스코드 설명/사용

소스 코드 (부록 A 참조)는 ANSI C로 작성되었으며, 모든 C 컴파일러와 호환이 되어야 한다. 가능하면 간단하게 사용하기 위해, 모든 코드와 내용이 단일 파일(2wire.c) 내에 존재해야 하며, 자원 사용을 위한 프로젝트에 포함되어야 할 헤더 파일은 없다.

2-wire 소스 코드 사용 방법:

  1. "2wire.c" 파일을 프로젝트 디렉토리에 놓는다.
  2. 병렬 포트에 액세스하게될 프로그램의 맨 위에 있는 "2wire.c" 내용에 #을 추가한다.
  3. ParPortSelect(1)을 불러내어 병렬 포트를 선택한다. 인수가 사용될 포트 번호 (예: 제시된 바와 같이 LPT1)를 결정한다. 유효 포트 번호는 1, 2, 3이다. 대부분의 PC는 LPT1을 사용한다.
  4. 표 3에 예시되어 있는 ChangeDelayCount(int i) 명령을 사용하여 2-wire 인터페이스 타이밍을 보정한다.
  5. 표 1와 2에서 설명된 기본적인 2-wire 함수 또는 다중 바이트 2-wire 함수를 불러온다.
병렬 포트 타이밍은 이 소프트웨어를 실행하는 PC의 속도에 크게 좌우된다. 그러므로 컴퓨터 사이의 편차로 인해 신뢰성 있는 통신 구축이 어렵다. 이 문제를 해결하기 위해, 딜레이 길이의 변수는 SDA와 SCL 신호 사이에 삽입하여 빠른 컴퓨터의 타이밍이 최대 정격의 인터페이스 속도 (고속 모드 디바이스에서 초당 400kbit)를 초과하지 않도록 한다. 딜레이 시간은 ChangeDelayCount(int i) 기능을 사용해 제어된다. 이 기능은 PC가 실행할 짧은 딜레이 횟수를 변경한다 (10 NOPs + a for( ; ; ) 루프의 실행 횟수). i의 디폴트 값은 1000이며, 이는 P3 600MHz 기종에서 중저속 통신을 제공한다. 이 경우 대부분의 PC에서 적정 성능을 제공하지만 작동상의 신뢰성이 있어야 한다. 낮은 i의 값은 인터페이스의 속도를 높이지만 프로그래머는 반드시 통신 속도가 2-wire 디바이스의 규격 내에 있도록 해야 한다. 컴퓨터의 속도가 빠를수록 통신 구축을 위해 i값이 커질 필요가 있을 수도 있다. 이는 디버깅의 필요 여부에 대한 시험의 문제이다.

기본적인 2-wire 기능은 2-wire 디바이스에 액세스하는 대부분의 애플리케이션용으로 사용될 수 있다. 스타트 조건을 전송하고, 바이트를 읽고 기록하며, 스탑 조건을 전송하는 장치는 이러한 루틴에서 처리된다. 그리고 타이밍과 루틴이 호출되는 순서만이 디바이스와의 통신에서 마지막 장애물로 남게 된다. 이러한 루틴을 사용하기 위해서는, 위에서 설명한 바와 같이 타이밍을 조정하고 레지스터에 액세스하도록 만들어진 호출 순서를 결정하기 위해 디바이스의 데이터 시트를 보라.

다중 바이트 2-wire 기능을 사용하여 하나의 명령을 갖는 디바이스로부터 256 바이트까지의 정보를 읽고 쓸 수 있지만 통신 중에 모든 디바이스가 다 동일한 데이터 시퀀스를 이용하는 것은 아니다. 이 기능을 사용하기 위해 고려하고 있다면 제공된 소스 코드를 확인하고 액세스되고 있는 디바이스와의 호환성을 확인해야 한다. 다중 바이트 쓰기/읽기의 일차적 장점은 애플리케이션에 필요한 호출 횟수의 제한인데 그 이유는 단일 명령으로 다중 바이트를 전송하며 단일 바이트의 쓰기/읽기를 위해 다중 명령을 보내기 때문이다. 다중 바이트 쓰기 및 읽기 루틴은 SetSlaveAddress() 명령에 의해 설정된 디바이스 어드레스를 사용하기 때문에 SetSlaveAddress()는 반드시 다중 바이트 쓰기 및 읽기 명령을 사용하기 전에 호출되어야 한다.

LED 인에이블 및 디스에이블 기능을 사용하여 AN3230에 표시된 LED를 상태 표시기로 사용할 수 있다. 스트로브 설정 및 클리어 기능을 통해 LED 핀을 오실로스코프의 트리거로 사용할 수 있다. 이러한 기능들은 하드웨어 및 소프트웨어 문제 디버깅에 매우 유용하다.

표 1. 기본적인 2-wire 기능
FUNCTION PROTOTYPE FUNCTION DESCRIPTION RETURN VALUE
int Start() Generates 2-Wire start condition. Can also be called to generate a re-start condition. 1
int Stop() Generates 2-Wire stop condition 1
int WriteData(unsigned char ucData); Writes the argument to the slave 1 if slave acknowledges,
0 if slave does not acknowledge
int ReadDataAck(unsigned char *ucData); Reads the data byte from slave to ucData and acknowledges 1
int ReadDataNack(unsigned char *ucData); Reads the data byte from slave to ucData and does not acknowledge 1
int ResetBus() Clocks SCL 9-times then generates a stop condition 1

표 2. 다중 바이트 2-wire 기능
FUNCTION PROTOTYPE FUNCTION DESCRIPTION RETURN VALUE
int SetSlaveAddress(unsigned char ucADDR) Sets the slave address for multiple-byte read and write accesses 1
int WriteBytes(int iCount, unsigned char ucMemAddr, unsigned char ucData[256]) Writes iCount bytes to the slave at the device address set by SetSlaveAddress(), beginning at memory address set by ucMemAddr. 1 if slave acknowledges,
0 if slave does not acknowledge any byte.
Int ReadBytes(int iCount, unsigned char ucMemAddr, unsigned char ucData[256]) Reads iCount bytes to the slave at the device address set by SetSlaveAddress(), beginning at memory address set by ucMemAddr. 1 if slave acknowledges during command writes,
0 if slave does not acknowledge during command writes.

표 3. 추가 포트 설정 및 디버깅 기능
FUNCTION PROTOTYPE FUNCTION DESCRIPTION RETURN VALUE
int ParPortSelect(int iLPT) Sets parallel port access variables to specified port number. iLPT = 1 for LPT1. 1 for successful change
0 for failure
int ChangeDelayCount(int iCount) This determines the "i" value used with the DelayASMx10() command during SDA and SCL communications. Call this function with higher i values to make communication slower. The default value is 1000, which should provide moderate to slow communication speed. This is a safe value for i. Most PCs will be able to use a lower value of i to speed up communications. 1
void DelayASMx10(int i) Delays 10 clock cycles per i. This is called as the delay that determines SDA and SCL timing. It does not need to be called by the software developer, it is already embedded into the start/stop/read/write commands. NULL
int EnableLED() enables LED in AN3230 circuit 1
int DisableLED() disables LED in AN3230 circuit 1
int SetStrobe() Sets the LED pin in the AN3230 circuit high for oscilloscope triggering 1
int ClearStrobe() Sets the LED pin in the AN3230 circuit low for oscilloscope triggering 1

기본적 2-wire 기능의 예

본 장에서는 DS1086 DAC 레지스터에 2 바이트를 쓰고, 기본적 2-wire 기능을 사용해 이를 읽어 들이는 방법을 예시한다. DS1086의 슬레이브 어드레스는 B0h이며 DAC 레지스터는 메모리 어드레스 08h에서 시작하는 2 바이트이다.

08h 및 09h 어드레스에 0180h를 쓰기 위해서는 다음의 절차를 사용할 수 있다.

unsigned char fail = 0;

Start();                   // Generates Start Condition
fail |= !WriteData(0xB0);  // Writes the slave address
fail |= !WriteData(0x08);  // Writes the memory address of the DAC register
fail |= !WriteData(0x01);  // Writes the MSB of the DAC register
fail |= !WriteData(0x80);  // Writes the LSB of the DAC register
Stop();                    // Generates Stop Condition
if(fail == 1)
      Error("Device failed to acknowledge during write attempt");
DAC 레지스터에 방금 기록된 바이트를 읽기 위해서는 다음의 코드를 사용할 수 있다.
unsigned char ucDataMSB=0;        // define variable for MSB data to be stored after the read
unsigned char ucDataLSB=0;        // define variable for LSB data to be stored after the read
unsigned char fail = 0;

Start();                          // Generate Start Condition
fail |= !WriteData(0xB0);         // Write the slave address, LSbit=0 to signify write byte
fail |= !WriteData(0x08);         // Write the memory address of the DAC register
Start();                          // Generates a re-start condition
WriteData(0xB1);                  // Writes the slave address, LSbit=1 to signify read byte
ReadDataAck(&ucDataMSB);          // Reads the MSB of DAC and sends acknowledgement to the slave
ReadDataNack(&ucDataLSB);         // Reads the LSB of DAC and does not acknowledge the slave
Stop();                           // Generates Stop Condition
if(fail ==1)
      Error("Device failed to acknowledge during read attempt");

Windows 병렬 포트 2-wire 소프트웨어

그림 1에 예시되어 있는 소프트웨어는 "2wire.c" 소프트웨어의 기본 기능을 구현하기 위해 작성되었으며, AN3230 하드웨어 디버깅에도 사용 가능하다.

그림 1. 2선식 소프트웨어에 대한 Windows 병렬 포트의 예.
그림 1. 2-wire 소프트웨어에 대한 Windows 병렬 포트의 예.

이 소프트웨어는 Parallel Port Select 섹션에 열거된 3병렬 포트 모두와 통신 가능하다.

2-Wire Functions 섹션의 버튼은 단순히 대화 상자 내의 파라미터를 수용하고 이에 상응하는 "2wire.c" 기능을 호출한다. Start는 시작 조건을 생성하고 Write Data는 버튼 우측 상자 내의 파라미터를 취하여 이를 슬레이브에 기록한다. 두 개의 읽기 버튼은 모두 슬레이브로부터 바이트를 읽지만 하나는 데이터 전송을 승인하고 다른 하나는 데이터 전송을 승인하지 않는다. Stop 버튼은 정지 조건을 생성한다. Write Byte 버튼은 0으로 설정된 LSbit를 갖는 2-wire Device 어드레스 상자 내에 이 값을 기록하며 Read Byte 버튼은 1로 설정된 LSbit를 갖는 동일한 값을 기록한다. 이 버튼들은 한 부분이 액세스될 때마다 매번 슬레이브 어드레스에 대해 값들 중 하나를 빈번하게 변경할 필요없이 데이터 및 어드레스 용으로 Write Data 버튼이 사용되도록 한다.

One-Byte writes는 단일 데이터 바이트(Data)를 Addr 상자에 열거된 메모리 어드레스의 2-wire Device Address 상자에 열거된 슬레이브 어드레스로 전송한다.

One-Byte reads는 Addr 상자에 열거된 메모리 어드레스의 2-wire Device Address 상자에 열거된 슬레이브 어드레스로부터 1 바이트를 읽는다. 대화는 승인없이 읽고 1 바이트 만을 읽고 있다는 것을 표시한다.

Two-Byte writes는 Addr 상자에 열거된 메모리 어드레스의 2-wire Device Address 상자에 열거된 슬레이브 어드레스로 2 데이터 바이트 (Data MSB 및 Data LSB)를 전송한다.

Two-Byte reads는Addr 상자에 열거된 메모리 어드레스의 2-wire Device Address 상자에 열거된 슬레이브 어드레스의 슬레이브로부터 2 데이터 바이트를 읽는다. 대화는 첫 번째 데이터 바이트 읽기를 승인하고 두 번째 데이터 바이트 읽기를 승인하지 않는다.

Find Address(es) 버튼은 2-wire 버스 (00h-FEh) 상의 모든 슬레이브 어드레스에 쓰기를 하며, 슬레이브를 가질 어드레스 결정을 승인하는 어드레스를 확인한다. 승인과 함께 반응하는 어드레스는 Status 상자에 열거된다. 이 버튼은 AN3230 하드웨어가 정확하게 설정되었는지, 또 데이터 수신이 가능한 슬레이브가 2-wire 버스에 연결되었는지를 결정하는데 사용될 수 있다.

Comm. Delay 버튼은 우측의 정수를 인수로 갖는 ChangeDelayCount() 기능을 호출한다. 이것은 2-wire 인터페이스의 타이밍 조정에 사용될 수 있다.

LED 버튼은 AN3230 회로 내에 예시된 표시 LED를 동작 이네이블 또는 디세이블하게 만든다. Strobe enable은 소프트웨어가 1 및 2 바이트 읽기/쓰기 기능 전에 LED 핀을 하이로 설정하게 하며, 통신 종료 후에는 LED 핀을 로우로 설정한다.

Test 버튼은 루프 백 시험을 수행하며 SDA 출력이 로우로 설정되어 있을 때 SDA 입력이 로우를 읽고 하이 조건에서도 이와 같이 동작하는지를 확인한다. 이 버튼은 또한 LED 핀이 로우 및 하이로 설정 가능한지 시험하며 사용자가 LED의 온 및 오프 상태로 깜박임을 볼 수 있도록 충분히 긴 시간 동안 멈춘다.

위에 열거된 모든 명령은 Status 윈도우에서 사용자 피드백을 제공한다.

결론

본 애플리케이션 노트는 "2wire.c" 파일에 제공된 소스 코드를 갖춘 AN3230에 예시된 병렬 포트 2-wire 회로를 사용한 2-wire 디바이스 프로그래밍의 용이성을 예시하였다. "2wire.c"의 루틴은 시그널링 기능을 수행하는데 이를 통해 프로그래머는 인터페이스 타이밍 조정과, 2-wire 디바이스의 데이터 시트에 요약된 바와 같이 적절한 통신 순서대로 2-wire 루틴을 호출하는데 집중할 수 있다.

"2wire.c" 용 소스 코드는 Dallas Semiconductor의 FTP 사이트에서 다운로드 가능하다.

http://files.dalsemi.com/system_extension/AppNotes/

본 애플리케이션 노트와 관련된 문의사항은 Dallas Semiconductor Mixed Signal Applications 그룹으로 보내주십시오. .

부록 A - 소스 코드

///////////////////////////////////////////////////////////////////////////////
// 2-Wire Parallel Port Functions for Win95/Win98
//
// Dallas Semiconductor (C) 2004
//
// This software is free and available "as is" for use by Dallas
// Semiconductor's customers. Dallas Semiconductor accepts no liability for any
// damages the software may cause. Use at your own risk.
//
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// Include Files

#include 


///////////////////////////////////////////////////////////////////////////////
// Definitions

#define LPT1 0x378
#define LPT2 0x3BC
#define LPT3 0x278
#define LPT4 0x378       // not implemented - set to LPT1 for now,
                                     // returns error code if assigned


///////////////////////////////////////////////////////////////////////////////
// Global Variables
unsigned short LPTData;           // parallel port base address
unsigned short LPTStatus;         // LPT Base Address + 1
unsigned short LPTControl;        // LPT Base Address + 2

unsigned char ucDeviceAddress;    // 2-Wire device address for
                                  // multibyte communication

int   DCNT = 1000;                // Delay Count...Sets the delay time used for SDA/SCL
      // during 2-Wire communication. DCNT=25 works well for MY P3 600MHz
      // Laptop. 1000 is the default value providing some guardband for
      // faster machines so they do not attempt to talk faster than the
      // 400kHz rating of the 2-Wire interface. This value can be changed
      // high or lower to find the best value using ChangeDelayCount();


///////////////////////////////////////////////////////////////////////////////
// Function Prototypes

// Parallel Port Utility Functions

void DelayASMx10(int i);                 // delays 10 clock cycles per i
int ChangeDelayCount(int iCount);        // changes i for DelayASMx10
int ParPortSelect(int iLPT);             // sets access variables to specified
      // port. Must be called before any other parallel port functions

// Basic 2-Wire Functions
int Start();                                    // 2-Wire Start Command
int Stop();                                     // 2-Wire Stop Command
int WriteData(unsigned char ucDATA);            // 2-Wire Write Byte
int ReadDataNack(unsigned char *ucDATA);        // 2-Wire Read Byte with NACK
int ReadDataAck(unsigned char *ucDATA);         // 2-Wire Read Byte with ACK

// MultiByte Write/Read 2-Wire Functions

int SetSlaveAddress(unsigned char ucADDR);      // sets slave address for
      // WriteBytes and ReadBytes Commands
int WriteBytes(int iCount, unsigned char ucMemAddr, unsigned char ucData[256]);
      // Write upto 256 bytes to device address set by SetSlaveAddress.
int ReadBytes(int iCount, unsigned char ucMemAddr, unsigned char ucData[256]);
      // Reads upto 256 bytes from device address set by SetSlaveAddress.

// Utility 2-Wire Functions

int ResetBus();                   // clocks SCL 9 times and performs stop to "free"
                                  // SDA and SCL for the software master.
int SetStrobe();                  // sets strobe pin for debugging (AN3230)
int ClearStrobe();                // clears strobe pin for debugging (AN3230)

// Enable / Disable LED on AN3230 circuit

int EnableLED();                  // enables LED in AN3230 circuit
int DisableLED();                 // disables LED in AN3230 circuit


///////////////////////////////////////////////////////////////////////////////
// Function Definitions

void DelayASMx10(int iDelayCount) // delays 10 NOPs iDelayCount times.
{ // See DCNT description in variable declarations for more information
      int iLoopCount = 1;
      for (; iLoopCount<=iDelayCount; iLoopCount++)
      {
            __asm
            {
                  NOP
                  NOP
                  NOP
                  NOP
                  NOP
                  NOP
                  NOP
                  NOP
                  NOP
                  NOP
            }
      }
}
int ParPortSelect(int iLPT)
{     // Selects the parallel port used for operation.
      if(iLPT == 1)
      {
            LPTData = LPT1;
            LPTStatus = LPTData + 1;     // LPT Data + 1
            LPTControl = LPTData + 2;    // LPT Data + 2
            return 1;                          // legal port value
      }
      else if(iLPT == 2)
      {
            LPTData = LPT2;
            LPTStatus = LPTData + 1;     // LPT Data + 1
            LPTControl = LPTData + 2;    // LPT Data + 2
            return 1;                          // legal port value
      }
      else if(iLPT == 3)
      {
            LPTData = LPT3;              // legal port value
            LPTStatus = LPTData + 1;     // LPT Data + 1
            LPTControl = LPTData + 2;    // LPT Data + 2
            return 1;                          // legal port value
      }
      else if(iLPT == 4)
      {
      LPTData = LPT4;                    // not implemented,but defined as LPT1
      LPTStatus = LPTData + 1;           // LPT Data + 1
      LPTControl = LPTData + 2;          // LPT Data + 2
      return 0;                          // return 0 for unimplemented value
      }
      else
            return 0;                    // illegal value, return 0 for error
      }

int ChangeDelayCount(int iCount)         // changes i for DelayASMx10
{     // Changes the DCNT to increase/decreas delays between 2-Wire edges
      DCNT = iCount;       // See DCNT declaration in variable declarations.
      return 1;
}
int EnableLED()
{     // Enables the LED shown on the AN3230 circuit
      unsigned char Data;

      // Read original value of control byte
      Data = _inp(LPTControl);

      // Turn LED on
      _outp(LPTControl, (Data & 0xF7));        // Clear P17 to turn LED on
      return 1;
}

int DisableLED()
{     // Disables the LED shown on the AN3230 circuit
      unsigned char Data;

      // Read original value of control byte
      Data = _inp(LPTControl);

      // Turn LED on
      _outp(LPTControl, (Data | 0x08));        // Clear P17 to turn LED on
      return 1;
}

int Start()
{     // Performs 2-Wire start condition
      unsigned char Data;

      // Read original value of data byte
      Data = _inp(LPTData);

      // Ensure SDA and SCL are high

      // Set SDA high (write D1 to a 0)
      Data = Data & 0xFD;
      _outp(LPTData, Data);
      DelayASMx10(DCNT);

      // Set SCL high (write D0 to a 0)
      Data = Data & 0xFE;
      _outp(LPTData, Data);
      DelayASMx10(DCNT);

// Bring SDA low, then bring SCL low

      // Bring SDA low (write D1 to a 1)
      Data = Data | 0x02;
      _outp(LPTData, Data);
      DelayASMx10(DCNT);

      // Bring SCL low (write D0 to a 1)
      Data = Data | 0x01;
      _outp(LPTData, Data);
      DelayASMx10(DCNT);

      return 1;
}

int Stop()
{     // Performs 2-Wire stop condition
      unsigned char Data;

      // Read original value of data byte
      Data = _inp(LPTData);
      // Ensure SDA and SCL are low

      // Make SCL low (write D0 to a 1)
      Data = Data | 0x01;
      _outp(LPTData, Data);
      DelayASMx10(DCNT);

      // Make SDA low (write D1 to a 1)
      Data = Data | 0x02;
      _outp(LPTData, Data);
      DelayASMx10(DCNT);

      // Bring SCL high, then bring SDA high

      // Bring SCL high (write D0 to a 0)
      Data = Data & 0xFE;
      _outp(LPTData, Data);
      DelayASMx10(DCNT);

      // Bring SDA high (write D1 to a 0)
      Data = Data & 0xFD;
      _outp(LPTData, Data);
      DelayASMx10(DCNT);

      return 1;
}

int WriteData(unsigned char ucDATA)
{
      // This routine writes 1 data byte and checks for slave acknoledgement
      // Assumes Start already issued and SDA and SCL are both low

      unsigned char shiftbyte, statusbyte;
      int i;
      unsigned char ucTempData;

      shiftbyte = ucDATA;
      ucTempData = _inp(LPTData);

      // loop for 8 bits
      for (i=0; i<8; i++)
      {
            if (shiftbyte & 0x80)
            {
                  // Set SDA high (D1=0)
                  ucTempData = ucTempData & 0xFD;
                  _outp(LPTData, ucTempData);
                  DelayASMx10(DCNT/2);

                  // Clock SCL (D0=0, D0=1)
                  ucTempData = ucTempData & 0xFE;
                  _outp(LPTData, ucTempData);
                  DelayASMx10(DCNT/2);
                  ucTempData = ucTempData | 0x01;
                  _outp(LPTData, ucTempData);
                  DelayASMx10(DCNT/2);

                  // Bring SDA low (D1=1)
                  ucTempData = ucTempData | 0x02;
                  _outp(LPTData, ucTempData);
                  DelayASMx10(DCNT/2);

            }
            else
            {
                  // Bring SDA low (D1=1)
                  ucTempData = ucTempData | 0x02;
                  _outp(LPTData, ucTempData);
                  DelayASMx10(DCNT/2);

                  // Clock SCL (D0=0, D0=1)
                  ucTempData = ucTempData & 0xFE;
                  _outp(LPTData, ucTempData);
                  DelayASMx10(DCNT/2);
                  ucTempData = ucTempData | 0x01;
                  _outp(LPTData, ucTempData);
                  DelayASMx10(DCNT/2);
            }
            shiftbyte = shiftbyte << 1;
      }

      // Release SDA (D1=0)
      ucTempData = ucTempData & 0xFD;
      _outp(LPTData, ucTempData);
      DelayASMx10(DCNT/2);

      // Check if slave ACKs

      // Bring SCL high (D0=0)
      ucTempData = ucTempData & 0xFE;
      _outp(LPTData, ucTempData);
      DelayASMx10(DCNT/2);

      // Read SDA
      statusbyte = _inp(LPTStatus);

      // Bring SCL low (D0=1)
      ucTempData = ucTempData | 0x01;
      _outp(LPTData, ucTempData);
      DelayASMx10(DCNT/2);

      // Display ACK
      if (statusbyte & 0x20)
      {  // Slave ACK'd
            return 1;
      }
      else
      {  // Slave did not ACK
            return 0;
      }
}

int ReadDataNack(unsigned char *ucDATA)
{     // This routine reads one byte and NACKs. It assumes SDA and SCL
      // are low becuase a start condition/communication has already occured
      unsigned char shiftbyte;
      int i;
      int ucTempData, Status;

      shiftbyte = 0x00;

      // Ensure SDA is released (D1=0) and SCL is low (D0=1)
      ucTempData = _inp(LPTData);
      ucTempData = ((ucTempData & 0xFD) | 0x01);
      _outp(LPTData, ucTempData);
      DelayASMx10(DCNT/2);

      // loop for 8 bits
      for (i=0; i<8; i++)
      {     // Clock in one bit
            // Bring SCL high (D0=0)
            ucTempData = ucTempData & 0xFE;
            _outp(LPTData, ucTempData);
            DelayASMx10(DCNT/2);

            // Read in SDA
            Status = _inp(LPTStatus);

            // Bring SCL low (D0=1)
            ucTempData = ucTempData | 0x01;
            _outp(LPTData, ucTempData);
            DelayASMx10(DCNT/2);

            if (Status & 0x20)
            {     // Bit is high (although inverted through the 7405)
                  shiftbyte = shiftbyte << 1;
                  shiftbyte = shiftbyte & 0xFE; // Just in case compiler does not shift in 0
            }
            else
            {  // Bit is low (although inverted through the 7405)
                  shiftbyte = shiftbyte << 1;
                  shiftbyte = shiftbyte | 0x01;
            }
      }

      // NACK - Release SDA and clock SCL
      // Release SDA high (D1=0)
      ucTempData = ucTempData & 0xFD;
      _outp(LPTData, ucTempData);
      DelayASMx10(DCNT/2);

      // Bring SCL high (D0=0)
      ucTempData = ucTempData & 0xFE;
      _outp(LPTData, ucTempData);
      DelayASMx10(DCNT/2);

      // Bring SCL low (D0=1)
      ucTempData = ucTempData | 0x01;
      _outp(LPTData, ucTempData);
      DelayASMx10(DCNT/2);

      *ucDATA = shiftbyte;

      return 1;
}

int ReadDataAck(unsigned char *ucDATA)
{
      // Read 8 bits of data and ACK
      unsigned char shiftbyte;
      int i;
      int ucTempData, Status;

      shiftbyte = 0x00;

      // Ensure SDA is released (D1=0) and SCL is low (D0=1)
      ucTempData = _inp(LPTData);
      ucTempData = ((ucTempData & 0xFD) | 0x01);
      _outp(LPTData, ucTempData);
      DelayASMx10(DCNT/2);

      // loop for 8 bits
      for (i=0; i<8; i++)
      {     // Clock in one bit
            // Bring SCL high (D0=0)
            ucTempData = ucTempData & 0xFE;
            _outp(LPTData, ucTempData);
            DelayASMx10(DCNT/2);

            // Read in SDA
            Status = _inp(LPTStatus);

            // Bring SCL low (D0=1)
            ucTempData = ucTempData | 0x01;
            _outp(LPTData, ucTempData);
            DelayASMx10(DCNT/2);

            if (Status & 0x20)
            {     // Bit is high (although inverted through the 7405)
                  shiftbyte = shiftbyte << 1;
                  shiftbyte = shiftbyte & 0xFE;   // Just in case compiler does not shift in 0
            }

            else
            {     // Bit is low (although inverted through the 7405)
                  shiftbyte = shiftbyte << 1;
                  shiftbyte = shiftbyte | 0x01;
            }
      }

      // ACK - Pull SDA low and clock SCL, then release SDA
      // Pull SDA low (D1=1)
      ucTempData = ucTempData | 0x02;
      _outp(LPTData, ucTempData);
      DelayASMx10(DCNT/2);

      // Bring SCL high (D0=0)
      ucTempData = ucTempData & 0xFE;
      _outp(LPTData, ucTempData);
      DelayASMx10(DCNT/2);

      // Bring SCL low (D0=1)
      ucTempData = ucTempData | 0x01;
      _outp(LPTData, ucTempData);
      DelayASMx10(DCNT/2);

      // Release SDA (D1=0)
      ucTempData = ucTempData & 0xFD;
      _outp(LPTData, ucTempData);
      DelayASMx10(DCNT/2);

      *ucDATA = shiftbyte;

      return 1;
}

int SetSlaveAddress(unsigned char ucADDR)    // sets slave address for
{     // WriteBytes and ReadBytes Commands
      ucDeviceAddress = ucADDR & 0xFE;
      return 1;
}
int WriteBytes(int iCount, unsigned char ucMemAddr, unsigned char ucData[256])
{     // Write upto 256 bytes to device address set by SetSlaveAddress.
      int fail = 0;
      int i;

      fail |= !Start();
      fail |= !WriteData((unsigned char)((long)ucDeviceAddress & 0xFE));
      fail |= !WriteData(ucMemAddr);
      for(i = 0; i 

	


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


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



추가 정보  APP 3315: May 04, 2005
DS1077 EconOscillator™/분배기 전체 데이터 시트
(PDF, 316kB)
무료 샘플
DS1085 EconOscillator 주파수 합성기 전체 데이터 시트
(PDF, 356kB)
무료 샘플
DS1086 확산 스펙트럼 EconOscillator 전체 데이터 시트
(PDF, 240kB)
무료 샘플
DS1803 주소지정이 가능한 듀얼 디지털 포텐쇼미터 전체 데이터 시트
(PDF, 304kB)
무료 샘플
DS1807 주소지정이 가능한 듀얼 오디오 테이퍼 포텐쇼미터 전체 데이터 시트
(PDF, 472kB)
무료 샘플
DS1845 듀얼 NV 포텐쇼미터 및 메모리 전체 데이터 시트
(PDF, 204kB)
무료 샘플
DS1855 듀얼 비휘발성 디지털 포텐쇼미터 및 보안 메모리 전체 데이터 시트
(PDF, 280kB)
무료 샘플
DS1858 3개 모니터를 가진 듀얼 온도 제어 저항기 전체 데이터 시트
(PDF, 428kB)
무료 샘플
DS1859 내부적으로 캘리브레이션된 모니터가 내장된 듀얼 온도 제어 저항기 전체 데이터 시트
(PDF, 812kB)
무료 샘플
DS3903 트리플, 128단계 NV 디지털 포텐쇼미터 전체 데이터 시트
(PDF, 632kB)
무료 샘플
DS3904 트리플, 128단계, NV 가변 디지털 저항/스위치 전체 데이터 시트
(PDF, 392kB)
무료 샘플
DS4510 비휘발성 메모리 및 프로그래밍 가능한 I/O가 내장된 CPU 감시소자 전체 데이터 시트
(PDF, 592kB)
무료 샘플
 

다운로드, PDF 형식다운로드, PDF 형식 (110kB)
 AN3315, AN 3315, APP3315, Appnote3315, Appnote 3315



         



   Copyright © 2008 by Maxim Integrated Products, Dallas Semiconductor    법적 고지    개인정보보호 정책