IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32F1读取MLX90632非接触式红外温度传感器 -> 正文阅读

[嵌入式]STM32F1读取MLX90632非接触式红外温度传感器

MLX90632 简介

MLX90632是一个小型SMD SFN封装中的非接触式红外温度传感器,可实现高精度非接触式温度测量,。该装置在出厂时使用存储在EEPROM存储器中的校准常数进行校准。环境温度和目标温度可根据这些校准常数和测量数据进行计算。
MLX90632在工厂进行校准,环境温度范围为-20至85摄氏度,目标温度范围为-20至200摄氏度。测量值是传感器视野内所有物体的平均温度。当传感器处于热平衡和恒温条件下(传感器组件之间无温差),应用程序设计者必须了解这些精度是有保证的,并且是可以实现的。
温度计的准确度可能会受到封装内温度差异的影响,原因包括(除其他外):传感器后面的热电子元件、传感器后面或旁边的加热器/冷却器,或靠近传感器的热/冷物体,不仅加热温度计中的传感元件,还加热温度计封装。
MLX90632的一个主要优点是通过内部测量算法,将传感器组件周围这些温差的测量效果降至最低。同样,局部热变化(如空气中的湍流)不会在热电堆的输出信号中产生热噪声。但是,有些极端情况会影响传感器。
MLX90632的典型电源电压为3.3V,与芯片的通信是由I 2 C在快速模式下完成的。通过I 2 C,外部微控制器可以访问以下块:用于测量数据的RAM存储器用于存储微调值、校准常数和设备/测量设置的EEPROM寄存器,以根据该数据控制传感器,外部微控制器可以计算目标温度,如果需要,还可以计算传感器温度。
传感器中集成了一个光学滤光片(长波通),可切断可见光和近红外辐射通量,以提供环境光抗扰度。该滤光片的波长通带为2~14μm。
其特性主要有:

  • 高温环境下精准稳定的工作
  • 采用 3mm x 3mm x 1mm DFN 封装,无需采用体积庞大的 TO 罐封装
  • 消费级:测量物体温度为 -20 °C 至 200 °C,精度±1 ℃;医疗级:测量物体温度为-20 °C 至 100 °C,人体温度测量精度高达±0.2 °C
  • 使用 I2C 数字接口进行出厂校准,50° 的视场角
  • 工作温度范围: -20 °C 至 85 °C

MLX90632 不同型号的异同

型号MLX90632-BCB-000MLX90632-DCB-000MLX90632-DCB-100
准确性标准精度医用级精度医用级精度
I2C电压等级3V31V81V8
电源电压范围3-5V DC(模块带低压差稳压)
能耗9.2μA(典型值)12μA(最大值)
温度工作范围-20°C - 85°C
输出信号I2C数字接口

PS: 传感器型号描述:

mlx90632型号描述

使用STM32F1单片机驱动MLX90632

  • bsp_mlx90632.c 文件
/*******************************************************************************
*   Filename:       bsp_mlx90632.c
*   Revised:        All copyrights reserved to Roger.
*   Date:           2020-10-17
*   Revision:       v1.0
*   Writer:	        Roger-WY.
*
*   Description:    非接触式红外温度传感器模块驱动(数字式)
*
*
*   Notes:          https://www.melexis.com/zh/product/MLX90632/MLX90632
*   All copyrights reserved to Roger-WY
*******************************************************************************/
#include "bsp_mlx90632.h"
#include <math.h>


//----------------------------------------------------------------------------//
#define MLX90632_I2C_SCL_RCC     RCC_APB2Periph_GPIOC
#define MLX90632_I2C_SCL_PIN	 GPIO_Pin_4			/* 连接到SCL时钟线的GPIO */
#define MLX90632_I2C_SCL_PORT    GPIOC

#define MLX90632_I2C_SDA_RCC     RCC_APB2Periph_GPIOC
#define MLX90632_I2C_SDA_PIN	 GPIO_Pin_5			/* 连接到SDA数据线的GPIO */
#define MLX90632_I2C_SDA_PORT    GPIOC


/* 定义读写SCL和SDA的宏 */
#define MLX90632_I2C_SCL_1()     MLX90632_I2C_SCL_PORT->BSRR = MLX90632_I2C_SCL_PIN			/* SCL = 1 */
#define MLX90632_I2C_SCL_0()     MLX90632_I2C_SCL_PORT->BRR  = MLX90632_I2C_SCL_PIN			/* SCL = 0 */

#define MLX90632_I2C_SDA_1()     MLX90632_I2C_SDA_PORT->BSRR = MLX90632_I2C_SDA_PIN			/* SDA = 1 */
#define MLX90632_I2C_SDA_0()     MLX90632_I2C_SDA_PORT->BRR  = MLX90632_I2C_SDA_PIN			/* SDA = 0 */

#define MLX90632_I2C_SDA_READ()  ((MLX90632_I2C_SDA_PORT->IDR & MLX90632_I2C_SDA_PIN) != 0)	/* 读SDA口线状态 */
#define MLX90632_I2C_SCL_READ()  ((MLX90632_I2C_SCL_PORT->IDR & MLX90632_I2C_SCL_PIN) != 0)	/* 读SCL口线状态 */

#define MLX90632_DELAY_MS(a) bsp_DelayNms(a);

//----------------------------------------------------------------------------//
#define POW10 10000000000LL

/* 灵敏度 */
static double emissivity = 0.0;

stMlx90632CalibraParTypeDef stMlxCalibraPar;
//============================================================================//


/*
********************************************************************************
*	函 数 名: Mlx90632_i2c_Delay
*	功能说明: I2C总线位延迟,最快400KHz
*	形    参:  无
*	返 回 值: 无
********************************************************************************
*/
static void Mlx90632_i2c_Delay(void)
{
    volatile uint8_t i;

    for(i = 0; i < 50; i++);
}


static void Mlx90632_i2c_Start(void)
{
    /* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */
    MLX90632_I2C_SDA_1();
    Mlx90632_i2c_Delay();
    MLX90632_I2C_SCL_1();
    Mlx90632_i2c_Delay();

    MLX90632_I2C_SDA_0();
    Mlx90632_i2c_Delay();
    MLX90632_I2C_SCL_0();
//	Mlx90632_i2c_Delay();
}

