/* ************************************************************************** 説明 : BA3830,HT16K33コントロール マイコン: PIC16F676 ************************************************************************** __ __ VDD =|・U |= VSS RA2(AN2) 63Hz ADC RA5 =| |= RA0 RA4(AN3) 150Hz ADC RA4 =| |= RA1 RC0(AN4) 330Hz ADC RA3 =| |= RA2 RC1(AN5) 1kHz ADC RC5 =| |= RC0 RC2(AN6) 3.3kHz ADC RC4 =| |= RC1 RC3(AN7) 10kHz ADC RC3 =| |= RC2 RA5 SDA (外部プルアップ) ~~~~~ RC5 SCL RC4 Reset RA0,RA1,RA3 LEDブライトネス */ #include <16F676.h> #device adc=8 #fuses NOWDT,INTRC_IO, NOPROTECT, BROWNOUT, NOMCLR, NOCPD, PUT #use delay(clock=4000000) #use fast_io(A) // #use fast_io(C) #define HT_WR_ADDR 0xe0 // HT16K33 WRTアドレス(0x70を左ビットシフト) #byte PORTA = 5 #byte PORTC = 7 #byte WPUA = 0x95 #byte OPTION_REG = 0x81 #bit SDA_TRIS = 0x85.5 // #bit SDA_PULL_UP = 0x95.5 // // ***** I/O 定義 ***** #define Reset PIN_C4 // BA3830 Reset #define SCL PIN_C5 // I2C SCL #define SDA PIN_A5 // I2C SDA #define Bright1 PIN_A0 // LED明るさ ポート0 #define Bright2 PIN_A1 // LED明るさ ポート1 #define Peak PIN_A3 // ピークホールドorノーマル表示 ポート2 // ******************************************************* // 関数名 long peak_Hold_led(int DATA) // 概要 ピーク値を算出 // ******************************************************* long peak_Hold_led(int AD_DATA) { long led_data; led_data = 0; if(AD_DATA > 204) // 4.0V以上 led_data = 0b100000000000000; else if(AD_DATA > 190) // 3.725V以上 led_data = 0b010000000000000; else if(AD_DATA > 176) // 3.45V以上 led_data = 0b001000000000000; else if(AD_DATA > 162) // 3.175V以上 led_data = 0b000100000000000; else if(AD_DATA > 148) // 2.9V以上 led_data = 0b000010000000000; /* else if(AD_DATA > 134) // 2.625V以上 led_data = 0b000001111111111; else if(AD_DATA > 120) // 2.35V以上 led_data = 0b000000111111111; else if(AD_DATA > 106) // 2.075V以上 led_data = 0b000000011111111; else if(AD_DATA > 92) // 1.8V以上 led_data = 0b000000001111111; else if(AD_DATA > 78) // 1.525V以上 led_data = 0b000000000111111; else if(AD_DATA > 64) // 1.25V以上 led_data = 0b000000000011111; else if(AD_DATA > 50) // 0.975V以上 led_data = 0b000000000001111; else if(AD_DATA > 36) // 0.7V以上 led_data = 0b000000000000111; else if(AD_DATA > 22) // 0.425V以上 led_data = 0b000000000000011; else if(AD_DATA > 8) // 0.15V以上 led_data = 0b000000000000001; if(AD_DATA > 176) // 3.45V以上 { led_data = 0b100000000000000; AD_DATA = AD_DATA - 4; } else if(AD_DATA > 164) // 3.22V以上 led_data = 0b010000000000000; else if(AD_DATA > 153) // 2.99V以上 led_data = 0b001000000000000; else if(AD_DATA > 141) // 2.76V以上 led_data = 0b000100000000000; else if(AD_DATA > 129) // 2.53V以上 led_data = 0b000010000000000; else if(AD_DATA > 117) // 2.30V以上 led_data = 0b000001000000000; else if(AD_DATA > 106) // 2.07V以上 led_data = 0b000000100000000; else if(AD_DATA > 94) // 1.84V以上 led_data = 0b000000010000000; else if(AD_DATA > 82) // 1.61V以上 led_data = 0b000000001000000; else if(AD_DATA > 70) // 1.38V以上 led_data = 0b000000000100000; else if(AD_DATA > 59) // 1.15V以上 led_data = 0b000000000010000; else if(AD_DATA > 47) // 0.92V以上 led_data = 0b000000000001000; else if(AD_DATA > 35) // 0.69V以上 led_data = 0b000000000000100; else if(AD_DATA > 23) // 0.46V以上 led_data = 0b000000000000010; else if(AD_DATA > 12) // 0.23V以上 led_data = 0b000000000000001; */ else led_data = 0; return(led_data); } // ******************************************************* // 関数名 long ad2led(int AD_DATA) // 概要 AD値をLEDデーターに変換 // ******************************************************* long ad2led(int AD_DATA) { long led_data; led_data = 0; if(AD_DATA > 204) // 4.0V以上 led_data = 0b111111111111111; else if(AD_DATA > 190) // 3.725V以上 led_data = 0b011111111111111; else if(AD_DATA > 176) // 3.45V以上 led_data = 0b001111111111111; else if(AD_DATA > 162) // 3.175V以上 led_data = 0b000111111111111; else if(AD_DATA > 148) // 2.9V以上 led_data = 0b000011111111111; else if(AD_DATA > 134) // 2.625V以上 led_data = 0b000001111111111; else if(AD_DATA > 120) // 2.35V以上 led_data = 0b000000111111111; else if(AD_DATA > 106) // 2.075V以上 led_data = 0b000000011111111; else if(AD_DATA > 92) // 1.8V以上 led_data = 0b000000001111111; else if(AD_DATA > 78) // 1.525V以上 led_data = 0b000000000111111; else if(AD_DATA > 64) // 1.25V以上 led_data = 0b000000000011111; else if(AD_DATA > 50) // 0.975V以上 led_data = 0b000000000001111; else if(AD_DATA > 36) // 0.7V以上 led_data = 0b000000000000111; else if(AD_DATA > 22) // 0.425V以上 led_data = 0b000000000000011; else if(AD_DATA > 8) // 0.15V以上 led_data = 0b000000000000001; else led_data = 0; return(led_data); } // ******************************************************* // 関数名 void i2c_start(void) // 概要 スタートコンディション // ******************************************************* void i2c_start(void) { SDA_TRIS = 0; // SDA 出力(Low) output_high(SCL); // クロック↑ output_low(SDA); } // ******************************************************* // 関数名 void i2c_stop(void) // 概要 ストップコンディション // ******************************************************* void i2c_stop(void) { SDA_TRIS = 0; // SDA 出力(Low) output_low(SDA); output_high(SCL); // クロック↑ output_high(SDA); } // ******************************************************* // 関数名 void i2c_write(int) // 概要 I2C 1バイト 転送 // ******************************************************* void i2c_write(int data) { int i; i = 8; SDA_TRIS = 0; // SDA 出力(Low) do { output_low(SCL); // クロック↓ i--; if(bit_test(data,i)) // MSBファースト output_high(SDA); else output_low(SDA); //delay_us(1); output_high(SCL); // クロック↑ }while(i>0); delay_us(1); output_low(SCL); SDA_TRIS = 1; // SDA 入力(Hi) delay_us(10); output_high(SCL); delay_us(5); output_low(SCL); } // ******************************************************* // 関数名 void i2c_send(long data) // 概要 HT16K33 表示データー転送 2バイト // ******************************************************* void i2c_send(int COM_NUM, long data) { int d0,d1; d0 = data & 0x00ff; d1 = data >> 8; i2c_start(); i2c_write(HT_WR_ADDR); i2c_write(COM_NUM); // COM番号 i2c_write(d0); // 下位データー i2c_stop(); i2c_start(); i2c_write(HT_WR_ADDR); i2c_write(COM_NUM + 1); // COM番号 i2c_write(d1); // 上位データー i2c_stop(); } // ******************************************************* // 関数名 void demo_ht16k33(void) // 概要 HT16K33 表示デモ // ******************************************************* void demo_ht16k33(void) { long data; int i; i = 0; do { switch(i) { case 0: data = 0x7fff; break; case 1: data = 0x3fff; break; case 2: data = 0x1fff; break; case 3: data = 0x0fff; break; case 4: data = 0x07ff; break; case 5: data = 0x03ff; break; case 6: data = 0x01ff; } data = 0x7fff; i2c_send(i*2, data); i++; delay_ms(10); }while(i<8); i = 0; do { switch(i) { case 0: data = 0x0001; break; case 1: data = 0x0003; break; case 2: data = 0x0007; break; case 3: data = 0x000f; break; case 4: data = 0x001f; break; case 5: data = 0x003f; break; case 6: data = 0x007f; } data = 0x7fff; i2c_send(i*2, data); i++; delay_ms(10); }while(i<8); } // ******************************************************* // 関数名 void clear_ht16k33(void) // 概要 HT16K33 RAM 初期化 // ******************************************************* void clear_ht16k33(void) { int i; i = 0; do { i2c_send(i*2, 0); i++; }while(i<8); } // ******************************************************* // 関数名 void init_ht16k33(void) // 概要 HT16K33の初期化 // ******************************************************* void init_ht16k33(void) { int Brightness; // 明るさ用 int i; i2c_start(); i2c_write(HT_WR_ADDR); // HT16K33 アドレス i2c_write(0x21); // SystemClockEnable i2c_stop(); i2c_start(); i2c_write(HT_WR_ADDR); // HT16K33 アドレス i2c_write(0xa0); // 端子ROW15は出力設定 i2c_stop(); //*** LED明るさ設定 4/16, 8/16, 12/16, 16/16 *** i = 0; if(input(Bright1) == 0) // RA0 (JPオン) i = 1; if(input(Bright2) == 0) // RA1 (JPオン) i = i + 2; switch(i) { case 3: Brightness = 0b11101111; // 16/16 Duty break; case 2: Brightness = 0b11100110; // 7/16 Duty break; case 1: Brightness = 0b11100011; // 4/16 Duty break; case 0: Brightness = 0b11100000; // 1/16 Duty } i2c_start(); i2c_write(HT_WR_ADDR); // HT16K33 アドレス i2c_write(Brightness); // 明るさ設定 E0 〜 EF // i2c_write(0xe0); // 明るさ設定 E0 〜 EF i2c_stop(); clear_ht16k33(); // ディスプレイRAM 初期化 // **** 表示 オン **** i2c_start(); i2c_write(HT_WR_ADDR); i2c_write(0x81); // Display On, no blinking i2c_stop(); clear_ht16k33(); } // ******************************************************* // 関数名 void init(void) // 概要 ハードウエアの初期化 // ******************************************************* void init(void) { set_tris_a(0b0000011111); set_tris_c(0b0000001111); PORTA = 0; OPTION_REG = 0; WPUA = 0b00100011; SDA_PULL_UP = 1; // SDA プルアップレジスタ オン output_high(SCL); // SCL ハイ output_high(SDA); output_high(Reset); // BA3830 リセット setup_adc_ports(sAN2|sAN3|sAN4|sAN5|sAN6|sAN7|VSS_VDD); setup_adc(ADC_CLOCK_INTERNAL); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); } int Max_DATA[6] = {0, 0, 0, 0, 0, 0}; int Peak_DATA[6] = {0, 0, 0, 0, 0, 0}; // ******************************************************* // 関数名 void main(void) // 概要 メイン // ******************************************************* void main() { int i, j, ch_num, data, time; long ad_to_led_data; long led_disp_data; short peak_on; peak_on = 0; j = 0; init(); //*** ピーク表示 有り・無し *** if(input(Peak) == 0) // RA3 (JPオン) peak_on = 1; init_ht16k33(); //demo_ht16k33(); // clear_ht16k33(); //*** スタート *** output_low(Reset); // BA3830リセット解除・・ リセットは必要かぁ? delay_ms(100); // 無くても動いたけど...... while(1) { /* if(input(Peak) == 0) // RA3 (JPオン) peak_on = 1; else peak_on = 0; */ // *** Max_DATAの抽出 20ms間のピーク検出 *** time = 0; do { for(i=0; i<6; i++) { ch_num = i + 2; // ADCは AN2からAN7の6ch set_adc_channel(ch_num); delay_us(100); // ACQUISITION TIME data = read_adc(); // ADCする if(data > Max_DATA[i]) Max_DATA[i] = data; } time++; }while(time<40); //*** 表示データー 変換と転送 *** for(i=0; i<6; i++) { if(Max_DATA[i] > Peak_DATA[i]) // ピークデーター Peak_DATA[i] = Max_DATA[i]; else { if(Peak_DATA[i] > 1) Peak_DATA[i] = Peak_DATA[i] - 2; } ad_to_led_data = ad2led(Max_DATA[i]); // 表示データー 変換 if(peak_on == 0) led_disp_data = ad_to_led_data | peak_Hold_led(Peak_DATA[i]); // レベル値とピーク値のOR else led_disp_data = ad_to_led_data; // ピーク値表示無し i2c_send(i*2, led_disp_data); // データー 転送 Max_DATA[i] = 0; // 配列の初期化 } } }