初始化提交
This commit is contained in:
471
arduino-cli/libraries/Bluebit/DuinoplusMLX90615.cpp
Normal file
471
arduino-cli/libraries/Bluebit/DuinoplusMLX90615.cpp
Normal file
@@ -0,0 +1,471 @@
|
||||
/* MLX90615.cpp
|
||||
MLX90615读写驱动
|
||||
驱动使用:
|
||||
1、调用begin()函数初始化。
|
||||
2、调用getTemp()获取温度值。
|
||||
|
||||
对EERPOM的写操作只能通过地址0(?),写之前要擦除
|
||||
*/
|
||||
#include "Wire.h"
|
||||
#include "DuinoplusMLX90615.h"
|
||||
|
||||
MLX90615::MLX90615(MODE rwMode)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MLX90615::~MLX90615()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* begin()
|
||||
设备初始化
|
||||
输入参数:
|
||||
*/
|
||||
void MLX90615::begin(void)
|
||||
{
|
||||
Wire.begin();
|
||||
//Wire.setClock(50000); //IIC速度为50K
|
||||
device_addr = getAddr();
|
||||
}
|
||||
|
||||
/* getAddr()
|
||||
获得地址前,可能预先不知器件地址,所以用地址0获取设备地址
|
||||
输入参数:
|
||||
返回值:设备地址
|
||||
*/
|
||||
uint8_t MLX90615::getAddr(void)
|
||||
{
|
||||
uint8_t temp[2];
|
||||
device_addr = 0; //从地址0读
|
||||
//device_addr = 0x5B; //从地址0读
|
||||
read(ADDRESS, temp);
|
||||
device_addr = temp[0];
|
||||
return temp[0];
|
||||
}
|
||||
|
||||
/* setAddr()
|
||||
设置地址,通过地址0设置
|
||||
输入参数:
|
||||
uint8_t dat_L:数据低字节
|
||||
uint8_t dat_H:数据高字节
|
||||
*/
|
||||
void MLX90615::setAddr(uint8_t addr_L, uint8_t addr_H)
|
||||
{
|
||||
write(ADDRESS, addr_L, addr_H);
|
||||
device_addr = addr_L; //保存读到的地址
|
||||
}
|
||||
|
||||
/* getEmissivity()
|
||||
获取红外测温修正系数
|
||||
输入参数:
|
||||
返回值:修正系数
|
||||
*/
|
||||
float MLX90615::getEmissivity(void)
|
||||
{
|
||||
uint8_t temp[2];
|
||||
uint16_t tmp;
|
||||
float tmp1;
|
||||
|
||||
read(EMISSIVITY, temp);
|
||||
//Serial.write(temp[0]);
|
||||
//Serial.write(temp[1]);
|
||||
tmp = temp[1];
|
||||
tmp = (tmp << 8) + temp[0];
|
||||
tmp1 = ((float)tmp) / 16384;
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
/* setEmissivity()
|
||||
设置红外测温修正系数
|
||||
输入参数:
|
||||
float e:修正系数
|
||||
返回值:
|
||||
*/
|
||||
void MLX90615::setEmissivity(float e)
|
||||
{
|
||||
uint8_t temp[2];
|
||||
uint16_t tmp;
|
||||
float tmp1 = e;
|
||||
|
||||
tmp = tmp1 * 16384;
|
||||
temp[0] = (uint8_t)(tmp & 0xFF);
|
||||
temp[1] = (uint8_t)((tmp & 0xFF00) >> 8);
|
||||
//Serial.write(temp[0]);
|
||||
//Serial.write(temp[1]);
|
||||
write(EMISSIVITY, temp[0], temp[1]);
|
||||
}
|
||||
|
||||
/* getPWM_T_min()
|
||||
获得最小温度值,只适用PWM方式
|
||||
输入参数:
|
||||
返回值:最小温度值 单位:度
|
||||
*/
|
||||
float MLX90615::getPWM_T_min(void)
|
||||
{
|
||||
uint8_t temp[2];
|
||||
uint16_t tmp;
|
||||
float tmp1;
|
||||
|
||||
read(PWM_T_MIN, temp);
|
||||
//Serial.write(temp[0]);
|
||||
//Serial.write(temp[1]);
|
||||
tmp = temp[1];
|
||||
tmp = (tmp << 8) + temp[0];
|
||||
tmp1 = ((float)tmp)*0.02 - 273.15;
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
/* setPWM_T_min()
|
||||
设置最小温度值,只适用PWM方式
|
||||
输入参数:最小温度值 单位:度
|
||||
返回值:
|
||||
*/
|
||||
void MLX90615::setPWM_T_min(float dat)
|
||||
{
|
||||
uint8_t temp[2];
|
||||
uint16_t tmp;
|
||||
float tmp1 = dat;
|
||||
|
||||
if (tmp1 == 0)
|
||||
{
|
||||
temp[0] = 0x5B;
|
||||
temp[1] = 035;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp = (tmp1 + 273.15) * 50;
|
||||
temp[0] = (uint8_t)(tmp & 0xFF);
|
||||
temp[1] = (uint8_t)((tmp & 0xFF00) >> 8);
|
||||
}
|
||||
//Serial.write(temp[0]);
|
||||
//Serial.write(temp[1]);
|
||||
write(PWM_T_MIN, temp[0], temp[1]);
|
||||
|
||||
device_addr = temp[0];
|
||||
}
|
||||
|
||||
/* getPWM_T_range()
|
||||
获得测温范围,只适用PWM方式
|
||||
输入参数:
|
||||
返回值:测温范围值 单位:度
|
||||
*/
|
||||
float MLX90615::getPWM_T_range(void)
|
||||
{
|
||||
uint8_t temp[2];
|
||||
uint16_t tmp;
|
||||
float tmp1;
|
||||
|
||||
read(PWM_T_RANGE, temp);
|
||||
//Serial.write(temp[0]);
|
||||
//Serial.write(temp[1]);
|
||||
tmp = temp[1];
|
||||
tmp = (tmp << 8) + temp[0];
|
||||
tmp1 = ((float)tmp)*0.02;
|
||||
return tmp1;
|
||||
}
|
||||
|
||||
/* setPWM_T_range()
|
||||
设置测温范围,只适用PWM方式
|
||||
输入参数:测温范围值 单位:度
|
||||
返回值:
|
||||
*/
|
||||
void MLX90615::setPWM_T_range(float dat)
|
||||
{
|
||||
uint8_t temp[2];
|
||||
uint16_t tmp;
|
||||
float tmp1 = dat;
|
||||
|
||||
tmp = tmp1 * 50;
|
||||
temp[0] = (uint8_t)(tmp & 0xFF);
|
||||
temp[1] = (uint8_t)((tmp & 0xFF00) >> 8);
|
||||
//Serial.write(temp[0]);
|
||||
//Serial.write(temp[1]);
|
||||
write(PWM_T_RANGE, temp[0], temp[1]);
|
||||
}
|
||||
|
||||
/* setConfig()
|
||||
设置config寄存器
|
||||
配置前,应把原来的值读出,3-11位的工厂设置是不能修改的。
|
||||
可选配置参数如下,各参数可或组合:
|
||||
1、通信方式 可选值: PWM(PWM 通信方式) IIC(SMBus 通信方式)
|
||||
2、PWM高低频选择 可选值: PWM_L 低频 PWM_H 高频
|
||||
3、PWM通信方式下测温目标选择 可选值: PWM_TEMP_TA 芯片 PWM_TEMP_TO 被测物体
|
||||
4、数字滤波参数选择 可选值: IIR_1 IIR_10 IIR_18 IIR_24 IIR_31 IIR_38 IIR_45
|
||||
输入参数:寄存器值
|
||||
返回值:
|
||||
*/
|
||||
void MLX90615::setConfig(uint16_t dat)
|
||||
{
|
||||
uint16_t configVal, tempVal;
|
||||
uint8_t temp[2];
|
||||
uint8_t i;
|
||||
|
||||
configVal = getConfig();
|
||||
tempVal = configVal; //保存好工厂设置
|
||||
tempVal &= 0x0FF8;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
if (dat & (1 << i)) //对dat按位测试,判断其为0还是1
|
||||
{
|
||||
configVal |= (1 << i); //为1,把相应位置1
|
||||
}
|
||||
else
|
||||
{
|
||||
configVal &= ~((uint16_t)(1 << i));
|
||||
}
|
||||
}
|
||||
configVal &= 0xF007; //恢复工厂设置位,确保中厂设置不被修改
|
||||
configVal |= tempVal;
|
||||
// configVal |= 0x04E0;
|
||||
temp[0] = (uint8_t)(configVal & 0xFF);
|
||||
temp[1] = (uint8_t)((configVal & 0xFF00) >> 8);
|
||||
Serial.write(temp[0]);
|
||||
Serial.write(temp[1]);
|
||||
write(CONFIG, temp[0], temp[1]);
|
||||
}
|
||||
|
||||
/* getConfig()
|
||||
设置config寄存器的值
|
||||
输入参数:
|
||||
返回值:寄存器值
|
||||
*/
|
||||
uint16_t MLX90615::getConfig(void)
|
||||
{
|
||||
uint8_t temp[2];
|
||||
uint16_t tmp;
|
||||
|
||||
read(CONFIG, temp);
|
||||
//Serial.write(temp[0]);
|
||||
//Serial.write(temp[1]);
|
||||
tmp = temp[1];
|
||||
tmp = (tmp << 8) + temp[0];
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* getIIR()
|
||||
获取数字滤波值
|
||||
输入参数:
|
||||
返回值:数字滤波值
|
||||
*/
|
||||
uint8_t MLX90615::getIIR(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* setIIR()
|
||||
设置数字滤波值
|
||||
输入参数:
|
||||
uint16_
|
||||
返回值:
|
||||
*/
|
||||
uint8_t MLX90615::setIIR(uint16_t )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* getID()
|
||||
获取产品ID号,共4字节
|
||||
返回值:ID号
|
||||
*/
|
||||
uint32_t MLX90615::getID(void)
|
||||
{
|
||||
uint32_t id;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/* getTemp()
|
||||
获得温度值,单位:度
|
||||
两种通信方式从设备读取温度值:IIC和PWM
|
||||
输入参数:
|
||||
uint8_t cmd:命令
|
||||
uint8_t dat_L:数据低字节
|
||||
uint8_t dat_H:数据高字节
|
||||
*/
|
||||
float MLX90615::getTemp(TEMP temp)
|
||||
{
|
||||
uint16_t a;
|
||||
float tmp;
|
||||
uint8_t tmp1[2];
|
||||
|
||||
if (rwMode == IIC_MODE) //IIC通信方式
|
||||
{
|
||||
if (temp == OBJ_TEMP)
|
||||
read(TEMP_TO, tmp1);
|
||||
else if (temp == CHIP_TEMP)
|
||||
read(TEMP_TA, tmp1);
|
||||
//Serial.write(tmp1[0]);
|
||||
//Serial.write(tmp1[1]);
|
||||
a = tmp1[1];
|
||||
a = (a << 8) + tmp1[0];
|
||||
tmp = (float)a*0.02 - 273.15;
|
||||
}
|
||||
else if (rwMode == PWM_MODE) //PWM通雠方式
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* sleep()
|
||||
进入/退出睡眠模式
|
||||
输入参数:
|
||||
boolean sleepFlag:模式选择
|
||||
*/
|
||||
void MLX90615::sleep(boolean sleepFlag)
|
||||
{
|
||||
boolean flag = sleepFlag;
|
||||
if (flag == SLEEP_ON) //进入睡眠
|
||||
{
|
||||
|
||||
}
|
||||
else //退出睡眠
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* PWM2IIC()
|
||||
PWM模式切换到IIC模式
|
||||
输入参数:
|
||||
*/
|
||||
void MLX90615::PWM2IIC(void)
|
||||
{
|
||||
pinMode(A5, OUTPUT);
|
||||
digitalWrite(A5, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(A5, LOW);
|
||||
delay(30);
|
||||
digitalWrite(A5, HIGH);
|
||||
delay(200);
|
||||
}
|
||||
/* erase()
|
||||
擦除,EEPROM数据更新时,通常先要执行擦除操作,即先把要修改的字清0
|
||||
输入参数:
|
||||
uint8_t cmd:擦除地址,对就相应命令
|
||||
*/
|
||||
void MLX90615::erase(uint8_t cmd)
|
||||
{
|
||||
write(cmd, 0, 0); //通过写0擦除
|
||||
delay(200);
|
||||
}
|
||||
|
||||
/* write()
|
||||
把数据写入EEPROM,RAM通常只读,所以不会用到本函数
|
||||
数据的写入格式参照datasheet的Bus Protocol一章
|
||||
输入参数:
|
||||
uint8_t cmd:命令
|
||||
uint8_t dat_L:数据低字节
|
||||
uint8_t dat_H:数据高字节
|
||||
*/
|
||||
void MLX90615::write(uint8_t cmd, uint8_t dat_L, uint8_t dat_H)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t buff[5];
|
||||
uint8_t tmp;
|
||||
|
||||
tmp = device_addr;
|
||||
device_addr = 0; //擦、写操作只能通过地址0
|
||||
//Serial.println(device_addr);
|
||||
|
||||
/*写之前先擦除*/
|
||||
buff[0] = device_addr;
|
||||
buff[1] = cmd;
|
||||
buff[2] = 0;
|
||||
buff[3] = 0;
|
||||
buff[4] = crc8(buff, 4);
|
||||
|
||||
Wire.beginTransmission(device_addr);
|
||||
Wire.write(cmd);
|
||||
Wire.write(0); //擦除就是写0
|
||||
Wire.write(0);
|
||||
Wire.write(buff[4]);
|
||||
Wire.endTransmission();
|
||||
delay(1000); //注意加点延时,等待擦除完成
|
||||
/*擦除后写入数据*/
|
||||
buff[0] = device_addr;
|
||||
buff[1] = cmd;
|
||||
buff[2] = dat_L;
|
||||
buff[3] = dat_H;
|
||||
buff[4] = crc8(buff, 4);
|
||||
//for (i = 0; i < 5; i++) //测试
|
||||
//{
|
||||
// Serial.write(buff[i]);
|
||||
//}
|
||||
Wire.beginTransmission(device_addr);
|
||||
Wire.write(cmd);
|
||||
Wire.write(dat_L);
|
||||
Wire.write(dat_H);
|
||||
Wire.write(buff[4]);
|
||||
Wire.endTransmission();
|
||||
delay(1000); //注意加点延时,等待写完成
|
||||
|
||||
device_addr = tmp;
|
||||
}
|
||||
|
||||
/* read()
|
||||
把数据从EEPRO或RAM中读出来,数据是16位的。
|
||||
输入参数:
|
||||
uint8_t cmd:命令地址
|
||||
uint8_t *buffer:读出数据缓存
|
||||
*/
|
||||
uint8_t MLX90615::read(uint8_t cmd, uint8_t *buffer)
|
||||
{
|
||||
uint8_t buff[6];
|
||||
uint8_t i = 0;
|
||||
|
||||
buff[0] = device_addr << 1;
|
||||
buff[1] = cmd;
|
||||
buff[2] = (device_addr << 1) + 1;
|
||||
|
||||
Wire.beginTransmission(device_addr);
|
||||
Wire.write(cmd);
|
||||
Wire.endTransmission(0); // stop transmitting
|
||||
|
||||
Wire.requestFrom(device_addr, 3); //从设备读3个字节,第1个字节为设备地址,第三个字节为CRC8校验。
|
||||
while (Wire.available()) {
|
||||
buff[i + 3] = Wire.read(); //设备地址码
|
||||
i++;
|
||||
}
|
||||
|
||||
//for (i = 0; i < 6; i++) //测试
|
||||
//{
|
||||
// Serial.write(buff[i]);
|
||||
//}
|
||||
|
||||
if (buff[5] == crc8(buff, 5)){
|
||||
*buffer = buff[3];
|
||||
*(buffer + 1) = buff[4];
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* crc8()
|
||||
CRC8校验
|
||||
输入参数:
|
||||
uint8_t *buf:待校验数据缓存
|
||||
uint8_t len:待校验字节数
|
||||
*/
|
||||
uint8_t MLX90615::crc8(uint8_t *buf, uint8_t len)
|
||||
{
|
||||
uint8_t i, l;
|
||||
uint16_t crc = 0;
|
||||
for (l = 0; l<len; l++)
|
||||
{
|
||||
crc ^= (buf[l] * 0x100);
|
||||
for (i = 0; i<8; i++)
|
||||
{
|
||||
if (crc & 0x8000)
|
||||
{
|
||||
crc ^= 0x8380;
|
||||
}
|
||||
crc *= 2;
|
||||
}
|
||||
}
|
||||
return(crc / 0x100);
|
||||
}
|
||||
Reference in New Issue
Block a user