Lorsque vous souhaitez utiliser un appareil I2C avec Raspberry Pi ou Jetson nano, RasPi dispose de bibliothèques telles que pigpio et WiringPi, mais Jetson n'a que Jetson.GPIO, ce qui peut être un problème lorsque vous souhaitez écrire en C / C ++. (As-tu des problèmes ??)
Pour ces moments, j'ai écrit un article sur la façon de communiquer avec les périphériques I2C à l'aide du pilote I2C polyvalent de Linux.
Il semble y avoir plusieurs façons de communiquer avec les périphériques I2C, mais ce code utilise 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";
/*!Lire les données de l'appareil esclave I2C.
* @param[in] dev_adresse de périphérique addr.
* @param[in] reg_adresse de registre addr.
* @param[out]data Un pointeur vers l'emplacement de stockage des données à lire.
* @param[in]length Longueur des données à lire.
*/
int8_t i2c_read(
uint8_t dev_addr, uint8_t reg_addr, uint8_t* data, uint16_t length) {
/*Ouvrez le périphérique I2C. */
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-Créer un message de lecture. */
struct i2c_msg messages[] = {
{ dev_addr, 0, 1, ®_addr }, /*Définir l'adresse du registre. */
{ dev_addr, I2C_M_RD, length, data }, /*Lire des octets de longueur dans les données. */
};
struct i2c_rdwr_ioctl_data ioctl_data = { messages, 2 };
/* I2C-Lis. */
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;
}
/*!Ecrire des données sur un appareil esclave I2C.
* @param[in] dev_adresse de périphérique addr.
* @param[in] reg_adresse de registre addr.
* @param[in]data Un pointeur vers l'emplacement de stockage des données à écrire.
* @param[in]length Longueur des données à écrire.
*/
int8_t i2c_write(
uint8_t dev_addr, uint8_t reg_addr, const uint8_t* data, uint16_t length) {
/*Ouvrez le périphérique I2C. */
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-Préparer un tampon pour l'écriture. */
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; /*Définissez l'adresse du registre dans le premier octet. */
memcpy(&buffer[1], data, length); /*Définir les données après le deuxième octet. */
/* I2C-Créer un message d'écriture. */
struct i2c_msg message = { dev_addr, 0, length + 1, buffer };
struct i2c_rdwr_ioctl_data ioctl_data = { &message, 1 };
/* I2C-Écrire. */
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;
}
Tout d'abord, l'inclusion de l'en-tête et la définition du nom de l'appareil.
python
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
static const char* dev_name = "/dev/i2c-1";
Les affectations des broches pour RasPi et Jetson nano I2C Bus1 sont les mêmes, et le nom de l'appareil est le même pour / dev / i2c-1
.
python
/* I2C-Créer un message de lecture. */
struct i2c_msg messages[] = {
{ dev_addr, 0, 1, ®_addr }, /*Définir l'adresse du registre. */
{ dev_addr, I2C_M_RD, length, data }, /*Lire des octets de longueur dans les données. */
};
struct i2c_rdwr_ioctl_data ioctl_data = { messages, 2 };
/* I2C-Lis. */
if (ioctl(fd, I2C_RDWR, &ioctl_data) != 2) {
Deux structures i2c_msg sont requises pour la lecture. Définissez d'abord l'adresse du registre, La deuxième taille à lire et l'emplacement de stockage des données sont spécifiés.
python
/* I2C-Préparer un tampon pour l'écriture. */
uint8_t* buffer = (uint8_t*)malloc(length + 1);
buffer[0] = reg_addr; /*Définissez l'adresse du registre dans le premier octet. */
memcpy(&buffer[1], data, length); /*Définir les données après le deuxième octet. */
/* I2C-Créer un message d'écriture. */
struct i2c_msg message = { dev_addr, 0, length + 1, buffer };
struct i2c_rdwr_ioctl_data ioctl_data = { &message, 1 };
/* I2C-Écrire. */
if (ioctl(fd, I2C_RDWR, &ioctl_data) != 1) {
Au moment de l'écriture, un tampon de "longueur des données à écrire + 1" est requis. Définissez l'adresse du registre dans le 1er octet, Définissez les données après le deuxième octet.
La structure i2c_msg en sera une.
J'ai pu communiquer avec des appareils I2C sur RasPi et Jetson Nano avec ce code, mais veuillez noter que le code et le contenu peuvent être incorrects.
Recommended Posts