【Raspberry Pi】C++-Bibliothek zur Handhabung von I2C, SPI und UART

1. Beschreibung

        Der Raspberry Pi ist ein Einplatinencomputer, den es mittlerweile in 4 Revisionen und einer minimalistischen Zero-Variante gibt. Aufgrund seiner geringen Größe, seines hohen Stromverbrauchs, seiner hohen Verarbeitungsgeschwindigkeit und seiner Tatsache, dass es sich um einen vollständig Linux-basierten Computer handelt, ist er eine beliebte Wahl für verschiedene Projekte.

        Eine Möglichkeit, mehrere Einplatinencomputer und/oder Mikrocontroller miteinander zu verbinden, ist die direkte Verkabelung. Die hierfür am häufigsten verwendeten Protokolle sind I2C, SPI und UART. In früheren Beiträgen der Blogreihe wurden die Prinzipien dieser Protokolle erläutert und Arduino-spezifische C-Bibliotheken vorgestellt. In diesem Artikel erkläre ich die C++-Bibliotheken, die die Verwendung dieser Protokolle auf dem Raspberry Pi ermöglichen. Für jedes Protokoll recherchiere ich die verfügbaren Bibliotheken und gebe eine kurze Erklärung und ein Codebeispiel. Bitte sagen Sie nicht, dass diese Beispiele nicht von mir entwickelt wurden, sondern aus der Bibliotheksdokumentation stammen und als Grundlage für konkrete Arbeitsbeispiele dienen sollen.

Dieser Artikel erschien ursprünglich auf meinem Blog admantium.com .

Zweitens, I2C

        I2C wird über das SMBus-Protokoll unterstützt, das als spezifische Variante des I2C-Busses beschrieben wird. Dieses Protokoll ist als  Linux-Kernelmodul verfügbar . Um es zu verwenden, müssen Sie Ihren Raspberry Pi konfigurieren. Im Terminal ausführen, auswählen und .raspi-config3 Interfacing OptionsP5 I2C

Wenn Sie dem Codebeispiel auf kernel.org         folgen  , müssen Sie die Gerätedatei öffnen, die das angeschlossene I2C-Gerät darstellt, und dann den SMBus-Befehl senden, indem Sie in die Geräteregister schreiben.

// SOURCE: https://www.kernel.org/doc/Documentation/i2c/dev-interface */
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>int file;
int adapter_nr = 2;
char filename[20];snprintf(filename, 19, "/dev/i2c-%d", adapter_nr);
file = open(filename, O_RDWR);
if (file < 0) {
  exit(1);
}  int addr = 0x40;if (ioctl(file, I2C_SLAVE, addr) < 0) {
  exit(1);
}__u8 reg = 0x10;
__s32 res;
char buf[10];res = i2c_smbus_read_word_data(file, reg);
if (res < 0) {
  /* ERROR HANDLING: i2c transaction failed */
} else {
  /* res contains the read word */
}buf[0] = reg;
buf[1] = 0x43;
buf[2] = 0x65;
if (write(file, buf, 3) != 3) {
  /* ERROR HANDLING: i2c transaction failed */
} 

3. SPI

        Um SPI verwenden zu können, müssen Sie außerdem ein bestimmtes Kernelmodul hinzufügen: Spidev . Raspberry Pi unterstützt dieses Modul. Sie müssen es durch Aufrufen konfigurieren und dann und auswählen.raspi-config3 Interfacing OptionsP4 SPI

        Um mit C/C++ auf SPI-Funktionen zuzugreifen,  kann die Spidev-Wrapper-Bibliothek verwendet werden . Nach dem Beispielcode müssen Sie die SPI-Verbindung konfigurieren, dann das Gerät öffnen, zu dem eine Verbindung hergestellt werden soll, und die Bibliotheksmethoden zum Lesen und Schreiben von Daten verwenden.

//SOURCE: https://raw.githubusercontent.com/milekium/spidev-lib/master/sample/spidev-testcpp.cc
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <spidev_lib++.h>spi_config_t spi_config;
uint8_t tx_buffer[32];
uint8_t rx_buffer[32];int  main( void)
{  SPI *mySPI = NULL;  spi_config.mode=0;
  spi_config.speed=1000000;
  spi_config.delay=0;
  spi_config.bits_per_word=8;  mySPI=new SPI("/dev/spidev1.0",&spi_config);  if (mySPI->begin())
  {
    memset(tx_buffer,0,32);
    memset(rx_buffer,0,32);
    sprintf((char*)tx_buffer,"hello world");
    printf("sending %s, to spidev2.0 in full duplex \n ",(char*)tx_buffer);
    mySPI->xfer(tx_buffer,strlen((char*)tx_buffer),rx_buffer,strlen((char*)tx_buffer));
    printf("rx_buffer=%s\n",(char *)rx_buffer);
    //mySPI->end();
    delete mySPI;
  }
 return 1;
} 