/*******************************************************************************
 * 名    称: i2c_Stop
 * 功    能: CPU发起I2C总线停止信号
 * 入口参数: 无
 * 出口参数: 无
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注: 停止时序
 *            SCL _____/ˉˉˉˉˉˉˉ
 *            SDA _________/ˉˉˉˉˉ
 *                       |   |
 *                       STOP
 *******************************************************************************/
static void Mlx90632_i2c_Stop(void)
{
    /* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */

    MLX90632_I2C_SCL_0();
    Mlx90632_i2c_Delay();
    MLX90632_I2C_SDA_0();
    Mlx90632_i2c_Delay();

    MLX90632_I2C_SCL_1();
    Mlx90632_i2c_Delay();
    MLX90632_I2C_SDA_1();
//	Mlx90632_i2c_Delay();
}

/*******************************************************************************
 * 名    称: i2c_WaitAck
 * 功    能: CPU产生一个时钟,并读取器件的ACK应答信号
 * 入口参数: 无
 * 出口参数: 返回0表示正确应答,1表示无器件响应
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
static uint8_t Mlx90632_i2c_WaitAck(void)
{
    uint8_t re;
    uint8_t TimeOutCnt = 20;  /* 超时计数器 */

    MLX90632_I2C_SDA_1();	/* CPU释放SDA总线 */
    Mlx90632_i2c_Delay();
    MLX90632_I2C_SCL_1();	/* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
    Mlx90632_i2c_Delay();

    while(TimeOutCnt --)
    {
        if(MLX90632_I2C_SDA_READ())	  /* CPU读取SDA口线状态 */
        {
            re = 1;
        }
        else
        {
            re = 0;
        }
    }
    MLX90632_I2C_SCL_0();
    Mlx90632_i2c_Delay();
    return re;
}

/*******************************************************************************
 * 名    称: i2c_Ack
 * 功    能: CPU产生一个ACK信号
 * 入口参数: 无
 * 出口参数: 无
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
static void Mlx90632_i2c_Ack(void)
{
    MLX90632_I2C_SDA_0();	/* CPU驱动SDA = 0 */
    Mlx90632_i2c_Delay();
    MLX90632_I2C_SCL_1();	/* CPU产生1个时钟 */
    Mlx90632_i2c_Delay();
    MLX90632_I2C_SCL_0();
    Mlx90632_i2c_Delay();
    MLX90632_I2C_SDA_1();	/* CPU释放SDA总线 */
}

/*******************************************************************************
 * 名    称: i2c_NAck
 * 功    能: CPU产生1个NACK信号
 * 入口参数: 无
 * 出口参数: 无
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
static void Mlx90632_i2c_NAck(void)
{
    MLX90632_I2C_SDA_1();	/* CPU驱动SDA = 1 */
    Mlx90632_i2c_Delay();
    MLX90632_I2C_SCL_1();	/* CPU产生1个时钟 */
    Mlx90632_i2c_Delay();
    MLX90632_I2C_SCL_0();
    Mlx90632_i2c_Delay();
}

/*******************************************************************************
* 名    称: bsp_InitI2C
* 功    能: 配置I2C总线的GPIO,采用模拟IO的方式实现
* 入口参数: 无
* 出口参数: 无
* 作  者: Roger-WY
* 创建日期: 2018-06-29
* 修    改:
* 修改日期:
* 备    注:
*******************************************************************************/
static void Mlx90632_InitI2C(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(MLX90632_I2C_SCL_RCC | MLX90632_I2C_SDA_RCC, ENABLE);	/* 打开GPIO时钟 */

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_OD;	        /* 开漏输出模式 */

    GPIO_InitStructure.GPIO_Pin = MLX90632_I2C_SCL_PIN;
    GPIO_Init(MLX90632_I2C_SCL_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = MLX90632_I2C_SDA_PIN;
    GPIO_Init(MLX90632_I2C_SDA_PORT, &GPIO_InitStructure);

    /* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */
    Mlx90632_i2c_Stop();
}

/*******************************************************************************
 * 名    称: i2c_SendByte
 * 功    能: CPU向I2C总线设备发送8bit数据
 * 入口参数: _ucByte : 等待发送的字节
 * 出口参数: 无
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
static void Mlx90632_i2c_SendByte(uint8_t _ucByte)
{
    uint8_t i;

    /* 先发送字节的高位bit7 */
    for(i = 0; i < 8; i++)
    {
        MLX90632_I2C_SCL_0();
        Mlx90632_i2c_Delay();

        if(_ucByte & 0x80)
        {
            MLX90632_I2C_SDA_1();
        }
        else
        {
            MLX90632_I2C_SDA_0();
        }

        _ucByte <<= 1;	/* 左移一个bit */

        Mlx90632_i2c_Delay();

        MLX90632_I2C_SCL_1();
        Mlx90632_i2c_Delay();
    }
    MLX90632_I2C_SCL_0();
    Mlx90632_i2c_Delay();

}

/*******************************************************************************
 * 名    称: Mlx90632_i2c_ReadByte
 * 功    能: CPU从I2C总线设备读取8bit数据
 * 入口参数: 无
 * 出口参数: 读到的数据
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
static uint8_t Mlx90632_i2c_ReadByte(void)
{
    uint8_t i;
    uint8_t value;

    /* 读到第1个bit为数据的bit7 */
    value = 0;
    for(i = 0; i < 8; i++)
    {
        value <<= 1;
        MLX90632_I2C_SCL_0();
        Mlx90632_i2c_Delay();
        MLX90632_I2C_SCL_1();
        Mlx90632_i2c_Delay();

        if(MLX90632_I2C_SDA_READ())
        {
            value++;
        }
    }
    MLX90632_I2C_SCL_0();
    Mlx90632_i2c_Delay();

    return value;
}


//============================================================================//


/*******************************************************************************
* 名    称: bsp_Mlx90632Init
* 功    能: Mlx90632传感器的初始化
* 入口参数: 无
* 出口参数: 无
* 作  者: Roger-WY.
* 创建日期: 2018-08-08
* 修    改:
* 修改日期:
* 备    注:
*******************************************************************************/
int8_t bsp_Mlx90632Init(void)
{
    int8_t ucError      = 0;

    Mlx90632_InitI2C();

    bsp_Mlx90632ReadCalibraParInit(&stMlxCalibraPar);

    ucError = bsp_Mlx90632ReadCalibraParFromEeprom(&stMlxCalibraPar);
    return (ucError);

}

