Wenn Sie ein I2C-Gerät mit Raspberry Pi oder Jetson nano verwenden möchten, verfügt RasPi über Bibliotheken wie pigpio und WiringPi, Jetson jedoch nur über Jetson.GPIO. Dies kann ein Problem sein, wenn Sie in C / C ++ schreiben möchten. (Bist Du in Schwierigkeiten ??)
Zu dieser Zeit schrieb ich einen Artikel über die Kommunikation mit I2C-Geräten mithilfe des universellen I2C-Treibers von Linux.
Es scheint verschiedene Möglichkeiten zu geben, mit I2C-Geräten zu kommunizieren, aber dieser Code verwendet ioctl I2C_RDWR.
i2c_example.c
#include <stdint.h>
// ...
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
static const char* dev_name = "/dev/i2c-1";
/*!Lesen Sie Daten vom I2C-Slave-Gerät.
* @param[in] dev_Adr-Geräteadresse.
* @param[in] reg_Adresse des Adr-Registers.
* @param[out]Daten Ein Zeiger auf den Speicherort der zu lesenden Daten.
* @param[in]Länge Länge der zu lesenden Daten.
*/
int8_t i2c_read(
uint8_t dev_addr, uint8_t reg_addr, uint8_t* data, uint16_t length) {
/*Öffnen Sie das I2C-Gerät. */
int32_t fd = open(dev_name, O_RDWR);
if (fd == -1) {
fprintf(stderr, "i2c_read: failed to open: %s\n", strerror(errno));
return -1;
}
/* I2C-Erstellen Sie eine Lesemeldung. */
struct i2c_msg messages[] = {
{ dev_addr, 0, 1, ®_addr }, /*Registeradresse einstellen. */
{ dev_addr, I2C_M_RD, length, data }, /*Längenbytes in Daten einlesen. */
};
struct i2c_rdwr_ioctl_data ioctl_data = { messages, 2 };
/* I2C-Lesen. */
if (ioctl(fd, I2C_RDWR, &ioctl_data) != 2) {
fprintf(stderr, "i2c_read: failed to ioctl: %s\n", strerror(errno));
close(fd);
return -1;
}
close(fd);
return 0;
}
/*!Schreiben Sie Daten auf das I2C-Slave-Gerät.
* @param[in] dev_Adr-Geräteadresse.
* @param[in] reg_Adresse des Adressregisters.
* @param[in]Daten Ein Zeiger auf den Speicherort der zu schreibenden Daten.
* @param[in]Länge Länge der zu schreibenden Daten.
*/
int8_t i2c_write(
uint8_t dev_addr, uint8_t reg_addr, const uint8_t* data, uint16_t length) {
/*Öffnen Sie das I2C-Gerät. */
int32_t fd = open(dev_name, O_RDWR);
if (fd == -1) {
fprintf(stderr, "i2c_write: failed to open: %s\n", strerror(errno));
return -1;
}
/* I2C-Bereiten Sie einen Puffer für Write vor. */
uint8_t* buffer = (uint8_t*)malloc(length + 1);
if (buffer == NULL) {
fprintf(stderr, "i2c_write: failed to memory allocate\n");
close(fd);
return -1;
}
buffer[0] = reg_addr; /*Stellen Sie die Registeradresse im ersten Byte ein. */
memcpy(&buffer[1], data, length); /*Daten nach dem zweiten Byte einstellen. */
/* I2C-Schreiben Nachricht schreiben. */
struct i2c_msg message = { dev_addr, 0, length + 1, buffer };
struct i2c_rdwr_ioctl_data ioctl_data = { &message, 1 };
/* I2C-Schreiben. */
if (ioctl(fd, I2C_RDWR, &ioctl_data) != 1) {
fprintf(stderr, "i2c_write: failed to ioctl: %s\n", strerror(errno));
free(buffer);
close(fd);
return -1;
}
free(buffer);
close(fd);
return 0;
}
Zunächst die Aufnahme des Headers und die Definition des Gerätenamens.
python
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
static const char* dev_name = "/dev/i2c-1";
Die Pinbelegung für den I2C-Bus1 von RasPi und Jetson nano ist identisch, und der Gerätename ist für / dev / i2c-1
identisch.
python
/* I2C-Erstellen Sie eine Lesemeldung. */
struct i2c_msg messages[] = {
{ dev_addr, 0, 1, ®_addr }, /*Registeradresse einstellen. */
{ dev_addr, I2C_M_RD, length, data }, /*Längenbytes in Daten einlesen. */
};
struct i2c_rdwr_ioctl_data ioctl_data = { messages, 2 };
/* I2C-Lesen. */
if (ioctl(fd, I2C_RDWR, &ioctl_data) != 2) {
Zum Lesen sind zwei i2c_msg-Strukturen erforderlich. Stellen Sie zuerst die Registeradresse ein, Die zweite zu lesende Größe und der Speicherort der Daten werden angegeben.
python
/* I2C-Bereiten Sie einen Puffer für Write vor. */
uint8_t* buffer = (uint8_t*)malloc(length + 1);
buffer[0] = reg_addr; /*Stellen Sie die Registeradresse im ersten Byte ein. */
memcpy(&buffer[1], data, length); /*Daten nach dem zweiten Byte einstellen. */
/* I2C-Schreiben Nachricht schreiben. */
struct i2c_msg message = { dev_addr, 0, length + 1, buffer };
struct i2c_rdwr_ioctl_data ioctl_data = { &message, 1 };
/* I2C-Schreiben. */
if (ioctl(fd, I2C_RDWR, &ioctl_data) != 1) {
Zum Zeitpunkt des Schreibens ist ein Puffer mit "Länge der zu schreibenden Daten + 1" erforderlich. Stellen Sie die Registeradresse im 1. Byte ein, Stellen Sie die Daten nach dem zweiten Byte ein.
Die i2c_msg-Struktur wird eins sein.
Ich konnte mit diesem Code sowohl auf RasPi als auch auf Jetson Nano mit I2C-Geräten kommunizieren. Beachten Sie jedoch, dass der Code und der Inhalt möglicherweise falsch sind.
Recommended Posts