Pico三昧(4) Pico C/C++ SDKで74HC595接続、PIO制御編2直列

Joseph Halfmoon

前回、ラズパイPicoのプログラマブルIO制御で、74HC595の2個並列と2個直列、同じ回で両方やってみようとしたら、まさかの半田不良で手間取りました。結局「並列」の方のみ実施。今回は、残りの直列接続の方をやってみます。形は出来ているので、今度こそ簡単に出来る筈。

(末尾に今回使用のソース全文を掲げました。)

今回は東芝デバイス&ストレージ社のTC74HC595AFを使って実験しているので、製品ページへのリンクを貼り付けておきます。

TC74HC595AF

DIP品の「AP」が手に入らなかったので、SOP16の「AF」にしたのですが、まさかの?(ちゃんと確かめてなかったので当然ともいう)1ピン半田不良で前回はトラぶりました。DIP化基板のお陰でブレッドボードで実験できるというものですが、要半田付け、それにDIPに比べると幅広だし。。。

今回実験の回路図は冒頭のアイキャッチ画像に掲げました。データ線部分をよくよく観察しなければ前回の回路図とほとんど同じです。

回路図はシンプルですが、実際のブレッドボードはゴチャゴチャです。

Pico_595_SER_DUT左にあるのが、ラズパイPicoの母艦であるラズパイ4です。パソコン上のVSCodeからラズパイ4にリモート接続して作業をしています。真ん中上がラズパイPicoボードのブレッドボードです。信号3本と電源(3.3V)、GNDが引き出されているのが分かると思います。真ん中下が74HC595AFをDIP化ボードに搭載したものを2個直列に接続したブレッドボードです。そして右端が、Digilent社Analog Discovery2です。今回はアナログではなくロジアナ機能で、2個の74HC595のパラレル出力合計16本を観察するのに使用しています。

ビルドと実動作

末尾に記載したソースでは、前回の並列動作のときのコードをコメントアウトして残してあります。隣に今回の直列動作のときのコードを並べてあります。必要な部分をちょちょいと直せば(前回は間違えましたが)、並列接続を直列に、あるいは逆にするのは簡単です。

動作確認のロジアナ画面はこちら。

LogicS216本のパラレル出力が制御されているのが分かります。今回は落穂ひろい的な回だから、トラブらなくてよかった。平和だな。

Pico三昧(3) Pico C/C++ SDKで74HC595接続、PIO制御編2並列 に戻る

Pico三昧(5) Pico C/C++ SDKでS93C46接続その1、ソフト制御 に進む

PIOアセンブラソース
; PIO595
; 74HC595 output test
; opin SI_A(18), SI_B(17) 
; spin SCK(19), RCK(20)

.program pio595
.side_set   2

.wrap_target
    pull    block           side    0
;    set     x, 7            side    0
    set     x, 15            side    0
loop:
    out     pins, 1         side    0
;    out     pins, 2         side    0
    nop                     side    0x1
    nop                     side    0
    jmp     x-- loop        side    0
    nop                     side    0x2
    nop                     side    0
.wrap

% c-sdk {
#include "hardware/gpio.h"

static inline void pio595_program_init(PIO pio, uint sm, uint offset, uint opin, uint spin)
{
    pio_sm_config c = pio595_program_get_default_config(offset);
    sm_config_set_out_pins(&c, opin, 1); // SER
//    sm_config_set_out_pins(&c, opin, 2);  // PAR
    sm_config_set_out_shift(&c, true, false, 0); // shift_right, no-autopull
    sm_config_set_sideset_pins(&c, spin);
    pio_gpio_init(pio, opin);  // SER
//    pio_gpio_init(pio, opin+1); // PAR
    pio_gpio_init(pio, spin);
    pio_gpio_init(pio, spin+1);
    pio_sm_set_consecutive_pindirs(pio, sm, opin, 1, true); //SER
//    pio_sm_set_consecutive_pindirs(pio, sm, opin, 2, true);  // PAR
    pio_sm_set_consecutive_pindirs(pio, sm, spin, 2, true);
    sm_config_set_clkdiv(&c, 128);
    pio_sm_init(pio, sm, offset, &c);
    pio_sm_set_enabled(pio, sm, true);
}

static inline void pio595_program_stop(PIO pio, uint sm)
{
    pio_sm_set_enabled(pio, sm, false);
}
%}
Cソース
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/pio.h"
#include "pio595.pio.h"

// 74HC595 PINS
#define SI      (18)
#define SIB     (17)
#define SCK     (19)
#define RCK     (20)
#define G_      (21)
#define SCLR_   (22)
// 74HC595 OPTION SWITCH
#define NO_G_SCLR

#ifndef NO_G_SLR
void clear595() {
    gpio_put(SCLR_, false); //SCLR_=Low, clear
    sleep_us(1);
    gpio_put(SCLR_, true);
}

void outputEnable595() {
    gpio_put(G_, false); //G_=Low, outputEnable
}

void outputDisable595() {
    gpio_put(G_, true); //G_=High, outputDisable
}

void setup595pio() {
    gpio_init(G_);
    gpio_set_dir(G_, GPIO_OUT);
    outputDisable595();
    gpio_init(SCLR_);
    gpio_set_dir(SCLR_, GPIO_OUT);
    clear595();
}
#endif

int main()
{
    uint16_t dat = 0x0001;

    stdio_init_all();
    puts("DUAL 74HC595(QH->SI) PIO state machine.");
#ifndef NO_G_SLR
    setup595pio();
#endif

    PIO pio = pio0;
    uint sm = pio_claim_unused_sm(pio, true);
    pio_sm_restart(pio, sm);
    uint offset = pio_add_program(pio, &pio595_program);
//    pio595_program_init(pio, sm, offset, SIB, SCK); //PAR
    pio595_program_init(pio, sm, offset, SI, SCK); //SER
    outputEnable595();

    while (1) {
        pio_sm_put(pio, sm, dat);
        if (dat == 0x8000) {
            dat = 0x0001;
        } else {
            dat <<= 1;
        }
        //dat = (dat < 255)? ++dat : 0;
        sleep_us(100);
    }

    pio595_program_stop(pio, sm);
    puts("End of Execution.\r\n");
    return 0;
}