/*******************************************************************************
 * 名    称: bsp_Mlx90632WriteReg
 * 功    能: 对寄存器写值
 * 入口参数: devAddr:设备地址 regAddr:寄存器地址 data:写入寄存器的值
 * 出口参数: 读到的数据
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
int8_t bsp_Mlx90632WriteReg(uint8_t devAddr, uint16_t regAddr, uint16_t data)
{
    uint8_t ucAck = 0;
    uint8_t sendBuffer[5] = {0}; //used to save the data to send

    sendBuffer[0] = devAddr << 1;
    sendBuffer[1] = (uint8_t)(regAddr >> 8);
    sendBuffer[2] = (uint8_t)regAddr;
    sendBuffer[3] = (uint8_t)(data >> 8);
    sendBuffer[4] = (uint8_t)data;

    Mlx90632_i2c_Start();
    for(uint8_t i = 0; i < 5; i ++)
    {
        Mlx90632_i2c_SendByte(sendBuffer[i]);
        ucAck = Mlx90632_i2c_WaitAck();
        if(ucAck)           /* 如果Mlx90632,没有应答 */
        {
            goto cmd_fail;	/* 器件无应答 */
        }
    }
    /* 发送I2C总线停止信号 */
    Mlx90632_i2c_Stop();
    return 0;	/* 执行成功 */

cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
    /* 发送I2C总线停止信号 */
    Mlx90632_i2c_Stop();
    return -1;

}

/*******************************************************************************
 * 名    称: bsp_Mlx90632ReadReg
 * 功    能: 从寄存器里读值
 * 入口参数: devAddr:设备地址 regAddr:寄存器地址 ppBuf:读取寄存器值的缓存区 nBytes:读取寄存器的字节数
 * 出口参数: 读到的数据
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
int8_t bsp_Mlx90632ReadReg(uint8_t devAddr, uint16_t regAddr, uint8_t* ppBuf, uint8_t nBytes)
{
    uint8_t ucAck = 0;
    uint8_t ValBuf[6] = {0};
    uint8_t prcRegVal = 0;
    uint8_t i = 0;

    ValBuf[0] = devAddr << 1;
    ValBuf[1] = (uint8_t)(regAddr >> 8);
    ValBuf[2] = (uint8_t)regAddr;

    ValBuf[3] = (devAddr << 1) | 0x01;


    Mlx90632_i2c_Start();
    for(i = 0; i < 3; i++)
    {
        Mlx90632_i2c_SendByte(ValBuf[i]);
        ucAck = Mlx90632_i2c_WaitAck();
        if(ucAck)           /* 如果没有应答 */
        {
            goto cmd_fail;	/* 器件无应答 */
        }
    }

    //------------------------------------------------------------------------//
    Mlx90632_i2c_Start();
    Mlx90632_i2c_SendByte(ValBuf[3]);
    ucAck = Mlx90632_i2c_WaitAck();
    if(ucAck)           /* 如果没有应答 */
    {
        goto cmd_fail;	/* 器件无应答 */
    }

    while(nBytes)
    {
        *ppBuf = Mlx90632_i2c_ReadByte();
        if(nBytes == 1)
            Mlx90632_i2c_NAck();
        else
            Mlx90632_i2c_Ack();

        nBytes--;
        ppBuf++;
    }

    /* 发送I2C总线停止信号 */
    Mlx90632_i2c_Stop();
    return 0;

cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
    /* 发送I2C总线停止信号 */
    Mlx90632_i2c_Stop();
    return -1;
}


/*******************************************************************************
 * 名    称: bsp_Mlx90632ReadWord
 * 功    能: 从寄存器里读一个字(16-bit)
 * 入口参数: regAddr:寄存器地址 value:读取寄存器值的缓存区
 * 出口参数: 0:读取成功 其他值,读取失败
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
int8_t bsp_Mlx90632ReadWord(uint16_t regAddr, uint16_t* value)
{
    int8_t ret = 0;
    uint8_t buf[2] = {0};
    ret = bsp_Mlx90632ReadReg(MLX90632_ADDR, regAddr, buf, 2);
    *value = buf[1] | (buf[0] << 8);
    return ret;
}

/*******************************************************************************
 * 名    称: bsp_Mlx90632ReadDoubleWord
 * 功    能: 从寄存器里读双字(32-bit)
 * 入口参数: regAddr:寄存器地址 value:读取寄存器值的缓存区
 * 出口参数: 0:读取成功 其他值,读取失败
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
int8_t bsp_Mlx90632ReadDoubleWord(uint16_t regAddr, uint32_t* value)
{
    int8_t ret = 0;
    uint8_t buf[4] = {0};
    ret = bsp_Mlx90632ReadReg(MLX90632_ADDR, regAddr, buf, 4);
    *value = buf[2] << 24 | buf[3] << 16 | buf[0] << 8 | buf[1];
    return ret;
}
/*******************************************************************************
 * 名    称: bsp_Mlx90632WriteWord
 * 功    能: 往寄存器里写入一个字(16-bit)
 * 入口参数: regAddr:寄存器地址 value:读取寄存器值的缓存区
 * 出口参数: 0:读取成功 其他值,读取失败
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
int8_t bsp_Mlx90632WriteWord(uint16_t regAddr, uint16_t data)
{
    int8_t ret = 0;
    ret = bsp_Mlx90632WriteReg(MLX90632_ADDR, regAddr, data) ;
    return (ret);
}

/*******************************************************************************
 * 名    称: bsp_Mlx90632ReadCalibraParInit
 * 功    能: 校准参数初始化,如果eeprom的校准参数读出来为空,就是使用此默认值
 * 入口参数: pPar:校准参数结构体指针
 * 出口参数: 无
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
void bsp_Mlx90632ReadCalibraParInit(stMlx90632CalibraParTypeDef* pPar)
{
    pPar->PR = 0x00587f5b;
    pPar->PG = 0x04a10289;
    pPar->PT = 0xfff966f8;
    pPar->PO = 0x00001e0f;
    pPar->Ea = 4859535;
    pPar->Eb = 5686508;
    pPar->Fa = 53855361;
    pPar->Fb = 42874149;
    pPar->Ga = -14556410;
    pPar->Ha = 16384;
    pPar->Hb = 0;
    pPar->Gb = 9728;
    pPar->Ka = 10752;
}


/*******************************************************************************
 * 名    称: bsp_Mlx90632ReadCalibraParFromEeprom
 * 功    能: 从传感器内部EEPROM中读取校准参数
 * 入口参数: pPar:校准参数结构体指针
 * 出口参数: 无
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
int8_t bsp_Mlx90632ReadCalibraParFromEeprom(stMlx90632CalibraParTypeDef* pPar)
{
    int8_t ret = 0;
    ret = bsp_Mlx90632ReadDoubleWord(MLX90632_EE_P_R, (uint32_t*)&pPar->PR);
    if(ret < 0)
        return ret;
    ret = bsp_Mlx90632ReadDoubleWord(MLX90632_EE_P_G, (uint32_t*)&pPar->PG);
    if(ret < 0)
        return ret;
    ret = bsp_Mlx90632ReadDoubleWord(MLX90632_EE_P_O, (uint32_t*)&pPar->PO);
    if(ret < 0)
        return ret;
    ret = bsp_Mlx90632ReadDoubleWord(MLX90632_EE_P_T, (uint32_t*)&pPar->PT);
    if(ret < 0)
        return ret;
    ret = bsp_Mlx90632ReadDoubleWord(MLX90632_EE_Ea, (uint32_t*)&pPar->Ea);
    if(ret < 0)
        return ret;
    ret = bsp_Mlx90632ReadDoubleWord(MLX90632_EE_Eb, (uint32_t*)&pPar->Eb);
    if(ret < 0)
        return ret;
    ret = bsp_Mlx90632ReadDoubleWord(MLX90632_EE_Fa, (uint32_t*)&pPar->Fa);
    if(ret < 0)
        return ret;
    ret = bsp_Mlx90632ReadDoubleWord(MLX90632_EE_Fb, (uint32_t*)&pPar->Fb);
    if(ret < 0)
        return ret;
    ret = bsp_Mlx90632ReadDoubleWord(MLX90632_EE_Ga, (uint32_t*)&pPar->Ga);
    if(ret < 0)
        return ret;
    ret = bsp_Mlx90632ReadWord(MLX90632_EE_Gb, (uint16_t*)&pPar->Gb);
    if(ret < 0)
        return ret;
    ret = bsp_Mlx90632ReadWord(MLX90632_EE_Ha, (uint16_t*)&pPar->Ha);
    if(ret < 0)
        return ret;
    ret = bsp_Mlx90632ReadWord(MLX90632_EE_Hb, (uint16_t*)&pPar->Hb);
    if(ret < 0)
        return ret;
    ret = bsp_Mlx90632ReadWord(MLX90632_EE_Ka, (uint16_t*)&pPar->Ka);
    if(ret < 0)
        return ret;
    return 0;
}


/*******************************************************************************
 * 名    称: bsp_Mlx90632StartMeasurement
 * 功    能: 触发传感器开始测量,但是只是触发测量周期,等待数据准备就绪,它不读取任何内容,只是触发并等待完成。
 * 入口参数: 无
 * 出口参数: 无
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注: 此处超时等待是阻塞的
 *******************************************************************************/
