KIT Solar Car Project / Mbed 2 deprecated BMS_6804_pb

Dependencies:   mbed INA226

main.cpp

Committer:
takuma1
Date:
2021-04-08
Revision:
5:f07de56debf3
Parent:
4:e57b023e41f3

File content as of revision 5:f07de56debf3:


#include "mbed.h"
#include "bms.h"
#include "LTC681x.h"
#include "LTC6811.h"
#include "INA226.hpp"



#define UI_BUFFER_SIZE 64
#define SERIAL_TERMINATOR '\n'

#define ENABLED 1
#define DISABLED 0

#define DATALOG_ENABLED 1
#define DATALOG_DISABLED 0



DigitalOut led1(LED1);
Serial pc(USBTX, USBRX);
CAN canSlave(p30,p29);
I2C i2c(p28,p27);
DigitalOut led2(LED2);
DigitalOut BAT_MIN_safty(p21);
DigitalOut BAT_MAX_safty(p22);
//Timer timer;  //書き込み時間を計測するタイマ

// CAN関係
short int forSend = 0;        //データ送信時に一時的に使用する変数
bool CANsendOK = 0;  //CAN送信完了時,セットする(mainでのprintfのため)
CANMessage msgSlave1;    //CAN送信用
short int  canSlaveID = 0x20;   //canSlaveのIDをに設定
void Handler_canSend();
bool flag_can = 1;

//測定関係の関数(変更の際触る必要がない)
void run_command(uint32_t cmd); //測定コマンド送信関数
void measurement_loop(uint8_t datalog_en);
void print_cells(uint8_t datalog_en); //セル電圧の測定表示関数
void print_open();
void print_aux(uint8_t datalog_en);
void print_stat();
void print_config();
void print_rxconfig();
void print_pec(void);
void serial_print_hex(uint8_t data);
void check_error(int error);

//測定関係関数(使ってる)
void wakeup();//ICの起動関数、消費電力削減関数
void cell_read();//セルの電圧の読み込みコマンド
void spi_error();//SPIエラー処理関数
void ic_check();//ICが測定可能状態か診断して次のコマンドに持ち込むための関数
void spi_check();//SPIエラーの確認関数
void print_CAN(uint8_t datalog_en);//セルの電圧の表示コマンドと過充電過放電検出
void BAT_safty();
void print_math();
void can_sent1();
void can_sent2();
void can_sent3();
void can_sent4();
//void can_set();
void can_wait();
void ic_set();




const uint8_t TOTAL_IC = 3; //IC数
char ui_buffer[UI_BUFFER_SIZE];



const uint8_t ADC_CONVERSION_MODE = MD_7KHZ_3KHZ;
const uint8_t ADC_DCP = DCP_DISABLED; 
const uint8_t CELL_CH_TO_CONVERT = CELL_CH_ALL; 
const uint8_t AUX_CH_TO_CONVERT = AUX_CH_ALL; 
const uint8_t STAT_CH_TO_CONVERT = STAT_CH_ALL; 

const uint16_t MEASUREMENT_LOOP_TIME = 10;//milliseconds(mS)
const uint16_t OV_THRESHOLD = 41000; //
const uint16_t UV_THRESHOLD = 30000; // 


const uint8_t WRITE_CONFIG = DISABLED; 
const uint8_t READ_CONFIG = DISABLED;
const uint8_t MEASURE_CELL = ENABLED; 
const uint8_t MEASURE_AUX = DISABLED; 
const uint8_t MEASURE_STAT = DISABLED; 
const uint8_t PRINT_PEC = DISABLED; 
short n =0;

uint8_t read_data();

float read_float();
INA226 VCmonitor(i2c); // INA226

int32_t read_int();
float BAT_MIN ; 
float BAT_MAX ;
float BAT_AVG ;
double BAT_C;
float BAT_SUM;
unsigned short BAT_CELL[23];

char *read_string();
/*
int Replace1;
int Replace2; 
int Replace3;
int Replace4;
*/

int8_t read_char();

cell_asic bms_ic[TOTAL_IC];


