这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 关于MXL90614传感器不能成功读取温度问题

共3条 1/1 1 跳转至

关于MXL90614传感器不能成功读取温度问题

菜鸟
2016-01-19 16:41:14     打赏

最近想用MLX90614ESF-DCI实现非接触测温,出现了一点问题,想请教一下论坛的各位能人。

采用的是STC12C50614RC芯片,目前采用动态数码管显示温度。

问题描述:

1、  可以实现地址修改。

2、  不能实现温度读取。具体为:我采用了LED灯(P2口)作为通信成功与否的指示器,(参考程序)执行子函数MEM_Read() 时只能进行到:

if(!WaitAck()){P26=0;I2CStop();goto begin;}else {P21=0;}

这句。

然后后面P2.6就亮了(低电平有效)。尝试了多次都不能成功通信。

我曾怀疑是传感器RAM坏了,想试一试读取EEPROM内容,但仍然在同一地方通信中断。

不知论坛中有没有人遇到过这个问题?

 

(有大神建议用示波器测测时序,碰巧示波器探头找不到了,买了明天能到。明天测一下时序,补充上来,看看能不能找到问题所在。)


下面附C程序,半成品,有点乱。闲太长可直接看紫色部分。

#include <reg52.h>
#include <intrins.h>
#define bool bit
#define uchar unsigned char 
#define false 0
#define true 1

#define I2C_100K 0 
#define I2C_400K 1 

