📄 gas_mon.c
字号:
writebyte(READ_ROM); // read ROM
//read family code and discard
readbyte();
monitor_id.asbytes.lowbyte = readbyte(); // read first byte of ID
monitor_id.asbytes.highbyte = readbyte(); // read second byte of ID
// to do: read all 4 bytes of ID
// terminate read sequence since we don't want anything else
// to do: read more bytes
asm("fset I"); // enable interrupts
return (monitor_id.asword);
}
//_____________________________________________________________________________
// gas_mon_readTemp
//_____________________________________________________________________________
// read the Temperature
// Units: degrees Celsius
//_____________________________________________________________________________
float gas_mon_readTemp(void)
{
word_union temperature;
int this_reading;
double accumulatedTemperature = 0;
asm("fclr I"); // disable interrupts
for(this_reading = 0; this_reading < MON_TEMP_READINGS_TO_AVERAGE ; this_reading++)
{
// start temp conversion
resetDQ(); // modify to check for presence pulse was received OK
writebyte(SKIP_ROM); // Skip ROM
writebyte(CONVERT_T); // start conversion
while (!readBit()); // the monitor outputs all zeros on the DQ line
// until the conversion is complete, at which
// time it outputs all ones.
//recall page 0 to scratchpad
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(RECALL_MEMORY); // recall SP command
writebyte(0x00); // page number to read
//read scratchpad
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(READ_SP); // read SP command
writebyte(0); // page number to read
readbyte(); // throw away first byte
temperature.asbytes.lowbyte = readbyte(); // read LSB of temperature
temperature.asbytes.highbyte= readbyte(); // read MSB of temperature
// convert from 13 bit signed int where each count represents 0.03125 degrees
// Celsius. The last 3 bits are always 000.
// 11001001 00000000 = 0xC900 = -55.0000 degrees Celsius
// MSB is whole parts of degrees, MS bit is a sign bit
// LSB is whole fractional parts of degrees
// See page 4 of the DS2438 data sheet
// terminate read sequence since we don't want anything else
// to do: CRC check
accumulatedTemperature += (double)(temperature.asSignedInt)/256.0; // convert
}
asm("fset I"); // enable interrupts
return (float)(accumulatedTemperature / MON_TEMP_READINGS_TO_AVERAGE )+getTempFromGasMonitorCalOffset();
}
//_____________________________________________________________________________
// gas_mon_readCurrentRegisterword
//_____________________________________________________________________________
// N.B.: If you have just set the IAD bit, you must wait 80ms to be safe that
// the current A/D is operating and updating the current register before
// calling this function.
// Read the current and return the actual content of the current register
// Units: mA
//_____________________________________________________________________________
word gas_mon_readCurrentRegisterword(void)
{
word_union currentRegister;
asm("fclr I"); // disable interrupts
//recall page 0 to scratchpad
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(RECALL_MEMORY); // recall SP command
writebyte(0x00); // page number to read
//read scratchpad
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(READ_SP); // read SP command
writebyte(0x00); // page number to read
readbyte(); // throw away these
readbyte(); // throw away these
readbyte(); // throw away these
readbyte(); // throw away these
readbyte(); // throw away these
currentRegister.asbytes.lowbyte = readbyte(); // read LSB of current
currentRegister.asbytes.highbyte = readbyte(); // read LSB of current
asm("fset I"); // enable interrupts
// to do: add CRC check
return currentRegister.asword;
}
//_____________________________________________________________________________
// gas_mon_readCurrent
//_____________________________________________________________________________
// N.B.: If you have just set the IAD bit, you must wait 80ms to be safe that
// the current A/D is operating and updating the current register before
// calling this function.
// Read the current and return a signed float indicating current magnitude
// and direction. -ve means discharging, +ve means charging. Units: mA
//_____________________________________________________________________________
float gas_mon_readCurrent(void)
{
word_union currentRegister;
currentRegister.asword = gas_mon_readCurrentRegisterword();
// from signed int, convert to mA
return (float)currentRegister.asSignedInt/(4096.0f*getGascellSenseResistor())*1000.0f;
}
//_____________________________________________________________________________
// gas_mon_readCurrentAbs
//_____________________________________________________________________________
// N.B.: If you have just set the IAD bit, you must wait 80ms to be safe that
// the current A/D is operating and updating the current register before
// calling this function.
// read the current and take the absolute value of it
// will return +ve value both for charging and discharging
// Units: mA
//_____________________________________________________________________________
float gas_mon_readCurrentAbs(void)
{
float signed_current;
signed_current = gas_mon_readCurrent();
return (signed_current > 0)? signed_current:-signed_current;
}
//_____________________________________________________________________________
// gas_mon_readICA
//_____________________________________________________________________________
// Read the integrating current accumulator
// Note: The ICA counts DOWN when the gascell is discharging
// Units: mA*hours
//_____________________________________________________________________________
float gas_mon_readICA(void)
{
byte ICA_register;
ICA_register = gas_mon_readRegister(1, 4); // ICA register is byte 4 on page 1
return( ((float)ICA_register)/(2048.0f*getGascellSenseResistor())*1000.0f ); // convert to mAhr
}
//_____________________________________________________________________________
// gas_mon_readICA_Registerbyte
//_____________________________________________________________________________
// Read the integrating current accumulator
// Note: The ICA counts DOWN when the gascell is discharging
// Returns the raw register value.
//_____________________________________________________________________________
byte gas_mon_readICA_Registerbyte(void)
{
return gas_mon_readRegister(1, 4); // ICA register is byte 4 on page 1
}
//_____________________________________________________________________________
// gas_mon_read_V_at_Vad_Pin
//_____________________________________________________________________________
// Note: Vad means Vad pin on gascell monitor pin, not necessarily Vad
// in the application.
//_____________________________________________________________________________
float gas_mon_read_V_at_Vad_Pin(void)
{
gas_mon_changeToVad();
return gas_mon_readVoltage();
}
//_____________________________________________________________________________
// gas_mon_read_V_at_Vdd_Pin
//_____________________________________________________________________________
// Note: Vdd means Vdd pin on gascell monitor pin, not necessarily Vdd
// in the application.
//_____________________________________________________________________________
float gas_mon_read_V_at_Vdd_Pin(void)
{
gas_mon_changeToVdd();
return gas_mon_readVoltage();
}
//_____________________________________________________________________________
// gas_mon_readRegister
//_____________________________________________________________________________
// reads a register given a register and page number
//_____________________________________________________________________________
byte gas_mon_readRegister(byte page, byte byteToRead)
{
int i;
asm("fclr I"); // disable interrupts
//recall page to scratchpad
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(RECALL_MEMORY); // recall SP command
writebyte(page); // page number to read
//read scratchpad and discard all bytes before required one
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(READ_SP); // read SP command
writebyte(page); // page number to read
for (i=0; i<byteToRead; i++)
{
readbyte(); // discard bytes until we get to the right one
}
asm("fset I"); // enable interrupts
return(readbyte());
}
//_____________________________________________________________________________
// gas_mon_writeRegister
//_____________________________________________________________________________
// Writes a register to a given register and page number.
// First, all bytes up to the byte to be written are read and saved.
// This is because you can't write to a byte in the page except as part
// of a sequence of writing to bytes in that page starting from byte 0.
// The saved bytes are replayed when the page is re-written with the new byte.
//_____________________________________________________________________________
void gas_mon_writeRegister(byte page, byte byteToChange, byte data)
{
int i;
byte storedbytes[8];
asm("fclr I"); // disable interrupts
//recall page to scratchpad
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(RECALL_MEMORY); // recall SP command
writebyte(page); // page number to read
//read scratchpad and store all bytes before required one
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(READ_SP); // read SP command
writebyte(page); // page number to read
for (i=0; i<byteToChange; i++)
{
storedbytes[i]=readbyte(); // store all bytes before the right one
}
//write to scratchpad page
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(WRITE_SP); // write to scratch pad
writebyte(page); // scratch pad
for (i=0; i<byteToChange; i++)
{
writebyte(storedbytes[i]); // write stored bytes until we get to the right one
}
writebyte(data); // write the given byte
// don't bother writing the rest - just reset it
resetDQ();
//copy scratchpad page to memory
writebyte(SKIP_ROM); // Skip ROM
writebyte(COPY_SP); // copy scratch pad
writebyte(page); // page number to copy
while (!readBit()); // the monitor outputs all zeros on the DQ line
// until the NV writing is complete, at which
// time it outputs all ones.
asm("fset I"); // enable interrupts
}
//_____________________________________________________________________________
// gas_mon_setIAD
//_____________________________________________________________________________
// IAD turns the current A/D on and off and must be off for performing some functions
// such as writing the threshold register.
// N.B.: When you set the IAD bit, you must wait 80ms to be safe that
// the current A/D is operating and updating the current register before
// reading the current register.
//_____________________________________________________________________________
void gas_mon_setIAD(void)
{
byte_union status_config_reg;
status_config_reg.asbyte = gas_mon_readRegister(0, 0);
status_config_reg.asBits.b0 = 1;
gas_mon_writeRegister(0, 0, status_config_reg.asbyte);
}
//_____________________________________________________________________________
// gas_mon_clearIAD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -