基于MLX90615的SMbus通讯
一、MLX90615简介
MLX90615由2种芯片,红外热电堆检测器和信号调节芯片构成MLX90325,由Melexis专门设计用于处理红外传感器的输出。该器件采用行业标准的TO-46封装。借助MLX90325的低噪声放大器,高分辨率16位ADC和功能强大的DSP单元,Melexis能够提供高精度和高分辨率的红外测温仪。计算对象MLX90325的RAM存储器中提供了环境温度和环境温度,分辨率为0.02˚C。可通过分辨率为0.02°C的2线串行SMBus兼容协议或通过10-来自设备的位PWM(脉冲宽度调制)信号。MLX90615在工厂校准为标准温度范围:-40至85 ℃(环境温度)温度范围为-40至115˚C。作为标准,MLX90615的编程对象发射率是1。它可以轻松实现由客户定制用于0.1-1.0范围内的任何其他发射率,而无需重新校准。MLX90615可以由电池供电。可以滤除可见光和近红外辐射通量的滤光片(5.5µm至14µm长波通过)是集成在包装中,使传感器对可见光不敏感。温度的数据是存在于RAM中,而相应的芯片配置,ID,模式选择,发射率等是存在芯片的eeprom中,其中注意的是eeprom中尽量不要去操作04-0D之间的地址,其芯片默认出厂地址为0X5B,其中0X00地址是每个芯片都会响应的

