📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

文字列「__FORCETOC__」を「{{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This pag…
 
(同じ利用者による、間の5版が非表示)
68行目: 68行目:
*: 各ワード転送後にCSをトグルするかどうかを指定する。
*: 各ワード転送後にCSをトグルするかどうかを指定する。
*: 通常、CSはトランザクション全体で低いままであるが、一部のデバイスでは各ワード間でCSをトグルする必要がある。
*: 通常、CSはトランザクション全体で低いままであるが、一部のデバイスでは各ワード間でCSをトグルする必要がある。
<br><br>
== SPI通信の共通クラスの定義 ==
SPI通信の設定を以下に示す。<br>
* LSB First
* 3線式SPIモード / 4線式SPIモード
* ループバックモード
* No Chip Select (CS)
* Ready
* CS Change
<br>
<u>※注意</u><br>
<u>一部のSPIデバイスやドライバでは、これらの設定の一部がサポートされていない場合がある。</u><br>
<u>使用する前に、ターゲットのハードウェアとドライバがこれらの設定をサポートしていることを確認すること。</u><br>
<br>
<syntaxhighlight lang="c++">
// SpiDevice.hファイル
#include <QObject>
#include <QFile>
#include <QFuture>
#include <QtConcurrent>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <fcntl.h>
#include <unistd.h>
class SpiDevice : public QObject
{
    Q_OBJECT
protected:
    QString m_devicePath;
public:
    enum class Mode {
      Mode0 = SPI_MODE_0,
      Mode1 = SPI_MODE_1,
      Mode2 = SPI_MODE_2,
      Mode3 = SPI_MODE_3
    };
    struct Config {
      Mode mode          = Mode::Mode0;
      bool lsbFirst      = false;
      bool threeWire      = false;
      bool loopback      = false;
      bool noCs          = false;
      bool ready          = false;
      bool csChange      = false;
      uint8_t bitsPerWord = 8;
      uint32_t speed      = 500000;
    };
    explicit SpiDevice(const QString& devicePath, QObject* parent = nullptr) : QObject(parent), m_devicePath(devicePath)
    {}
    bool configure(const Config& config)
    {
      QFile spiDevice(m_devicePath);
      if (!spiDevice.open(QIODevice::ReadWrite)) {
          emit errorOccurred("SPIデバイスを開けませんでした: " + spiDevice.errorString());
          return false;
      }
      int fd = spiDevice.handle();
      uint8_t mode = static_cast<uint8_t>(config.mode);
      if (config.lsbFirst)  mode |= SPI_LSB_FIRST;
      if (config.threeWire) mode |= SPI_3WIRE;
      if (config.loopback)  mode |= SPI_LOOP;
      if (config.noCs)      mode |= SPI_NO_CS;
      if (config.ready)    mode |= SPI_READY;
      if (config.csChange)  mode |= SPI_CS_HIGH;
      if (ioctl(fd, SPI_IOC_WR_MODE, &mode) < 0 || ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &config.bitsPerWord) < 0 ||
            ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &config.speed) < 0) {
          emit errorOccurred("SPIの設定に失敗しました");
          spiDevice.close();
          return false;
      }
      spiDevice.close();
      return true;
    }
signals:
    void errorOccurred(const QString& error);
};
</syntaxhighlight>
<br><br>
<br><br>


84行目: 173行目:
  #include <fcntl.h>
  #include <fcntl.h>
  #include <unistd.h>
  #include <unistd.h>
#include "SpiDevice.h"
   
   
  class SpiReader : public QObject
  class SpiReader : public SpiDevice
  {
  {
     Q_OBJECT
     Q_OBJECT
   
   
  private:
  private:
    QString          m_devicePath;
     std::atomic<bool> m_stopReading{false};
     std::atomic<bool> m_stopReading{false};
   
   
  public:
  public:
     explicit SpiReader(const QString& devicePath, QObject* parent = nullptr) : QObject(parent), m_devicePath(devicePath)
     using SpiDevice::SpiDevice;
    {}
   
   
     void startReading(int bufferSize = 1024)
     void startReading(int bufferSize = 1024)
107行目: 195行目:
   
   
           int fd = spiDevice.handle();
           int fd = spiDevice.handle();
          uint8_t mode  = SPI_MODE_0;
          uint8_t bits  = 8;
          uint32_t speed = 500000;
          if (ioctl(fd, SPI_IOC_WR_MODE, &mode) < 0 || ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0 ||
              ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) {
            emit errorOccurred("SPIの設定に失敗");
            spiDevice.close();
            return;
          }
           QByteArray buffer(bufferSize, 0);
           QByteArray buffer(bufferSize, 0);
           while (!m_stopReading) {
           while (!m_stopReading) {
142行目: 219行目:
  signals:
  signals:
     void dataRead(const QByteArray& data);
     void dataRead(const QByteArray& data);
    void errorOccurred(const QString& error);
     void readingFinished();
     void readingFinished();
  };
  };
159行目: 235行目:
   
   
     SpiReader reader("/dev/spidev0.0");
     SpiReader reader("/dev/spidev0.0");
    SpiDevice::Config config;
    config.mode        = SpiDevice::Mode::Mode0;
    config.lsbFirst    = true;
    config.threeWire  = true;
    config.loopback    = false;
    config.noCs        = true;
    config.ready      = false;
    config.csChange    = false;
    config.bitsPerWord = 8;
    config.speed      = 1000000;
    if (!reader.configure(config) || !writer.configure(config)) {
      qDebug() << "SPIデバイスの設定に失敗";
      return -1;
    }
   
   
     QObject::connect(&reader, &SpiReader::dataRead, [](const QByteArray& data) {
     QObject::connect(&reader, &SpiReader::dataRead, [](const QByteArray& data) {
180行目: 272行目:
<br><br>
<br><br>


== SPI通信の受信 ==
== SPI通信の送信 ==
以下の例では、非同期処理を使用して、SPI通信でデータを送信している。<br>
以下の例では、非同期処理を使用して、SPI通信でデータを送信している。<br>
<br>
<br>
186行目: 278行目:
  // SpiWriter.hファイル
  // SpiWriter.hファイル
   
   
#include <QObject>
  class SpiWriter : public SpiDevice
#include <QFile>
#include <QFuture>
#include <QtConcurrent>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <fcntl.h>
#include <unistd.h>
  class SpiWriter : public QObject
  {
  {
     Q_OBJECT
     Q_OBJECT
   
   
  public:
  public:
     explicit SpiWriter(const QString& devicePath, QObject* parent = nullptr) : QObject(parent), m_devicePath(devicePath)
     using SpiDevice::SpiDevice;
    {}
   
   
     void writeData(const QByteArray& data)
     void writeData(const QByteArray& data)
213行目: 295行目:
   
   
           int fd = spiDevice.handle();
           int fd = spiDevice.handle();
          uint8_t mode  = SPI_MODE_0;
          uint8_t bits  = 8;
          uint32_t speed = 500000;
          if (ioctl(fd, SPI_IOC_WR_MODE, &mode) < 0 ||
            ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0 ||
            ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) {
            emit errorOccurred("SPIの設定に失敗");
            spiDevice.close();
            return;
          }
           ssize_t ret = write(fd, data.constData(), data.size());
           ssize_t ret = write(fd, data.constData(), data.size());
           if (ret < 0) {
           if (ret < 0) {
239行目: 309行目:
  signals:
  signals:
     void dataWritten(int bytes);
     void dataWritten(int bytes);
    void errorOccurred(const QString& error);
  };
  };
  </syntaxhighlight>
  </syntaxhighlight>
248行目: 317行目:
  #include <QCoreApplication>
  #include <QCoreApplication>
  #include <QTimer>
  #include <QTimer>
  #include "SpiWriter.h"
  #include "SpiDevice.h"
   
   
  int main(int argc, char *argv[])
  int main(int argc, char *argv[])
255行目: 324行目:
   
   
     SpiWriter writer("/dev/spidev0.0");
     SpiWriter writer("/dev/spidev0.0");
    SpiDevice::Config config;
    config.mode        = SpiDevice::Mode::Mode0;
    config.lsbFirst    = true;
    config.threeWire  = true;
    config.loopback    = false;
    config.noCs        = true;
    config.ready      = false;
    config.csChange    = false;
    config.bitsPerWord = 8;
    config.speed      = 1000000;
   
   
     QObject::connect(&writer, &SpiWriter::dataWritten, [](int bytes) {
     QObject::connect(&writer, &SpiWriter::dataWritten, [](int bytes) {
263行目: 343行目:
       qDebug() << "エラーが発生: " << error;
       qDebug() << "エラーが発生: " << error;
     });
     });
 
     QTimer::singleShot(5000, [&writer]() {
     QTimer::singleShot(5000, [&writer]() {
       writer.writeData(QByteArray::fromHex("0102030405"));
       writer.writeData(QByteArray::fromHex("0102030405"));
273行目: 353行目:
<br><br>
<br><br>


{{#seo:
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux
|image=/resources/assets/MochiuLogo_Single_Blue.png
}}


__FORCETOC__
__FORCETOC__
[[カテゴリ:Qt]]
[[カテゴリ:Qt]]