2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

初めてのRaspberry Pi Pico ⑨ C言語で7セグメントLEDを点灯 その1

Last updated at Posted at 2021-02-07

 7セグメントLEDは八つのLEDを数字の形になるように点灯させます。桁数が増えると配線の量が加速度的に増えます。

ファイル名

 専用のコントローラをつなぐ方法があり、4桁などにはHT16K33があります。ここでは、シフトレジスタ74HC595と緑色LEDを組み合わせた秋月電子通商の製品を利用します。
  緑色7セグメントLEDシリアルドライバモジュール 完成品

 6個つなげて6桁の7セグメントLEDを作りました。6桁は市販品にありません。

ファイル名

接続

 74HC595への書き込みは、SPIのタイミングが利用できます。LATCHはCE(CS)と同じタイミングです。SCK(GP6)はクロックで、データを送るSDIはMOSI(GP7)につなぎます。
 こちらの資料が詳しいです。

 PicoのMOSIから最初のLEDのSDIにデータを入れ、SDOからそのままデータを次のLEDのSDIへ送ります。これを6個分繰り返します。
 LATCH、SCK、GND、3.3Vはそれぞれ全部共通につなぎます。
7seg-6d.png

プログラム

 前回のblinkと同様に、worksフォルダにプログラムを作ります。LED7seg_74HC595フォルダを作ります。worksフォルダにあるCMakeLists.txtを次のように変更します。変更点は、最後の行にフォルダを追加しました。

cmake_minimum_required(VERSION 3.12)

# Pull in SDK (must be before project)
include(pico_sdk_import.cmake)

project(pico_examples C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

set(PICO_EXAMPLES_PATH ${PROJECT_SOURCE_DIR})

# Initialize the SDK
pico_sdk_init()

include(example_auto_set_url.cmake)
# Add blink example
add_subdirectory(blink)
add_subdirectory(cmake)
add_subdirectory(LED7seg_74HC595)

 LED7seg_74HC595フォルダの中にはLED7seg_74HC595.cとCMakeLists.txtの二つのファイルを作ります。CMakeLists.txtの内容です。blinkのときと異なるのは、hardware_spiのライブラリを追加したところです。

add_executable(LED7seg_74HC595
        LED7seg_74HC595.c
        )

# Pull in our pico_stdlib which pulls in commonly used features
target_link_libraries(LED7seg_74HC595 pico_stdlib  hardware_spi)

# create map/bin/hex file etc.
pico_add_extra_outputs(LED7seg_74HC595)

# add url via pico_set_program_url
example_auto_set_url(LED7seg_74HC595)

  超精密温度計の製作⑤7セグLEDに表示の記事を参照してプログラムを作ります。
 SPIバスのチップ・セレクト信号CSは、プログラムで制御します。デフォルトはHighで、転送開始前にLowに落とし、転送が終わるとHighに戻します。

 LED7seg_74HC595.cのソースです。

 spi_write_blocking(SPI_PORT, XXdataXX, 1);

で転送すると一番左のLEDにデータXXdataXXが書き込まれます。同じく2回目のデータを転送すると、最初のデータは左に押し出されて、2桁のLEDが表示されます。6回転送すると、全桁の表示が終わります。

/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

# include <stdio.h>
# include <string.h>
# include "pico/stdlib.h"
# include "hardware/spi.h"

# define PIN_CS   5
# define PIN_SCK  6
# define PIN_MOSI 7

# define SPI_PORT spi0
# define READ_BIT 0x80

const uint8_t digits[] = {
  0b00111111, // 0
  0b00000110, // 1
  0b01011011, // 2
  0b01001111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00000111, // 7
  0b01111111, // 8
  0b01101111, // 9
};
const uint8_t  dot   = 0b10000000;
const uint8_t  blank = 0b00000000;
const uint8_t  minus = 0b01000000;  // -

static inline void cs_select() {
    asm volatile("nop \n nop \n nop");
    gpio_put(PIN_CS, 0);  // Active low
    asm volatile("nop \n nop \n nop");
}

static inline void cs_deselect() {
    asm volatile("nop \n nop \n nop");
    gpio_put(PIN_CS, 1);
    asm volatile("nop \n nop \n nop");
}

static void write_register(uint8_t reg, uint8_t data) {
    uint8_t buf[2];
    buf[0] = reg & 0x7f;  // remove read bit as this is a write
    buf[1] = data;
    cs_select();
    spi_write_blocking(SPI_PORT, buf, 2);
    cs_deselect();
    sleep_ms(10);
}

void clearLED(){
    // clear all segments
    cs_select();
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    spi_write_blocking(SPI_PORT, &blank, 1);
    cs_deselect();
}
void setup_SPI(){
    // This example will use SPI0 at 0.5MHz.
    spi_init(SPI_PORT, 500 * 1000);
    gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);

    // Chip select is active-low, so we'll initialise it to a driven-high state
    gpio_init(PIN_CS);
    gpio_set_dir(PIN_CS, GPIO_OUT);
    gpio_put(PIN_CS, 1);
}

