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

📄 f300_highspeed_bc.c

📁 F300 High Speed Li Ion charger
💻 C
📖 第 1 页 / 共 3 页
字号:
  FLKEY = 0xF1;                         // enable flash write
  *pwrite = temp_LONG_2.b[0];
  pwrite = (char xdata *)&(I_NOAMP_OFFSET.b[1]);
  FLKEY = 0xA5;
  FLKEY = 0xF1;                         // enable flash write
  *pwrite = temp_LONG_2.b[1];
  pwrite = (char xdata *)&(I_NOAMP_OFFSET.b[2]);
  FLKEY = 0xA5;
  FLKEY = 0xF1;                         // enable flash write
  *pwrite = temp_LONG_2.b[2];
  pwrite = (char xdata *)&(I_NOAMP_OFFSET.b[3]);
  FLKEY = 0xA5;
  FLKEY = 0xF1;                         // enable flash write
  *pwrite = temp_LONG_2.b[3];
  
  PSCTL = 0;                            // MOVX writes target XRAM
}

//-----------------------------------------------------------------------------
// Measure
//-----------------------------------------------------------------------------
//
// This routine averages 65536 ADC samples and returns a 16-bit unsigned 
// result.
// 
unsigned int Measure (void)
{
  unsigned i;                           // sample counter
  unsigned long accumulator=0L;         // here's where we integrate the
                                        // ADC samples

  // read the ADC value and add to running total
  i = 0;
  do {
    AD0INT = 0;                         // clear end-of-conversion indicator
    AD0BUSY = 1;                        // initiate conversion
    while(!AD0INT);                     // wait for conversion to complete
    accumulator += ADC0;                // read adc value and accumulate
    i++;                                // update counter
  } while (i != 0x0000);
   
  // the accumulator now contains 16 added bits of which 8 are usable 
  return (unsigned int) (accumulator >> 8);    
}

//-----------------------------------------------------------------------------
// Regulate_Current
//-----------------------------------------------------------------------------
// This routine monitors the battery's current and adjusts 
// the PWM (i.e. duty cycle) to keep the current at a known value
//
void Regulate_Current(int passed_current)
{ unsigned int temp = 0,delay_count = 0;
  do{
    temp = Monitor_Battery(CURRENT);    // Measure Current
    if (temp < passed_current)
    {     PCA0CPH1--;
	      for(delay_count = 0;delay_count<2500;delay_count++);
	}
    if (temp > passed_current)
    {  PCA0CPH1++;
       for(delay_count = 0;delay_count<2500;delay_count++);
    }
  
  }while ((temp < (passed_current - CURRENT_TOLERENCE)) || 
          (temp > (passed_current + CURRENT_TOLERENCE)));  
                                        // I_BULK or I_LOWCURRENT is set now

  temp = Monitor_Battery(VOLTAGE_PWM_OFF);
                                        // If VOLTAGE within range, 
                                        // change from constant CURRENT charge
                                        // mode to constant VOLTAGE charge mode
  if ((temp >= (VOLT_LOWCURRENT - VOLT_TOLERANCE*2)) &&
   (temp <= (VOLT_LOWCURRENT + VOLT_TOLERANCE*2)))
  {
    CONST_C = 0;
    CONST_V = 1;
  }

}

//-----------------------------------------------------------------------------
// Regulate_Voltage
//-----------------------------------------------------------------------------
// This routine monitors the battery's voltage and adjusts 
// the PWM (i.e. duty cycle) to keep the voltage at a known value
//
void Regulate_Voltage(void)
{ unsigned int temp = 0,delay_count = 0;
                                        // set VOLT_BULK (with "soft start")
  do{
    temp = Monitor_Battery(VOLTAGE);
    
	if (temp < VOLT_BULK)
    {      PCA0CPH1--;
           for(delay_count = 0;delay_count<2500;delay_count++);
    }
    if (temp > VOLT_BULK)
    {  PCA0CPH1++;
       for(delay_count = 0;delay_count<2500;delay_count++);
    }

  }while ((temp < (VOLT_BULK - VOLT_TOLERANCE)) || 
            (temp > (VOLT_BULK + VOLT_TOLERANCE)));
                                        // VOLTAGE is set now
}

//-----------------------------------------------------------------------------
// Turn_PWM_Off
//-----------------------------------------------------------------------------
// This routine peforms a soft charge turn off by taking the PWM's  
// duty cycle slowly to zero.
//
void Turn_PWM_Off(void)
{ 
  do{
    if (PCA0CPH1 < 0xF0)
      PCA0CPH1++;
                  
  }while (PCA0CPH1 < 0xF0);                       
  // Duty Cycle is now small and safe to turn off.

  PCA0CPM0 = 0x00;                      // Disable PWM
}

//-----------------------------------------------------------------------------
// Monitor_Battery
//-----------------------------------------------------------------------------
// This routine acts as a switch when gathering different conversion types.
// It adjusts the throughput, adjust the AMUX and returns the current in mA,
//  voltage in mV, and temperature in C, 2% accurate.
//
int Monitor_Battery(unsigned char value)
{
  char i;
  unsigned long av =0,delay_count=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 |= 0x01;                   // Set PGA gain = 1
      break;
	
  }  
  
  //Compute average of next 10 A/D conversions
  for(delay_count = 0;delay_count<2500;delay_count++);// Allow Settling Time
  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 = 0x46;                      // 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 *= 100;                    // Account for Math Truncation Error
      result *= RESAB;                  // Account for Divide Resistors
	  result /= VOLT_SLOPE.l;           // Convert to Voltage in Millivolts
      result /= RESB;                   
      result -= ((RSENSE*Current)/100); // Account for Sense Resistor Voltage Drop
	break;
    case CURRENT:
      result = (av - I_NOAMP_OFFSET.l); // Account for System Errors
      result *= 100;                    // Account for Math Truncation Error
      result *= 100;                    // Account for Sense Resistor
	  result /= I_NOAMP_SLOPE.l;        // Convert to Milliamps
      result /= RSENSE;                 // Account for Sense Resistor
      result /= EXT_CURRENT_GAIN;       // Account for external Amplifier
	  Current = (int) result;
	  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?  
    Voltage = temp;                     // for Debug

	if ((temp <= (MAX_VOLT_ABS + VOLT_TOLERANCE)) && (temp > MIN_VOLT_BULK))
    {
      PCA0CPM0 = 0x46;                  // Turn on PWM
	 
      // Enter main loop in Bulk_Charge()
      while ((BULK == 1) && (ERROR == 0))
      {
        if (CONST_C == 1)
          Regulate_Current(I_BULK);
		
        else if (CONST_V == 1)
        {  Current = Monitor_Battery(CURRENT);    // Measure Current
           if((Current < IMIN)||(Current > IMAX))
           { CONST_V = 0;                // Exit CONST_V
             CONST_C = 1;                // Prepare to enter CONST_C

⌨️ 快捷键说明

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