⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2cdllfuncunit.pas

📁 Delphi源码,实现I2C接口,非常适合硬件开发人员
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit I2CDLLFuncUnit;

interface

uses
  Windows, Classes, SysUtils, DateUtils, Dialogs, Controls, FT2232CI2CUnit;

procedure DisplayFT2232CI2CDllError(ProgFunctionName, DllFunctionName: String; ftStatus: FTC_STATUS);
function GetI2CDeviceNames(var DeviceNames: TStringList): Boolean;
function Read_24C02_Device(DevAddress: Integer; bBlockRead: Boolean; var DisplayLines: TStringList): FTC_STATUS;
function Read_M24C64_Device(DevAddress: Integer; bBlockRead: Boolean; var DisplayLines: TStringList): FTC_STATUS;
function Read_DS1621_Device(DevAddress: Integer; var DisplayLines: TStringList): FTC_STATUS;
function Read_M41T81_Device(DevAddress: Integer; bBlockRead: Boolean; var DisplayLines: TStringList): FTC_STATUS;
procedure Read_External_Device(DeviceName: String; DeviceIndex, ExternalDeviceIndex: Integer; ClockDivisor: Dword; DevAddress: Integer; bBlockRead: Boolean; var DisplayLines: TStringList);
function  Program_M24C64_Device(DevAddress: Integer; bErase, bPageWrite: Boolean; ByteValue: String; var DisplayLines: TStringList): FTC_STATUS;
function  Program_24C02_Device(DevAddress: Integer; bErase, bPageWrite: Boolean; ByteValue: String; var DisplayLines: TStringList): FTC_STATUS;
function  Program_DS1621_Device(DevAddress: Integer; var DisplayLines: TStringList): FTC_STATUS;
function  Program_M41T81_Device: FTC_STATUS;
function  Program_External_Device(DeviceName: String; DeviceIndex, ExternalDeviceIndex: Integer; ClockDivisor: Dword;
                                  DevAddress: Integer; bErase, bPageWrite: Boolean; ByteValue: String;
                                  var DisplayLines: TStringList): Boolean;

var
  FT2232CI2C: TFT2232CI2C;
  FT2232CI2CDll: Boolean;
  ftHandle: Dword;
  LocationIDs : array[0..19] of Dword;
  CommsMode: Dword;

const
  FrequencyLabelDefaultText = 'Freq';

  MaxFreq24C02ClockDivisor = 60;   // equivalent to 100KHz
  MaxFreqM24C64ClockDivisor = 15;  // equivalent to 400KHz
  MaxFreqDS1621ClockDivisor = 15;  // equivalent to 400KHz
  MaxFreqM41T81ClockDivisor = 15;  // equivalent to 400KHz

  MaxI2C24C02ChipSizeInBytes = 256;
  MaxI2CM24C64ChipSizeInBytes = 512; //8192;
  MaxI2M41T81ChipSizeInBytes = 20;

  Num24C02Pages = 1;
  Num24C02BytesPerPage = 2;
  NumM24C64Pages = 1;
  NumM24C64BytesPerPage = 32;

  NumI2CChips = 4;
  I2CChips: array[0..(NumI2CChips - 1)] of String = ('24C02', 'M24C64', 'DS1621', 'M41T81');
  
  I2C24C02ChipIndex = 0;
  I2CM24C64ChipIndex = 1;
  I2CDS1621ChipIndex = 2;
  I2CM41T81ChipIndex = 3;

  M41T81DevAddress = $D0;  

implementation

uses DSI2C, DateTimeDialogUnit;

procedure DisplayFT2232CI2CDllError(ProgFunctionName, DllFunctionName: String; ftStatus: FTC_STATUS);
var
  ErrorMsg: TErrorMessage;
begin
  FT2232CI2C.GetErrorCodeString(ENGLISH, ftStatus, @ErrorMsg, MAX_NUM_ERROR_MESSAGE_CHARS);

  ShowMessage('Program function name = ' + ProgFunctionName +
              ', FT2232CI2C Dll function name = ' + DllFunctionName +
              ', Error message = ' + ErrorMsg);
end;

function GetI2CDeviceNames(var DeviceNames: TStringList): Boolean;
var
  ftStatus: FTC_STATUS;
  NumDevices, DeviceIndex: Dword;
  DeviceName: TDeviceName;
  LocationID: Dword;
