Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 8082

SDK • Bewildered by SPI and 74HC595 used to drive 8 LED

$
0
0
I am stumped trying to use SPI on the pico to drive a series of 8 LED from the 74HC595 shift register. I understand the waveforms and the timings, but what I don't understand is how the SPI SCK clock translates to the shift-register SRCLK, or how the SPI TX translates to the shift-register SER in or how the SPI CSn chip select translates to the shift-register RCLK (latch clock).

The wiring of the shift-register is fine. It works great driven from a hackish PWM where the latch clock is driven from the PWM interrupt on roll-over, so the hardware setup is good. It's when I move it from the MSP432 to the pico and try and use SPI to drive the chip that the wheels come off.

The wiring and SPI connections on the pico are:

Code:

#define SPI_PORT    spi0      /* 74HC595 pinout                     */#define SPI_CLK        2      /*  SRCLK  shift-register clock       */#define SPI_TX         3      /*  SER    serial data                */#define SPI_CS         5      /*  RCLK   latch clock                */#define SRCLR_PIN     10      /*  SRCLR  clear (pull hi/active low) */#define OE_PIN        11      /*  OE     output enable (pull low)   */
So you have the shift-register driven from SPI CLK on GP2, the serial data from SPI TX on GP3 and the latch clock driven by SPI CSn on GP5. The shift-register clear is pulled high (active low) on GP10 and the output enable for the shift register is pulled low (active low) on GP11. Now going though examples and forum posts, and the SDK docs, I've had trouble figuring out just how I should initialize the SPI and GPIO setup. The code below does not work (the shift-register clear works fine and clears whatever state the register was last left in), but as far as driving meaningful data from the shift-register, it doesn't happen.

I know the handling and initialization of the SPI CSn pin via GPIO likely is wrong, but from other forum post, trying to glean information on how the SPI CS (RCLK) signal should be handled, the posts show SPI asserting the CSn after a spi_write_blocking(), so that is how I arrived at this guess (and it is a guess, because the SDK docs and examples don't really describe a SPI transmit only configuration -- at least not in the way I understood it)) The attempted code is:

Code:

#include <stdio.h>#include <stdint.h>#include "pico/stdlib.h"#include "hardware/spi.h"#ifdef PICO_DEFAULT_LED_PIN#define LED_PIN PICO_DEFAULT_LED_PIN#endif#define SPI_PORT    spi0#define SPI_CLK        2#define SPI_TX         3#define SPI_CS         5#define SRCLR_PIN     10#define OE_PIN        11int main (void) {  uint8_t val = 0;  unsigned baudrate = 0;  int ret = 0;  stdio_init_all();  /* configure GPIO SRCLR and OE pins (SRCLR pulled up, OE pulled down) */  gpio_init (SRCLR_PIN);  gpio_set_dir (SRCLR_PIN, GPIO_OUT);  gpio_pull_up (SRCLR_PIN);  gpio_init (OE_PIN);  gpio_set_dir (OE_PIN, GPIO_OUT);  gpio_pull_down (OE_PIN);  /* clear the shift-register contents */  gpio_put (SRCLR_PIN, 0);  sleep_ms (50);  gpio_put (SRCLR_PIN, 1);#ifdef LED_PIN  gpio_init (LED_PIN);  gpio_set_dir (LED_PIN, GPIO_OUT);#endif  /* SPI initialization  (56KHz requested) */  baudrate = spi_init (SPI_PORT, 56 * 1000);  printf ("\nSPI baudrate : %u\033[?25l\n\n", baudrate);  gpio_set_function (SPI_CLK, GPIO_FUNC_SPI);  gpio_set_function (SPI_TX, GPIO_FUNC_SPI);  gpio_set_function (SPI_CS, GPIO_FUNC_SPI);  while (1) {#ifdef LED_PIN    /* temporary test */    gpio_put (LED_PIN, 1);    sleep_ms (400);    gpio_put (LED_PIN, 0);    sleep_ms (400);#else    sleep_ms (50);#endif    printf ("val : %hhu  (%d)\033[0K\r", val, ret);    ret = spi_write_blocking (SPI_PORT, &val, sizeof val);    val += 1;    if (val == 128) {      val = 0;    }  }}
The spi_write_blocking() does return 1-byte written, so at least it thinks it has written 8-bits to the shift-register. The blink of PICO_DEFAULT_LED_PIN was just a debug indication that the main loop was executing before I started writing the value and the spi_write_blocking() return to stdout. I think the gpio_set_function (SPI_CS, GPIO_FUNC_SPI); is wrong -- but how are you supposed to initialize the SPI CSn function so it provides the RCLK latch after the spi_write_blocking() finishes?

For what it is worth, here is a shot of the setup of the pico and the 74HC595:

Image (good until 8/28/25) The image doesn't show, so here is link to the image on opensuse

How do I get this SPI/shift-register issues sorted out? I took this on as an exercise to understand the spi transmit only setup -- but so far it isn't quite working out. (there are micropython examples galore, but those are not that helpful) Any help appreciated.

Statistics: Posted by drankinatty — Tue Jul 29, 2025 12:49 am



Viewing all articles
Browse latest Browse all 8082

Trending Articles