基于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 }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2021-01-15 17:50  banglezyl  阅读(877)  评论(0)    收藏  举报