⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 liion_bc_main.c

📁 用C8051F300设计锂离子电池充电器的解决方案!给大家参考!
💻 C
📖 第 1 页 / 共 2 页
字号:
//  voltage in mV, and temperature in C, 2% accurate.
//
int Monitor_Battery(unsigned char value)
{
  char i;
  unsigned long av =0;
  long signed result;

  ADC0CF = (SYSCLK/5000000) << 3;       // ADC conversion clock = 5.0MHz
  ADC0CF &= 0xF8;                       // Clear any Previous Gain Settings
  
  switch (value)
  {
    case TEMPERATURE:
      Turn_PWM_Off();                   // Turn PWM Off   
      AMX0SL = TBAT;                    // Select appropriate input for AMUX
      ADC0CF |= 0x02;                   // Set PGA gain = 2
      break; 
     
    case VOLTAGE: 
      AMX0SL = VBAT;                    // Select appropriate input for AMUX
      ADC0CF |= 0x01;                   // Set PGA gain = 1
      break;   

    case VOLTAGE_PWM_OFF: 
      Turn_PWM_Off();                   // Turn PWM Off   
      AMX0SL = VBAT;                    // Select appropriate input for AMUX
      ADC0CF |= 0x01;                   // Set PGA gain = 1
      break;  

   case CURRENT: 
      AMX0SL = IBAT;                    // Select appropriate input for AMUX
      ADC0CF |= 0x03;                   // Set PGA gain = 4
      break;
   
  }  
  
  //Compute average of next 10 A/D conversions
  for(av=0,i=10;i;--i){ 
    AD0INT = 0;                         // clear end-of-conversion indicator
    AD0BUSY = 1;                        // initiate conversion
    while(!AD0INT);                     // wait for conversion to complete
    av = av+ADC0;
  }

  av = av/10;                           // Compute the average
  av = av<<8;                           // Convert to 16-bit conversion
                                        // ...to account for 16-bit cal.
                                        //    coefficients

  PCA0CPM0 = 0x42;                      // Turn on PWM

  switch (value)
  { case TEMPERATURE:
      result =  (long) av * 1000/TEMP_SLOPE; 
      break;

    case VOLTAGE:
    case VOLTAGE_PWM_OFF:
    result = (av - VOLT_OFFSET.l);      // Account for System Errors
    result /= VOLT_SLOPE.l;             // Convert to Voltage in Millivolts
    result *= 100;                      // Account for Math Truncation Error
    result *= RESAB;                    // Account for Divide Resistors
    result /= RESB;                   
    break;
    case CURRENT:
      result =  av*2;                   // Account for Differential Mode   
      result -= I_NOAMP_OFFSET.l;       // Account for System Errors
      result /= I_NOAMP_SLOPE.l;        // Convert to Milliamps
      result *= 100;                    // Account for Math Truncation Error
      result /= RSENSE;                 // Account for Sense Resistor
      result *= RESAB;                  // Account for Divide Resistors
      result /= RESB;
      result /= CURRENT_GAIN;
      break;
  }

  return (int) result;     
}

