STM32实现MLX90614非接触测温串口显示(标准库与HAL库实现)

2023-11-16

目录

模块选择

编程环境

 MLX90614基本原理

通信协议(SMBus通信,类IIC通信)

代码实现

STM32与模块之间接线表

1.标准库实现温度采集

2.HAL库实现温度采集


模块选择

        ·STM32F103C8T6

        ·MLX90614 非接触式红外测温传感器

编程环境

        ·KEIL5(μVision V5.30.0.0) 其它版本影响并不大

         ·STM32CubeMX,版本不限

         ·串口助手

 MLX90614基本原理

 引脚说明

编号 名称 功能
1 VCC 电源正,3-5V
2 GND 电源地
3 SCL 串行时钟输入
4 SDA 串行地址和数据输入/输出

MLX90614是一种红外温度计,用于非接触式温度测量。红外测温是根据被测物体的红外辐射能量来确定物体的温度,不与被测物体接触,具有不影响被测物体温度分布场,温度分辨率高、响应速度快、测温范围广、不受测温上限的限制、稳定性好等特点。适合于汽车空调、室内暖气、家用电器、手持设备以及医疗设备应用等。

MLX90614的出厂校准温度范围很广:环境温度为-40°C——125°C,目标温度为-70°C——380°C。测量值是传感器视场中所有物体的平均温度。在室温下,MLX90614的标准精确度为±0.5°C。

 MLX90614由MLX81101红外热电堆传感器和包括含有稳压电路、低噪声放大器、A/D转换器、DSP单元、脉宽调制电路及逻辑控制电路的MLX90302信号处理芯片构成。

其工作原理为:红外热电堆传感器输出的温度信号经过内部低噪声、低失调的运算放大器(OPA)放大后经过A/D转换器(ADC)转换为17位数字信号通过可编程FIR及IIR低通数字滤波器(即DSP)处理后输出,输出结果存储在其内部RAM存储单元中。
MLX90614 是由内部状态机控制物体温度和环境温度的测量和计算,进行温度后处理,并将结果通过 PWM 或是 SMBus 模式输出。 ASSP 支持两个 IR 传感器。 (MLX90614xAx 只有一个 IR 传感器) IR 传感器的输出通过增益可编程的低噪声低失 调电压放大器放大,经过 Sigma Delta 调制器转换为单一比特流并反馈给 DSP 做后续的处理。信号通过可编程的 (用 EEPROM 实现) FIR 和 IIR 低通滤波器以进一步减低输入信号的带宽从而达到所需的噪声特性和刷新率。IIR 滤波器的输出为测量结果并存于内部 RAM 中,其中三个单元可被用到:一个是片内温度传感器(片上 PTAT 或 PTC),其余两个为 IR 传感器。 基于以上测量结果,计算出对应的环境温度 Ta物体温度 To,两个温度分辨率都为 0.01 ˚C。Ta 和 To 可通过两种方式读取:通过两线接口读取 RAM 单元,(0.02°C 分辨率,固定范围) 或者通过 PWM 数字模式输出。 (10 位分辨率, 范围可配置) 测量周期的最后一步为:测量所得 Ta 和 To 被重新调节为 PWM 所需的输出分辨率,并且该数据存在 PWM 状态 机的寄存器中,状态机可以产生固定频率和一定占空比来表示测量的数据。

通信协议(SMBus通信,类IIC通信)

单片机与MLX90614红外测温模块之间通信的方式是“类IIC”通信,意思就是通信方式跟IIC通信方式很像但又不是IIC,它有另外一个名字叫做SMBus。SMBus (System Management Bus)是 1995 年由 intel 公司提出的一种高效同步串行总线,SMBus 只有两根信号线:双向数据线和时钟信号线,容许 CPU 与各种外围接口器件以串行方式进行通信、交换信息,既可以提高传输速度也可以减小器件的资源占用,另外即使在没有SMBus 接口的单片机上也可利用软件进行模拟。

代码实现

STM32与模块之间接线表
MLX90614 STM32F103C8T6
VCC VCC
GND GND
SCL PB8
SDA PB9
- PA9(USART1_ TX)
- PA10(USART1_RX)
1.标准库实现温度采集

