//
//
// solar_charger.c by PIC16F88. 2台の電圧電流計INA226の読み込み及びBQ24650EVMの制御。
// VisualBasic2008のproject名solar_charger　電圧／電流計測結果の読み込み
//
//太陽電池充電器制御及び電圧電流測定結果表示、内部RC 2MHZ
//
//INA226が16回の平均を取るように設定する。それ以外は基本通りの使い方。
//
//  create 2014.4.19
//  update 2014.5.24　USARTの追加
//  update 2014.5.26　クロックの変更
//  update 2014.6.24　ポートの変更、INT0割込みの追加
//  update 2014.6.30　INT0割込みの追加
//  update 2014.7.2　 Calibration Registerの内容が勝手に書き換わるため、
//                    INA226とのデータ通信をタイマー1の100ms毎に変更する。
//  update 2014.7.12  PC側のシリアル受信が誤読しているためBAUDを下げる
//  update 2014.7.17  1byteテータを4bitずつに分け、0x30を加え2byteデータにする。16byte+チェックデジット1byteの送信。baudは4800に戻す
//                    cdの計算は送信する16byteデータを加算した結果の下位4bit＋0x30とする
//  update 2014.8.15  充電完了電圧に達してからの経過時間表示。上段スイッチを押したままで、中断スイッチを操作。@A
//  update 2014.9.1   充電完了電圧に達してからの経過時間表示数の追加。9個を順繰りに表示。
//  update 2014.9.3   継続時間カウンタを1byteから2byte変数へ変更。表示も3桁から4桁へ変更。9999分＝166.5時間。1byte3桁だと4.25時間と微妙に少ないか。
//  update 2014.9.6   シャットダウン機能追加。充電指示(out_chargeがhigh)かつVout＞10VかつI＜?7のときはシャットダウンする。
//
#include <16f88.h>    //*
#fuses INTRC_IO,WDT,NOPROTECT,NOBROWNOUT,PUT,NOLVP,NODEBUG,MCLR//*,NOPBADEN,NOFCMEN,NOIESO,
//NOWDTはプログラム中でWDTを使用する場合ここではNO指定が必要。NOIESOも同様か？
#use delay(CLOCK =  4000000)                            //クロック周波数指定。setup_oscillatorと一致させること。
#use rs232(BAUD = 4800, XMIT = PIN_B5, RCV = PIN_B2)    //USART設定4800bps*
#use fast_io(A)
#use i2c(master, sda=PIN_B1, scl=PIN_B4,SLOW,FORCE_SW)
//ポートのio指定は以下で行うこと。
#define mode          0b00110000//@A
//RA0   :out LCD data DB4
//RA1   :out LCD data DB5
//RA2   :out LCD data DB6
//RA3   :out LCD data DB7
//RA4   :in 切替え@A
//RA5   :in  MCKR.
//RA6   :out LCD RS
//RA7   :out LCD E
#define input_x         input_A         //ポートA使用
#define output_x        output_A
#define set_tris_x      set_tris_A//
#define   sw            PIN_A4      //切替え信号入力。アクティブLOW@A
#define   rs            PIN_A6
#define   stb           PIN_A7
#include  <lcd_lib4.c>//この位置に記述しないとコンパイルエラーとなる。
//
#define port_b_io       0b00000101//
//RB0   :in not used
//RB1   :i/o i2c sda set_tris_Bでは取りあえず出力モード
//RB2   :in RX
//RB3   :out Shutdown　LT1129シャットダウンピンへ
//RB4   :i/o i2c scl set_tris_Bでは取りあえず出力モード
//RB5   :out TX
//RB6   :out led
//RB7   :out charge sw　アクティブhigh
#define out_shdn        PIN_B3
#define out_led         PIN_B6
#define out_charge      PIN_B7
//
//
//#define timer1_interval 0x85ee  //500ms=( (1/clock=  2MHZ)×4×8×31250 )。2^16-31250=34286(85ee)からスタートしてオーバーフローさせて割込1を使用。
//#define timer1_interval 0x0bdc  //500ms=( (1/clock=  4MHZ)×4×8×62500 )。2^16-62500=3036(bdc)からスタートしてオーバーフローさせて割込1を使用。
#define timer1_interval 0xcf2c  //100ms=( (1/clock=  4MHZ)×4×8×12500 )。2^16-12500=53036(cf2c)からスタートしてオーバーフローさせて割込1を使用。
////// その他
static int      result;//*
static int      i;//
static int1     int_usart;              //USART外部割込フラグ
static int      lcd_cnt;                 //液晶画面の区別。0は通常、1以上は充電完了電圧表示@A
static int1     timer1_1s = 0;          //1s毎に1となるフラグ。@A
static int1     timer1_100ms = 0;       //100ms毎に1となるフラグ。
static int1     int0_f = 0;
static int1     dsp_sw = 0;
static int      timer1_500ms_cnt = 0;
static int      timer1_1s_cnt = 0;//@A
static long     timer1_60s_cnt = 0;//@A
static int      avg_cnt = 0;//電圧の合計回数(1-10)@A
static int      vh1;//電圧値の上位1バイト
static int      vh1h;//電圧値の上位1バイトを4bitに分けて0x30を加えた上位
static int      vh1l;//電圧値の上位1バイトを4bitに分けて0x30を加えた下位
static int      vl1;//電圧値の下位1バイト
static int      vl1h;//電圧値の下位1バイトを4bitに分けて0x30を加えた上位
static int      vl1l;//電圧値の下位1バイトを4bitに分けて0x30を加えた下位
static int      ch1;//電流値の上位1バイト
static int      ch1h;//電流値の上位1バイトを4bitに分けて0x30を加えた上位
static int      ch1l;//電流値の上位1バイトを4bitに分けて0x30を加えた下位
static int      cl1;//電流値の下位1バイト
static int      cl1h;//電流値の下位1バイトを4bitに分けて0x30を加えた上位
static int      cl1l;//電流値の下位1バイトを4bitに分けて0x30を加えた下位
static int      vh2;//電圧値の上位1バイト
static int      vh2h;//電圧値の上位1バイトを4bitに分けて0x30を加えた上位
static int      vh2l;//電圧値の上位1バイトを4bitに分けて0x30を加えた下位
static int      vl2;//電圧値の下位1バイト
static int      vl2h;//電圧値の下位1バイトを4bitに分けて0x30を加えた上位
static int      vl2l;//電圧値の下位1バイトを4bitに分けて0x30を加えた下位
static int      ch2;//電流値の上位1バイト
static int      ch2h;//電流値の上位1バイトを4bitに分けて0x30を加えた上位
static int      ch2l;//電流値の上位1バイトを4bitに分けて0x30を加えた下位
static int      cl2;//電流値の下位1バイト
static int      cl2h;//電流値の下位1バイトを4bitに分けて0x30を加えた上位
static int      cl2l;//電流値の下位1バイトを4bitに分けて0x30を加えた下位
static int      cd;//チェックデジット用バイト。上記16byteの合計値。
//static char     vh1c;//電圧値の上位1バイト
//static char     vl1c;//電圧値の下位1バイト
//static char     ch1c;//電流値の上位1バイト
//static char     cl1c;//電流値の下位1バイト
//static char     vh2c;//電圧値の上位1バイト
//static char     vl2c;//電圧値の下位1バイト
//static char     ch2c;//電流値の上位1バイト
//static char     cl2c;//電流値の下位1バイト

