※拡張子の変更 〜.txt => 〜.c /********************************************************************* * HHR-P104用・放電・充電器 Pic:16F1827 * MPLAB IDE v8.84 Hi_tech C v9.83 * RA5:開始 RA6とRA7:I2c_LCDへの接続 * RA1-(charge)10Ω-RA0 RA3-(discharge)10Ω-RA2 電流値計測 *********************************************************************/ #include #define _XTAL_FREQ 4000000 /***** コンフィギュレーションの設定 ********/ __CONFIG(FOSC_INTOSC // INTOSCIO oscillator I/O function & WDTE_OFF // Watchdog Timer disabled & PWRTE_ON // Power-up Timer enabled & BOREN_ON // Brown Out enabled & MCLRE_OFF // MCLR RA5_pin function is PORT & CP_OFF // Program memory code protection is disabled & CPD_OFF // データメモリーを保護しない(OFF) & CLKOUTEN_OFF // CLKOUTピンをRA6ピンで使用する(OFF) & IESO_OFF // Internal External Switchover mode is disabled & FCMEN_OFF // Fail-Safe Clock Monitor is disabled & WRT_OFF ); // Flashメモリーを保護しない(OFF) __CONFIG(PLLEN_OFF // 動作クロックを32MHzでは動作させない(OFF) & STVREN_ON // Stack Overflow/Underflow will cause a Reset & BORV_HI // 電源電圧降下常時監視電圧(2.5V)設定(HI) & LVP_OFF ); // 低電圧プログラミング機能使用しない(OFF) // I2Cポートの定義 #define SDA RA7 #define SCL RA6 #define TRISSDA TRISA7 unsigned int C1, C2, C3, C4; unsigned int Cul1, Cul2;// 電流値 unsigned int keisoku(unsigned char port); void hyoji1(void); // LCD表示(初期) void hyoji2(void); // LCD表示(放電中) void hyoji3(void); // LCD表示(充電中) void delay_5us(unsigned char time); // 5μs遅延 void delay_5ms(unsigned char time); // 5ms遅延 void delay_100ms(unsigned char time); // 100ms遅延 // 整数=>文字 変換 桁数   データ名  書込む場所 void itostring(char digit, unsigned int data, char *buffer); void I2CStart(void); void I2CStop(void); unsigned char I2COut(unsigned char data); void lcd_data(unsigned char data); void lcd_cmd(unsigned char cmd); void lcd_str(char *ptr); void lcd_init(void); unsigned char Title0[] = "Volatge : xxxx "; unsigned char Title1[] = "Discharg xxx mA"; unsigned char Title2[] = "Volt:xxxx =>2800"; unsigned char Title3[] = "Charging xxx mA"; unsigned char Title4[] = "Volt:xxxx =>4300"; void main(void){ OSCCON = 0x68; // 内部発振 4MHz ANSELA = 0x0F; // RA0〜3はアナログ(ADC) ANSELB = 0x00; // 全てデジタル TRISA = 0x2F; // PORTA は、基本入力に(RA6,RA7は出力,RA4未使用) TRISB = 0x00; // 基本出力に // CM1CON0 = 0x00; // コンパレータ不使用 ADCON0 = 0x00; // 初期値は0 使う時=>0b0xxxxx01(有効化) ADCON1 = 0xD0; // Fosc/16,右詰,基準(Vdd-Vss) /* ポートの初期化 */ PORTA = 0xEF; PORTB = 0x00; /* 液晶表示器の初期化 */ lcd_init(); /**** メインループ *****/ RA5 = 1; while(1){ // プッシュボタンON=>放電処理へ C3 = keisoku(2);// バッテリーの電圧 hyoji1(); if(RA5 == 0)break; } while(1){ // 放電処理 C3 = keisoku(2); C4 = keisoku(3); // 10Ωの下流 if(C3 < 2700){ RB7 = 0; // 黄消灯 RB3 = 0; // 放電処理停止 break; // 次(充電処理)へ } RB7 = 1; // 黄点灯 RB3 = 1; // 放電ON Cul1 = (C3 - C4) / 10; // 10Ω hyoji2(); delay_100ms(5); } while(1){ // 充電処理 C3 = keisoku(2); // バッテリー電圧 C1 = keisoku(0); // 10Ωの前の電圧 C2 = keisoku(1); // 10Ωの下流の電圧 if(C3 > 4350){ RB6 = 0; // 緑消灯 RB4 = 0; } if(C3 < 4150){ RB6 = 1; // 緑点灯 RB4 = 1; // 充電処理 } // 電流値 Cul2 = (C1 - C2) / 10; // I=E/R(10Ω) hyoji3(); delay_100ms(5); } // end_while } // mainの終わり // 計測サブ  unsigned int keisoku(unsigned char port){ unsigned int value; port = port << 2; // ADポートの指定 ADCON0 = 0b00000001 | port; delay_5ms(2); GO = 1; while(GO); // GO = GODONEビット 0になるまで待つ value = (ADRESH * 256 + ADRESL) * 2; value = (long)value * 3300 / 1023; // 実測値(理論3300) return(value); } /***** 開始前の表示 *****/ void hyoji1(void){ itostring(4,C3,Title0+10); lcd_cmd(0x80); lcd_str(Title0); } /***** 放電中の表示 *****/ void hyoji2(void){ itostring(3,Cul1,Title1+10); itostring(4,C3, Title2+5); lcd_cmd(0x80); lcd_str(Title1); lcd_cmd(0xC0); lcd_str(Title2); } /***** 充電中の表示 *****/ void hyoji3(void){ itostring(3,Cul2,Title3+10); itostring(4,C3,Title4+5); lcd_cmd(0x80); lcd_str(Title3); lcd_cmd(0xC0); lcd_str(Title4); } /*** 5us遅延タイマ ***/ void delay_5us(unsigned char time){ while(time){ __delay_us(5); // 5usec time--; // 5usec x time } } /*** 5ms遅延タイマ ***/ void delay_5ms(unsigned char time){ while(time){ __delay_ms(5); // 5msec time--; // 5msec x time } } /*** 100ms遅延タイマ ***/ void delay_100ms(unsigned char time){ while(time){ __delay_ms(100);// 100msec time--; // 100msec x time } } /*************************************** * int整数からASCII文字に変換 ****************************************/ void itostring(char digit, unsigned int data, char *buffer){ char i; buffer += digit; // 最後の数字位置 for(i=digit; i>0; i--) { // 変換は下位から上位へ buffer--; // ポインター1 *buffer = (data % 10) + '0';// ASCIIへ data = data / 10; // 次の桁へ } } /***************************** * I2c Start *****************************/ void I2CStart(void){ /* SCL,SDAは常時Highとする */ SDA = 0; // 先に SDA=Low TRISSDA = 0; // SDA出力 } /***************************** * I2c Stop *****************************/ void I2CStop(void){ SCL = 0; // SCL Low SDA = 0; // SDA Low TRISSDA = 0; // 出力モードに戻す SCL = 1; // 先にSCLをHigh SDA = 1; // 後からSDAをHigh } /**************************** * I2Cで1バイト出力 ****************************/ unsigned char I2COut(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; // SCL 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チェック for delay ACK = SDA; // ACKチェック SCL = 1; // クロックHighに戻す return(ACK); // ACKを戻り値とする } /********************************* * 液晶へ1文字表示データ出力 *********************************/ void lcd_data(unsigned char data){ I2CStart(); // スタート I2COut(0x7C); // アドレス I2COut(0x40); // 表示データ指定 I2COut(data); // 表示データ出力 I2CStop(); // ストップ delay_5us(6); // 遅延 } /******************************* * 液晶へ1コマンド出力 *******************************/ void lcd_cmd(unsigned char cmd){ I2CStart(); // スタート I2COut(0x7C); // アドレス I2COut(0x00); // コマンド指定 I2COut(cmd); // コマンド出力 I2CStop(); // ストップ /* ClearかHomeか */ if((cmd == 0x01)||(cmd == 0x02)) delay_5ms(1); // 5msec待ち else delay_5us(6); // 30μsec待ち } /***************************** * 文字列表示 *****************************/ void lcd_str(char *ptr){ while(*ptr != 0) //文字取り出し lcd_data(*ptr++);//文字表示 } /*** LCD 初期化 ***/ void lcd_init(void){ delay_100ms(1); lcd_cmd(0x38); // 8bit 2line Normal mode delay_5us(6); lcd_cmd(0x39); // 8bit 2line Extend mode delay_5us(6); lcd_cmd(0x14); // OSC 183Hz BIAS 1/5 delay_5us(6); /** コントラスト設定 **/ lcd_cmd(0x73); // Contrast set:推奨値(73) delay_5us(6); lcd_cmd(0x56); // Power/ICON/Contrast control delay_5us(6); lcd_cmd(0x6C); // Follwer for 3.3V delay_100ms(2); lcd_cmd(0x38); // 標準コマンド指定=0x38 delay_5us(6); lcd_cmd(0x01); // Clear Display( =0x01) delay_5us(6); lcd_cmd(0x0C); // Display On/Off Control( =0x0C) delay_5us(6); lcd_cmd(0x06); // EntryModeSet:カーソルは右へ=0x06(通常) delay_5ms(1); }