int main() {
    stdio_init_all();

    printf("\nHello, 7SegmentLED via SPI...\n");
    setup_SPI();
    clearLED();

  float Temp=-1.4567;
  // Serial.println(Temp,4);
  char sTemp[8];
  snprintf(sTemp, 8, "%f", Temp);
  puts(sTemp);
  int seisuu;
  for (int i=0; i<8; i=i+1){
      //printf("moji %d ",sTemp[i]);
      if (sTemp[i] == 46){        // 46=.
          //printf("seisuu %d\n",i);
          seisuu = i;
          break;
      }
  }
 
  cs_select();
  if (Temp > 0.0) {
    if (seisuu == 2) {  // 23.4567
      spi_write_blocking(SPI_PORT, &digits[sTemp[0]-48], 1);
      uint8_t pp = digits[sTemp[1]-48] ^ dot;
      spi_write_blocking(SPI_PORT, &pp, 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[3]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[4]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[5]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[6]-48], 1);
    }
    if (seisuu == 1) {     // 1.2345
      spi_write_blocking(SPI_PORT, &blank, 1); // blank
      uint8_t pp = digits[sTemp[0]-48] ^ dot;
      spi_write_blocking(SPI_PORT, &pp, 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[2]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[3]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[4]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[5]-48], 1);
    }
  }else{  // minus
    if (seisuu == 3) {     // -12.3456
      spi_write_blocking(SPI_PORT, &minus, 1); // -
      uint8_t pp = digits[sTemp[2] - 48] ^ dot;
      spi_write_blocking(SPI_PORT, &digits[sTemp[1]-48], 1);
      spi_write_blocking(SPI_PORT, &pp, 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[4]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[5]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[6]-48], 1);
    }
    if (seisuu == 2) {     // -1.2222
      spi_write_blocking(SPI_PORT, &blank, 1); // blank
      spi_write_blocking(SPI_PORT, &minus, 1); // -
      uint8_t pp = digits[sTemp[1]-48] ^ dot;
      spi_write_blocking(SPI_PORT, &pp, 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[3]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[4]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[5]-48], 1);
      spi_write_blocking(SPI_PORT, &digits[sTemp[6]-48], 1);   
    }
  }
  cs_deselect();
  sleep_ms(2000);;

    return 0;
}

 /home/pi/pico/works/buildに移動します。

cmake ..

 /home/pi/pico/works/build/LED7seg_74HC595に移動します。

make -j4

 ラズパイのデスクトップにPico(PRI-RP2)をマウントするために、BOOTSELボタンを押したままUSBケーブルをつなげました(抜き差し)。
 できたLED7seg_74HC585.uf2をPRI-RP2ドライブへドロップします。

 Temp=-1.4567がテスト・データです。
IMGP0182.png

(※)LEDの合計の消費電流がいくらかは不明です。輝度は十分とれています。Picoの3.3V端子からどのくらいの電流が流せるかは不明(300mA?)です。LEDを全部点灯させたときに一番電流が流れます。Pico以外から3.3Vの電源を取るのが望ましいです。

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?