// // PICによる電子ボリュームIC(LM1972)制御 // // ver 1.0 2012/03/03 // // (c) kiry // // 使用PIC 12F1822 // #include #include // 動作クロック4MHzを宣言 #define _XTAL_FREQ 4000000 //LM1972のLOAD/SHIFTをRA2、CLOCKをRA1、DATA_INをRA4に接続する //アナログ入力をAN0(RA0)に設定する #define OUT_CLK RA1 #define OUT_LS RA2 #define OUT_DIN RA4 // コンフィギュレーション1の設定 // CLKOUTピンをRA4ピンで使用する(CLKOUTEN_OFF):内部クロック使用する(INTIO) // 外部クロック監視しない(FCMEN_OFF):外部・内部クロックの切替えでの起動はなし(IESO_OFF) // 電源電圧降下常時監視機能ON(BOREN_ON):電源ONから64ms後にプログラムを開始する(PWRTEN_ON) // ウオッチドッグタイマー無し(WDTE_OFF): // 外部リセット信号は使用せずにデジタル入力(RA3)ピンとする(MCLRE_OFF) // プログラムメモリーを保護しない(CP_OFF):データメモリーを保護しない(CPD_OFF) __CONFIG(CLKOUTEN_OFF & FOSC_INTOSC & FCMEN_OFF & IESO_OFF & BOREN_ON & PWRTE_ON & WDTE_OFF & MCLRE_OFF & CP_OFF & CPD_OFF) ; // コンフィギュレーション2の設定 // 動作クロックを32MHzでは動作させない(PLLEN_OFF) // スタックがオーバフローやアンダーフローしたらリセットをする(STVREN_ON) // 低電圧プログラミング機能使用しない(LVP_OFF) // Flashメモリーを保護しない(WRT_OFF) __CONFIG(PLLEN_OFF & STVREN_ON & WRT_OFF & LVP_OFF); // 関数プロトタイプ宣言 void setvol (void); void ctrlvol (void) ; // 変数宣言 unsigned char power_on ; unsigned char data_flag ; unsigned char ad_data ; unsigned char old_data ; unsigned char vr_data ; unsigned char bit7, bit6, bit5, bit4, bit3, bit2, bit1, bit0; // アナログ値の入力処理 unsigned int adconv() { unsigned int temp; GO_nDONE = 1 ; // PICにアナログ値読取り開始を指示 while(GO_nDONE) ; // PICが読取り完了するまで待つ temp = ADRESH ; // PICは読取った値をADRESHのレジスターにセットする return temp ; } // メインの処理 void main() { OSCCON = 0b01101010 ; // 内部クロックは4MHzとする ANSELA = 0b00000001 ; // アナログ入力をAN0に設定 TRISA = 0b00001001 ; // AN0(RA0)だけを入力、その他のピンは出力に設定する(RA3は入力専用) PORTA = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) ADCON1 = 0b01100000 ; // 読取値は左寄せ、A/D変換クロックはFOSC/32、VDDをリファレンスとする ADCON0 = 0b00000001 ; // アナログ変換情報設定(AN0から読込む) __delay_us(5) ; // アナログ変換情報が設定されるまでとりあえず待つ (*1:20→5) power_on = 1 ; // 初回設定用フラグ data_flag = 0 ; // データ設定フラグ old_data = 0 ; // 以前のVR設定値 vr_data = 0 ; // VR設定値 OUT_LS = 1; // データ非送信時はL/SをLowにする while(1) { ad_data = adconv() ; // VRでVDD・GNDを分圧し、分圧した電圧値を取得する // 取得電圧の値と以前の値を比較する if(ad_data > old_data){ if((ad_data - old_data) > 5 ){ data_flag = 1 ; } } else if(old_data > ad_data){ if ((old_data - ad_data) > 4 ){ data_flag = 1 ; } } else { data_flag = 0 ; } // 比較結果が閾値を超えたら制御する if((data_flag || power_on) == 1){ vr_data = ad_data ; setvol (); old_data = vr_data ; // 設定した値をサンプリング power_on = 0 ; // } } } // VR制御 void setvol () { // ch1にデータ送信 OUT_DIN = 0; //DINをLowにする OUT_LS = 0; //L/SをLowにする __delay_us(1) ; int num ; for (num = 1; num <= 8 ; num = num +1){ OUT_DIN = 0; OUT_CLK = 1; OUT_CLK = 0; __delay_us (2); } ctrlvol (); OUT_LS = 1 ; // データ送信完了・L/Sをハイに戻す __delay_us(2); // ch2にデータ送信 OUT_DIN = 0; //DINをLowにする OUT_LS = 0; //L/SをLowにする __delay_us(1) ; int num ; for (num = 1; num <= 7 ; num = num +1){ OUT_DIN = 0; OUT_CLK = 1; OUT_CLK = 0; __delay_us (2); } OUT_DIN = 1; OUT_CLK = 1; OUT_CLK = 0; __delay_us (2); ctrlvol (); OUT_LS = 1 ; // データ送信完了・L/Sをハイに戻す __delay_us(2); } void ctrlvol () { bit7 = (vr_data & 0x80) >> 7; bit6 = (vr_data & 0x40) >> 6; bit5 = (vr_data & 0x20) >> 5; bit4 = (vr_data & 0x10) >> 4; bit3 = (vr_data & 0x08) >> 3; bit2 = (vr_data & 0x04) >> 2; bit1 = (vr_data & 0x02) >> 1; bit0 = (vr_data & 0x01); OUT_DIN = bit7 ; OUT_CLK = 1 ; OUT_CLK = 0 ; __delay_us(2); OUT_DIN = bit6 ; OUT_CLK = 1 ; OUT_CLK = 0 ; __delay_us(2); OUT_DIN = bit5 ; OUT_CLK = 1 ; OUT_CLK = 0 ; __delay_us(2); OUT_DIN = bit4 ; OUT_CLK = 1 ; OUT_CLK = 0 ; __delay_us(2); OUT_DIN = bit3 ; OUT_CLK = 1 ; OUT_CLK = 0 ; __delay_us(2); OUT_DIN = bit2 ; OUT_CLK = 1 ; OUT_CLK = 0 ; __delay_us(2); OUT_DIN = bit1 ; OUT_CLK = 1 ; OUT_CLK = 0 ; __delay_us(2); OUT_DIN = bit0 ; OUT_CLK = 1 ; OUT_CLK = 0 ; __delay_us(2); }