二、SMbus通信协议
SMBus是System Management Bus的缩写,是1995年由Intel提出的,应用于移动PC和桌面PC系统中的低速率通讯。它主要是希望通过一条廉价并且功能强大的总线(由两条线组成),来控制主板上的设备并收集相应的信息,SMBus为系统和电源管理这样的任务提供了一条控制总线,使用SMBus的系统,设备之间发送和接收消息都是通过SMBus,而不是使用单独的控制线,这样可以节省设备的管脚数。使用SMBus,设备还可以提供它的生产信息,告诉系统它的型号,部件号等,针对挂起事件保存它的状态,报告不同类别的错误,接收控制参数,并返回它的状态等,属于IIC通信协议的子集
SMBus的数据传输率为100kbps,虽然速度较慢,却以其结构简洁造价低廉的特点,成为业界普遍欢迎的接口标准。Windows中显示的各种设备的制造商名称和型号等信息,都是通过SMBus总线收集的。主板监控系统中传送各种传感器的测量结果,以及BIOS向监控芯片发送命令,也是利用SMBus实现的SMBus器件存在现有7层OSI网络模型中的前3层,即物理层,数据链路层和网络层。SMBus最初的目的是为智能电池,充电电池和与其他系统通信的微控制器之间的通信链路而定义的。SMBus也被用来连接各种设备,包括电源相关设备,系统传感器,EEPROM通讯设备等等。
三、开发过程
(1)总线上产生终止和起始状态。并发送和接收数据
2 /** 下降沿触发起始状态 3 *******************************************************************************/ 4 void SMBus_StartBit(void) 5 { 6 SMBUS_SDA_H(); //设置SDA线为高电平 7 delay_us(5); //延时5us 8 SMBUS_SCK_H(); //设置SCK线为高电平 9 delay_us(5); //在终止和起始状态之间产生总线空闲时间(Tbuf=4.7us 最小值) 10 SMBUS_SDA_L(); //设置SDA线为低电平 11 delay_us(5); //(重复)开始状态后的保持时间,在该时间后,产生第一个时钟信号(thd:sta=4us最小值) 12 SMBUS_SCK_L(); //设置SCK线为低电平 13 delay_us(5); 14 } 15 16 /******************************************************************************* 17 **上升沿触发终止状态 18 *******************************************************************************/ 19 void SMBus_StopBit(void) 20 { 21 SMBUS_SCK_L(); 22 delay_us(5); 23 SMBUS_SDA_L(); 24 delay_us(5); 25 SMBUS_SCK_H(); 26 delay_us(5); 27 SMBUS_SDA_H(); 28
1 /*******************************************************************************
2 在SMBus总线上发送一个字节,从第八位开始发送 3 *******************************************************************************/ 4 u8 SMBus_SendByte(u8 Tx_buffer) 5 { 6 u8 Bit_counter; 7 u8 Ack_bit; 8 u8 bit_out; 9 10 for(Bit_counter=8; Bit_counter; Bit_counter--) 11 { 12 if (Tx_buffer&0x80) 13 { 14 bit_out=1; 15 } 16 else 17 { 18 bit_out=0; 19 } 20 SMBus_SendBit(bit_out); 21 Tx_buffer<<=1; 22 } 23 24 Ack_bit=SMBus_ReceiveBit(); 25 return Ack_bit; 26 } 27 28 /******************************************************************************* 33 发送一位数据 34 *******************************************************************************/ 35 void SMBus_SendBit(u8 bit_out) 36 { 37 if(bit_out==0) 38 { 39 SMBUS_SDA_L(); 40 } 41 else 42 { 43 SMBUS_SDA_H(); 44 } 45 delay_us(2); 46 SMBUS_SCK_H(); 47 delay_us(6); 48 SMBUS_SCK_L(); 49 delay_us(3); 50 51 return; 52 } 53 54 /******************************************************************************* 接收一位数据 60 *******************************************************************************/ 61 u8 SMBus_ReceiveBit(void) 62 { 63 u8 Ack_bit; 64 65 SMBUS_SDA_H(); 66 delay_us(2); 67 SMBUS_SCK_H(); 68 delay_us(5); 69 70 if (SMBUS_SDA_PIN()) 71 { 72 Ack_bit=1; 73 } 74 else 75 { 76 Ack_bit=0; 77 } 78 SMBUS_SCK_L(); 79 delay_us(3); 81 return Ack_bit; 83 84 /******************************************************************************* 接收一个字节,0为确认ACK,1为 90 *******************************************************************************/ 91 u8 SMBus_ReceiveByte(u8 ack_nack) 92 { 93 u8 RX_buffer; 94 u8 Bit_Counter; 95 96 for(Bit_Counter=8; Bit_Counter; Bit_Counter--) 97 { 98 if(SMBus_ReceiveBit()) 99 { 100 RX_buffer <<= 1; 101 RX_buffer |=0x01; 102 } 103 else 104 { 105 RX_buffer <<= 1; 106 RX_buffer &=0xfe; 107 } 108 } 109 SMBus_SendBit(ack_nack); 110 return RX_buffer; 111 }
(2)给定受控地址和命令是由MLX90615读取数据
1 u16 SMBus_ReadMemory(u8 slaveAddress, u8 command) 2 { 3 u16 data; // 由MLX90615返回的寄存器数据 4 u8 Pec; 5 u8 DataL=0; 6 u8 DataH=0; //读取的数据包 7 u8 arr[6]; //存储已发送字节的缓冲器 8 u8 PecReg; //存储计算所得的pec字节 9 u8 ErrorCounter; //用于与MLX90614数据沟通 10 11 ErrorCounter=0x00; // Initialising of ErrorCounter 12 // slaveAddress <<= 1; //可以增加多个从机 13 14 do 15 { 16 repeat: 17 SMBus_StopBit(); //SMBus总线进入终止位 18 --ErrorCounter; //Pre-decrement ErrorCounter 19 if(!ErrorCounter) //ErrorCounter=0? 20 { 21 break; //跳出当前循环 22 } 23 24 SMBus_StartBit(); //起始位 25 if(SMBus_SendByte(slaveAddress))//发送从机地址 26 { 27 goto repeat; 28 } 29 if(SMBus_SendByte(command)) //发送命令 30 { 31 goto repeat; 32 } 33 34 SMBus_StartBit(); //发送重复起始位 35 if(SMBus_SendByte(slaveAddress+1)) //发送从机地址,最低位Rd=1表示接下来的数据 36 { 37 goto repeat; 38 } 39 40 DataL = SMBus_ReceiveByte(ACK); //读取低字节数据,主机发送ACK 41 DataH = SMBus_ReceiveByte(ACK); //读取高字节数据,主机发送ACK 42 Pec = SMBus_ReceiveByte(NACK); //读取PEC字节,主机必须发送NACK 43 SMBus_StopBit(); //发送终止位 44 45 arr[5] = slaveAddress; 46 arr[4] = command; 47 arr[3] = slaveAddress+1; 48 arr[2] = DataL; 49 arr[1] = DataH; 50 arr[0] = 0; 51 PecReg=PEC_Calculation(arr);//存储PEC运算的结果 52 } 53 while(PecReg != Pec); // 54 55 data = (DataH<<8) | DataL; 56 return data; 57 }

浙公网安备 33010602011771号