#define I2C_SPEED I2C_400K //ÅäÖÃËÙ¶ÈΪ400K
#define NOP() _nop_() //¿ÕµÈ´ý
#define SomeNOP(); _nop_();_nop_();_nop_();_nop_();
unsigned char SystemError;
unsigned int A1,A2,A3,A4,A5;
unsigned char temperature[]={0,0,0};
sbit SMG_q = P1^0; 
sbit SMG_b = P1^1; 
sbit SMG_s = P1^2; 
sbit SMG_g = P1^3;
sbit SCL = P0^0;
sbit SDA = P0^1;
sbit P20=P2^0;
sbit P21=P2^1;
sbit P22=P2^2;
sbit P23=P2^3;
sbit P24=P2^4;
sbit P25=P2^5;
sbit P26=P2^6;
sbit P27=P2^7;
unsigned char table1[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//±í£º¹²ÑôÊýÂë¹Ü 0-9 
unsigned char table2[]=
{0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
static void DelayI2C(void)
{
uchar i;
for(i=5;i>0;i--)
{
SomeNOP();
}

void delay2ms(void)  

    unsigned char a,b;     
for(b=4;b>0;b--) 
        for(a=248;a>0;a--); 
{NOP();}
}
void delay(void)
{
unsigned char i=10;
while(i--);
}

void I2CStart(void)
{
SDA = 1; SCL = 1; DelayI2C(); //INI
SDA = 0; DelayI2C(); //START
SCL = 0;
}

void I2CStop(void)
{
SCL = 0; SDA = 0; DelayI2C(); //INI
SCL = 1; DelayI2C(); SDA = 1; //STOP
}

bool WaitAck(void)
{
uchar errtime = 255;
SDA = 1;DelayI2C();
SCL = 1;DelayI2C();
while(SDA) 
{
errtime--; 
if (!errtime) 
{
  I2CStop();
SystemError=0x11;
return false;
}
}
SCL = 0;
return true;
}

void SendAck(void)
{
SDA = 0; DelayI2C();
SCL = 1; DelayI2C();
SCL = 0;
}

void SendNotAck(void)
{
SDA = 1; DelayI2C();
SCL = 1; DelayI2C();
SCL = 0;
}

void I2CSendByte(uchar ch)
{
uchar i = 8;
while (i--)
{
SCL = 0; NOP();
SDA = (bool)(ch&0x80); 
ch <<= 1; DelayI2C();
SCL = 1; DelayI2C();
}
SCL = 0;
}

unsigned char I2CReceiveByte(void)
{
uchar i = 8;
uchar ddata = 0;
SDA = 1;
while (i--)
{
ddata <<= 1;
SCL = 0; DelayI2C();
SCL = 1; DelayI2C();
ddata |= SDA;
}
SCL = 0;
return ddata;
}

unsigned char PEC_cal(unsigned char pec[],uchar n)
{
    unsigned char crc[6];
    unsigned char Bitposition=47;
    unsigned char shift;
    unsigned char i;
    unsigned char j;
    unsigned char temp;
  do{
    crc[5]=0; //Load CRC value 0x000000000107
    crc[4]=0;
    crc[3]=0;
    crc[2]=0;
    crc[1]=0x01;
    crc[0]=0x07;
    Bitposition=47; //Set maximum bit position at 47
    shift=0;        //Find first 1 in the transmitted bytes
    i=5; //Set highest index (package byte index)
    j=0; //Byte bit index, from lowest
    while((pec[i]&(0x80>>j))==0 && (i>0))
    {
     Bitposition--;
     if(j<7){ j++;}
     else {j=0x00;i--;}
    }//the position of highest "1" bit in Bitposition is calculated
    shift=Bitposition-8; //Get shift value for CRC value

    while(shift)
    {
      for(i=5;i<0xFF;i--)
      {
       if((crc[i-1]&0x80) && (i>0)) //Check if the MSB of the byte lower is "1"
        { //Yes - current byte + 1
         temp=1; //No - current byte + 0
        } //So that "1" can shift between bytes
       else { temp=0;}
      crc[i]<<=1;
      crc[i]+=temp;
      }
    shift--;
    }
    //Exclusive OR between pec and crc
    for(i=0;i<=5;i++) { pec[i]^=crc[i]; }
    }
    while(Bitposition>8);
    return pec[0];
 }
 //**********read temp function***************(complite)//
 unsigned long int MEM_Read(unsigned char slave_addr)
{
uchar DataLow,DataHig;
uchar PEC_Re;
unsigned char SLA;
unsigned long int Data;
unsigned char arr[6];
unsigned char Pecreg;
SLA=(slave_addr<<1);
begin:
I2CStart();
I2CSendByte(SLA);
if(!WaitAck()){P26=0;I2CStop();goto begin;} else {P20=0;}
I2CSendByte(0x10);
if(!WaitAck()){P26=0;I2CStop();goto begin;}else {P21=0;}
I2CStart();
I2CSendByte(SLA+1);
if(!WaitAck()){P26=0;I2CStop();goto begin;}else {P22=0;}
DataLow=I2CReceiveByte();
SendAck();
if (DataLow!=0){P23=0;}
DataHig=I2CReceiveByte();
  SendAck();
PEC_Re=I2CReceiveByte();
SendAck();
I2CStop();

arr[5]=(SLA);
  arr[4]=0x10;
  arr[3]=(SLA+1);
arr[2]=DataLow;
  arr[1]=DataHig;
  arr[0]=0;
  Pecreg=PEC_cal(arr,6); //Calculate CRC
  if(PEC_Re!=Pecreg){P24=0;goto begin;}

Data=(DataHig*256)+DataLow;
return Data;
}

void CALTEMP(unsigned long int TEMP)
{
   unsigned long int T;
   unsigned int A, B;
     
   T=TEMP*2;
   if(T>=27315)
   {
     T=T-27315;
     A=T/100;
     B=T-A*100;
     if(A>=100){A1=A/100;A=A%100;A2=A/10;A=A%10;A3=A;}
     else if(A>=10){A1=0;A2=A/10;A=A%10;A3=A;}
     else {A1=0;A2=0;A3=A;}
     if(B>=10){A4=B/10;B=B%10;A5=B;}
     else{A4=0;A5=B;}
    }
   else
    {
     T=27315-T;
     A=T/100;
     B=T-A*100;
     A1=9;
     if(A>=10){A2=A/10;A=A%10;A3=A;}
     else{A2=0;A3=A;}
     if(B>=10){ A4=A/10;B=B%10;A5=B;}
     else{A4=0;A5=B;}
    }
}
void LED_saomiao(void)
{
SMG_q=0;
P0=table1[A2];
delay();
    delay();
P0=0XFF;
SMG_q=1;

SMG_b=0;
P0=table2[A3];
delay();
    delay();
P0=0XFF;
SMG_b=1;

SMG_s=0;
P0=table1[A4];
delay();
P0=0XFF;
SMG_s=1;

SMG_g=0;
P0=table1[A5];
delay();
P0=0XFF;
SMG_g=1;
}
void EEPROM_WRITE(unsigned char slave_addW,unsigned char cmdW,unsigned char DataL,unsigned char DataH)

 unsigned char Pecreg;                
 unsigned char SLA;
 unsigned char arr[6];  
uchar a,b;
 SLA=(slave_addW<<1);      
arr[5]=0;     
arr[4]=SLA;      
arr[3]=cmdW;     
arr[2]=DataL;      
arr[1]=DataH;    
  arr[0]=0; 
  Pecreg=PEC_cal(arr,6);  
begin: 
     I2CStart();      
I2CSendByte(SLA);      
 if(!WaitAck()){P26=0;I2CStop();goto begin;} else {P24=0;}
    I2CSendByte(cmdW);        
 if(!WaitAck()){P26=0;I2CStop();goto begin;} else {P25=0;}
    I2CSendByte(DataL);     
 if(!WaitAck()){P26=0;I2CStop();goto begin;} else {P27=0;}
    I2CSendByte(DataH);      
 if(!WaitAck()){P26=0;I2CStop();goto begin;} else {P20=0;}
    I2CSendByte(Pecreg);      
if(!WaitAck()){P26=0;I2CStop();goto begin;} else{P21=0;}
    I2CStop();                           
for(b=19;b>0;b--)     
for(a=130;a>0;a--); 
}

unsigned  char read_flag(unsigned char slave_addr)
{
uchar DataLow,DataHig;
uchar PEC_Re;
unsigned char SLA;
unsigned long int Data;
unsigned char arr[6];
unsigned char Pecreg;
SLA=(slave_addr<<1);
begin:
I2CStart();
I2CSendByte(SLA);
if(!WaitAck()){P26=0;I2CStop();goto begin;} else {P20=0;}
I2CSendByte(0xf0);
if(!WaitAck()){P26=0;I2CStop();goto begin;} else {P21=0;}
DataLow=I2CReceiveByte();
SendAck();
DataHig=I2CReceiveByte();
  SendAck();
PEC_Re=I2CReceiveByte();
if(PEC_Re!=0)
{
P23=0;
}

SendAck();
I2CStop();

arr[5]=(0);
  arr[4]=(SLA);
  arr[3]=0xf0;
arr[2]=DataLow;
  arr[1]=DataHig;
  arr[0]=0;
  Pecreg=PEC_cal(arr,6); //Calculate CRC
  if(PEC_Re!=Pecreg){goto begin;P25=0;}

return DataLow;
}

//µØÖ·ÐÞ¸Ä
void ChangSlaveaddr(unsigned char Newaddr)
{
uchar DataL=Newaddr;
//uchar slaveaddress=MEM_Read(0x00,0x2E);
uchar DataH=0x00;
EEPROM_WRITE(0x00,0x2E,0x00,0x00); 
P23=0;
EEPROM_WRITE(0x00,0x2E,DataL,DataH);     
}
/*void Mult_readT(void)
{
temperature[0]=MEM_Read(0x01,0x07);
temperature[1]=MEM_Read(0x02,0x07);
temperature[2]=MEM_Read(0x03,0x07);
}
*/

//************˯Ãßģʽ***************//
void Sleepmode()
{
begin:
I2CStart();
I2CSendByte(0);
if(!WaitAck()){P26=0;I2CStop();goto begin;}// else {P20=0;}
I2CSendByte(0xff);
if(!WaitAck()){P26=0;I2CStop();goto begin;}//else {P21=0;}
I2CSendByte(0xf3);
if(!WaitAck()){P26=0;I2CStop();goto begin;}//else {P22=0;}
I2CStop();
}
void exit_sleepmode()
{ int i;
SDA = 1;
SCL = 1;
SDA = 0;
for(i=0;i<20;i++)
{delay2ms;}
SDA = 1;
}
//*********Ö÷º¯Êý***********//
void main()
{
unsigned long int DATA,i,j;
delay2ms;
P2=0xff;
//ChangSlaveaddr(0x01);
DATA=MEM_Read(0x01);
//CALTEMP(DATA);
//Sleepmode();
while(1){LED_saomiao(); }
}







关键词: MXL90614     读取     温度    

菜鸟
2016-01-21 18:04:57     打赏
2楼

菜鸟
2016-01-21 18:08:53     打赏
3楼
现在初步判断是从机根本就没有控制SDA。SDA状态保持上一位 状态。

共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]