最近想用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(); }
}