主函数:

int main(void)
{	
	float Temperature=10;
	char temStr[100] = "";
	int i = 0;			//	循环变量
	delay_init();		//	延时函数初始化配置
	uart_init(115200);
	
	USART_SendData(USART1, 'A');
	Mlx96014_Configuration();
  /* Infinite loop */
  while (1)
  {
		Temperature=SMBus_ReadTemp();
		sprintf(temStr,"The Temperature is:%.2f\r\n",Temperature);
		for(i=0;i<strlen(temStr);i++)
		{
			USART_SendData(USART1, temStr[i]);
			delay_ms(1);
		}
		delay_ms(500);
  }
}

mlx90614.c

/*******************************************************************************
* 文件名   : mlx90614.c
* 作  者        : 
* 版  本        : 
* 日  期        : 2015-08-07
* 描  述        : mlx90614函数
*******************************************************************************/
#include "stm32f10x.h"
#include "mlx90614.h"

/*******************************************************************************
* Function Name  : Mlx90614_Configuration
* Description    : Mlx90614_Configuration
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Mlx96014_Configuration(void)
{
	GPIO_InitTypeDef GPIO; //声明一个结构体变量
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	// 温度传感器引脚配置
	GPIO.GPIO_Pin = GPIO_Pin_9;//非接触温度传感器SDA 连接PB9
	GPIO.GPIO_Speed = GPIO_Speed_50MHz;//管脚频率为50MHZ
	GPIO.GPIO_Mode = GPIO_Mode_Out_OD;//输出模式为
	GPIO_Init(GPIOB,&GPIO);//初始化GPIOB寄存器
	
	GPIO.GPIO_Pin = GPIO_Pin_8;//非接触温度传感器SCL 连接PB8
	GPIO.GPIO_Speed = GPIO_Speed_50MHz;//管脚频率为50MHZ
	GPIO.GPIO_Mode = GPIO_Mode_Out_OD;//输出模式为
	GPIO_Init(GPIOB,&GPIO);//初始化GPIOB寄存器

	SDA_H;
	SCL_H; //因为SMBus是下降沿触发
}

/*******************************************************************************
* Function Name  : SMBus_StartBit
* Description    : Generate START condition on SMBus
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SMBus_StartBit(void)
{
	SDA_H;               // Set SDA line 
	SMBus_Delay(1);      // Wait a few microseconds 
	SCL_H;               // Set SCK line  
	SMBus_Delay(5);      // Generate bus free time between Stop
	SDA_L;               // Clear SDA line
	SMBus_Delay(10);     // Hold time after (Repeated) Start
											 // Condition. After this period, the first clock is generated.
											 //(Thd:sta=4.0us min)
	SCL_L;               // Clear SCK line
	SMBus_Delay(2);      // Wait a few microseconds
}

/*******************************************************************************
* Function Name  : SMBus_StopBit
* Description    : Generate STOP condition on SMBus
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/

void SMBus_StopBit(void)
{
	SCL_L;                // Clear SCK line
	SMBus_Delay(5);       // Wait a few microseconds
	SDA_L;                // Clear SDA line
	SMBus_Delay(5);       // Wait a few microseconds
	SCL_H;                // Set SCK line
	SMBus_Delay(10);      // Stop condition setup time(Tsu:sto=4.0us min)
	SDA_H;                // Set SDA line
}

/*******************************************************************************
* Function Name  : SMBus_SendByte
* Description    : Send a byte on SMBus
* Input          : Tx_buffer
* Output         : None
* Return         : None
*******************************************************************************/
u8 SMBus_SendByte(u8 Tx_buffer)
{
	u8        Bit_counter;
	u8        Ack_bit;
	u8        bit_out;


	for(Bit_counter=8; Bit_counter; Bit_counter--)
	{
			if (Tx_buffer&0x80)
			{
					bit_out=1;       // If the current bit of Tx_buffer is 1 set bit_out
			}
			else
			{
					bit_out=0;      // else clear bit_out
			}
			SMBus_SendBit(bit_out);           // Send the current bit on SDA
			Tx_buffer<<=1;                    // Get next bit for checking
	}
	Ack_bit=SMBus_ReceiveBit();           // Get acknowledgment bit
	return        Ack_bit;
}