static long         pass_cnt;//充電完了電圧になってから（出力電圧の最大値）の経過時間（分）@A
static long         d_pass_cnt[10];//[0]には現在値更新中の最高値継続時間
static long         voltage_16;//2バイトの電圧値
static long         avg_voltage_16;//2バイトの電圧値の10回平均値@A
static long         max_voltage_16;//2バイトの電圧値の10回平均値の最大値@A
static long         d_max_voltage_16[10];//[0]には現在値更新中の最高値
static int32        sum_voltage_32;//2バイトの電圧値の10回平均の合計@A
static signed long  current_s16;//符号付2バイトの電流値
static long         test_16;//2バイト
static signed long  test_s16;//符号付2バイト
static int          test_cnt = 0;
static int          set_cnt;//配列にセットするインデックス値
static int          shdn_cnt;//シャットダウンまでのカウンタ。充電開始直後、10mA程度バッテリーから消費される時間を回避するため。
//
//
////////////////////////////////////////////////////////////////////
////// タイマー1割り込み500ms毎。16bitレジスタオーバーフロー割込。
//////////////////////////////////////////////////////////////////
#INT_TIMER1
  void intval1()
  {
        set_timer1(timer1_interval);
//
        timer1_100ms = 1;
        if (  timer1_500ms_cnt == 5)
            {
                 output_toggle(out_led);
                 timer1_500ms_cnt = 0;
            }
        timer1_500ms_cnt = timer1_500ms_cnt + 1;
//
        if (  timer1_1s_cnt == 10)
            {
                 timer1_1s = 1;
                 timer1_1s_cnt = 0;
            }
        timer1_1s_cnt = timer1_1s_cnt + 1;
//
        if (  timer1_60s_cnt == 600)
            {
                pass_cnt = pass_cnt + 1;
                timer1_60s_cnt = 0;
            }
        timer1_60s_cnt = timer1_60s_cnt + 1;
  }