void Handler_canSend() {
    
     int Replace1 = 0;
     int Replace2 = 0;
     int Replace3 = 0;
     short int Replace4 = 0;

    short n =0;
    int BAT_SUM = 0; // 0にする
    int BAT_MIN = 55876;
    double C;
    //unsigned short BTA_MAX = 0;
    
    for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) {
        for (int i=0; i < bms_ic[0].ic_reg.cell_channels; i++) {
                                                                       
                     //pc.printf("C%d:", i+1);
                    printf("%.4f, ",bms_ic[current_ic].cells.c_codes[i]*0.0001);
                     BAT_SUM = bms_ic[current_ic].cells.c_codes[i] +  BAT_SUM;
                     
                     if(bms_ic[current_ic].cells.c_codes[i] > 10000){ 
                     if(bms_ic[current_ic].cells.c_codes[i] < BAT_MIN){
                           BAT_MIN = bms_ic[current_ic].cells.c_codes[i];
                                                                      }
                                                                      }
                                                                 
                     if( bms_ic[current_ic].cells.c_codes[i] > BAT_MAX){
                           BAT_MAX = bms_ic[current_ic].cells.c_codes[i];
                                                                       }
                                                                       }
                                                                      
                    if(VCmonitor.getCurrent(&C) == 0){       // INA226
                        BAT_C = C;
                        printf("C,%f\n",C);
                                                    }
            
        }
// BMA_SUM
    Replace1 = (int)(BAT_SUM / 100); 
    msgSlave1.data[0] = Replace1 / 100; 
    msgSlave1.data[1] = Replace1 % 100;    
//BAT_MIN     
    Replace2 = (int)(BAT_MIN / 10); 
    msgSlave1.data[2] = Replace2 / 100;   
    msgSlave1.data[3] = Replace2 % 100;
//BAT_MAX
    Replace3 = (int)(BAT_MAX /10);        
    msgSlave1.data[4] = Replace3 / 100;
    msgSlave1.data[5] = Replace3 % 100;
//BAT_C

  //short BAT_C = -233; 
    if(BAT_C < 1000){
        BAT_C = BAT_C + 9002;
                    }
        
    if(BAT_C < 0){   //正電流か負電流を判定する
        BAT_C = BAT_C + 9001;  //負だと正の電流に変更する。さらにモニタ側でマイナスに戻すための定数を9001とする
                               //最大放電電流は50000mA 充電電流は-40000mAであるため9001とした。
                 }
                 
    Replace4 = (short int)(BAT_C / 1); 
    msgSlave1.data[6] = Replace4 / 100;   
    msgSlave1.data[7] = Replace4 % 100; 
    pc.printf("BAT_C %d\n",Replace4 );   
    printf("Data in msgSlave1.data[6] : %d\n\r", msgSlave1.data[6]); 
    
    
    if(canSlave.write(msgSlave1)){   //格納したデータを送信する
        led1 = !led1;
        CANsendOK = 1;
                                 }
    ic_check();
}

void Handler_canRecieve(){ //canMasterから送信要求が来たとき,データ送信するための関数
    if( flag_can ){ 
        if( canSlave.read( msgSlave1 ) ){ //msgに送られたデータが入る   
            led2 = !led2;
            if( msgSlave1.id == canSlaveID ){ //IDがcanSlaveIDであれば処理する   
                Handler_canSend();
            }
        }
    }
}