/*******************************************************************************
* Function Name  : SMBus_SendBit
* Description    : Send a bit on SMBus
* Input          : bit_out
* Output         : None
* Return         : None
*******************************************************************************/
void SMBus_SendBit(u8 bit_out)
{
	if(bit_out==0)
	{
		SDA_L;   
	}
	else
	{
	SDA_H;
	}
	SMBus_Delay(2);                            // Tsu:dat = 250ns minimum
	SCL_H;                                     // Set SCK line
	SMBus_Delay(10);                           // High Level of Clock Pulse
	SCL_L;                                     // Clear SCK line
	SMBus_Delay(10);                           // Low Level of Clock Pulse
//        SMBUS_SDA_H();                       // Master release SDA line ,
	return;
}
/*******************************************************************************
* Function Name  : SMBus_ReceiveBit
* Description    : Receive a bit on SMBus
* Input          : None
* Output         : None
* Return         : Ack_bit
*******************************************************************************/
u8 SMBus_ReceiveBit(void)
{
	u8 Ack_bit;


	SDA_H;             //引脚靠外部电阻上拉,当作输入
	SCL_H;             // Set SCL line
	SMBus_Delay(2);    // High Level of Clock Pulse
	if (SMBUS_SDA_PIN)
	{
			Ack_bit=1;
	}
	else
	{
			Ack_bit=0;
	}
	SCL_L;                    // Clear SCL line
	SMBus_Delay(4);           // Low Level of Clock Pulse
	return   Ack_bit;
}
/*******************************************************************************
* Function Name  : SMBus_ReceiveByte
* Description    : Receive a byte on SMBus
* Input          : ack_nack
* Output         : None
* Return         : RX_buffer
*******************************************************************************/
u8 SMBus_ReceiveByte(u8 ack_nack)
{
	u8        RX_buffer;
	u8        Bit_Counter;
	for(Bit_Counter=8; Bit_Counter; Bit_Counter--)
	{
			if(SMBus_ReceiveBit())         // Get a bit from the SDA line
			{
					RX_buffer <<= 1;           // If the bit is HIGH save 1  in RX_buffer
					RX_buffer |=0x01;
			}
			else
			{
					RX_buffer <<= 1;           // If the bit is LOW save 0 in RX_buffer
					RX_buffer &=0xfe;
			}
	}
	SMBus_SendBit(ack_nack);           // Sends acknowledgment bit
	return RX_buffer;
}


/*******************************************************************************
* Function Name  : SMBus_Delay
* Description    : 延时  一次循环约1us
* Input          : time
* Output         : None
* Return         : None
*******************************************************************************/
void SMBus_Delay(u16 time)
{
	u16 i, j;
	for (i=0; i<4; i++)
	{
			for (j=0; j<time; j++);
	}
}