int bsp_Mlx90632StartMeasurement(void)
{
    int ret, tries = 100;
    uint16_t reg_status;

    ret = bsp_Mlx90632ReadWord(MLX90632_REG_STATUS, &reg_status);
    if(ret < 0)
        return ret;

    ret = bsp_Mlx90632WriteWord(MLX90632_REG_STATUS, reg_status & (~MLX90632_STAT_DATA_RDY));
    if(ret < 0)
        return ret;

    while(tries-- > 0)
    {
        ret = bsp_Mlx90632ReadWord(MLX90632_REG_STATUS, &reg_status);
        if(ret < 0)
            return ret;
        if(reg_status & MLX90632_STAT_DATA_RDY)
            break;
        /* minimum wait time to complete measurement
         * should be calculated according to refresh rate
         * atm 10ms - 11ms
         */
        //usleep(10000, 11000);
        MLX90632_DELAY_MS(10);  //提供延时函数,此处延时10ms左右
    }

    if(tries < 0)
    {
        // data not ready
        return -ETIMEDOUT;
    }

    return (reg_status & MLX90632_STAT_CYCLE_POS) >> 2;
}

/*******************************************************************************
 * 名    称: bsp_Mlx90632ChannelNewSelect
 * 功    能: 根据 bsp_Mlx90632StartMeasurement 的返回值,获取通道的顺序。
 * 入口参数: ret:bsp_Mlx90632StartMeasurement 的返回值  *channel_new:指向存储新通道值的内存位置的指针 *channel_new:指向存储旧通道值的内存位置的指针
 * 出口参数: 0:正常
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注: 如果返回值不是1/2 则不分配通道序列
 *******************************************************************************/
int32_t bsp_Mlx90632ChannelNewSelect(int32_t ret, uint8_t* channel_new, uint8_t* channel_old)
{
    switch(ret)
    {
    case 1:
        *channel_new = 1;
        *channel_old = 2;
        break;

    case 2:
        *channel_new = 2;
        *channel_old = 1;
        break;

    default:
        return -EINVAL;
    }
    return 0;
}