begin
  if (FT2232CI2CDll = True) then
  begin
    NumDevices := 0;
    ftStatus := FT2232CI2C.GetNumDevices(@NumDevices);

    if (ftStatus = FTC_SUCCESS) then
    begin
      if (NumDevices > 0) then
      begin
        DeviceIndex := 0;
        repeat
          ftStatus := FT2232CI2C.GetDeviceNameLocID(DeviceIndex, @DeviceName, MAX_NUM_DEVICE_NAME_CHARS, @LocationID);

          DeviceNames.Add(DeviceName);

          LocationIDs[DeviceIndex] := LocationID;

          Inc(DeviceIndex);
        until ((DeviceIndex >= NumDevices) or (ftStatus <> FTC_SUCCESS));

        if (ftStatus <> FTC_SUCCESS) then
          DisplayFT2232CI2CDllError('GetNames', 'GetDeviceNameLocID', ftStatus);
      end
      else
        ShowMessage('No FT2232C dual types devices connected.');
    end
    else
      DisplayFT2232CI2CDllError('GetNames', 'GetNumDevices', ftStatus);
  end;

  if (ftStatus = FTC_SUCCESS) then
    Result := True
  else
    Result := False;
end;

function Read_24C02_Device(DevAddress: Integer; bBlockRead: Boolean; var DisplayLines: TStringList): FTC_STATUS;
var
  ftStatus: FTC_STATUS;
  LocationAddress: Dword;
  ControlDevAddress, ControlLocAddress: Byte;
  WriteControlBuffer: WriteControlByteBuffer;
  ReadDataBuffer: ReadDataByteBuffer;
begin
  LocationAddress := 0;

  //passed := Write_Location(j,DevAddress,j);
  // set up device address
  ControlDevAddress := (DevAddress shl 1);
  ControlDevAddress := (ControlDevAddress or $A1);
  ControlDevAddress := (ControlDevAddress and $FF);

  if (not bBlockRead) then
  begin
    repeat
      ControlLocAddress := (LocationAddress and $FF);

      WriteControlBuffer[0] := ControlDevAddress;
      WriteControlBuffer[1] := ControlLocAddress;

      ftStatus := FT2232CI2C.Read(fthandle, @WriteControlBuffer, 2, True, 20,
                                  BYTE_READ_TYPE, @ReadDataBuffer, 1);

      if (ftStatus = FTC_SUCCESS) then
        DisplayLines.Add('Loc Addr : ' + HexWrdToStr(LocationAddress) + ' Data : ' + HexWrdToStr(ReadDataBuffer[0]))
      else
        DisplayFT2232CI2CDllError('Read_24C02_Device', 'Byte Read', ftStatus);

      Inc(LocationAddress);
    until ((LocationAddress >= MaxI2C24C02ChipSizeInBytes) or (ftStatus <> FTC_SUCCESS))
  end
  else
  begin
    ControlLocAddress := (LocationAddress and $FF);

    WriteControlBuffer[0] := ControlDevAddress;
    WriteControlBuffer[1] := ControlLocAddress;

    ftStatus := FT2232CI2C.Read(fthandle, @WriteControlBuffer, 2, True, 20,
                                BLOCK_READ_TYPE, @ReadDataBuffer, MaxI2C24C02ChipSizeInBytes);

    if (ftStatus = FTC_SUCCESS) then
    begin
      LocationAddress := 0;

      repeat
        DisplayLines.Add('Loc Addr : ' + HexWrdToStr(LocationAddress) + ' Data : ' + HexWrdToStr(ReadDataBuffer[LocationAddress]) );

        Inc(LocationAddress);
      until (LocationAddress >= MaxI2C24C02ChipSizeInBytes);
    end
    else
      DisplayFT2232CI2CDllError('Read_24C02_Device', 'Block Read', ftStatus);
  end;
  
  Result := ftStatus;
end;

function Read_M24C64_Device(DevAddress: Integer; bBlockRead: Boolean; var DisplayLines: TStringList): FTC_STATUS;
var
  ftStatus: FTC_STATUS;
  LocationAddress: Dword;
  ControlDevAddress, ControlLocAddress0, ControlLocAddress1: Byte;
  WriteControlBuffer: WriteControlByteBuffer;
  ReadDataBuffer: ReadDataByteBuffer;