/*******************************************************************************
 * Function Name  : SMBus_ReadMemory
 * Description    : READ DATA FROM RAM/EEPROM
 * Input          : slaveAddress, command
 * Output         : None
 * Return         : Data
*******************************************************************************/
u16 SMBus_ReadMemory(u8 slaveAddress, u8 command)
{
    u16 data;               // Data storage (DataH:DataL)
    u8 Pec;                 // PEC byte storage
    u8 DataL=0;             // Low data byte storage
    u8 DataH=0;             // High data byte storage
    u8 arr[6];              // Buffer for the sent bytes
    u8 PecReg;              // Calculated PEC byte storage
    u8 ErrorCounter;        // Defines the number of the attempts for communication with MLX90614


    ErrorCounter=0x00;                                // Initialising of ErrorCounter
        slaveAddress <<= 1;        //2-7位表示从机地址

    do
    {
repeat:
        SMBus_StopBit();                //If slave send NACK stop comunication
        --ErrorCounter;                 //Pre-decrement ErrorCounter
        if(!ErrorCounter)               //ErrorCounter=0?
        {
            break;                      //Yes,go out from do-while{}
        }

        SMBus_StartBit();               //Start condition
        if(SMBus_SendByte(slaveAddress))//Send SlaveAddress 最低位Wr=0表示接下来写命令
        {
            goto  repeat;               //Repeat comunication again
        }
        if(SMBus_SendByte(command))     //Send command
        {
            goto    repeat;             //Repeat comunication again
        }

        SMBus_StartBit();                //Repeated Start condition
        if(SMBus_SendByte(slaveAddress+1))  //Send SlaveAddress 最低位Rd=1表示接下来读数据
        {
            goto        repeat;           //Repeat comunication again
        }

        DataL = SMBus_ReceiveByte(ACK);   //Read low data,master must send ACK
        DataH = SMBus_ReceiveByte(ACK);   //Read high data,master must send ACK
        Pec = SMBus_ReceiveByte(NACK);    //Read PEC byte, master must send NACK
        SMBus_StopBit();                  //Stop condition

        arr[5] = slaveAddress;        
        arr[4] = command;
        arr[3] = slaveAddress+1;         //Load array arr
        arr[2] = DataL;                 
        arr[1] = DataH;                
        arr[0] = 0;                   
        PecReg=PEC_Calculation(arr);     //Calculate CRC
    }
    while(PecReg != Pec);                //If received and calculated CRC are equal go out from do-while{}
        data = (DataH<<8) | DataL;       //data=DataH:DataL
    return data;
}

/*******************************************************************************
* Function Name  : PEC_calculation
* Description    : Calculates the PEC of received bytes
* Input          : pec[]
* Output         : None
* Return         : pec[0]-this byte contains calculated crc value
*******************************************************************************/
u8 PEC_Calculation(u8 pec[])
{
    u8         crc[6];
    u8        BitPosition=47;
    u8        shift;
    u8        i;
    u8        j;
    u8        temp;


    do
    {
        /*Load pattern value 0x000000000107*/
        crc[5]=0;
        crc[4]=0;
        crc[3]=0;
        crc[2]=0;
        crc[1]=0x01;
        crc[0]=0x07;
        /*Set maximum bit position at 47 ( six bytes byte5...byte0,MSbit=47)*/
        BitPosition=47;
        /*Set shift position at 0*/
        shift=0;
        /*Find first "1" in the transmited message beginning from the MSByte byte5*/
        i=5;
        j=0;
        while((pec[i]&(0x80>>j))==0 && i>0)
        {
            BitPosition--;
            if(j<7)
            {
                j++;
            }
            else
            {
                j=0x00;
                i--;
            }
        }/*End of while */


        /*Get shift value for pattern value*/
        shift=BitPosition-8;
        /*Shift pattern value */
        while(shift)
        {
            for(i=5; i<0xFF; i--)
            {
                if((crc[i-1]&0x80) && (i>0))
                {
                    temp=1;
                }
                else
                {
                    temp=0;
                }
                crc[i]<<=1;
                crc[i]+=temp;
            }/*End of for*/
            shift--;
        }/*End of while*/
        /*Exclusive OR between pec and crc*/
        for(i=0; i<=5; i++)
        {
            pec[i] ^=crc[i];
        }/*End of for*/
    }
    while(BitPosition>8); /*End of do-while*/

    return pec[0];
}

 /*******************************************************************************
 * Function Name  : SMBus_ReadTemp
 * Description    : Calculate and return the temperature
 * Input          : None
 * Output         : None
 * Return         : SMBus_ReadMemory(0x00, 0x07)*0.02-273.15
*******************************************************************************/
float SMBus_ReadTemp(void)
{   
    return SMBus_ReadMemory(SA, RAM_ACCESS|RAM_Ta)*0.02-273.15;
}

/*********************************END OF FILE*********************************/

 注意:

float SMBus_ReadTemp(void)
{   
    return SMBus_ReadMemory(SA, RAM_ACCESS|RAM_Ta)*0.02-273.15;
}

测的是环境温度,如果需要测量物体表面温度。

#define RAM_TOBJ1     0x07 //To1 address in the eeprom	表面温度
#define RAM_Ta     		0x06 //Ta address in the eeprom		环境温度

实现效果:

2.HAL库实现温度采集

 因为代码封装的较好,移植性较好,和标准库代码基本相似,只需要修改部分核心代码。