int main(void)
{
    uint32_t user_command;
    //short int BAT_C = 2322;
    pc.baud(115200);
    
    //printf("main()\n\r");
    canSlave.attach(&Handler_canRecieve, CAN::RxIrq);   //CAN受信割り込みの設定
    msgSlave1.id = canSlaveID; //CAN送信側(slave)のIDを決定
    msgSlave1.len = 8;   //CAN送信側で送るデータのバイト数
    
    while(1) { 
        BAT_MIN = 0;
        BAT_MAX = 0;   // 0にする
        /*
    if ( fp == NULL )
    {
        pc.printf("USB fileopen!\r\n");
        exit(1);
    }
        FILE *fp = fopen( "/usb/test.csv", "w");   //ファイルを開く   "W"は新規作成して書き込みっていう命令?
      */
          ic_check();
        //timer.start();    //書き込み時間測定開始
        //timer.stop();     //書き込み時間測定終了
        //fclose(fp);         //ファイルを閉じる
         if( CANsendOK ) {
            CANsendOK = 0;     
            printf("Data in msgSlave1.data[0] : %d\n\r", msgSlave1.data[0]);    //CANで送信したデータをそのまま表示
            printf("Data in msgSlave1.data[1] : %d\n\r", msgSlave1.data[1]);    //上に同じ
            printf("Data in msgSlave1.data[2] : %d\n\r", msgSlave1.data[2]);    //上に同じ
            printf("Data in msgSlave1.data[3] : %d\n\r", msgSlave1.data[3]);  
            printf("Data in msgSlave1.data[4] : %d\n\r", msgSlave1.data[4]);  
            printf("Data in msgSlave1.data[5] : %d\n\r", msgSlave1.data[5]);  
            printf("Data in msgSlave1.data[6] : %d\n\r", msgSlave1.data[6]);   
            printf("Data in msgSlave1.data[7] : %d\n\r", msgSlave1.data[7]);   //上に同じ
            printf("\n\r");
                        } 
        BAT_safty();
    }
}

/*
void ic_set(){
        
  //      __disable_irq();
//        flag_can = 0;
        ic_check();
        spi_check();
        spi_error();
        wakeup();
        cell_read();
           }
*/
void ic_check(){  //1

//__disable_irq();
   
    spi_enable();
    LTC681x_init_cfg(TOTAL_IC, bms_ic);
    LTC6811_reset_crc_count(TOTAL_IC,bms_ic);
    LTC6811_init_reg_limits(TOTAL_IC,bms_ic);
    wakeup_sleep(TOTAL_IC);
            LTC6811_wrcfg(TOTAL_IC,bms_ic);
            print_config();
            spi_check();           
}
    
    
void spi_check(){  //2

//__disable_irq();
     int countup;
    int8_t error = 0;
    
     wakeup_sleep(TOTAL_IC);
            error = LTC6811_rdcfg(TOTAL_IC,bms_ic);
            check_error(error);
            print_rxconfig();           
            spi_error();    
               }

void wakeup(){  //3

 //__disable_irq();
    int countup;
    int8_t error = 0;
    uint32_t conv_time = 0;
                 
                 
            wakeup_sleep(TOTAL_IC);
            LTC6811_adcv(ADC_CONVERSION_MODE,ADC_DCP,CELL_CH_TO_CONVERT);
            conv_time = LTC6811_pollAdc();
            cell_read();
            }
    
    
void spi_error(){
             
          //  __disable_irq();
            
            int8_t error = 0;
            int countup;
            /*
            if(error = -1 ){
            for(countup = 0; countup <= 2; countup++){
             spi_check();
            if(error =1){             
                 break;
                        }
                                                        }                                       
                           }
             if(error = 1){
                   wakeup();
                          }
                          */
             wakeup();
                 }
                 
void cell_read(){  //4  電圧読み取り

 //__disable_irq();
    int8_t error = 0;
    uint32_t conv_time = 0;
    int8_t readIC=0;
    
         wakeup_sleep(TOTAL_IC);
            error = LTC6811_rdcv(0, TOTAL_IC,bms_ic); 
            check_error(error);
            //print_cells(DATALOG_DISABLED);
             print_CAN(DATALOG_DISABLED);
                }           

