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 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> MXL90614红外线测温传感器 -> 正文阅读

[嵌入式]MXL90614红外线测温传感器

特性和优点:
体积小,成本低
易集成
宽温度范围内的出厂校准设置:
传感器温度范围-40…+125 °C
物体温度范围-70…+380 °C
Ta和To 由0到+50°C 温度范围内,精度可达到0.5°C
(医用) 高精度校准
测量辨析度可达 0.02°C
单个和双重视野版本
兼容SMBus数字接口
客户定制的PWM连续读数输出
3V和 5V 电源电压
电源电压可从 8…16V 调节
节能工作模式
适用于不同应用领域的多种封装方式和测量方式
车用级别标准
应用实例:
高精度无接触测量
用于车用空调控制系统的温度舒适度传感器
用于住宅,商业和工业建筑的空调温度感应元件
挡风玻璃防雾应用
汽车视野死角检测
工业移动元件温度控制
打印机、复印机温度控制
家电温度控制
卫生保健
家畜监控
移动物体探测
多区域温度控制 – 两线通信可支持多达100个传感器
热动继电器 / 警报
体温测量??

MLX90614是一款红外非接触温度计。TO-39金属封装里同时集成了红外感应热电堆探测器芯片和信号处理专用集成芯片。
由于集成了低噪声放大器、17位模数转换器和强大的数字信号处理单元,使得高精度和高分辨度的温度计得以实现。
温度计具备出厂校准化,有数字PWM和SMBus(系统管理总线)输出模式。
作为标准,配置为10位的PWM输出格式用于连续传送温度范围为-20…120 °C的物体温度,其分辨率为0.14 °C。POR默认模式是SMBus输出格式。

? ? ?时序

? ? ? ? SCL 引脚的辅助功能 (齐纳二极管) 会给时钟脉冲增加下脉冲信号 (5V 版本) ,如图所示。 (见图 9) 这个脉冲是由片上合成齐纳二极管的瞬态响应造成的,典型时间大约为15μs。SCL线上电抗增加也会加剧该效应。该脉冲不会影响MLX90614识别SCL的上升沿。但可能会妨碍总线上非MLX90614从动器件的正常工作。

?

? ? ? PWM/SDA 的数据必须在SCL为低时改变。 (SCL下降沿后间隔至少) 在SCL的上升沿,MD和SD的数据被读出,建议在SCL为低电平的中间时刻改变数据。

? ? ?睡眠模式
? ? ?MLX90614可通过SMBus接口发送“进入睡眠模式”命令来进入睡眠模式。5V版本没有该功能。为了将电流损耗降为2.5uA (典型值),在模式中SCL保持低电平 。通过将SCL引脚置为高电平,并将PWM/SDA引脚保持低电平不少于tDDq=80ms来使 MLX90614回到POR默认模式 (通过重置 POR)
? ? ?如果EEPROM 配置为 PWM模式, (EN_PWM 为高) 在唤醒器件之后,并PWM control[2], PPODB为1,将选择PWM模式,MLX90614会通过推挽式输出PWM脉冲序列。

?退出睡眠模式

? ? ? ?在退出睡眠模式后,间隔0.25s(典型值),才输出数据。第一次测量时片上IIR滤波器被跳过。所有测量结果都会通过由EEPROM设置的嵌入式数字滤波器。嵌入式滤波器的详细介绍请参考www.melexis.com网站上的应用指南“理解MLX90614片上信号滤波器”。
? ? ? ?将SCL 引脚置为低以降低引脚上的漏电流。 (合成齐纳二极管接于该引脚)

? ? ? ?PWM 使能
? ? ? ?下图显示了在PWM使能情况下,切换到SMBus的方式。 (POR后MLX90614为出厂默认输出方式SMBus,,PWM 未使能)。注意SCL引脚需要保持高电平以便使用PWM。

? ? ? 如果PWM 使能, MLX90614’s 需要SMBus请求状态使PWM不使能并在开始SMBus通信之前重新配置PWM/SDA引脚。一旦PWM未使能,它只能通过切断-打开电源或是退出睡眠模式来使其使能。The MLX90614’s SMBus 请求状态需要将SCL引脚持续多于请求时间 (tREQ) >1,44ms保持为低电平。此情形下SDA线上的数据被忽略。

配置地址

#define ACK?? ? 0
#define?? ?NACK 1
#define SA?? ??? ??? ??? ?0x00 //从机地址,单个MLX90614时地址为0x00,多个时地址默认为0x5a
#define RAM_ACCESS?? ??? ?0x00 //RAM access command
#define EEPROM_ACCESS?? ?0x20 //EEPROM access command
#define RAM_TOBJ1?? ??? ?0x07 //To1 address in the eeprom

#define SMBUS_PORT?? ? ? ?GPIOB
#define SMBUS_SCK?? ??? ?GPIO_Pin_12
#define SMBUS_SDA?? ??? ?GPIO_Pin_13

#define RCC_APB2Periph_SMBUS_PORT?? ??? ?RCC_APB2Periph_GPIOB

#define SMBUS_SCK_H()?? ? ? ?SMBUS_PORT->BSRR = SMBUS_SCK
#define SMBUS_SCK_L()?? ? ? ?SMBUS_PORT->BRR = SMBUS_SCK
#define SMBUS_SDA_H()?? ? ? ?SMBUS_PORT->BSRR = SMBUS_SDA
#define SMBUS_SDA_L()?? ? ? ?SMBUS_PORT->BRR = SMBUS_SDA

#define SMBUS_SDA_PIN()?? ? ? ?SMBUS_PORT->IDR & SMBUS_SDA //读取引脚电平

配置功能