begin
  LocationAddress := 0;

  //passed := Write_Location(j,DevAddress,j);
  // set up device address
  ControlDevAddress := (DevAddress shl 1);
  ControlDevAddress := (ControlDevAddress or $A1);
  ControlDevAddress := (ControlDevAddress and $FF);

  if (not bBlockRead) then
  begin
    repeat
      // shift down by 8 bits
      ControlLocAddress1 := ((LocationAddress SHR 8) and $FF);
      ControlLocAddress0 := (LocationAddress and $FF);

      WriteControlBuffer[0] := ControlDevAddress;
      WriteControlBuffer[1] := ControlLocAddress1;
      WriteControlBuffer[2] := ControlLocAddress0;

      ftStatus := FT2232CI2C.Read(fthandle, @WriteControlBuffer, 3, True, 20,
                                  BYTE_READ_TYPE, @ReadDataBuffer, 1);

      if (ftStatus = FTC_SUCCESS) then
        DisplayLines.Add('Loc Addr : ' + HexWrdToStr(LocationAddress) + ' Data : ' + HexWrdToStr(ReadDataBuffer[0]) )
      else
        DisplayFT2232CI2CDllError('Read_M24C64_Device', 'Byte Read', ftStatus);

      Inc(LocationAddress);
    until ((LocationAddress >= MaxI2CM24C64ChipSizeInBytes) or (ftStatus <> FTC_SUCCESS));
  end
  else
  begin
    ControlLocAddress0 := (LocationAddress and $FF);

    WriteControlBuffer[0] := ControlDevAddress;
    WriteControlBuffer[1] := 0;
    WriteControlBuffer[2] := ControlLocAddress0;

    ftStatus := FT2232CI2C.Read(fthandle, @WriteControlBuffer, 3, True, 20, BLOCK_READ_TYPE,
                                @ReadDataBuffer, MaxI2CM24C64ChipSizeInBytes);

    if (ftStatus = FTC_SUCCESS) then
    begin
      LocationAddress := 0;

      repeat
        DisplayLines.Add('Loc Addr : ' + HexWrdToStr(LocationAddress) + ' Data : ' + HexWrdToStr(ReadDataBuffer[LocationAddress]) );

        Inc(LocationAddress);
      until (LocationAddress >= MaxI2CM24C64ChipSizeInBytes);
    end
    else
      DisplayFT2232CI2CDllError('Read_M24C64_Device', 'Block Read', ftStatus);
  end;

  Result := ftStatus;
end;

function Read_DS1621_Device(DevAddress: Integer; var DisplayLines: TStringList): FTC_STATUS;
var
  ftStatus: FTC_STATUS;
  ControlDevAddress: Byte;
  WriteControlBuffer: WriteControlByteBuffer;
  ReadDataBuffer: ReadDataByteBuffer;
  TemperatureC, TemperatureHalfC: Byte;
  LoopCntr: Dword;
begin
  //passed := Write_Location(j,DevAddress,j);
  // set up device address
  ControlDevAddress := (DevAddress shl 1);
  ControlDevAddress := (ControlDevAddress or $91);
  ControlDevAddress := (ControlDevAddress and $FF);

  WriteControlBuffer[0] := ControlDevAddress;
  WriteControlBuffer[1] := $AA;

  ReadDataBuffer[1] := 77;

  LoopCntr := 0;
  repeat
    ftStatus := FT2232CI2C.Read(fthandle, @WriteControlBuffer, 2, True, 20, BLOCK_READ_TYPE, //BYTE_READ_TYPE,
                                @ReadDataBuffer, 2);

    if (ftStatus = FTC_SUCCESS) then
    begin
      TemperatureC := ReadDataBuffer[0];

      TemperatureHalfC := 0;
      if ((ReadDataBuffer[1] and $80) = $80) then
        TemperatureHalfC := 5;

      if (TemperatureC < 127) then
        DisplayLines.Add('Temperature = +' + IntToStr(TemperatureC) + '.' +
                         IntToStr(TemperatureHalfC) + 'C')
      else
      begin
        TemperatureC := ((255 - TemperatureC) + 1);

        if (TemperatureHalfC = 5) then
          TemperatureC := TemperatureC - 1;

        DisplayLines.Add('Temperature = -' + IntToStr(TemperatureC) + '.' +
                         IntToStr(TemperatureHalfC) + 'C')
      end;
    end
    else
      DisplayFT2232CI2CDllError('Read_DS1621_Device', 'Read', ftStatus);

    Sleep(500);
    Inc(LoopCntr);
  until ((LoopCntr >= 20) or (ftStatus <> FTC_SUCCESS));

  Result := ftStatus;