void print_CAN(uint8_t datalog_en){
    /*
__disable_irq();
    short n =0;
    int BAT_SUM = 0; // 0にする
    int BAT_MIN = 55876;
    double C;
    //unsigned short BTA_MAX = 0;
        
    for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) {
        for (int i=0; i < bms_ic[0].ic_reg.cell_channels; i++) {
                                                                       
                     //pc.printf("C%d:", i+1);
                    //pc.printf("%.4f, ",bms_ic[current_ic].cells.c_codes[i]*0.0001);
                     BAT_SUM = bms_ic[current_ic].cells.c_codes[i] +  BAT_SUM;           
                     if(bms_ic[current_ic].cells.c_codes[i] > 10000){ 
                     if(bms_ic[current_ic].cells.c_codes[i] < BAT_MIN){
                           BAT_MIN = bms_ic[current_ic].cells.c_codes[i];
                                                                      }
                                                                      }
                                                                 
                     if( bms_ic[current_ic].cells.c_codes[i] > BAT_MAX){
                           BAT_MAX = bms_ic[current_ic].cells.c_codes[i];
                                                                       }
                                                                      
                    if(VCmonitor.getCurrent(&C) == 0){       // INA226
                        BAT_C = C;
                        //printf("C,%f\n",C);
                                                    }
            }
        } 
        /*
    for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) {
        
        //if (datalog_en == 0) {
            //pc.printf("IC%d, ", current_ic+1);
            //for(n = 0; n <= 12; n++){
        for (int i=0; i < bms_ic[0].ic_reg.cell_channels; i++) {
                    
                    //BAT_CELL= bms_ic[current_ic].cells.c_codes[i];
                                                                        
                    //fprintf(fp,"C%d:", i+1);
                    //fprintf(fp,"%.4f, ",bms_ic[current_ic].cells.c_codes[i]*0.0001);
                     BAT_SUM = bms_ic[current_ic].cells.c_codes[i] +  BAT_SUM;
                     
                     if(bms_ic[current_ic].cells.c_codes[i] > 10000){
                     if(bms_ic[current_ic].cells.c_codes[i] < BAT_MIN){
                           BAT_MIN = bms_ic[current_ic].cells.c_codes[i];
                                                                      }
                                                                      }
                    //unsigned short BTA_MAX = 0;                                                 
                     if( bms_ic[current_ic].cells.c_codes[i] > BAT_MAX){
                           BAT_MAX = bms_ic[current_ic].cells.c_codes[i];
                                                                       }                                                             
                    if(VCmonitor.getCurrent(&C) == 0){       // INA226
                        BAT_C = C;
                                                     }
                                                     
    }
        }             
                         
                    fprintf(fp,"SUM");
                    fprintf(fp,"%0.4f, ",BAT_SUM*0.0001);
                    BAT_AVG = BAT_SUM / 20;
                    fprintf(fp,"AVG");
                    fprintf(fp,"%.4f, ",BAT_AVG*0.0001);
                    fprintf(fp,"MIN");
                    fprintf(fp,"%.4f, ",BAT_MIN*0.0001);
                    fprintf(fp,"MAX");
                    fprintf(fp,"%.4f, ",BAT_MAX*0.0001);
                    fprintf(fp,"BAT_Current,%f\n",BAT_Current);           
    */
    }
       
void BAT_safty(){
      if( BAT_MIN < 25000 ){
                            BAT_MIN_safty = 1 ;
                            wait(1);
                            BAT_MIN_safty = 0 ;         
                           } 
     if( BAT_MAX > 42000){
                            BAT_MAX_safty = 1;
                            wait(1);
                            BAT_MAX_safty = 0;
                          }
     if(BAT_C > 60000){
                            BAT_MIN_safty = 1 ;
                            wait(1);
                            BAT_MIN_safty = 0 ;
                            }
                }
                
                
void measurement_loop(uint8_t datalog_en)
{
    int8_t error = 0;
    if (WRITE_CONFIG == ENABLED) {
        wakeup_sleep(TOTAL_IC);
        LTC6811_wrcfg(TOTAL_IC,bms_ic);
        print_config();
    }

    if (READ_CONFIG == ENABLED) {
        wakeup_sleep(TOTAL_IC);
        error = LTC6811_rdcfg(TOTAL_IC,bms_ic);
        check_error(error);
        print_rxconfig();
    }

    if (MEASURE_CELL == ENABLED) {
        wakeup_idle(TOTAL_IC);
        LTC6811_adcv(ADC_CONVERSION_MODE,ADC_DCP,CELL_CH_TO_CONVERT);
        LTC6811_pollAdc();
        wakeup_idle(TOTAL_IC);
        error = LTC6811_rdcv(0, TOTAL_IC,bms_ic);
        check_error(error);
        print_cells(datalog_en);

    }

    if (MEASURE_AUX == ENABLED) {
        wakeup_idle(TOTAL_IC);
        LTC6811_adax(ADC_CONVERSION_MODE , AUX_CH_ALL);
        LTC6811_pollAdc();
        wakeup_idle(TOTAL_IC);
        error = LTC6811_rdaux(0,TOTAL_IC,bms_ic); // Set to read back all aux registers
        check_error(error);
        print_aux(datalog_en);
    }

    if (MEASURE_STAT == ENABLED) {
        wakeup_idle(TOTAL_IC);
        LTC6811_adstat(ADC_CONVERSION_MODE, STAT_CH_ALL);
        LTC6811_pollAdc();
        wakeup_idle(TOTAL_IC);
        error = LTC6811_rdstat(0,TOTAL_IC,bms_ic); // Set to read back all aux registers
        check_error(error);
        print_stat();
    }

    if (PRINT_PEC == ENABLED) {
        print_pec();
    }

}