//-----------------------------------------------------------------------------
// Bulk_Charge Function
//-----------------------------------------------------------------------------
void Bulk_Charge(void)
{
  unsigned int temp = 0;
  unsigned int bulk_finish_hour = 0;
  unsigned int bulk_finish_min = 0;
  unsigned int delay_hour = 0;  
  unsigned int delay_min = 0;
  unsigned int last_min = 0;
                                          
  Reset_Time_Base();                    // Reset Time Base to zero

                                        // Calculate BULK charge finish time
  bulk_finish_min = (TIME.min + MAX_TIME_BULK);
  bulk_finish_hour = TIME.hour;
  while (bulk_finish_min > 60)
  {
    bulk_finish_min = bulk_finish_min - 60;
    bulk_finish_hour++;
  }

  CONST_C = 1;                          // Start in constant current charge mode
  DELAY   = 0;                          // Reset timer DELAY
    

  temp = Monitor_Battery(TEMPERATURE);  // Monitor Temperature
                                        // Is temperature within range? 

  if ((temp > MIN_TEMP_ABS) && (temp < MAX_TEMP_ABS))
  {
    temp = Monitor_Battery(VOLTAGE);    // Monitor Voltage
                                        // Is Voltage within range?  
    if ((temp <= (MAX_VOLT_ABS + VOLT_TOLERANCE)) && temp > MIN_VOLT_BULK)
    {
      PCA0CPM0 = 0x42;                  // Configure CCM0 to 8-bit PWM mode
    
      // Enter main loop in Bulk_Charge()
      while ((BULK == 1) && (ERROR == 0))
      {
        if (CONST_C == 1)
          Regulate_Current(I_BULK);     // Charge with Constant Current
        
        else if (CONST_V == 1)
          Regulate_Voltage();           // Charge with Constant Voltage
               
        // Now, Check for error and charge termination conditions
        // If above max charge time, flag error    
        // Test for BULK Charge Time Out

                                        // Monitor Time 
        if ((TIME.hour == bulk_finish_hour) && (TIME.min == bulk_finish_min) 
           &&  (DELAY == 0))                               
        {
          Turn_PWM_Off();               // Turn Off PWM
          TIME_MAX = 1;                 // Set Time max error flag
          ERROR    = 1;                 // Set general error flag 
        }

                                        // Monitor Temperature  
        temp = Monitor_Battery(TEMPERATURE);
        if ((temp < MIN_TEMP_ABS) && (temp > MAX_TEMP_ABS))
      {
          Turn_PWM_Off();               // Turn Off PWM
          
        if (temp < MIN_TEMP_ABS)          
            TEMP_MIN = 1;               // Set Temperature below minimum flag
          else
            TEMP_MAX = 1;               // Set Temperature exceeds maximum flag
                                            
          ERROR    = 1;                 // Set general error flag
        }

                                        // Minute elapsed?
                                        // Check for minimum current
                                        // if reached, enter last DELAY charge
        if (TIME.min != last_min)   
        {
          last_min = TIME.min;
          if ((CONST_V == 1) && (DELAY == 0) && (Monitor_Battery(CURRENT) 
             <= MIN_I_BULK))
          {
                                        // Calculate TOP OFF Battery Time finish time 
            delay_min = (TIME.min + BULK_TIME_DELAY);
            delay_hour = TIME.hour;
            while (delay_min > 60)
            {
              delay_min = delay_min - 60;
              delay_hour++;
            }            
            DELAY = 1;                  // Set Delay Flag
          }
 
                                        // Monitor Delay time, time up?
          if ((TIME.hour == delay_hour)&&(TIME.min == delay_min) &&
             (DELAY == 1))
          {
            Turn_PWM_Off();             // Turn Off PWM
            CONST_V = 0;                // Exit CONST_V
            CONST_C = 1;                // Prepare to enter CONST_C
            BULK = 0;                   // Prepare to exit BULK mode 
            LOWCURRENT = 1;             // Prepare to enter LOWCURRENT Mode
          }                         
        }                        
      }                                 // End Main While loop
    }

    else if(ERROR == 0)
    {
      if (temp > (MAX_VOLT_ABS + VOLT_TOLERANCE))
      { VOLT_MAX = 1;                   // Set Max Voltage error flag
        ERROR    = 1;                   // Set general error flag
      }
     else if(temp < MIN_VOLT_BULK)
      { VOLT_MIN = 1;                   // Set Minimum bulk voltage error flag  
        LOWCURRENT = 1;                 // Switch to LOWCURRENT mode
        BULK = 0;                       // Exit Bulk Charge mode
      }                                 // battery's voltage very low
    }     
  }       

  else if(ERROR == 0)                   // Absolute temperature out of range?
  {   
    if (temp < MIN_TEMP_ABS)          
     TEMP_MIN = 1;                      // Set Temperature below minimum flag
    else
     TEMP_MAX = 1;                      // Set Temperature exceeds maximum flag

      ERROR = 1;                        // Set general error flag
  }
}

//-----------------------------------------------------------------------------
// Lowcurrent_Charge 
//-----------------------------------------------------------------------------

