📄 f300_highspeed_bc.c
字号:
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 + -