PIC18F46K22でSPIで7セグLEDを4桁ドライブする(C言語)(ソフトウェアディレイ)

icon 項目のみ表示/展開表示の切り替え

概要

PIC18F46K22 のSPIに74HC595経由で7セグメントLED4桁をドライブする。
回路はSPIで7セグLEDを4桁ドライブする回路のとおりである。
本プログラムはダイナミック点灯のタイミングはソフトウェアディレイを使用する。
1ms置きに桁を切り替えて表示する。

プログラムの説明

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

ソースファイル

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

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


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

#include <p18f46k22.h>
#include <plib\delays.h>
#include <plib\spi.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

char SPI2rw(char w);            //  SPI2入出力
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;

    OpenSPI2(SPI_FOSC_16,MODE_11,SMPMID);

    SPI2rw(0xff);   // LED消灯

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

char SPI2rw(char w){            //  SPI2入出力
    SS=0;
    SSP2BUF=w;
    while(!SSP2STATbits.BF);
    char r=SSP2BUF;
    SS=1;
    return r;
}

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
}