void Lowcurrent_Charge(void)
{
  unsigned int temp = 0;
  unsigned int lowcurrent_finish_min = 0;
  unsigned int lowcurrent_finish_hour = 0;

  Reset_Time_Base();                    // Reset Time base to zero

                                        // Calculate LOWCURRENT finish time
  lowcurrent_finish_min = (TIME.min + MAX_TIME_LOWCURRENT); 
  lowcurrent_finish_hour = TIME.hour;
  while (lowcurrent_finish_min > 60)
  {
    lowcurrent_finish_min = lowcurrent_finish_min - 60;
    lowcurrent_finish_hour++;
  }

  // Enter Main Lowcurrent Loop. 
  // Only exits are upon error and full charge
  while ((LOWCURRENT == 1) && (ERROR == 0))  
  {    
    temp = Monitor_Battery(TEMPERATURE);// Get Temperature Reading
                                        // Is TEMPERATURE within limits 
    if ((temp > MIN_TEMP_ABS) && (temp < MAX_TEMP_ABS))   
    {
      // Is Battery's Charge Voltage below max charge voltage
      temp = Monitor_Battery(VOLTAGE);  // Get Voltage Reading
      if (temp <= (VOLT_LOWCURRENT + VOLT_TOLERANCE))
      {
        if (CONST_C == 1)               // CONST_C ?, charge w/ constant current
          Regulate_Current(I_LOWCURRENT);

        if (CONST_V == 1)               // CONST_V?, charge w/ constant voltage
          Regulate_Voltage();       
      
        if ((temp >= MIN_VOLT_BULK) && (DELAY == 0))// Bulk Threshold voltage met?
        { LOWCURRENT = 0;               // Exit LOWCURRENT mode
          BULK = 1;                     // Switch to Bulk Charge mode
        }
                                        // Check elapsed time 
        if ((TIME.hour == lowcurrent_finish_hour) && 
        ( TIME.min == lowcurrent_finish_min))
        {
          TIME_MAX = 1;                 // Set Time MAX error flag
          ERROR    = 1;                 // Set general error flag    
        }
      }
      else if(ERROR == 0)               // Voltage to high?
      {
        VOLT_MAX = 1;                   // Set Max voltage error flag
        ERROR    = 1;                   // Set general error flag
      }      
    }     
    else if(ERROR == 0)                 // Absolute temperature out of range?
    {   
      if (temp < MIN_TEMP_ABS)          
        TEMP_MIN = 1;                   // Set Temperature below minimum flag
      else
        TEMP_MAX = 1;                   // Set Temperature exceeds maximum flag
      
      ERROR = 1;                        // Set general error flag
    }
  }
}

//-----------------------------------------------------------------------------
// Main Function
//-----------------------------------------------------------------------------
void main(void)
{ 
  EA = 0;                               // Disable All Interrupts
  Reset_Time_Base();
  Config_F300();                        // Config F300
  CalibrateADCforMeasurement();         // Calibrate F300

  EA = 1;                               // Enable All Active Interrupts 
  
  while(1)
  {
    LED0 = 0;                           // Turn LED0 off    
   
    TERMINATION = 0x00;                 // Reset Termination Flags
    CHARGE_STATUS = 0x00;               // Reset Charge Status Flags
    BULK = 1;                           // Start in LOWCURRENT Charge mode
    CONST_C = 1;
    
    while (SW0 == 1);                   // Wait until SW0 pushed
    Delay_Loop();                       // Wait for Switch Bounce
    
    while (ERROR == 0)
    {
      if (BULK == 1)
      {
        LED0 = 1;                       // Turn LED0,indicates Bulk Mode
        Bulk_Charge();                  // Enter Bulk Charge Mode
     }                   
      if (LOWCURRENT == 1)
        Lowcurrent_Charge();            // Enter Lowcurrent_Charge function 
                                        // Toggle LED0 at 1 Hz rate via ISR
    }

    if (ERROR == 1)
    {
      Turn_PWM_Off();;                  // Turn PWM Off
      LED0 = 0;                         // Turn OFF LED0 to indicate "ERROR". 
      EA = 0;                           // Disable All Interrupts
      while (1);                        // Enter a eternal loop 
                                        // No recovery except "reset-button"
    }   
  } 
}

//-----------------------------------------------------------------------------
// PCA_ISR
//-----------------------------------------------------------------------------
// This routine counts the elapsed time in seconds, minutes, hours.
// It also toggles LED0 every second when in Lowcurrent Charge Mode.
// This routine interrupts every time the PCA counter overflows, every 256
//  SYSCLK cycles. After SYSCLK/256 interrupts, one second has elapsed.
// 
void PCA_OVERFLOW_ISR (void) interrupt 9
{ 
  PCA0CN = 0x40;                        // Reset all PCA Interrupt Flags

  PCA0H = 0x00;                         // Reset High Byte of PCA Counter 
                                        //   of 8-bit PWM we are using Module1 

  if (0x0000 == --TIME.t_count)
  {
    TIME.t_count = PWM_CLOCK;           // Reset 1 Second Clock
    if ( 60 == ++TIME.sec )             // Account for elapsed seconds
    {                                   // Reset second counter every minute
      TIME.sec = 0x00;                  
      if ( 60 == ++TIME.min )           // Account for elapsed minutes
      {                                 // Reset minute counter every hour
        TIME.min = 0x00;
        if ( 24 == ++TIME.hour )        // Account for elapsed hours
          TIME.hour = 0x00;             // Reset hour counter every day
      }
    }

    if ((LOWCURRENT == 1) && (ERROR == 0))
    {                                   // Blink LED0 at 1 Hz if in Lowcurrent 
      if (TIME.sec % 2)
        LED0 = 0;                       // Turn on LED every odd second
      else 
        LED0 = 1;                       // Turn on LED every even second
    }          
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -