Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

shiftIn and shiftOut do not work with SPI_MODE 3 and 4

オープン
#94 コメント 4 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
42/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
cpp
領域
embedded-iot

調査の方向性

wiring_shift.c から始め、shiftIn() と shiftOut() を SPI library による SPI モードの処理と比較します。影響を受けるクロックモードで報告された 74HC165 の動作を再現し、その後、既存のモードとビット順序について標準のシフト動作が引き続き正しいことを確認します。ソフトウェア関数が報告されたモードを、ビットの欠落や追加なしに処理できれば完了です。

索引モデルが issue の本文から書いたものです。

説明

The solution described here might well fix several other problems in this thread where bits go missing or additional bits appear...
I was trying to use the standard Arduino shiftIn and shiftOut to operate a 74HC165 shift register. I found that it always clocked one too many bits, and therefore shifted all the bits to the left, losing the top one. This did not happen when I used hardware SPI (the SPI library).
I therefore took a close look at the source code for shiftIn and shiftOut in (wiring_shift.c) and soon spotted the problem: shiftIn and shiftOut assume a clock polarity of 0. They will therefore only work with SPI_MODE0 and 1.

This can be fixed by inverting the clock signal if the SPI_MODE is 3 or 4. I give my solution below. The functions require the SPI mode as an additional parameter, using the Arduino standard definitions SPI_MODE0 etc.
While I was at it, I gained a little speed by taking the test for MSBFIRST or LSBFIRST outside the bit loop and by declaring the method ‘inline’.
I have tested NEWshiftIn with the 74HC165 shift register (SPI_MODE3) and it works fine. I have not tested NEWshiftOut yet as I do not have a MOD3 or 4 device output to test it with. I have also not tested the timings to see if there is a real improvement, as I do not have access to the necessary equipment at the moment. I will be happy to hear from anyone who does any of these tests.
Happy shifting in SPI_MODES 3 and 4!

// ===============================================================================================================================
// New version of shiftIn() and shiftOut with the clock polarity bug removed
// Requires SPI_MODE as a parameter
// Also speeded up by taking the bit direction test out of the loop
// Andrew W Symons 9-Aug-2018
//
// SHIFT IN
//
inline uint8_t NEWshiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t spiMode )
{
    uint8_t value = 0;
    uint8_t i;
    
    uint8_t clock_polarity = spiMode >> 1 ;
    switch ( bitOrder )
    {
        case LSBFIRST:
        {
            for (i = 0; i < 8; ++i)
            {
                digitalWrite(clockPin, HIGH ^ clock_polarity );
                value |= digitalRead(dataPin) << i;
                digitalWrite(clockPin, LOW ^ clock_polarity );
            } ;
        } ;
        break ;
    
        case MSBFIRST:
        {
            for (i = 0; i < 8; ++i)
            {
                digitalWrite(clockPin, HIGH ^ clock_polarity );
                value |= digitalRead(dataPin) << (7 - i);
                digitalWrite(clockPin, LOW ^ clock_polarity );
            } ;
        } ;
        break ;
    } ;
    return value;
} ;
//
// ===============================================================================================================================
// SHIFT OUT
//
inline void NEWshiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val, uint8_t spiMode )
{
    uint8_t i;
    uint8_t clock_polarity = spiMode >> 1 ;
    switch ( bitOrder )
    {
        case LSBFIRST:
        {
            digitalWrite(dataPin, !!(val & (1 << i)));
            digitalWrite(clockPin, HIGH ^ clock_polarity );
            digitalWrite(clockPin, LOW ^ clock_polarity );
        } ;
        break ;
    
        case MSBFIRST:
        {
            digitalWrite(dataPin, !!(val & (1 << (7 - i))));
            digitalWrite(clockPin, HIGH ^ clock_polarity );
            digitalWrite(clockPin, LOW ^ clock_polarity );
        } ;
        break ;
    } ;
} ;
//
// ===============================================================================================================================
// END OF FILE
//
主要言語
C++
スター
306
フォーク
150
PR マージ指標
30日以内にマージされた PR はありません

環境構築

このプロジェクトの環境構築ファイルはまだ確認していません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

arduino/ArduinoCore-API のほかの issue

arduino/ArduinoCore-API の issue をすべて見る

似ている issue

C++ の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。