※元は Hitech_c のソースです。 /***************************************************** * 7Seg_LEDのテストプログラム <<2分カウントダウン>> * I2Cインターフェース(IC:HT16K33)で接続 * (スレーブアドレス0x70<<1+'0'→0xE0) * * PIC 12F683 MPLAB IDE Ver8.84 HI-TECH C * GP5(2p):SDA GP4(3p):SCL GP2(5p):LED+ ******************************************************/ #include #define _XTAL_FREQ 4000000 // クロック周波数設定 /***** コンフィギュレーションの設定 ********/ __CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & BOREN_ON & MCLRE_ON & CP_OFF & IESO_OFF & FCMEN_OFF); /* I2c スレーブ・アドレス 0x70 + '0' => 0xE0 */ #define ADDR 0xE0 #define SDA GP5 #define SCL GP4 #define TRISSDA TRISIO5 char const LED_SEG[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x67 }; // 0〜9の数字 unsigned int Count, g_time; // 20mSのカウントと残り秒数 unsigned char s1,s2,s3,s4; // 7seg に送る数字のデータ unsigned char chflg; void HT16K33_init(void); void I2c_Start(void); void I2c_Stop(void); void I2c_cmd(char dat); void keisan(void); void S7_Hyoji(char n1, char n2, char n3, char n4); unsigned char I2c_Out(unsigned char data); /******** メイン関数 ************/ void main(void){ CMCON0 = 0x07; // コンパレータオフ OSCCON = 0x60; // Set to 4MHz OPTION_REG = 0x06; // 内部プルアップ使用、プリスケーラ 1/128 INTCON = 0xC0; // GIE=1, PEIE=1; T0IE=0, T0IF=0 GPIO = 0x30; // GP4,5 default High TRISIO = 0x00; // 全出力設定 ANSEL = 0x00; // デジタルに設定 WPU = 0x30; // GP4,5 プルアップ TMR0 = 0x64; // 初期値:100 (256-100)×128 => 20mS T0IE = 1; // Timer0 始動 /**** メインループ *****/ HT16K33_init(); Count = 0; g_time = 120; // 初期値120秒(2分) chflg = 1; GP2 = 0; while(1){ if(chflg == 1){ chflg = 0;// 1秒フラグ keisan(); S7_Hyoji(s1,s2,s3,s4); GP2 ^= 1; } // 表示は遅いため割込み処理とは別に動作させる } } // 割込み処理 void interrupt Time_cnt( void ){ if (T0IF == 1){ // タイマー0の割込み発生か? TMR0 = 0x64; // タイマー0の初期化 Count++; // 割込み発生の回数をカウントする T0IF = 0; // タイマー0割込フラグをリセット if (Count >= 45){ // 割込みを45(本当は50)回カウントすると約1秒 Count = 0; g_time--; chflg = 1; // 秒数変化フラグ if(g_time==0)g_time=120; } // 0になったら初期値を入れて繰り返す } } // 計算 void keisan(void){ s1 = LED_SEG[g_time / 600]; s2 = LED_SEG[g_time % 600 / 60]; s3 = LED_SEG[g_time % 60 / 10]; s4 = LED_SEG[g_time % 10]; } // カウントダウン表示 void S7_Hyoji(char n1,char n2,char n3,char n4){ I2c_Start(); I2c_Out(ADDR); I2c_Out(0x00); // COM0左端桁指定 I2c_Out(n1); // 10分 I2c_Out(0x02); // 2桁目指定 I2c_Out(n2); // 分 I2c_Out(0x04); // 'コロン'の桁 I2c_Out(0x02); // 2番目のビットが'1'なら点灯 I2c_Out(0x06); // 3桁目3 I2c_Out(n3); // 10秒 I2c_Out(0x08); // 右端桁 I2c_Out(n4); // 秒 I2c_Stop(); } // Start Condiotion void I2c_Start(void){ /* SCL,SDAは通常:High */ SDA = 0; // 先に SDA=Low TRISSDA = 0; // SDA出力 } // Stop Condition void I2c_Stop(void){ SCL = 0; // SCL Low SDA = 0; // SDA Low TRISSDA = 0; // 出力モードに戻す SCL = 1; // 先にSCLをHigh SDA = 1; // 後からSDAをHigh } // 7セグドライバの初期化 void HT16K33_init(void){ I2c_cmd(0x21); // wake up I2c_cmd(0x81); // display_on no_blink I2c_cmd(0xE5); // Brightness(E0-EF) // I2c_cmd(0xA0); // default:A0 } // コマンドを送信 void I2c_cmd(char dat){ I2c_Start(); I2c_Out(ADDR); I2c_Out(dat); I2c_Stop(); } // I2c_で1バイト出力(1ビットずつ) unsigned char I2c_Out(unsigned char data){ int i; unsigned char BitPos, ACK; /* Data Out */ TRISSDA = 0; // SDA出力モード BitPos = 0x80; // ビット位置初期値(左端) for(i=0; i<8; i++){ // 8回繰り返し SCL = 0; // CLK Low if((data & BitPos) != 0){// ビット出力 SDA = 1; // SDA High } else { SDA = 0; // SDA Low } BitPos = BitPos >> 1; // ビット位置移動 SCL = 1; // SCL Highに戻す } /* Ack チェック */ SCL = 0; // クロック1Low TRISSDA = 1; // 入力モードにしてACK入力 ACK = SDA; // ACKチェック SCL = 1; // クロックHighに戻す return(ACK); // ACKを戻り値とする }