/*******************************************************************************
 * 名    称: bsp_Mlx90632ReadTempAmbientRaw
 * 功    能: 读取环境原始旧值和新值
 * 入口参数: ambient_new_raw:原始环境温度新值  ambient_old_raw:原始环境温度旧值
 * 出口参数: 0:正常
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
int32_t bsp_Mlx90632ReadTempAmbientRaw(int16_t* ambient_new_raw, int16_t* ambient_old_raw)
{
    int32_t ret;
    uint16_t read_tmp;

    ret = bsp_Mlx90632ReadWord(MLX90632_RAM_3(1), &read_tmp);
    if(ret < 0)
        return ret;
    *ambient_new_raw = (int16_t)read_tmp;

    ret = bsp_Mlx90632ReadWord(MLX90632_RAM_3(2), &read_tmp);
    if(ret < 0)
        return ret;
    *ambient_old_raw = (int16_t)read_tmp;

    return ret;
}

/*******************************************************************************
 * 名    称: bsp_Mlx90632ReadTempObjectRaw
 * 功    能: 读取对象原始温度新值和旧值
 * 入口参数: start_measurement_ret: 返回值 object_new_raw:物体原始温度新值  object_old_raw:物体原始温度旧值
 * 出口参数: 0:正常
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
int32_t bsp_Mlx90632ReadTempObjectRaw(int32_t start_measurement_ret,
                                      int16_t* object_new_raw, int16_t* object_old_raw)
{
    int32_t ret;
    uint16_t read_tmp;
    int16_t read;
    uint8_t channel, channel_old;

    ret = bsp_Mlx90632ChannelNewSelect(start_measurement_ret, &channel, &channel_old);
    if(ret != 0)
        return -EINVAL;

    ret = bsp_Mlx90632ReadWord(MLX90632_RAM_2(channel), &read_tmp);
    if(ret < 0)
        return ret;

    read = (int16_t)read_tmp;

    ret = bsp_Mlx90632ReadWord(MLX90632_RAM_1(channel), &read_tmp);
    if(ret < 0)
        return ret;
    *object_new_raw = (read + (int16_t)read_tmp) / 2;

    ret = bsp_Mlx90632ReadWord(MLX90632_RAM_2(channel_old), &read_tmp);
    if(ret < 0)
        return ret;
    read = (int16_t)read_tmp;

    ret = bsp_Mlx90632ReadWord(MLX90632_RAM_1(channel_old), &read_tmp);
    if(ret < 0)
        return ret;
    *object_old_raw = (read + (int16_t)read_tmp) / 2;

    return ret;
}
/*******************************************************************************
 * 名    称: bsp_Mlx90632ReadTempRaw
 * 功    能: 读取温度原始值
 * 入口参数: ambient_new_raw:环境原始温度新值  ambient_old_raw:环境原始温度旧值
*             object_new_raw:物体原始温度新值  object_old_raw:物体原始温度旧值
 * 出口参数: 0:正常
 * 作  者: Roger-WY
 * 创建日期: 2022-05-04
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
int32_t bsp_Mlx90632ReadTempRaw(int16_t* ambient_new_raw, int16_t* ambient_old_raw,
                                int16_t* object_new_raw, int16_t* object_old_raw)
{
    int32_t ret, start_measurement_ret;

    // trigger and wait for measurement to complete
    start_measurement_ret = bsp_Mlx90632StartMeasurement();
    if(start_measurement_ret < 0)
        return start_measurement_ret;

    /** Read new and old **ambient** values from sensor */
    ret = bsp_Mlx90632ReadTempAmbientRaw(ambient_new_raw, ambient_old_raw);
    if(ret < 0)
        return ret;

    /** Read new and old **object** values from sensor */
    ret = bsp_Mlx90632ReadTempObjectRaw(start_measurement_ret, object_new_raw, object_old_raw);

    return ret;
}

/* DSPv5 */
double bsp_Mlx90632PreprocessTempAmbient(int16_t ambient_new_raw, int16_t ambient_old_raw, int16_t Gb)
{
    double VR_Ta, kGb;

    kGb = ((double)Gb) / 1024.0;

    VR_Ta = ambient_old_raw + kGb * (ambient_new_raw / (MLX90632_REF_3));
    return ((ambient_new_raw / (MLX90632_REF_3)) / VR_Ta) * 524288.0;
}

double bsp_Mlx90632PreprocessTempObject(int16_t object_new_raw, int16_t object_old_raw,
                                        int16_t ambient_new_raw, int16_t ambient_old_raw,
                                        int16_t Ka)
{
    double VR_IR, kKa;

    kKa = ((double)Ka) / 1024.0;

    VR_IR = ambient_old_raw + kKa * (ambient_new_raw / (MLX90632_REF_3));
    return ((((object_new_raw + object_old_raw) / 2) / (MLX90632_REF_12)) / VR_IR) * 524288.0;
}

double bsp_Mlx90632CalcTempAmbient(int16_t ambient_new_raw, int16_t ambient_old_raw, int32_t P_T,
                                   int32_t P_R, int32_t P_G, int32_t P_O, int16_t Gb)
{
    double Asub, Bsub, Ablock, Bblock, Cblock, AMB;

    AMB = bsp_Mlx90632PreprocessTempAmbient(ambient_new_raw, ambient_old_raw, Gb);

    Asub = ((double)P_T) / (double)17592186044416.0;
    Bsub = (double)AMB - ((double)P_R / (double)256.0);
    Ablock = Asub * (Bsub * Bsub);
    Bblock = (Bsub / (double)P_G) * (double)1048576.0;
    Cblock = (double)P_O / (double)256.0;

    return Bblock + Ablock + Cblock;
}


/*******************************************************************************
* 名    称: bsp_Mlx90632CalcTempObjectIteration
* 功    能: 物体温度的迭代计算
* 入口参数: prev_object_temp: 上次计算的物体温度值,如果没有,默认为25.0摄氏度
*            object: 通过 bsp_Mlx90632PreprocessTempObject 函数获取的物体温度值
*            剩余的参数都是校正值
* 出口参数: 0:正常
* 作  者: Roger-WY
* 创建日期: 2022-05-04
* 修    改:
* 修改日期:
* 备    注:
*******************************************************************************/
static double bsp_Mlx90632CalcTempObjectIteration(double prev_object_temp, int32_t object, double TAdut,
        int32_t Ga, int32_t Fa, int32_t Fb, int16_t Ha, int16_t Hb,
        double emissivity)
{
    double calcedGa, calcedGb, calcedFa, TAdut4, first_sqrt;
    // temp variables
    double KsTAtmp, Alpha_corr;
    double Ha_customer, Hb_customer;


    Ha_customer = Ha / ((double)16384.0);
    Hb_customer = Hb / ((double)1024.0);
    calcedGa = ((double)Ga * (prev_object_temp - 25)) / ((double)68719476736.0);
    KsTAtmp = (double)Fb * (TAdut - 25);
    calcedGb = KsTAtmp / ((double)68719476736.0);
    Alpha_corr = (((double)(Fa * POW10)) * Ha_customer * (double)(1 + calcedGa + calcedGb)) /
                 ((double)70368744177664.0);
    calcedFa = object / (emissivity * (Alpha_corr / POW10));
    TAdut4 = (TAdut + 273.15) * (TAdut + 273.15) * (TAdut + 273.15) * (TAdut + 273.15);

    first_sqrt = sqrt(calcedFa + TAdut4);

    return sqrt(first_sqrt) - 273.15 - Hb_customer;
}


void bsp_Mlx90632SetEmissivity(double value)
{
    emissivity = value;
}

double bsp_mlx90632GetEmissivity(void)
{
    if(emissivity == 0.0)
    {
        return 1.0;
    }
    else
    {
        return emissivity;
    }
}

