📄 gas_mon.c
字号:
//_____________________________________________________________________________
// IAD turns the current A/D on and off and must be off for performing some functions
// such as writing the threshold register.
//_____________________________________________________________________________
void gas_mon_clearIAD(void)
{
byte_union status_config_reg;
status_config_reg.asbyte = gas_mon_readRegister(0, 0);
status_config_reg.asBits.b0 = 0;
gas_mon_writeRegister(0, 0, status_config_reg.asbyte);
}
//_____________________________________________________________________________
// gas_mon_getIAD
//_____________________________________________________________________________
// gets the state of the IAD bit.
//_____________________________________________________________________________
byte gas_mon_getIAD(void)
{
byte_union status_config_reg;
status_config_reg.asbyte = gas_mon_readRegister(0, 0);
return (byte)status_config_reg.asBits.b0;
}
//=============================================================================
// private
//=============================================================================
//_____________________________________________________________________________
// gas_mon_changeToVad
//_____________________________________________________________________________
// change to Vad rather than Vdd
// Note: Vad means Vad pin on gascell monitor pin, not necessarily Vad pin on MCU
//_____________________________________________________________________________
static void gas_mon_changeToVad(void)
{
asm("fclr I"); // disable interrupts
//write to scratchpad 0
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(WRITE_SP); // write to scratch pad
writebyte(0x00); // scratch pad 0
writebyte(0x07); // to do: ******* read modify write instead of just writing
// don't bother writing the rest
//copy scratchpad 0 to memory
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(COPY_SP); // copy entire scratch pad: to do read and re-write threshold register
writebyte(0x00); // page number to read
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_changeToVdd
//_____________________________________________________________________________
// change to Vdd rather than Vad
// Note: Vdd means Vdd pin on gascell monitor pin, not necessarily Vdd pin in
// the application.
//_____________________________________________________________________________
static void gas_mon_changeToVdd(void)
{
asm("fclr I"); // disable interrupts
//write to scratchpad 0
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(WRITE_SP); // write to scratch pad
writebyte(0x00); // scratch pad 0
writebyte(0x0F); // to do: ******* read modify write instead of just writing
// don't bother writing the rest
//copy scratchpad 0 to memory
resetDQ();
writebyte(SKIP_ROM); // Skip ROM
writebyte(COPY_SP); // copy entire scratch pad: to do read and re-write threshold register
writebyte(0x00); // page number to read
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_readVoltage
//_____________________________________________________________________________
// Read the voltage from the selected source: Vdd or Vad pin on gas monitor IC.
// The Vdd pin might not be actually connected to "Vdd" in the application.
// The Vad pin might not be actually connected to "Vad" in the application.
// Units: Volts
//_____________________________________________________________________________
static float gas_mon_readVoltage(void)
{
word_union voltage;
asm("fclr I"); // disable interrupts
// start voltage conversion
resetDQ(); // modify to check for presence pulse was received OK
writebyte(SKIP_ROM); // Skip ROM
writebyte(CONVERT_V); // 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(0x00); // page number to read
readbyte(); // throw away these
readbyte(); // throw away these
readbyte(); // throw away these
voltage.asbytes.lowbyte = readbyte(); // read LSB
voltage.asbytes.highbyte = readbyte(); // read LSB
asm("fset I"); // enable interrupts
// convert data
// See page 4 of the DS2438 data sheet
return (float)voltage.asword/100;
}
//_____________________________________________________________________________
// gas_mon_set_threshold
//_____________________________________________________________________________
// Sets the value of the current register value below which no accumulation
// of current measurements is made.
// I.e., small apparent currents are assumed to be offset errors and are prevented
// from accumulating in the ICA.
// See the data sheet for the full meaning of th1 and th2
//
// th2 th1 Threshold (+/- least sig bit)
// -----+-----+----------------------------------
// 0 0 no threshold (default)
// 0 1 +/- 2LSB
// 1 0 +/- 4LSB
// 1 1 +/- 8LSB
//_____________________________________________________________________________
static void gas_mon_set_threshold(byte th2, byte th1)
{
byte_union threshold_reg;
threshold_reg.asbyte = 0x00;
threshold_reg.asBits.b7 = th2;
threshold_reg.asBits.b6 = th1;
// When writing to the threshold register, current measurement MUST be disabled
gas_mon_clearIAD();
gas_mon_writeRegister(0, 7, threshold_reg.asbyte); // threshold register is byte 7 on page 0
gas_mon_setIAD();
}
//_____________________________________________________________________________
// resetDQ
//_____________________________________________________________________________
// Generate a 1-Wire reset, return 1 if no
// presence detect was found, return 0 otherwise.
//_____________________________________________________________________________
static int resetDQ(void)
{
int result = 1; // 1 means no gas monitor connected
//asm("fclr I"); // disable interrupts
DQ=LOW;
DQ_DIRECTION = OUTPUT; // Drives DQ low to excite presence pulse
delay_100ns((word) 4900); // keep line low for at 480us
//DQ=HIGH; // If required,
// drive line high quickly, then release the bus
// DQ is set to output a 1 briefly to improve the rise time
// (helps the weak internal pull-up resistor)
DQ_DIRECTION = INPUT;
delay_100ns((word) 650); // wait till the middle of the expected presence pulse
result = DQ; //Sample and return the presence pulse value: 0 = presence
delay_100ns((word) 3600);
//asm("fset I"); // enable interrupts
return result;
}
//_____________________________________________________________________________
// write1
//_____________________________________________________________________________
// generate a write1
//_____________________________________________________________________________
static void write1(void)
{
//asm("fclr I"); // disable interrupts
DQ=0; DQ_DIRECTION = OUTPUT; // Drives DQ low
delay_100ns((word) 85); // bring it high within 15us to indicate a 1
DQ=1; DQ_DIRECTION = INPUT; //Releases the bus
delay_100ns((word) 600); // all write slots must be a minimum of 60us
// they must end with a minimum if 1us high
//asm("fset I"); // enable interrupts
}
//_____________________________________________________________________________
// write0
//_____________________________________________________________________________
// Generate a Write0. There is a 5us recovery
// time in case the rise time of DQ line in the system is
// slower than 1us.
//_____________________________________________________________________________
static void write0(void)
{
//asm("fclr I"); // disable interrupts
DQ=LOW;
DQ_DIRECTION = OUTPUT; // Drives DQ low
delay_100ns((word) 700); // keep it low for at least 60us to indicate a 0
DQ=1; DQ_DIRECTION = INPUT; //Releases the bus
delay_100ns((word) 100); // all write slots must be a minimum of 60us
// they must end with a minimum if 1us high
//asm("fset I"); // enable interrupts
}
//_____________________________________________________________________________
// readBit
//_____________________________________________________________________________
// read 1 bit from the bus and return it
//_____________________________________________________________________________
static BOOL readBit(void)
{
BOOL result;
//asm("fclr I"); // disable interrupts
DQ=LOW;
DQ_DIRECTION = OUTPUT; // Drives DQ low
delay_2_us();
DQ_DIRECTION = INPUT; //Releases the bus to allow the device to drive the line
delay_2_us(); // slightly more delay here because if the gas monitor is not pulling low
delay_2_us(); // then it takes about 3us for the line to be pulled weakly high
delay_2_us(); // by the internal pull-up
result = DQ; //sample DQ for data
//LED_Green = ON; // spike to show where DQ is being sampled by MCU
delay_100ns((word) 600); // all read slots must be a minimum of 60us
// they must end with a minimum if 1us high
//LED_Green = OFF;
//asm("fset I"); // enable interrupts
return result;
}
//_____________________________________________________________________________
// writebyte
//_____________________________________________________________________________
// write data byte
//_____________________________________________________________________________
static void writebyte(byte data)
{
byte loop;
//Do 1 complete byte
for(loop=0; loop<8; loop++)
{
//0x01,0x02,0x04,0x08,0x10,etc.
if(data & ((byte) 0x01<<loop))
write1();
else
write0();
}
}
//_____________________________________________________________________________
// readbyte
//_____________________________________________________________________________
// read data byte and return it
//_____________________________________________________________________________
static byte readbyte(void)
{
byte loop;
byte result=0;
for(loop=0; loop<8; loop++)
{
result = result + (readBit() << loop);
}
return result;
}
// End of file: gas_mon.c
//_____________________________________________________________________________
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -