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.
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.
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
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]