概要

PIC18F46K22 のSPIに74HC595経由で7セグメントLED4桁をドライブする。
回路はSPIで7セグLEDを4桁ドライブする回路のとおりである。
本プログラムはダイナミック点灯のタイミングはソフトウェアディレイを使用する。
SPIはIOポートを直接操作して信号を作成する。データは最上位ビットである7bit目を送信し、左シフトをしながら8回繰り返す。SPI2rw関数参照。 1ms置きに桁を切り替えて表示する。

プログラムの説明

disp_7seg関数はunsigned int型の整数を4桁LEDに10進数として表示する。
ダイナミック点灯なので、連続してこの関数を呼び出さないと表示が継続しない。

ソースファイル

以下のファイルで構成されている
7seg4c2.c ・・・ メインプログラムとLED制御プログラム

ソースファイルのダウンロード 7seg4c2.zip

/*
 * 7SEG LED4桁 ソフトウェアSPIダイナミックスキャンサンプル(ソフトウェアディレイ) Version 1.00
 * File:        7seg4c2.c
 * Target:      PIC18F46K22 64MHz
 * コンパイラ:   Microchip MPLAB XC8 C Compiler V1.20
 * 書き込み:     PICKit 3
 * リリース:     2014/02/07 21:30
 * IOポートでSPIのデータを作成 74HC595に接続されたLEDに0000から9999まで1ずつカウントしながら表示する。
 * 接続(MSPP2モジュールと同一ピン)
 *   SCK2(RD0),SDO2(RD4),SS2(RD3)
 * LEDのデータフォーマット
 *   MSB xxxxdddd LSB
 *   xxxxは各ビットが桁位置に対応(Lで点灯)
 *   ddddは桁データ
*/

#include <p18f46k22.h>
#include <plib\delays.h>

#pragma config  FOSC = HSHP,PRICLKEN=ON,PLLCFG=ON,WDTEN=OFF,LVP=OFF

#define SCK PORTDbits.RD0
#define SS  PORTDbits.RD3
#define SDO PORTDbits.RD4

void SPI2rw(unsigned char w); // ソフトSPI出力
void disp_7seg(unsigned w);    //  引数Wを10進数とみなして7SEG表示データを設定

void main(void){
    ANSELDbits.ANSD0=0; //  SCK2
    ANSELDbits.ANSD3=0; //  SS2
    ANSELDbits.ANSD4=0; //  SDO2
    SS=0;
    SCK=0;
    SDO=0;
    TRISDbits.RD3=0;
    TRISDbits.RD0=0;
    TRISDbits.RD4=0;

    SPI2rw(0xff);   // LED消灯

    for(;;)
        for(int n=0;n<10000;n++){
            for(unsigned char w=0;w<50;w++)
                disp_7seg(n);
       }
}

// ソフトSPI出力

void SPI2rw(unsigned char w){
    SS=0;
    for(unsigned char  n=0;n<8;n++){
        SCK=0;
        SDO = (w & 0x80) ? 1 : 0;
        SCK=1;
        w=w<<1;
    }
    SS=1;
}

void disp_7seg(unsigned w){    //  引数Wを10進数とみなして7SEG表示
    unsigned d;
    d=w % 10;
    SPI2rw(0xe0+d);      //  1桁目
    Delay100TCYx( 160);  // 64MHz/4*1m秒/100
    d=(w/10) % 10;
    SPI2rw(0xd0+d);      //  2桁目
    Delay100TCYx( 160);  // 64MHz/4*1m秒/100

    d=(w/100) % 10;
    SPI2rw(0xb0+d);      //  3桁目
    Delay100TCYx( 160);  // 64MHz/4*1m秒/100

    d=(w/1000) % 10;
    SPI2rw(0x70+d);      //  4桁目
    Delay100TCYx( 160);  // 64MHz/4*1m秒/100
}