4. UART

        Eine UART-Verbindung kann mit der gemeinsamen C-Bibliothek hergestellt werden. Wenn Sie die sehr detaillierten Anweisungen in diesem Artikel befolgen , müssen Sie das Gerät öffnen, dann die verschiedenen Eigenschaften verwenden, die das TTY-Gerät definieren, und dann auf den seriellen Port schreiben und von diesem lesen.termios struct

// SOURCE: https://blog.mbedded.ninja/programming/operating-systems/linux/linux-serial-ports-using-c-cpp/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>int main() {
  int serial_port = open("/dev/ttyUSB0", O_RDWR);  struct termios tty;  if(tcgetattr(serial_port, &tty) != 0) {
      printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
      return 1;
  }  tty.c_cflag &= ~PARENB;
  tty.c_cflag &= ~CSTOPB;
  tty.c_cflag &= ~CSIZE;
  tty.c_cflag |= CS8;
  tty.c_cflag &= ~CRTSCTS;
  tty.c_cflag |= CREAD | CLOCAL;  tty.c_lflag &= ~ICANON;
  tty.c_lflag &= ~ECHO;
  tty.c_lflag &= ~ECHOE;
  tty.c_lflag &= ~ECHONL;
  tty.c_lflag &= ~ISIG;
  tty.c_iflag &= ~(IXON | IXOFF | IXANY);
  tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);  tty.c_oflag &= ~OPOST;
  tty.c_oflag &= ~ONLCR;  tty.c_cc[VTIME] = 10;
  tty.c_cc[VMIN] = 0;  cfsetispeed(&tty, B9600);
  cfsetospeed(&tty, B9600);  if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {
      printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
      return 1;
  }  unsigned char msg[] = { 'H', 'e', 'l', 'l', 'o', '\r' };
  write(serial_port, "Hello, world!", sizeof(msg));  char read_buf [256];  memset(&read_buf, '\0', sizeof(read_buf);  int num_bytes = read(serial_port, &read_buf, sizeof(read_buf));  if (num_bytes < 0) {
      printf("Error reading: %s", strerror(errno));
      return 1;
  }  printf("Read %i bytes. Received message: %s", num_bytes, read_buf);  close(serial_port)
  return 0; 

5. Allgemeiner GPIO-Zugriff

Die Bibliothek libgpiod bietet generischen Zugriff auf die GPIOs jedes Geräts, auf dem Linux ausgeführt wird. Es erkennt verfügbare GPIOs, kann Daten lesen und schreiben und wartet auf Triggerereignisse. Damit können Sie eigenen Code schreiben, um den UART mit jedem angeschlossenen Gerät zu kommunizieren.

        Um es zu installieren, führen Sie den folgenden Befehl aus:

apt-get install autoconf autoconf-archive libtool libkmod-dev pkg-config
git clone https://github.com/brgl/libgpiod.gitcd libgpiod
./autogen.sh --enable-tools=yes --prefix=/usr/local/bin
make
sudo make install 

        Wenn die Kompilierung und Installation erfolgreich war, finden Sie in einem Unterordner Binärdateien, die zum Durchsuchen des GPIO verwendet werden können. Sehen Sie sich die Beispiele unten an../toolsgpiodetectgpioinfo

 ./tools/gpiodetect
gpiochip0 [pinctrl-bcm2711] (58 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)./tools/gpioinfo
gpiochip0 - 58 lines:
 line   0:     "ID_SDA"       unused   input  active-high
 line   1:     "ID_SCL"       unused   input  active-high
 line   2:       "SDA1"       unused   input  active-high
 line   3:       "SCL1"       unused   input  active-high
 line   4:  "GPIO_GCLK"       unused   input  active-high
 line   5:      "GPIO5"       unused   input  active-high
... 

        Wenn Sie die Bibliothek nutzen möchten, lesen Sie diesen Artikel für detaillierte Anweisungen.

6. Fazit

        Um I2C, SPI und UART auf dem Raspberry Pi nutzen zu können, können nicht nur Python-, sondern auch C++-Bibliotheken genutzt werden. Konkret müssen Sie die I2C- und SPI-Funktionen aktivieren, wodurch die entsprechenden Kernelmodule lokal geladen werden. Wählen Sie dann die Clientbibliothek und andere erforderliche C++-Header aus. Die Verwendung der Bibliothek folgt den gleichen Prinzipien: Bestimmen Sie die Gerätedatei für die Verbindung, konfigurieren Sie das Verbindungsobjekt, öffnen Sie die Gerätedatei und lesen/schreiben Sie darauf. Schließlich bietet Ihnen die praktische Bibliothek libgpiod direkten Zugriff auf alle GPIO-Pins, was beim Debuggen hilfreich ist.raspi-config

 

Je suppose que tu aimes

Origine blog.csdn.net/gongdiwudu/article/details/131913868
conseillé
Classement