初始化提交

This commit is contained in:
王立帮
2024-07-20 22:09:06 +08:00
commit c247dd07a6
6876 changed files with 2743096 additions and 0 deletions

View 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、通信方式 可选值: PWMPWM 通信方式) IICSMBus 通信方式)
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()
把数据写入EEPROMRAM通常只读所以不会用到本函数
数据的写入格式参照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);
}