void print_cells(uint8_t datalog_en)
{
    for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) {

        if (datalog_en == 0) {
            pc.printf("IC%d, ", current_ic+1);
            for (int i=0; i < bms_ic[0].ic_reg.cell_channels; i++) {
                pc.printf("C%d:", i+1);
                pc.printf("%.4f, ", bms_ic[current_ic].cells.c_codes[i]*0.0001);
                } 
                   
            pc.printf("\n");
            }
            
        else {
            pc.printf("Cells, ");
            for (int i=0; i<bms_ic[0].ic_reg.cell_channels; i++) {
                pc.printf("%.4f, ",bms_ic[current_ic].cells.c_codes[i]*0.0001);  
                
            }
        }
        
    }
    pc.printf("\n");
}

void print_open()
{
    for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++) {
        if (bms_ic[current_ic].system_open_wire == 0) {
            pc.printf("No Opens Detected on IC%d\n", current_ic+1);
        } else {
            for (int cell=0; cell<bms_ic[0].ic_reg.cell_channels+1; cell++) {
                if ((bms_ic[current_ic].system_open_wire &(1<<cell))>0) {
                    pc.printf("There is an open wire on IC%d Channel: %d\n", current_ic + 1, cell);
                }
            }
        }
    }
}


void print_aux(uint8_t datalog_en)
{

    for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++) {
        if (datalog_en == 0) {
            pc.printf(" IC%d", current_ic+1);
            for (int i=0; i < 5; i++) {
                pc.printf(" GPIO-%d:%.4f,", i+1, bms_ic[current_ic].aux.a_codes[i]*0.0001);
            }
            pc.printf("Vref2:%.4f\n", bms_ic[current_ic].aux.a_codes[5]*0.0001);
        } else {
            pc.printf("AUX, ");
            for (int i=0; i < 6; i++) {
                pc.printf("%.4f,", bms_ic[current_ic].aux.a_codes[i]*0.0001);
            }
        }
    }
    pc.printf("\n");
}


void print_stat()
{

    for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++) {
        pc.printf("IC%d", current_ic+1);
        pc.printf(" SOC:%.4f,", bms_ic[current_ic].stat.stat_codes[0]*0.0001*20);
        pc.printf(" Itemp:%.4f,", bms_ic[current_ic].stat.stat_codes[1]*0.0001);
        pc.printf(" VregA:%.4f,", bms_ic[current_ic].stat.stat_codes[2]*0.0001);
        pc.printf(" VregD:%.4f\n", bms_ic[current_ic].stat.stat_codes[3]*0.0001);
    }

    pc.printf("\n");
}


void print_config()
{
    int cfg_pec;

    //pc.printf("Written Configuration: \n");
    for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++) {
        //pc.printf(" IC ");
        //pc.printf("%d", current_ic+1);
       // pc.printf(": ");
        //pc.printf("0x");
        serial_print_hex(bms_ic[current_ic].config.tx_data[0]);
       // pc.printf(", 0x");
        serial_print_hex(bms_ic[current_ic].config.tx_data[1]);
        //pc.printf(", 0x");
        serial_print_hex(bms_ic[current_ic].config.tx_data[2]);
        //pc.printf(", 0x");
        serial_print_hex(bms_ic[current_ic].config.tx_data[3]);
       // pc.printf(", 0x");
        serial_print_hex(bms_ic[current_ic].config.tx_data[4]);
       // pc.printf(", 0x");
        serial_print_hex(bms_ic[current_ic].config.tx_data[5]);
        //pc.printf(", Calculated PEC: 0x");
        cfg_pec = pec15_calc(6,&bms_ic[current_ic].config.tx_data[0]);
        serial_print_hex((uint8_t)(cfg_pec>>8));
        //pc.printf(", 0x");
        serial_print_hex((uint8_t)(cfg_pec));
       // pc.printf("\n");
    }
   // pc.printf("\n");
}


void print_rxconfig()
{
    //pc.printf("Received Configuration ");
    for (int current_ic=0; current_ic<TOTAL_IC; current_ic++) {
       // pc.printf(" IC ");
      //  pc.printf("%d", current_ic+1);
        //pc.printf(": 0x");
        serial_print_hex(bms_ic[current_ic].config.rx_data[0]);
        //pc.printf(", 0x");
        serial_print_hex(bms_ic[current_ic].config.rx_data[1]);
        //pc.printf(", 0x");
        serial_print_hex(bms_ic[current_ic].config.rx_data[2]);
        //pc.printf(", 0x");
        serial_print_hex(bms_ic[current_ic].config.rx_data[3]);
        //pc.printf(", 0x");
        serial_print_hex(bms_ic[current_ic].config.rx_data[4]);
       // pc.printf(", 0x");
        serial_print_hex(bms_ic[current_ic].config.rx_data[5]);
        //pc.printf(", Received PEC: 0x");
        serial_print_hex(bms_ic[current_ic].config.rx_data[6]);
        //pc.printf(", 0x");
        serial_print_hex(bms_ic[current_ic].config.rx_data[7]);
       // pc.printf("\n");
    }
    pc.printf("\n");
}

void print_pec()
{
    for (int current_ic=0; current_ic<TOTAL_IC; current_ic++) {
        pc.printf("\n%d", bms_ic[current_ic].crc_count.pec_count);
        pc.printf(" : PEC Errors Detected on IC");
        pc.printf("%d\n", current_ic+1);
    }
}


void serial_print_hex(uint8_t data)
{
    /*
    if (data < 16) {
        //pc.printf("0x0%X", data);
    } else
       pc.printf("0x%X", data);
       */
}

//Function to check error flag and print PEC error message
void check_error(int error)
{
    if (error == -1) {
        pc.printf("A PEC error was detected in the received data");
    }
}



char hex_digits[16]= {
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};



char hex_to_byte_buffer[5]= {
    '0', 'x', '0', '0', '\0'
};               // buffer for ASCII hex to byte conversion
char byte_to_hex_buffer[3]= {
    '\0','\0','\0'
};

// シリアル インターフェイスから ui_バッファへのデータの読み取り
uint8_t read_data()
{
    uint8_t index = 0; // 内の現在の場所を保持するインデックス
    int c; // 着信キーストロークの格納に使用される単一の文字
    //pc.printf("check 1\n");
    while (index < UI_BUFFER_SIZE-1) {
        //pc.printf("check 2\n");
        c = pc.getc(); 
        //return c;
        //pc.printf("check 3\n");
        
        if (((char) c == '\r') || ((char) c == '\n')) break; 
        if ( ((char) c == '\x7F') || ((char) c == '\x08') ) { 
            if (index > 0) index--;
        } else if (c >= 0) {
            ui_buffer[index++]=(char) c; 
        }
        //pc.printf("check 4\n");
        
    }
    ui_buffer[index]='\0';  

    if ((char) c == '\r') {  
        wait_ms(1);
        //pc.printf("check 5\n");
        
        if (pc.readable()==1) {
            //pc.printf("check 6\n");
            pc.getc(); 
        }
        
        
    }
    
        
    return index; 
}


float read_float()
{
    float data;
    read_data();
    data = atof(ui_buffer);
    return(data);
}


int32_t read_int()
{
    int32_t data;
    read_data();
    if (ui_buffer[0] == 'm')
        return('m');
    if ((ui_buffer[0] == 'B') || (ui_buffer[0] == 'b')) {
        data = strtol(ui_buffer+1, NULL, 2);
    } else
        data = strtol(ui_buffer, NULL, 0);
    return(data);
}

char *read_string()
{
    read_data();
    return(ui_buffer);
}


int8_t read_char()
{
    read_data();
    return(ui_buffer[0]);
}