double bsp_Mlx90632CalcTempObject(int32_t object, int32_t ambient,
                                  int32_t Ea, int32_t Eb, int32_t Ga, int32_t Fa, int32_t Fb,
                                  int16_t Ha, int16_t Hb)
{
    double kEa, kEb, TAdut;
    double temp = 25.0;
    double tmp_emi = bsp_mlx90632GetEmissivity();
    int8_t i;

    kEa = ((double)Ea) / ((double)65536.0);
    kEb = ((double)Eb) / ((double)256.0);
    TAdut = (((double)ambient) - kEb) / kEa + 25;

    //iterate through calculations
    for(i = 0; i < 5; ++i)
    {
        temp = bsp_Mlx90632CalcTempObjectIteration(temp, object, TAdut, Ga, Fa, Fb, Ha, Hb, tmp_emi);
    }
    return temp;
}



/***************************** (END OF FILE) **********************************/

  • bsp_mlx90632.h 文件
/*******************************************************************************
*   Filename:       bsp_mlx90632.h
*   Revised:        All copyrights reserved to Roger.
*   Date:           2022-05-02
*   Revision:       v1.0
*   Writer:	        Roger-WY.
*
*   Description:    非接触式红外温度传感器模块驱动(数字式)  头文件
*******************************************************************************/
#ifndef __BSP_MLX90632_H__
#define __BSP_MLX90632_H__

#include "stm32f10x.h"
#include "bsp_timer.h"

#define MLX90632_TEMP_READ_ERR_CODE -99
/* Solve errno not defined values */
#ifndef ETIMEDOUT
#define ETIMEDOUT 110 /**< From linux errno.h */
#endif
#ifndef EINVAL
#define EINVAL 22 /**< From linux errno.h */
#endif
#ifndef EPROTONOSUPPORT
#define EPROTONOSUPPORT 93 /**< From linux errno.h */
#endif

typedef struct __mlx90632calibrationpar
{
    int32_t PR;
    int32_t PG;
    int32_t PO;
    int32_t PT;
    int32_t Ea;
    int32_t Eb;
    int32_t Fa;
    int32_t Fb;
    int32_t Ga;
    int16_t Gb;
    int16_t Ha;
    int16_t Hb;
    int16_t Ka;
}stMlx90632CalibraParTypeDef;

/* MLX90632 内部寄存器地址定义 */
/* Private defines -----------------------------------------------------------*/
/* Definition of I2C address of MLX90632 */
#define MLX90632_ADDR       0x3A
#define MLX90632_ADDR_WR   (MLX90632_ADDR << 1)

#define BITS_PER_LONG 32