////////////////////////////////////////////////////////////////////
/////// USART外部割込み
////////////////////////////////////////////////////////////////////
#INT_RDA
void intval5()
    {
        int_usart = 1;
        result = getc();//0d(\r)
        clear_interrupt(INT_RDA);
    }
//////////////////////////
/////// 外部割り込み0
//////////////////////////
#INT_EXT
void intval2()
    {
        int0_f = 1;
        clear_interrupt(INT_EXT);
//表示切替え判断のための入力
        if ( input(sw) == 1 )//表示切替え判断のための入力
            {
                if (input_state(out_charge) == 0 )//充電出力はOFF。直後output_toggleでONするので、その前に初期化
                    {
                        sum_voltage_32 = 0;
                        max_voltage_16 = 0;
                        avg_cnt = 0;
                        pass_cnt = 0;
                        lcd_cnt = 0;
                        set_cnt = 0;
                        shdn_cnt = 0;
                        for ( i=0   ;   i<10    ;  i = i + 1)
                            {
                                d_pass_cnt[i] = 0;
                                d_max_voltage_16[i] = 0;
                            }
                    }
                output_toggle(out_charge);     //充電開始出力
            }
        else
            {
                if ( lcd_cnt == 10 )
                    {
                        lcd_cnt = 0;
                    }
                else
                    {
                        lcd_cnt = lcd_cnt + 1;
                    }
            }
    }
//
void  main() {
    setup_oscillator(OSC_4MHZ);   //内部発振子。
    SETUP_WDT(WDT_2304MS);
//
    setup_adc_ports(NO_ANALOGS);
    set_tris_B(port_b_io);
    output_float(PIN_B1);       //I2CピンFLOATモード
    output_float(PIN_B4);       //I2CピンFLOATモード
    output_high(out_shdn);      //LT1129のシャットダウンピンをON
    output_low(out_charge);     //充電開始出力
//
    //Aポートの設定も行う。
    test_cnt = 0;
    test_16 = 0;
    test_s16 = -9999;
    lcd_init();                   //LCD初期化
    lcd_clear();               //LCD全消
    setup_uart(0);//シリアル停止。
    int_usart = 0;
    int0_f = 0;
    timer1_100ms = 0;
    timer1_1s = 0;
    timer1_500ms_cnt = 0;
    timer1_1s_cnt = 0;
    timer1_60s_cnt = 0;
    sum_voltage_32 = 0;
    max_voltage_16 = 0;
    avg_cnt = 0;
    pass_cnt = 0;
    lcd_cnt = 0;
    set_cnt = 0;
    shdn_cnt = 0;
    for ( i=0   ;   i<10    ;  i = i + 1)
        {
            d_pass_cnt[i] = 0;
            d_max_voltage_16[i] = 0;
        }
    ext_int_edge( H_TO_L );             //RB0/INT立ち下がり
    //
    //1行目best
    lcd_cursor(0x80);
    printf(lcd_data,"Solar Charger   ");
    //2行目
    lcd_cursor(0xc0);
    printf(lcd_data,"Controller      ");
    output_low(out_led);
//
    output_high(out_led);
    delay_ms(200);
    output_low(out_led);
    delay_ms(200);
    output_high(out_led);
    delay_ms(200);
    output_low(out_led);
//
    setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 );//内部クロック(Fosc/4、プリスケラー1/8、16bitレジスタ(記述無し)タイマー0の500ms間隔用。
//  未使用モジュールの停止
  //setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 );//内部クロック(Fosc/4、プリスケラー1/256、8bitレジスタ(記述無し)タイマー0の10.24ms間隔用。
  //setup_timer_1(T1_DISABLED);     //未使用タイマーを止める
    setup_timer_2(T2_DISABLED,0,1); //未使用タイマーを止める
    SETUP_CCP1(CCP_OFF);            //未使用モジュールを止める
    setup_adc(ADC_OFF);             //未使用モジュールを止める
