山本ワールド
PIC18F46K22でSPIで7セグLEDを4桁ドライブする(C言語)(timer0使用)
概要
PIC18F46K22 のSPIに74HC595経由で7セグメントLED4桁をドライブする。
回路はSPIで7セグLEDを4桁ドライブする回路のとおりである。
本プログラムはダイナミック点灯のタイミングはtimer0を使用する。
1ms置きに割り込みを掛け桁を切り替えて表示する。
プログラムの説明
disp_7seg関数はunsigned int型の整数を4桁LEDに10進数として表示データを作成する。
割り込み発生時にこのデータを順次出力してLEDに表示する。
割り込み発生時にこのデータを順次出力してLEDに表示する。
ソースファイル
以下のファイルで構成されている7seg4c3.c ・・・ メインプログラムとLED制御プログラム
ソースファイルのダウンロード 7seg4c3.zip
/*
* 7SEG LED4桁 ハードウェアSPIダイナミックスキャンサンプル(timer0使用) Version 1.00
* File: 7seg4c3c.c
* Target: PIC18F46K22 64MHz
* コンパイラ: Microchip MPLAB XC8 C Compiler V1.20
* 書き込み: PICKit 3
* リリース: 2014/02/07 19:20
* MSPP2モジュールでSPIのデータを作成 74HC595に接続されたLEDに0000から9999まで1ずつカウントしながら表示する。表示タイミングはtimer0による割り込みを使用
* 接続
* 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 interrupt isr(void); // 1ms置きの割り込み処理ルーチン
void disp_7seg(unsigned w); // 引数Wを10進数とみなして7SEG表示データを設定
void disp_7seg_hex(unsigned w);// 引数Wを16進数とみなして7SEG表示データを設定
unsigned char disp7seg_data[4]; // 表示データ4桁分
unsigned char disp7seg_count=0; // 表示桁位置
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消灯
// 1ms周期に設定
OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_128);
WriteTimer0(131);
INTCONbits.TMR0IE=1;
INTCONbits.GIE=1;
for(;;)
for(unsigned n=0;n<10000;n++){
disp_7seg(n);
Delay10KTCYx( 250); // 64MHz/4*0.16秒/10000
}
}
// 1ms置きの割り込み処理ルーチン
void interrupt isr(void){
INTCONbits.TMR0IF=0;
if(disp7seg_count>3)
disp7seg_count=0;
SPI2rw(disp7seg_data[disp7seg_count]);
++disp7seg_count;
WriteTimer0(131);
}
// SPI2入出力
char SPI2rw(char w){
SS=0;
SSP2BUF=w;
while(!SSP2STATbits.BF);
char r=SSP2BUF;
SS=1;
return r;
}
// 引数Wを10進数とみなして7SEG表示データを設定
void disp_7seg(unsigned w){
unsigned d;
d=w % 10;
disp7seg_data[3]=0xe0+d; // 1桁目
d=(w/10) % 10;
disp7seg_data[2]=0xd0+d; // 2桁目
d=(w/100) % 10;
disp7seg_data[1]=0xb0+d; // 3桁目
d=(w/1000) % 10;
disp7seg_data[0]=0x70+d; // 4桁目
}
// 引数Wを16進数とみなして7SEG表示データを設定
void disp_7_hex(unsigned w){
unsigned d;
d=w & 0x0f;
disp7seg_data[3]=0xe0+d; // 1桁目
d=(w>>4) & 0xf;
disp7seg_data[2]=0xd0+d; // 2桁目
d=(w>>8) & 0xf;
disp7seg_data[1]=0xb0+d; // 3桁目
d=(w>>12) & 0xf;
disp7seg_data[0]=0x70+d; // 4桁目
}
Copyright (C) 2012 山本ワールド All Rights Reserved.