end;

function Read_M41T81_Device(DevAddress: Integer; bBlockRead: Boolean; var DisplayLines: TStringList): FTC_STATUS;
var
  ftStatus: FTC_STATUS;
  LocationAddress: Dword;
  ControlDevAddress: Byte;
  WriteControlBuffer: WriteControlByteBuffer;
  ReadDataBuffer: ReadDataByteBuffer;
  ReadData: array[0..(MaxI2M41T81ChipSizeInBytes - 1)] of Byte;
  TimeSeconds, TimeMinutes, TimeHours, DayOfWeek, DayOfMonth, MonthOfYear, YearOfCentury: Word;
  ReadDateTime: TDateTime;
begin
  LocationAddress := 0;

  ControlDevAddress := (M41T81DevAddress or $01); // Set Read/Write mode bit to 1 ie Read
  ControlDevAddress := (ControlDevAddress and $FF);

  if (not bBlockRead) then
  begin
    WriteControlBuffer[0] := ControlDevAddress;

    repeat
      WriteControlBuffer[1] := LocationAddress; // Start at address 0

      ftStatus := FT2232CI2C.Read(fthandle, @WriteControlBuffer, 2, True, 20,
                                  BYTE_READ_TYPE, @ReadDataBuffer, 1);

      if (ftStatus = FTC_SUCCESS) then
        ReadData[LocationAddress] := ReadDataBuffer[0]
      else
        DisplayFT2232CI2CDllError('Read_M41T81_Device', 'Byte Read', ftStatus);

      Inc(LocationAddress);
    until ((LocationAddress >= MaxI2M41T81ChipSizeInBytes) or (ftStatus <> FTC_SUCCESS));
  end
  else
  begin
    WriteControlBuffer[0] := ControlDevAddress;
    WriteControlBuffer[1] := 0;

    ftStatus := FT2232CI2C.Read(fthandle, @WriteControlBuffer, 2, True, 20, BLOCK_READ_TYPE,
                                @ReadDataBuffer, MaxI2M41T81ChipSizeInBytes);

    if (ftStatus = FTC_SUCCESS) then
    begin
      LocationAddress := 0;

      repeat
        ReadData[LocationAddress] := ReadDataBuffer[LocationAddress];

        Inc(LocationAddress);
      until (LocationAddress >= MaxI2M41T81ChipSizeInBytes);
    end
    else
      DisplayFT2232CI2CDllError('Read_M41T81_Device', 'Block Read', ftStatus);
  end;

  if (ftStatus = FTC_SUCCESS) then
  begin
    for LocationAddress := 0 to (MaxI2M41T81ChipSizeInBytes - 1) do
      DisplayLines.Add('Loc Addr : ' + HexWrdToStr(LocationAddress) + ' Data : ' + HexWrdToStr(ReadData[LocationAddress]));

    TimeSeconds := ReadData[$01];
    TimeSeconds := (((TimeSeconds and $F0) SHR 4) * 10);
    TimeSeconds := TimeSeconds + (ReadData[$01] and $0F);
    TimeMinutes := ReadData[$02];
    TimeMinutes := (((TimeMinutes and $F0) SHR 4) * 10);
    TimeMinutes := TimeMinutes + (ReadData[$02] and $0F);
    TimeHours := ReadData[$03];
    TimeHours := (((TimeHours and $F0) SHR 4) * 10);
    TimeHours := TimeHours + (ReadData[$03] and $0F);
    DayOfWeek := ReadData[$04];
    DayOfMonth := ReadData[$05];
    DayOfMonth := (((DayOfMonth and $F0) SHR 4) * 10);
    DayOfMonth := DayOfMonth + (ReadData[$05] and $0F);
    MonthOfYear := ReadData[$06];
    MonthOfYear := (((MonthOfYear and $F0) SHR 4) * 10);
    MonthOfYear := MonthOfYear + (ReadData[$06] and $0F);
    YearOfCentury := 2000 + ReadData[$07];

    ReadDateTime := EncodeDateTime(YearOfCentury, MonthOfYear, DayOfMonth, TimeHours, TimeMinutes, TimeSeconds, 0);
    DisplayLines.Add(FormatDateTime('dddd, d mmmm, yyyy, " " h:mm:ss am/pm', ReadDateTime));
  end;
  
  Result := ftStatus;
end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -