芯片简介
根据芯片手册,该芯片有以下几种流量测量:
芯片默认采样频率为0.5ms,IRQn管脚的下降沿表示芯片完成了一次测量,如果一次新的测量还没完成就开始读取,将读取失败:收到一个NACK;上电启动或软件复位后,IRQn管脚都是低电平,在收到测量命令后才会被拉高电平。
该芯片IIC地址通过ADDR管脚状态来分配,注意:该地址为7bits地址。
读取芯片id例程如下:
HAL_I2C_Mem_Read(hi2c1, (0x2a<<1), 0xe102, I2C_MEMADD_SIZE_16BIT, data, sizeof(data), 100);
芯片指令包括:
1、启动xx气体流量测试指令:氧气、笑气、空气以及混合气体的测量指令是分开的,如测量氧气指令为0x3603、测空气指令为0x3608;
2、停止测量指令、
3、更新气体浓度指令、
4、测量均值配置、
5、软件复位指令、
6、进入/退出睡眠指令、
7、读产品id指令、
8、读比例因数/偏移量/流量单位指令
初始化流程
该芯片在上电启动或软件复位后, 需要等待约16ms用于芯片内部初始化。在每次start continuous measurement command下发后,需要等待12ms用于测量初始化。
由于该芯片的测量原理是基于热测量原理,在软件复位或芯片上电启动后,芯片内部加热器是关闭的,在接收到start continuous measurement command后才打开内部加热器,打开加热器的时间为30ms,所以在第一次启动测量后要等30ms,才能获得准确的测量数据。
该芯片在启动时会使用CRC自动检查芯片内容完整性,用户可以使用0xE102指令码,通过读取产品ID来检查芯片是否正确连接、IIC地址是否正确分配。
CRC校验
该芯片使用CRC来验证数据完整性, 在芯片手册4.4节有讲CRC算法:
CRC代码例程如下:
uint8_t CRC8(uint8_t * p_buf, UINT16 num)
{uint8_t result = 0xff;uint8_t const ploynomial = 0x31;for(uint8_t i = 0; i < num; i++){result ^= p_buf[i];for(uint8_t j = 0; j < 8; j++){if(result&0x80){result <<= 1;result ^= ploynomial;}else{result <<= 1;}}}return result;
}
初始化例程如下:
void initDevice(void)
{UINT8 data[18] = {0};UINT32 serial_number = 0;UINT32 product_number = 0;HAL_I2C_Mem_Read(hi2c1, 0x2A << 1, 0xE102, I2C_MEMADD_SIZE_16BIT, data, sizeof(data), 1000);if((CRC8(&data[0], 2) == data[2]) && (CRC8(&data[3], 2) == data[5])){product_number = (data[0] << 24) | (data[1] << 16) | (data[4] << 8) | (data[5] << 0);}if((getCRC8(&data[12], 2) == data[14]) && (getCRC8(&data[15], 2) == data[17])){serial_number = (data[12] << 24) | (data[13] << 16) | (data[15] << 8) | (data[16] << 0);}UINT8 cmd_tx[2] = {0x36, 0x6A};HAL_I2C_Master_Transmit(hi2c1, 0x2A << 1, cmd_tx, 2, 1000);
}
启动测量
在下发启动测量后,可以直接读取测量结果;在测量过程中可以直接修改O气浓度,修改浓度后不需要重新下发启动测量指令就可以直接读取;
typedef struct{uint16_t flow;uint16_t temp;uint16_t stat;
}Param;uint8_t read_measure_data(Param *param)
{UINT8 data[9] = {0};HAL_I2C_Master_Receive(hi2c1, 0x2A << 1, data, 9, 1000);if((CRC8(&data[0], 2) == data[2]) && (CRC8(&data[3], 2) == data[5]) && (CRC8(&data[6], 2) == data[8])){param->flow = (data[0] << 8) | data[1];param->temp = (data[3] << 8) | data[4];param->stat = (data[6] << 8) | data[7];return TRUE;}return FALSE;
}
测量过程中,在发送停止指令前,除了软件复位指令、修改浓度指令外,其它指令都不可以使用。
停止指令 | 0x3ff9 |
修改浓度指令 | 0xe17d |
设置平均值指令 | 0x366a |
总结
这个芯片存在自我矛盾的地方:芯片手册4.3.1节讲:
翻译过来就是:在发送停止指令前,不能发送其它指令。而在4.3.3节讲:
翻译过来就是: 为了动态更新气体浓度,如不中断当前测量模式……