SysI2CWrRd, escribe / lee en el bus de extensión I2C

Lista

Esta página es parte del Manual de programación IEC 61131-3. Ir al índice.

Esta función gestiona la escritura/lectura en el bus I2C de extensión. El uso de esta función le permite administrar cualquier componente I2C conectado al bus de extensión. Al llamar a la función con WrBytes y RdBytes establecidos en cero, realiza una verificación de nodo que devuelve VERDADERO si existe el nodo I2c.

Atención, el bus I2C se utiliza para acceder a los módulos de extensión para no ralentizar el acceso, se recomienda ejecutar comandos I2C de no más de 4 bytes en escritura y lectura. Si necesita administrar más bytes, es recomendable dividir el comando en varios comandos consecutivos.

Círculo de información

Funzione

CÓDIGOS: indisponible

Laboratorio lógico: eLLabXUnified12Lib

Descripción

Address (BYTE) Rango de direcciones de dispositivos I2C de 16 # 00 a 16 # 7F.
WrBytes (USINT) Número de bytes de datos para escribir. 0 si es de solo lectura.
WrBuffer (PVOID) Dirección del búfer de memoria que contiene los datos que se van a escribir, eNULL si solo lees.
RdBytes (USINT) Número de bytes de datos para leer. 0 si solo escribe.
RdBuffer (PVOID) Dirección de búfer para almacenar datos de lectura, eNULL si solo escribiendo.

La función devuelve un BOOL, FALSE: Error de ejecución, TRUE: Función realizada correctamente.

Imagen F SysI2CWrRd
Comprobar dispositivo I2C

Para verificar si un dispositivo con una determinada dirección I2C está conectado al bus de expansión del sistema, puede usar la función SysI2CWrRd pasando la dirección I2C para que se verifique con los otros parámetros no asignados.

    IF (SysI2CWrRd(16#30, 0, eNULL, 0, eNULL)) THEN
        // Device with 16#30 I2C address is connected.
    ELSE
        // Device with 16#30 I2C address is not connected.
    END_IF;

Ejemplos

Cómo utilizar los ejemplos..

ST_SysI2CWrRd: La adquisición del valor de temperatura y humedad se realiza desde un sensor Sensirion SHT30-DIS como este conectado al bus I2C de un sistema SlimLine. El control en el CRC de los valores adquiridos no se realiza. en este artículo la misma gestión se lleva a cabo con la gestión de bus I2C FB.

Dispositivos ST_ScanI2C: Mediante conexión telnet al puerto indicado, se escanean todas las direcciones I2C posibles y se devuelve la lista de dispositivos conectados al bus I2C de expansión.

Laboratorio lógico (Ptp116, ST_SysI2CWrRd)
PROGRAM ST_SysI2CWrRd
VAR
    CaseNr : USINT; (* Program case *)
    TimeBf : UDINT; (* Time buffer (mS) *)
    Errors : UDINT; (* Error counter *)
    Temperature : REAL; (* Temperature value (°C) *)
    Humidity : REAL; (* Humidity value (%) *)
    I2CWrite : ARRAY[0..1] OF BYTE; (* I2C write buffer *)
    I2CRead : ARRAY[0..7] OF BYTE; (* I2C read buffer *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_SysI2CWrRd"
// *****************************************************************************
// Temperature and humidity acquisistion from a Sensirion SHT30-DIS.
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // PROGRAM CASES
    // -------------------------------------------------------------------------
    // Program cases management.

    CASE (CaseNr) OF

        // ---------------------------------------------------------------------
        // Conversion command "Single Shot Mode high repeatability" clock
        // streching disabled.

        0:
        I2CWrite[0]:=16#24; //MSB
        I2CWrite[1]:=16#00; //LSB
        IF NOT(SysI2CWrRd(16#44, 2, ADR(I2CWrite), 0, eNULL)) THEN
            Errors:=Errors+1; //Error counter
            CaseNr:=0; //Program case
            RETURN;
        END_IF;

        // Save time to wait

        TimeBf:=SysTimeGetMs(); //Time buffer (mS)
        CaseNr:=CaseNr+1; //Program case

        // ---------------------------------------------------------------------
        // Wait conversion complete (Max time oh high repeatability 15 mS).

         1:
         IF ((SysTimeGetMs()-TimeBf) < T#15ms) THEN RETURN; END_IF;

        // Read the conversion results.

        IF NOT(SysI2CWrRd(16#44, 0, eNULL, 6, ADR(I2CRead))) THEN
            Errors:=Errors+1; //Error counter
            CaseNr:=0; //Program case
            RETURN;
        END_IF;

        // Convert the acquired values.

        Temperature:=-45.0+(175.0*(TO_REAL((I2CRead[0]*256)+I2CRead[1])/65535.0));
        Humidity:=100.0*(TO_REAL((I2CRead[3]*256)+I2CRead[4])/65535.0);
        CaseNr:=0; //Program case
    END_CASE;

// [End of file]
Laboratorio lógico (Ptp116, ST_ScanI2CDevices)
PROGRAM ST_ScanI2CDevices
VAR
    i : UDINT; (* Auxiliary variable *)
    Fp : eFILEP; (* File pointer array *)
    SOut : STRING[ 128 ]; (* String output *)
    TCPServer : SysTCPServer; (* TCP server *)
    CaseNr : USINT; (* Program case *)
    I2CAddress : BYTE; (* I2C address *)
END_VAR

// *****************************************************************************
// PROGRAM "ST_ScanI2CDevices"
// *****************************************************************************
// Opens a TCP server and when a client connect to it the extension I2C is
// scanned.
// -----------------------------------------------------------------------------

    // -------------------------------------------------------------------------
    // INITIALIZATION
    // -------------------------------------------------------------------------
    // TCPServer initialization.

    IF (SysFirstLoop) THEN
        TCPServer.FilesArr:=ADR(Fp); //Files array
        TCPServer.LocalAdd:=ADR('0.0.0.0'); //Local address
        TCPServer.LocalPort:=1120; //Local port 
        TCPServer.MaxConn:=1; //Accepted connections
        TCPServer.FlushTm:=50; //Flush time (mS)
        TCPServer.LifeTm:=15; //Life time (S)
        TCPServer.RxSize:=128; //Rx buffer size
        TCPServer.TxSize:=128; //Tx buffer size
    END_IF;

    // -------------------------------------------------------------------------
    // OBJECT EXECUTION
    // -------------------------------------------------------------------------
    // Manage the TCP server and check if a client has been connected.

    TCPServer(); //TCPServer management
    TCPServer.Enable:=TRUE; //TCPServer enable
    IF NOT(SysFIsOpen(Fp)) THEN CaseNr:=0; RETURN; END_IF;

    // -------------------------------------------------------------------------
    // PROGRAM CASES
    // -------------------------------------------------------------------------
    // Program cases management.

    CASE (CaseNr) OF

        // ---------------------------------------------------------------------
        // Init check.

        0:
        i:=SysVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('Scan I2C Bus devices%s'), STRING_TYPE, ADR('$r$n'));
        I2CAddress:=16#00; //I2C address
        CaseNr:=CaseNr+1; //Program case

        // ---------------------------------------------------------------------
        // Check if the I2C device is present.

        1:
        IF NOT(SysI2CWrRd(Address:=I2CAddress, WrBytes:=0, WrBuffer:=eNULL, RdBytes:=0, RdBuffer:=eNULL)) THEN
            i:=SysCVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%s '), STRING_TYPE, ADR('--'));
        ELSE
            i:=SysCVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%02X '), USINT_TYPE, ADR(I2CAddress));
        END_IF;

        // Increase the I2C address to check.
        
        I2CAddress:=I2CAddress+1; //I2C address

        // Every 16 addresses return the result.

        IF (MOD(I2CAddress, 16) = 0) THEN    
            i:=SysCVsnprintf(ADR(SOut), SIZEOF(SOut), ADR('%s'), STRING_TYPE, ADR('$r$n'));
            i:=Sysfwrite(ADR(SOut), TO_INT(LEN(SOut)), 1, Fp);
            i:=SysFOBfFlush(Fp); //Flush the socket data
            CaseNr:=CaseNr+1; //Program case
            RETURN;
        END_IF;

        // ---------------------------------------------------------------------
        // Waits the output buffer empty.

        2:
        IF (SysFGetOSpace(Fp) <> TO_INT(SysFGetOBfSize(Fp))) THEN RETURN; END_IF;
        i:=Sysmemset(ADR(SOut), 0, SIZEOF(SOut));

        // Check if all possible addresses has been tested.

        IF (I2CAddress < 16#80) THEN CaseNr:=CaseNr-1; RETURN; END_IF;
        i:=SysFOBfFlush(Fp); //Flush the socket data
        i:=Sysfclose(Fp); //Close socket
        CaseNr:=0; //Program case
    END_CASE;

// [End of file]
¿Le resultó útil este artículo?