//
    setup_uart(1);//シリアル稼働。
    clear_interrupt(INT_EXT);
    clear_interrupt(INT_TIMER1);
    clear_interrupt(INT_TIMER2);
    clear_interrupt(INT_RDA);
    enable_interrupts(INT_EXT);//外部割り込み0許可
    enable_interrupts(INT_TIMER1);//タイマー1許可
    enable_interrupts(INT_RDA);//UASRT割り込み許可
    enable_interrupts(GLOBAL);//全割り込み許可
    set_timer1(timer1_interval);
//
//INA226レジスタ初期設定VIN側
    i2c_start();    //start condition
    i2c_write(0x94);//VIN INA226 address send (0b1001010 0)最下位ビットはライトモードで0)
    i2c_write(0x00);//INA226 Configuration register address 00h send
    i2c_write(0x45);//INA226 Configuration register　上位1バイトデータ send 16回の平均
    i2c_write(0x27);//INA226 Configuration register　下位1バイトデータ send
    i2c_stop();     //stop condition
    i2c_start();    //start condition
    i2c_write(0x94);//VIN INA226 address send (0b1001010 0)最下位ビットはライトモードで0)
    i2c_write(0x05);//INA226 Calibration Register address 05h send
    i2c_write(0x0a);//INA226 Calibration Register　上位1バイトデータ send
    i2c_write(0x00);//INA226 Calibration Register　下位1バイトデータ send
    i2c_stop();     //stop condition
//
//INA226レジスタ初期設定VOUT側
    i2c_start();    //start condition
    i2c_write(0x9a);//VIN INA226 address send (0b1001101 0)最下位ビットはライトモードで0)
    i2c_write(0x00);//INA226 Configuration register address 00h send
    i2c_write(0x45);//INA226 Configuration register　上位1バイトデータ send 16回の平均
    i2c_write(0x27);//INA226 Configuration register　下位1バイトデータ send
    i2c_stop();     //stop condition
    i2c_start();    //start condition
    i2c_write(0x9a);//VIN INA226 address send (0b1001101 0)最下位ビットはライトモードで0)
    i2c_write(0x05);//INA226 Calibration Register address 05h send
    i2c_write(0x0a);//INA226 Calibration Register　上位1バイトデータ send
    i2c_write(0x00);//INA226 Calibration Register　下位1バイトデータ send
    i2c_stop();     //stop condition