修改片段:

#define SMBUS_SCK_H()            HAL_GPIO_WritePin(GPIOB, SMBus_SCL_Pin, GPIO_PIN_SET)
#define SMBUS_SCK_L()            HAL_GPIO_WritePin(GPIOB, SMBus_SCL_Pin, GPIO_PIN_RESET)
#define SMBUS_SDA_H()            HAL_GPIO_WritePin(GPIOB, SMBus_SDA_Pin, GPIO_PIN_SET)
#define SMBUS_SDA_L()            HAL_GPIO_WritePin(GPIOB, SMBus_SDA_Pin, GPIO_PIN_RESET)

#define SMBUS_SDA_PIN()          HAL_GPIO_ReadPin(GPIOB,SMBus_SDA_Pin)

基本就可以实现数据采集了。

注意:

float SMBus_ReadTemp(void)
{   
	return (SMBus_ReadMemory(SA, RAM_ACCESS|RAM_TaA)*0.02-273.15);
}

例子中测试的是物体温度,物体表面温度修改:

#define RAM_TOBJ1                 0x07 			//	物体表面温度
#define RAM_TaA                 	0x06 			//	环境温度

这里需要需要注意的地方,CubeMX生成的代码需要修改一下,不然不能实现采集功能。

推挽输出

GPIO_MODE_OUTPUT_PP

修改成 开漏输出模式

GPIO_MODE_OUTPUT_OD

实现效果:

 源码下载链接:

STM32实现MLX90614非接触测温串口显示(标准库与HAL库实现)资源-CSDN文库

吾芯电子工作室

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32实现MLX90614非接触测温串口显示(标准库与HAL库实现) 的相关文章

  • IDEA的一些有点用的插件

    工欲善其事 必先利其器 想知道你和IDEA还差哪些人机合一的插件么 看文章就对了 1 Key Promoter X Key Promoter X 插件 IDEA 快捷键提示工具 在每次我们使用鼠标进行 IDEA 的某个操作 Key Prom

随机推荐

  • JS 中 delete 与 splice 与 循环

    JS Array 循环5万数据并删除1万数据 对比Delete与Splice 的运行效果 已经很晚了 但是 还是把中午实验的东西码上来吧 不然我就可能要忘记了 快点写完 好休息 趁这几天还有激情研究代码 多写点 充实充实自己 JS 中有 O
  • FastDFS下的storage服务启动卡住

    环境 ubuntu 16 04 STORAGE SERVER的状态通常有七种 FDFS STORAGE STATUS INIT 初始化 尚未得到同步已有数据的源服务器 FDFS STORAGE STATUS WAIT SYNC 等待同步 已
  • java基础面试题系列(21 -30)

    20200708 by 1z 请你解释Object如果不重写hashcode 的话 hashcode 是如何计算出来的 Object的hashcode方法是本地方法 是使用c语言或者c 语言实现的 通常是根据 某种策略而形成的 hashco
  • 春秋云镜 CVE-2022-0410

    春秋云镜 CVE 2022 0410 WordPress plugin The WP Visitor Statistics SQLI 靶标介绍 WordPress plugin The WP Visitor Statistics Real
  • Mysql精华总结01——架构、存储引擎和数据类型

    一 Mysql架构 和其它数据库相比 MySQL有点与众不同 它的架构可以在多种不同场景中应用并发挥良好作用 主要体现在存储引擎的架构上 插件式的存储引擎架构将查询处理和其它的系统任务以及数据的存储提取相分离 这种架构可以根据业务的需求和实
  • 显卡RTX2080 + CUDA10 + win10 + tensorflow配置安装探坑记

    步骤主要参考该博客https blog csdn net mayunhe cs article details 87216299 结合自己探坑经历记录了具体过程 1 安装显卡驱动 先是在微星官网上下载对应显卡的驱动 不知道为啥给的是nvid
  • 前端学习--常用PS方法

    本文使用的软件为ps CC 2019 1 切图 1 打开一张psd文件 2 取消背景色 3 选择切片工具 4 按住 CTRL 键进行切图 切完后自行调整切图宽高 当切好第一张图后同时按住 CTRL 和 ALT 可按照的第一张切图的宽高进行第
  • Redis主从复制失败(master_link_status:down)

    Redis配置主从复制时遇到这个问题 先确认配置文件没有不对后开始苦恼 在网上查这个问题发现说的都一样 根据网上的再排查配置文件还是没有问题 又确认了不是防火墙的问题 陷入了更大的苦恼 后来看到了stackoverflow上一个评论 意识到
  • 数据库设计-简化字典表

    在进行数据库设计时 我们经常会遇到各种各样的业务需求 从而设计出各种各样的表 而想要做好一个数据库 不但需要前期对各种业务需求的深度理解 还需要在后期项目完善的过程中对数据库更新修改从而使得数据库设计的越发完美 对于那些涉及到业务的表或许不
  • 我希望在 25 岁时知道的14件事(现在我已经 38 岁了)

    我在 38 岁生日后不久写作 是反思的时候了 我不得不把我现在所知道的一点点传递出去 1 专注于变得有用 所有这些关于寻找快乐和做你热衷的事情都是一种分心 专注于建立你对世界的价值 当然 首先要尝试很多东西 然后逐渐开始专注于在更少的事情上
  • Dubbo架构整体设计

    一 Dubbo调用关系说明 1 1 组成部分 在这里主要由四部分组成 Provider 暴露服务的服务提供方 Protocol 负责提供者和消费者之间的协议交互数据 Service 真实的业务服务信息 可以理解成接口和实现 Containe
  • 神经网络综述

    本文指在介绍机器学习中的神经网络的多种变种 包括简单的代码实现及优缺点并尽量不涉及到公式 希望能给阅读者建立起一个关于神经网络的综合概念 因此 本文会涉及到一点神经网络的原理但不会太深入以致于读者迷失在其中而无法得到一个全局性的概念 另外
  • SQLServer2019安装教程

    可以去官网下载 我百度网盘也有都一样 https pan baidu com s 1i3umqHXSUMbxJ9rRi6mU4A 提取码 5g9q 打开应用程序 点击安装 点第一个全新得SQL server独立安装 下一步 在这一步可能有需
  • TCP-IP详解:超时重传机制

    参考教材 TCP IP Guide 超时重传是TCP保证数据传输可靠性的又一大措施 本文主要介绍重传TCP报文的两大举措 超时重传和快速重传 超时重传机制 超时重传指的是 发送数据包在一定的时间周期内没有收到相应的ACK 等待一定的时间 超
  • 几款好用的指纹识别工具

    几款好用的指纹识别工具 在web渗透过程中 对站点进行指纹探测识别非常重要 了解网站所用的web框架或者cms可以为后续的渗透提供思路和突破口 这篇文章主要用于总结几款我平时工作中经常使用的指纹识别工具 一 whatweb whatweb是
  • Python Requests使用Cookie的几种方式

    本文主要给大家介绍了关于Python Requests使用Cookie的几种方式 Python中的requests库可以使用cookie来维持会话状态 实现登录等操作 需要的朋友可以参考下 一 通过headers参数使用 通过headers
  • c语言实现字符串的指定位置删除

    要求 任意输入一串字符串 指定要删除的位置 并输入要删除指定位置后字符的个数 实现代码如下 include
  • el-table绑定的数组里面的对象值进行修改时,视图没有更新

    在Vue js中 如果您在对绑定到el table的数组里面的对象值进行修改后发现视图没有更新 可能是因为Vue js无法检测到数据的变化 解决这个问题的方法有以下几种 使用Vue set 方法显式地告诉Vue js数据已经发生了变化 例如
  • GNN等优缺点总结及解决方案

    https www zhihu com question 338051122 https www zhihu com question 346942899 https zhuanlan zhihu com p 291230435 GCN的缺
  • STM32实现MLX90614非接触测温串口显示(标准库与HAL库实现)

    目录 模块选择 编程环境 MLX90614基本原理 通信协议 SMBus通信 类IIC通信 代码实现 STM32与模块之间接线表 1 标准库实现温度采集 2 HAL库实现温度采集 模块选择 STM32F103C8T6 MLX90614 非接