/* BIT, GENMASK and ARRAY_SIZE macros are imported from kernel */
#ifndef BIT
#define BIT(x) (1UL << (x))
#endif
#ifndef GENMASK
#ifndef BITS_PER_LONG
#warning "Using default BITS_PER_LONG value"
#define BITS_PER_LONG 64 /**< Define how many bits per long your CPU has */
#endif
#define GENMASK(h, l) \
    (((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) /**< Return number of elements in array */
#endif

/* Memory sections addresses */
#define MLX90632_ADDR_RAM   0x4000 /**< Start address of ram */
#define MLX90632_ADDR_EEPROM    0x2480 /**< Start address of user eeprom */

/* EEPROM addresses - used at startup */
#define MLX90632_EE_CTRL    0x24d4 /**< Control register initial value */
#define MLX90632_EE_CONTROL MLX90632_EE_CTRL /**< More human readable for Control register */

#define MLX90632_EE_I2C_ADDRESS 0x24d5 /**< I2C address register initial value */
#define MLX90632_EE_VERSION 0x240b /**< EEPROM version reg - assumed 0x101 */

#define MLX90632_EE_P_R     0x240c /**< Calibration constant ambient reference register 32bit */
#define MLX90632_EE_P_G     0x240e /**< Calibration constant ambient gain register 32bit */
#define MLX90632_EE_P_T     0x2410 /**< Calibration constant ambient tc2 register 32bit	*/
#define MLX90632_EE_P_O     0x2412 /**< Calibration constant ambient offset register 32bit */
#define MLX90632_EE_Aa      0x2414 /**< Aa calibration const register 32bit */
#define MLX90632_EE_Ab      0x2416 /**< Ab calibration const register 32bit */
#define MLX90632_EE_Ba      0x2418 /**< Ba calibration const register 32bit */
#define MLX90632_EE_Bb      0x241a /**< Bb calibration const register 32bit */
#define MLX90632_EE_Ca      0x241c /**< Ca calibration const register 32bit */
#define MLX90632_EE_Cb      0x241e /**< Cb calibration const register 32bit */
#define MLX90632_EE_Da      0x2420 /**< Da calibration const register 32bit */
#define MLX90632_EE_Db      0x2422 /**< Db calibration const register 32bit */
#define MLX90632_EE_Ea      0x2424 /**< Ea calibration constant register 32bit */
#define MLX90632_EE_Eb      0x2426 /**< Eb calibration constant register 32bit */
#define MLX90632_EE_Fa      0x2428 /**< Fa calibration constant register 32bit */
#define MLX90632_EE_Fb      0x242a /**< Fb calibration constant register 32bit */
#define MLX90632_EE_Ga      0x242c /**< Ga calibration constant register 32bit */

#define MLX90632_EE_Gb      0x242e /**< Ambient Beta calibration constant 16bit */
#define MLX90632_EE_Ka      0x242f /**< IR Beta calibration constant 16bit */

#define MLX90632_EE_Ha      0x2481 /**< Ha customer calibration value register 16bit */
#define MLX90632_EE_Hb      0x2482 /**< Hb customer calibration value register 16bit */

/* Register addresses - volatile */
#define MLX90632_REG_I2C_ADDR   0x3000 /**< Chip I2C address register */

/* Control register address - volatile */
#define MLX90632_REG_CTRL   0x3001 /**< Control Register address */
#define MLX90632_CFG_SOC_SHIFT 3 /**< Start measurement in step mode */
#define MLX90632_CFG_SOC_MASK BIT(MLX90632_CFG_SOC_SHIFT)
#define MLX90632_CFG_PWR_MASK GENMASK(2, 1) /**< PowerMode Mask */
/* PowerModes statuses */
#define MLX90632_PWR_STATUS(ctrl_val) (ctrl_val << 1)
#define MLX90632_PWR_STATUS_HALT MLX90632_PWR_STATUS(0) /**< Pwrmode hold */
#define MLX90632_PWR_STATUS_SLEEP_STEP MLX90632_PWR_STATUS(1) /**< Pwrmode sleep step*/
#define MLX90632_PWR_STATUS_STEP MLX90632_PWR_STATUS(2) /**< Pwrmode step */
#define MLX90632_PWR_STATUS_CONTINUOUS MLX90632_PWR_STATUS(3) /**< Pwrmode continuous*/

/* Device status register - volatile */
#define MLX90632_REG_STATUS         0x3fff /**< Device status register */
#define MLX90632_STAT_BUSY          BIT(10) /**< Device busy indicator */
#define MLX90632_STAT_EE_BUSY       BIT(9) /**< Device EEPROM busy indicator */
#define MLX90632_STAT_BRST          BIT(8) /**< Device brown out reset indicator */
#define MLX90632_STAT_CYCLE_POS     GENMASK(6, 2) /**< Data position in measurement table */
#define MLX90632_STAT_DATA_RDY      BIT(0) /**< Data ready indicator */

/* RAM_MEAS address-es for each channel */
#define MLX90632_RAM_1(meas_num)    (MLX90632_ADDR_RAM + 3 * meas_num)
#define MLX90632_RAM_2(meas_num)    (MLX90632_ADDR_RAM + 3 * meas_num + 1)
#define MLX90632_RAM_3(meas_num)    (MLX90632_ADDR_RAM + 3 * meas_num + 2)

/* Timings (ms) */
#define MLX90632_TIMING_EEPROM      100 /**< Time between EEPROM writes */

/* Magic constants */
#define MLX90632_EEPROM_VERSION     0x105 /**< EEPROM DSP version for constants */
#define MLX90632_EEPROM_WRITE_KEY   0x554C /**< EEPROM write key 0x55 and 0x4c */
#define MLX90632_RESET_CMD          0x0006 /**< Reset sensor (address or global) */
#define MLX90632_MAX_MEAS_NUM       31 /**< Maximum number of measurements in list */
#define MLX90632_EE_SEED            0x3f6d /**< Seed for the CRC calculations */
#define MLX90632_REF_12             12.0 /**< ResCtrlRef value of Channel 1 or Channel 2 */
#define MLX90632_REF_3              12.0 /**< ResCtrlRef value of Channel 3 */


/* MLX90632 供外部调用函数 */
int8_t bsp_Mlx90632Init(void);
int8_t bsp_Mlx90632ReadCalibraParFromEeprom(stMlx90632CalibraParTypeDef *pPar);
void bsp_Mlx90632ReadCalibraParInit(stMlx90632CalibraParTypeDef *pPar);
int bsp_Mlx90632StartMeasurement(void);
int32_t bsp_Mlx90632ChannelNewSelect(int32_t ret, uint8_t *channel_new, uint8_t *channel_old);
int32_t bsp_Mlx90632ReadTempAmbientRaw(int16_t *ambient_new_raw, int16_t *ambient_old_raw);
void bsp_Mlx90632SetEmissivity(double value);
double bsp_Mlx90632CalcTempObject(int32_t object, int32_t ambient,
                                 int32_t Ea, int32_t Eb, int32_t Ga, int32_t Fa, int32_t Fb,
                                 int16_t Ha, int16_t Hb);
double bsp_Mlx90632CalcTempAmbient(int16_t ambient_new_raw, int16_t ambient_old_raw, int32_t P_T,
                                  int32_t P_R, int32_t P_G, int32_t P_O, int16_t Gb);
double bsp_Mlx90632PreprocessTempObject(int16_t object_new_raw, int16_t object_old_raw,
                                       int16_t ambient_new_raw, int16_t ambient_old_raw,
                                       int16_t Ka);
double bsp_Mlx90632PreprocessTempAmbient(int16_t ambient_new_raw, int16_t ambient_old_raw, int16_t Gb);
int32_t bsp_Mlx90632ReadTempRaw(int16_t *ambient_new_raw, int16_t *ambient_old_raw,
                               int16_t *object_new_raw, int16_t *object_old_raw);

extern stMlx90632CalibraParTypeDef stMlxCalibraPar;

#endif
/***************************** (END OF FILE) **********************************/

  • main 函数读取温度
/*******************************************************************************
 *   Filename:       main.c
 *   Revised:        All copyrights reserved to Roger-WY.
 *   Revision:       v1.0
 *   Writer:	     Roger-WY.
 *
 *   Description:    主函数模块
 *
 *   Notes:
 *     				E-mail:261313062@qq.com
 *
 *******************************************************************************/


/***************************头文件声明区***************************************/

#include "includes.h"
#include "app_var.h"

#include "bsp_mlx90632.h"

/********************************宏定义区**************************************/
/* 定义例程名和例程发布日期 */
#define EXAMPLE_NAME	"STM32F103XXX_MLX90632_Demo"
#define EXAMPLE_DATE	"2022-05-02"
#define DEMO_VER		"1.0.0"

/***************************变量定义及声明区***********************************/

double pre_ambient, pre_object, ambient, object;
stMlx90632CalibraParTypeDef stmlxCalibraPar = {0};

/***************************函数定义及声明区***********************************/
void app_SeggerRttInit(void);
static void app_ShowPowerOnInfo(void);


/*============================================================================*/
/*============================================================================*/
/*============================================================================*/


/*******************************************************************************
 * 名    称: main
 * 功    能: 主函数
 * 入口参数: 无
 * 出口参数: 无
 * 作  者: Roger-WY.
 * 创建日期: 2015-06-25
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
int main(void)
{
	int16_t ambient_new_raw;
	int16_t ambient_old_raw;
	int16_t object_new_raw;
	int16_t object_old_raw;
    /***********************************************
    * 描述: 初始化硬件设备
    */
    bsp_Init(); /* 为了是main函数看起来更简洁些,将硬件初始化的代码封装到这个函数 */

    bsp_Mlx90632Init();
    
    /***********************************************
    * 描述:打印上电信息
    */
    app_SeggerRttInit();
	app_ShowPowerOnInfo();

    /***********************************************
    * 描述: 创建软定时器
    */
    bsp_StartAutoTimer( 0,1000 );   /* 启动自动重载软定时器0 用于1S定时任务 */
    /***********************************************
    * 描述: 进入主程序循环体
    */
    while(1)
    {
        /***********************************************
        * 描述:用户可以在此函数内执行CPU休眠和喂狗等
        * 这个函数在bsp.c 中定义。
        */
        bsp_Idle();                                     /* 调用MODS_Poll() */

        /*   用户执行的任务    */
        /*   1S定时到    */
        if(bsp_CheckTimer(0)) {
            bsp_LedToggle(1);  /* 翻转LED1 */
            
            /* Get raw data from MLX90632 */
            bsp_Mlx90632ReadTempRaw(&ambient_new_raw, &ambient_old_raw, &object_new_raw, &object_old_raw);
            /* Pre-calculations for ambient and object temperature calculation */
            pre_ambient = bsp_Mlx90632PreprocessTempAmbient(ambient_new_raw, ambient_old_raw, stMlxCalibraPar.Gb);
            pre_object = bsp_Mlx90632PreprocessTempObject(object_new_raw, object_old_raw, ambient_new_raw, ambient_old_raw, stMlxCalibraPar.Ka);
            /* Set emissivity = 1 */
            bsp_Mlx90632SetEmissivity(1.0);
            /* Calculate ambient and object temperature */
            ambient = bsp_Mlx90632CalcTempAmbient(ambient_new_raw, ambient_old_raw, stMlxCalibraPar.PT, stMlxCalibraPar.PR, stMlxCalibraPar.PG, stMlxCalibraPar.PO, stMlxCalibraPar.Gb);
            object = bsp_Mlx90632CalcTempObject(pre_object, pre_ambient, stMlxCalibraPar.Ea, stMlxCalibraPar.Eb, stMlxCalibraPar.Ga, stMlxCalibraPar.Fa, stMlxCalibraPar.Fb, stMlxCalibraPar.Ha, stMlxCalibraPar.Hb);
            

            printf("MLX90632 Measure Object Temp:%f ℃,Ambient Temp:%f\n",object,ambient);
            
         }
    }
}


void app_SeggerRttInit(void)
{
    /***********************************************
    * 描述: RTT使用配置
    */
    /* 配置通道0,上行配置*/
	SEGGER_RTT_ConfigUpBuffer(0, "RTTUP", NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
	/* 配置通道0,下行配置*/
	SEGGER_RTT_ConfigDownBuffer(0, "RTTDOWN", NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
}
/*******************************************************************************
 * 名    称: app_ShowPowerOnInfo
 * 功    能: 上电打印相关信息
 * 入口参数: 无
 * 出口参数: 无
 * 作  者: Roger-WY.
 * 创建日期: 2015-06-25
 * 修    改:
 * 修改日期:
 * 备    注:
 *******************************************************************************/
static void app_ShowPowerOnInfo(void)
{
	/***********************************************
    * 描述: 通过RTT打印信息
    */
    SEGGER_RTT_SetTerminal(0);
    SEGGER_RTT_printf(0,"\n\r");
	SEGGER_RTT_printf(0,"*************************************************************\n\r");
	SEGGER_RTT_printf(0,"* 例程名称   : %s\r\n", EXAMPLE_NAME);	/* 打印例程名称 */
	SEGGER_RTT_printf(0,"* 例程版本   : %s\r\n", DEMO_VER);		/* 打印例程版本 */
	SEGGER_RTT_printf(0,"* 发布日期   : %s\r\n", EXAMPLE_DATE);	/* 打印例程日期 */

	/* 打印ST固件库版本,这3个定义宏在stm32f10x.h文件中 */
	SEGGER_RTT_printf(0,"* 固件库版本 : V%d.%d.%d (STM32F10x_StdPeriph_Driver)\r\n", __STM32F10X_STDPERIPH_VERSION_MAIN,
           __STM32F10X_STDPERIPH_VERSION_SUB1,__STM32F10X_STDPERIPH_VERSION_SUB2);
	SEGGER_RTT_printf(0,"* \r\n");	/* 打印一行空格 */
	SEGGER_RTT_printf(0,"* Email : wangyao@zhiyigroup.cn \r\n");
	SEGGER_RTT_printf(0,"* 淘宝店: zhisheng.taobao.com\r\n");
	SEGGER_RTT_printf(0,"* 技术支持QQ群  : 539041646 \r\n");
	SEGGER_RTT_printf(0,"* Copyright www.zhiyigroup.cn 至一电子科技\r\n");
	SEGGER_RTT_printf(0,"*************************************************************\n\r");

	/***********************************************
    * 描述: 通过串口打印信息
    */
    printf("\n\r");
	printf("*************************************************************\n");
	printf("* 例程名称   : %s\r\n", EXAMPLE_NAME);	/* 打印例程名称 */
	printf("* 例程版本   : %s\r\n", DEMO_VER);		/* 打印例程版本 */
	printf("* 发布日期   : %s\r\n", EXAMPLE_DATE);	/* 打印例程日期 */
	printf("* --------------------------\r\n");	/*  */
	printf("* 接线方式       \r\n");	/* 接线方式 */
    printf("* VCC ---- 3.3VDC~5VDC      \r\n");	/* 接线方式 */
    printf("* GND ---- GND              \r\n");	/* 接线方式 */
    printf("* SCL ---- PC4              \r\n");	/* 接线方式 */
    printf("* SDA ---- PC5              \r\n");	/* 接线方式 */
	printf("* 串口使用 UASRT1(PA9/PA10) \r\n");	/*  */
	printf("* --------------------------\r\n");	/* 接线方式 */
    
	/* 打印ST固件库版本,这3个定义宏在stm32f10x.h文件中 */
	printf("* 固件库版本 : V%d.%d.%d (STM32F10x_StdPeriph_Driver)\r\n", __STM32F10X_STDPERIPH_VERSION_MAIN,
           __STM32F10X_STDPERIPH_VERSION_SUB1,__STM32F10X_STDPERIPH_VERSION_SUB2);
	printf("* \r\n");	/* 打印一行空格 */
	printf("* Email : wangyao@zhiyigroup.cn \r\n");
	printf("* 淘宝店: zhisheng.taobao.com\r\n");
	printf("* 技术支持QQ群  : 539041646 \r\n");
	printf("* Copyright www.zhiyigroup.cn 至一电子科技\r\n");
	printf("*************************************************************\n\r");
}

完整的工程

STM32F1 使用标准库函数读取MLX90632非接触式温度传感器的完整工程可点击此处下载(有积分或者是会员的小伙伴可以支持一下!)

PS:鉴于积分实在有点糟心,所以我把工程上传到 Gitee|Github 上了,没有积分的小伙伴可以直接去下载

结束语

如果觉得文章对您有帮助,请关注、点赞,谢谢!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 11:00:44  更:2022-08-06 11:02:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:26:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码