//
    dsp_sw = 0;
    lcd_clear();               //LCD全消
    while(1)
            {
                if ( timer1_100ms == 1) 
                    {
                        timer1_100ms = 0;
                        restart_wdt();
                        //Bus電圧取得VIN側
                        i2c_start();    //start condition
                        i2c_write(0x94);//VIN INA226 address send (0b1001010 0)最下位ビットはライドモードで0)
                        i2c_write(0x02);//INA226 Bus register address 02h send
                        i2c_stop();     //stop condition
                        i2c_start();    //start condition
                        i2c_write(0x95);//VIN INA226 address send (0b1001010 1)最下位ビットはリードモードで1)
                        vh1=i2c_read();
                        vl1=i2c_read(0);
                        i2c_stop();
                        //
                        voltage_16=(int16)make16(vh1,vl1)*1.25;
                        if ( lcd_cnt == 0 )
                            {
                                //1行目best
                                lcd_cursor(0x80);
                                printf(lcd_data,"%5lumV ",voltage_16);
                            }
                        else
                            {
                                //1行目best
                                lcd_cursor(0x80);
                                printf(lcd_data,"%5lumVMAX",d_max_voltage_16[lcd_cnt - 1]);
                            }
                        //
                        //Current電流取得VIN側
                        i2c_start();    //start condition
                        i2c_write(0x94);//VIN INA226 address send (0b1001010 0)最下位ビットはライドモードで0)
                        i2c_write(0x04);//INA226 Current register address 04h send
                        i2c_stop();     //stop condition
                        i2c_start();    //start condition
                        i2c_write(0x95);//VIN INA226 address send (0b1001010 1)最下位ビットはリードモードで1)
                        ch1=i2c_read();
                        cl1=i2c_read(0);
                        i2c_stop();
                        //
                        current_s16=make16(ch1,cl1);
                        if ( lcd_cnt == 0 )
                            {
                                //1行目best
                                lcd_cursor(0x88);
                                printf(lcd_data,"%6ldmA",current_s16);
                            }
                        else
                            {
                                //1行目best
                                lcd_cursor(0x8a);
                                printf(lcd_data,"%1u%4lum",lcd_cnt - 1,d_pass_cnt[lcd_cnt - 1]);
                            }
        //
                        //Bus電圧取得VOUT側
                        i2c_start();    //start condition
                        i2c_write(0x9a);//VIN INA226 address send (0b1001101 0)最下位ビットはライドモードで0)
                        i2c_write(0x02);//INA226 Bus register address 02h send
                        i2c_stop();     //stop condition
                        i2c_start();    //start condition
                        i2c_write(0x9b);//VIN INA226 address send (0b1001101 1)最下位ビットはリードモードで1)
                        vh2=i2c_read();
                        vl2=i2c_read(0);
                        i2c_stop();
                        //
                        voltage_16=(int16)make16(vh2,vl2)*1.25;
                        if ( lcd_cnt == 0 )
                            {
                                //2行目best
                                lcd_cursor(0xc0);
                                printf(lcd_data,"%5lumV",voltage_16);
                            }
                        else
                            {
                                //2行目best
                                lcd_cursor(0xc0);
                                printf(lcd_data,"%5lumV",voltage_16);
                            }
                      //printf(lcd_data,"%2X %3u ",result,test_cnt);
                        //
                        //shunt電圧取得VOUT側 テスト用
                      //i2c_start();    //start condition
                      //i2c_write(0x9a);//VIN INA226 address send (0b1001101 0)最下位ビットはライドモードで0)
                      //i2c_write(0x01);//INA226 shunt register address 01h send
                      //i2c_stop();     //stop condition
                      //i2c_start();    //start condition
                      //i2c_write(0x9b);//VIN INA226 address send (0b1001101 1)最下位ビットはリードモードで1)
                      //vh2=i2c_read();
                      //vl2=i2c_read(0);
                      //i2c_stop();
                      //current_s16=make16(vh2,vl2);
                        //Calibration Register VOUT側 テスト用
                      //if (dsp_sw == 1)
                      //{
                      //i2c_start();    //start condition
                      //i2c_write(0x9a);//VIN INA226 address send (0b1001101 0)最下位ビットはライトモードで0)
                      //i2c_write(0x05);//INA226 Calibration Register address 05h send
                      //i2c_stop();     //stop condition
                      //i2c_start();    //start condition
                      //i2c_write(0x9b);//VIN INA226 address send (0b1001101 1)最下位ビットはリードモードで1)
                      //vh2=i2c_read();
                      //vl2=i2c_read(0);
                      //i2c_stop();
                      //}
                        //
                        //2行目best
                      //lcd_cursor(0xc0);
                      //printf(lcd_data,"%2x%2x%4ld",vh2,vl2,current_s16);
                        //
                        //Current電流取得VOUT側
                        i2c_start();    //start condition
                        i2c_write(0x9a);//VIN INA226 address send (0b1001101 0)最下位ビットはライドモードで0)
                        i2c_write(0x04);//INA226 Current register address 04h send
                        i2c_stop();     //stop condition
                        i2c_start();    //start condition
                        i2c_write(0x9b);//VIN INA226 address send (0b1001101 1)最下位ビットはリードモードで1)
                        ch2=i2c_read();
                        cl2=i2c_read(0);
                        i2c_stop();
                        //
                        current_s16=make16(ch2,cl2);
                      //if ( current_s16 == -7)
                      //{
                      //    dsp_sw = 1;
                      //}
                      //else
                      //{
                      //    dsp_sw = 0;
                      //}
                        if ( lcd_cnt == 0 )
                            {
                                //2行目best
                                lcd_cursor(0xc8);
                                printf(lcd_data,"%6ldmA",current_s16);
                            }
                        else
                            {
                                //2行目best
                                lcd_cursor(0xc8);
                                printf(lcd_data,"%6ldmA",current_s16);
                            }
                        //
                    }
                //@A↓
                if ( timer1_1s == 1)
                    {
                        timer1_1s = 0;
                        //
                        d_pass_cnt[0] = pass_cnt;//現在値更新中の最高値継続時間
                        d_max_voltage_16[0] = max_voltage_16;//現在値更新中の最高値
                        //シャットダウン
                        if (input_state(out_charge) == 1 )//充電出力はON。
                            {
                                if (voltage_16 > 10000)//Vout＞10V
                                    {
                                        if (current_s16 < -7 )//I＜?7
                                            {
                                                shdn_cnt = shdn_cnt + 1;
                                                if ( shdn_cnt > 5 )
                                                    {
                                                        output_low(out_shdn);      //LT1129のシャットダウンピンをOFF
                                                        while (1) {restart_wdt();}
                                                    }
                                            }
                                    }
                            }
                        //
                        sum_voltage_32 = sum_voltage_32 + voltage_16;//1秒毎の平均値合算
                        avg_cnt = avg_cnt + 1;
                        if ( avg_cnt == 10 )//10回合算完了
                            {
                                sum_voltage_32 = sum_voltage_32 / 10;//10で割り、平均値を算出
                                avg_voltage_16 = sum_voltage_32;
                                sum_voltage_32 = 0;
                                avg_cnt = 0;
                                if ( max_voltage_16 < ( avg_voltage_16 - 9 ) )//9mVを超える値だったらmaxと入れ替え。
                                    {
                                        if ( set_cnt == 9 )
                                            {
                                                set_cnt = 1;
                                            }
                                        else
                                            {
                                                set_cnt = set_cnt + 1 ;
                                            }
                                                d_max_voltage_16[set_cnt] = max_voltage_16;//今までの最高値を残す
                                                max_voltage_16 = avg_voltage_16;
                                                d_pass_cnt[set_cnt] = pass_cnt;//
                                                pass_cnt = 0;
                                                timer1_60s_cnt = 0;
                                    }
                            }
                    }
                //@A↑
                if (int_usart == 1 )
                    {
                        int_usart = 0;
                      //test_cnt = test_cnt + 1;
                      //vh1=make8(test_16,1);
                      //vl1=make8(test_16,0);
                      //vh2=make8(test_16,1);
                      //vl2=make8(test_16,0);
                      //ch1=make8(test_s16,1);
                      //cl1=make8(test_s16,0);
                      //ch2=make8(test_s16,1);
                      //cl2=make8(test_s16,0);
                      //test_16 = test_16 + 1;
                      //test_s16 = test_s16 + 1;
                        //4bitずつに分け0x30を加え2byteデータにする
                        cd = 0;
                        vh1h = ( vh1>>4 ) | 0x30;
                        cd = cd + vh1h;
                        vh1l = ( vh1 & 0x0f ) | 0x30;
                        cd = cd + vh1l;
                        vl1h = ( vl1>>4 ) | 0x30;
                        cd = cd + vl1h;
                        vl1l = ( vl1 & 0x0f ) | 0x30;
                        cd = cd + vl1l;
                        ch1h = ( ch1>>4 ) | 0x30;
                        cd = cd + ch1h;
                        ch1l = ( ch1 & 0x0f ) | 0x30;
                        cd = cd + ch1l;
                        cl1h = ( cl1>>4 ) | 0x30;
                        cd = cd + cl1h;
                        cl1l = ( cl1 & 0x0f ) | 0x30;
                        cd = cd + cl1l;
                        vh2h = ( vh2>>4 ) | 0x30;
                        cd = cd + vh2h;
                        vh2l = ( vh2 & 0x0f ) | 0x30;
                        cd = cd + vh2l;
                        vl2h = ( vl2>>4 ) | 0x30;
                        cd = cd + vl2h;
                        vl2l = ( vl2 & 0x0f ) | 0x30;
                        cd = cd + vl2l;
                        ch2h = ( ch2>>4 ) | 0x30;
                        cd = cd + ch2h;
                        ch2l = ( ch2 & 0x0f ) | 0x30;
                        cd = cd + ch2l;
                        cl2h = ( cl2>>4 ) | 0x30;
                        cd = cd + cl2h;
                        cl2l = ( cl2 & 0x0f ) | 0x30;
                        cd = cd + cl2l;
                        cd = ( cd & 0x0f ) | 0x30;
                        //vh1c=vh1;
                        //vl1c=vl1;
                        //ch1c=ch1;
                        //cl1c=cl1;
                        //vh2c=vh2;
                        //vl2c=vl2;
                        //ch2c=ch2;
                        //cl2c=cl2;
                     // delay_ms(5);
                        //putc(0);
                        //putc(3);
                        //putc(0);
                        //putc(7);
                        //putc(0);
                        //putc(3);
                        //putc(0);
                        //putc(7);
                        printf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",vh1h,vh1l,vl1h,vl1l,ch1h,ch1l,cl1h,cl1l,vh2h,vh2l,vl2h,vl2l,ch2h,ch2l,cl2h,cl2l,cd);
                        //printf("%c%c%c%c%c%c%c%c",vh1,vl1,ch1,cl1,vh2,vl2,ch2,cl2);
                        //putc(vh1);
                        //putc(vl1);
                        //putc(ch1);
                        //putc(cl1);
                        //putc(vh2);
                        //putc(vl2);
                        //putc(ch2);
                        //putc(cl2);
                    }
    }
}






