void SMBus_StartBit(void)
{
? ? SMBUS_SDA_H();?? ??? ?// Set SDA line
? ? SMBus_Delay(5);?? ? ? ?// Wait a few microseconds
? ? SMBUS_SCK_H();?? ??? ?// Set SCL line
? ? SMBus_Delay(5);?? ? ? ?// Generate bus free time between Stop
? ? SMBUS_SDA_L();?? ??? ?// Clear SDA line
? ? SMBus_Delay(5);?? ? ? ?// Hold time after (Repeated) Start
? ? // Condition. After this period, the first clock is generated.
? ? //(Thd:sta=4.0us min)
? ? SMBUS_SCK_L();?? ? ? ?// Clear SCL line
? ? SMBus_Delay(5);?? ? ? ?// Wait a few microseconds
}


void SMBus_StopBit(void)
{
? ? SMBUS_SCK_L();?? ??? ?// Clear SCL line
? ? SMBus_Delay(5);?? ? ? ?// Wait a few microseconds
? ? SMBUS_SDA_L();?? ??? ?// Clear SDA line
? ? SMBus_Delay(5);?? ? ? ?// Wait a few microseconds
? ? SMBUS_SCK_H();?? ??? ?// Set SCL line
? ? SMBus_Delay(5);?? ? ? ?// Stop condition setup time(Tsu:sto=4.0us min)
? ? SMBUS_SDA_H();?? ??? ?// Set SDA line
}


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;
}


void SMBus_SendBit(u8 bit_out)
{
? ? if(bit_out==0)
? ? {
? ? ? ? SMBUS_SDA_L();
? ? }
? ? else
? ? {
? ? ? ? SMBUS_SDA_H();
? ? }
? ? SMBus_Delay(2);?? ??? ??? ??? ??? ?// Tsu:dat = 250ns minimum
? ? SMBUS_SCK_H();?? ??? ??? ??? ??? ?// Set SCL line
? ? SMBus_Delay(6);?? ??? ??? ??? ??? ?// High Level of Clock Pulse
? ? SMBUS_SCK_L();?? ??? ??? ??? ??? ?// Clear SCL line
? ? SMBus_Delay(3);?? ??? ??? ??? ??? ?// Low Level of Clock Pulse
//?? ?SMBUS_SDA_H();?? ??? ??? ??? ? ? ?// Master release SDA line ,
? ? return;
}


u8 SMBus_ReceiveBit(void)
{
? ? u8 Ack_bit;

? ? SMBUS_SDA_H(); ? ? ? ? ?//引脚靠外部电阻上拉,当作输入
?? ?SMBus_Delay(2);?? ??? ??? ?// High Level of Clock Pulse
? ? SMBUS_SCK_H();?? ??? ??? ?// Set SCL line
? ? SMBus_Delay(5);?? ??? ??? ?// High Level of Clock Pulse
? ? if (SMBUS_SDA_PIN())
? ? {
? ? ? ? Ack_bit=1;
? ? }
? ? else
? ? {
? ? ? ? Ack_bit=0;
? ? }
? ? SMBUS_SCK_L();?? ??? ??? ?// Clear SCL line
? ? SMBus_Delay(3);?? ??? ??? ?// Low Level of Clock Pulse

? ? return?? ?Ack_bit;
}


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;
}


void SMBus_Delay(u16 time)
{
? ? u16 i, j;
? ? for (i=0; i<4; i++)
? ? {
? ? ? ? for (j=0; j<time; j++);
? ? }
}


void SMBus_Init()
{
? ? GPIO_InitTypeDef ? ?GPIO_InitStructure;

?? ?/* Enable SMBUS_PORT clocks */
?? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_SMBUS_PORT, ENABLE);

? ? /*配置SMBUS_SCK、SMBUS_SDA为集电极开漏输出*/
? ? GPIO_InitStructure.GPIO_Pin = SMBUS_SCK | SMBUS_SDA;
? ? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
? ? GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
? ? GPIO_Init(SMBUS_PORT, &GPIO_InitStructure);

? ? SMBUS_SCK_H();
? ? SMBUS_SDA_H();
}


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;
}


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];
}

最后计算出温度值

float SMBus_ReadTemp(void)
{ ??
?? ?return SMBus_ReadMemory(SA, RAM_ACCESS|RAM_TOBJ1)*0.02-273.15+2;
}

H文件

#ifndef __BSP_MLX90614_H
#define __BSP_MLX90614_H

#include "stm32f10x.h"

void SMBus_StartBit(void);
void SMBus_StopBit(void);
void SMBus_SendBit(u8);
u8 SMBus_SendByte(u8);
u8 SMBus_ReceiveBit(void);
u8 SMBus_ReceiveByte(u8);
void SMBus_Delay(u16);
void SMBus_Init(void);
u16 SMBus_ReadMemory(u8, u8);
u8 PEC_Calculation(u8*);
float SMBus_ReadTemp(void); ? ?//获取温度值?
#endif

主函数(这里使用的窜口打印)

#include "bsp-led.h"
#include "bsp-usart.h"
#include "bsp-mlx90614.h"

void delay(uint32_t i)
{
? for(;i!=0;i--);
}


int main(void)
{
?? ??? ?float Temperature;
?? ??? ?USART_Config();
? ? ? ? SMBus_Init();
?? ??? ?while(1)
?? ??? ? {
?? ??? ??? ?Temperature=SMBus_ReadTemp();
?? ??? ? ?printf("The Temperature is:%f\n",Temperature);
?? ??? ??? ?delay(0xffffff);

? ? ? ? ? }

? ? }

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 12:15:04  更:2021-08-07 12:15:55 
 
开发: 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年5日历 -2024/5/10 7:22:39-

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