标题:
基于STM32F103的MLX90614红外测温驱动
[打印本页]
作者:
七十二反弹户口
时间:
2020-4-27 15:36
标题:
基于STM32F103的MLX90614红外测温驱动
最近做了一个用STM32F103C8T6芯片控制的MLX90614红外测温传感器驱动,直接上代码
#include "stdlib.h"
#include "stm32f10x.h"
#include "SysTick.h"
#include "4422.h"
#include <math.h>
float GT_Temp=0;
float GT_TOmax=0;
#define RCC_APB2Periph_SMBUS_PORT RCC_APB2Periph_GPIOB
#define SMBUS_PORT GPIOB
#define SMBUS_SCK GPIO_Pin_6
#define SMBUS_SDA GPIO_Pin_7
#define ClrBit_SDA GPIO_ResetBits(GPIOB,GPIO_Pin_7)
#define SetBit_SDA GPIO_SetBits(GPIOB,GPIO_Pin_7)
#define SetBit_SCK GPIO_SetBits(GPIOB,GPIO_Pin_6)
#define ClrBit_SCK GPIO_ResetBits(GPIOB,GPIO_Pin_6)
#define STA_SDA GPIOB->IDR & GPIO_Pin_7
#define STA_SCL GPIOB->IDR & GPIO_Pin_6
#define RCC_APB2Periph_SMBUS_PORT1 RCC_APB2Periph_GPIOA
#define SMBUS_PORT1 GPIOA
#define SMBUS_SCK1 GPIO_Pin_1
#define SMBUS_SDA1 GPIO_Pin_2
#define ClrBit_SDA1 GPIO_ResetBits(GPIOA,GPIO_Pin_2)
#define SetBit_SDA1 GPIO_SetBits(GPIOA,GPIO_Pin_2)
#define SetBit_SCK1 GPIO_SetBits(GPIOA,GPIO_Pin_1)
#define ClrBit_SCK1 GPIO_ResetBits(GPIOA,GPIO_Pin_1)
#define STA_SDA1 GPIOA->IDR & GPIO_Pin_2
#define STA_SCL1 GPIOA->IDR & GPIO_Pin_1
#define RCC_APB2Periph_SMBUS_PORT2 RCC_APB2Periph_GPIOA
#define SMBUS_PORT2 GPIOA
#define SMBUS_SCK2 GPIO_Pin_11
#define SMBUS_SDA2 GPIO_Pin_12
#define ClrBit_SDA2 GPIO_ResetBits(GPIOA,GPIO_Pin_12)
#define SetBit_SDA2 GPIO_SetBits(GPIOA,GPIO_Pin_12)
#define SetBit_SCK2 GPIO_SetBits(GPIOA,GPIO_Pin_11)
#define ClrBit_SCK2 GPIO_ResetBits(GPIOA,GPIO_Pin_11)
#define STA_SDA2 GPIOA->IDR & GPIO_Pin_12
#define STA_SCL2 GPIOA->IDR & GPIO_Pin_11
#define RAM 0x00
#define EEPROM 0x20
#define MODE 0x60
#define EXITMODE 0x61
#define READFLAG 0xf0
#define SLEEP 0xff
#define RD 0x01
#define WR 0x00
#define AMBITEMPADDR 0x03
#define IR1ADDR 0x04
#define IR2ADDR 0x05
#define ENVITEMPADDR 0x06
#define OBJ1TEMPADDR 0x07
#define OBJ2TEMPADDR 0x08
#define TOBJMAXADDR 0x00
#define TOBJMINADDR 0x01
#define PWMCTRLADDR 0x02
#define TARANGEADDR 0x03
#define KEADDR 0x04
#define CONFIGADDR 0x05
#define SMBUSADDR 0x0e
#define RES1ADDR 0x0f
#define RES2ADDR 0x19
#define ID1ADDR 0x1c
#define ID2ADDR 0x1d
#define ID3ADDR 0x1e
#define ID4ADDR 0x1f
#define ACK_SUCCESS 0x01
#define ACK_FAIL 0x00
#define N 5
static u8 PEC_Cal(u8 pec[],uint16_t n);
void SMBus_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SMBUS_PORT, ENABLE);
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);
SetBit_SCK;
SetBit_SDA;
}
static void I2C_Delay(void)
{
Delay_us(4);
}
static void XLM99614_I2C_Start(void)
{
SetBit_SDA;
SetBit_SCK;
I2C_Delay();
ClrBit_SDA;
I2C_Delay();
ClrBit_SCK;
I2C_Delay();
}
static void XLM99614_I2C_Start1(void)
{
SetBit_SDA1;
SetBit_SCK1;
I2C_Delay();
ClrBit_SDA1;
I2C_Delay();
ClrBit_SCK1;
I2C_Delay();
}
static void XLM99614_I2C_Start2(void)
{
SetBit_SDA2;
SetBit_SCK2;
I2C_Delay();
ClrBit_SDA2;
I2C_Delay();
ClrBit_SCK2;
I2C_Delay();
}
static void XLM99614_I2C_Stop(void)
{
ClrBit_SDA;
ClrBit_SCK;
I2C_Delay();
SetBit_SCK;
I2C_Delay();
SetBit_SDA;
I2C_Delay();
}
static void XLM99614_I2C_Stop1(void)
{
ClrBit_SDA1;
ClrBit_SCK1;
I2C_Delay();
SetBit_SCK1;
I2C_Delay();
SetBit_SDA1;
I2C_Delay();
}
static void XLM99614_I2C_Stop2(void)
{
ClrBit_SDA2;
ClrBit_SCK2;
I2C_Delay();
SetBit_SCK2;
I2C_Delay();
SetBit_SDA2;
I2C_Delay();
}
static u8 I2C_ReadByte(u8 ack_nack)
{
u8 i=0;
u8 dat=0;
ClrBit_SCK;
Delay_us(5);
for(i=0; i<8; i++)
{
dat = dat<<1;
ClrBit_SCK;
Delay_us(5*N);
SetBit_SCK;
Delay_us(5*N);
if(STA_SDA)
{
dat = dat | 0x01;
}
}
ClrBit_SCK;
Delay_us(3*N);
if(!ack_nack)
ClrBit_SDA;
else
SetBit_SDA;
Delay_us(3*N);
SetBit_SCK;
Delay_us(4*N);
ClrBit_SCK;
Delay_us(4*N);
return dat;
}
static u8 I2C_ReadByte1(u8 ack_nack)
{
u8 i=0;
u8 dat=0;
ClrBit_SCK1;
Delay_us(5);
for(i=0; i<8; i++)
{
dat = dat<<1;
ClrBit_SCK1;
Delay_us(5*N);
SetBit_SCK1;
Delay_us(5*N);
if(STA_SDA1)
{
dat = dat | 0x01;
}
}
ClrBit_SCK1;
Delay_us(3*N);
if(!ack_nack)
ClrBit_SDA1;
else
SetBit_SDA1;
Delay_us(3*N);
SetBit_SCK1;
Delay_us(4*N);
ClrBit_SCK1;
Delay_us(4*N);
return dat;
}
static u8 I2C_ReadByte2(u8 ack_nack)
{
u8 i=0;
u8 dat=0;
ClrBit_SCK2;
Delay_us(5);
for(i=0; i<8; i++)
{
dat = dat<<1;
ClrBit_SCK2;
Delay_us(5*N);
SetBit_SCK2;
Delay_us(5*N);
if(STA_SDA2)
{
dat = dat | 0x01;
}
}
ClrBit_SCK2;
Delay_us(3*N);
if(!ack_nack)
ClrBit_SDA2;
else
SetBit_SDA2;
Delay_us(3*N);
SetBit_SCK2;
Delay_us(4*N);
ClrBit_SCK2;
Delay_us(4*N);
return dat;
}
static u8 I2C_WriteByte(u8 dat)
{
u8 i =0;
u8 s_ack=0;
ClrBit_SCK;
ClrBit_SDA;
I2C_Delay();
for(i=0; i<8; i++)
{
ClrBit_SCK;
Delay_us(3*N);
if(dat&0x80)
{
SetBit_SDA;
}
else
{
ClrBit_SDA;
}
dat = dat<<1;
Delay_us(4*N);
SetBit_SCK;
Delay_us(4*N);
}
ClrBit_SCK;
SetBit_SDA;
Delay_us(2*N);
SetBit_SCK;
if(STA_SDA)
{
s_ack = ACK_FAIL;
}
else
{
s_ack = ACK_SUCCESS;
}
Delay_us(2*N);
ClrBit_SCK;
Delay_us(4*N);
return s_ack;
}
static u8 I2C_WriteByte1(u8 dat)
{
u8 i =0;
u8 s_ack=0;
ClrBit_SCK1;
ClrBit_SDA1;
I2C_Delay();
for(i=0; i<8; i++)
{
ClrBit_SCK1;
Delay_us(3*N);
if(dat&0x80)
{
SetBit_SDA1;
}
else
{
ClrBit_SDA1;
}
dat = dat<<1;
Delay_us(4*N);
SetBit_SCK1;
Delay_us(4*N);
}
ClrBit_SCK1;
SetBit_SDA1;
Delay_us(2*N);
SetBit_SCK1;
if(STA_SDA1)
{
s_ack = ACK_FAIL;
}
else
{
s_ack = ACK_SUCCESS;
}
Delay_us(2*N);
ClrBit_SCK1;
Delay_us(4*N);
return s_ack;
}
static u8 I2C_WriteByte2(u8 dat)
{
u8 i =0;
u8 s_ack=0;
ClrBit_SCK2;
ClrBit_SDA2;
I2C_Delay();
for(i=0; i<8; i++)
{
ClrBit_SCK2;
Delay_us(3*N);
if(dat&0x80)
{
SetBit_SDA2;
}
else
{
ClrBit_SDA2;
}
dat = dat<<1;
Delay_us(4*N);
SetBit_SCK2;
Delay_us(4*N);
}
ClrBit_SCK2;
SetBit_SDA2;
Delay_us(2*N);
SetBit_SCK2;
if(STA_SDA2)
{
s_ack = ACK_FAIL;
}
else
{
s_ack = ACK_SUCCESS;
}
Delay_us(2*N);
ClrBit_SCK2;
Delay_us(4*N);
return s_ack;
}
static uint16_t I2C_ReadRAM(u8 saddr,u8 cmd)
{
uint16_t Data;
u8 DataL;
u8 DataH;
u8 PEC;
u8 retry = 10;
u8 s_ack = 0;
u8 Pecreg;
u8 buf[6];
ClrBit_SCK;
while(retry--)
{
XLM99614_I2C_Start();
s_ack = I2C_WriteByte((saddr<<1)|WR);
if(s_ack == ACK_SUCCESS)
{
s_ack = 0;
s_ack = I2C_WriteByte(RAM|cmd);
if(s_ack == ACK_SUCCESS)
{
s_ack = 0;
XLM99614_I2C_Start();
s_ack = I2C_WriteByte((saddr<<1)+1);
if(s_ack == ACK_SUCCESS)
{
s_ack = 0;
DataL = I2C_ReadByte(1);
DataH = I2C_ReadByte(1);
PEC = I2C_ReadByte(1);
XLM99614_I2C_Stop();
buf[5]=(saddr<<1);
buf[4]=EEPROM|cmd;
buf[3]=(saddr<<1)|RD;
buf[2]=DataL;
buf[1]=DataH;
buf[0]=0;
Pecreg=PEC_Cal(buf,6);
if(Pecreg == PEC)
{
break;
}
}
else goto stop_rr;
}
else goto stop_rr;
}
else goto stop_rr;
stop_rr:
XLM99614_I2C_Stop();
}
PEC = PEC+1;
Data =(DataH<<8)+ DataL;
return Data;
}
static uint16_t I2C_ReadRAM1(u8 saddr,u8 cmd)
{
uint16_t Data;
u8 DataL;
u8 DataH;
u8 PEC;
u8 retry = 10;
u8 s_ack = 0;
u8 Pecreg;
u8 buf[6];
ClrBit_SCK1;
while(retry--)
{
XLM99614_I2C_Start1();
s_ack = I2C_WriteByte1((saddr<<1)|WR);
if(s_ack == ACK_SUCCESS)
{
s_ack = 0;
s_ack = I2C_WriteByte1(RAM|cmd);
if(s_ack == ACK_SUCCESS)
{
s_ack = 0;
XLM99614_I2C_Start1();
s_ack = I2C_WriteByte1((saddr<<1)+1);
if(s_ack == ACK_SUCCESS)
{
s_ack = 0;
DataL = I2C_ReadByte1(1);
DataH = I2C_ReadByte1(1);
PEC = I2C_ReadByte1(1);
XLM99614_I2C_Stop1();
buf[5]=(saddr<<1);
buf[4]=EEPROM|cmd;
buf[3]=(saddr<<1)|RD;
buf[2]=DataL;
buf[1]=DataH;
buf[0]=0;
Pecreg=PEC_Cal(buf,6);
if(Pecreg == PEC)
{
break;
}
}
else goto stop_rr;
}
else goto stop_rr;
}
else goto stop_rr;
stop_rr:
XLM99614_I2C_Stop1();
}
PEC = PEC+1;
Data =(DataH<<8)+ DataL;
return Data;
}
static uint16_t I2C_ReadRAM2(u8 saddr,u8 cmd)
{
uint16_t Data;
u8 DataL;
u8 DataH;
u8 PEC;
u8 retry = 10;
u8 s_ack = 0;
u8 Pecreg;
u8 buf[6];
ClrBit_SCK2;
while(retry--)
{
XLM99614_I2C_Start2();
s_ack = I2C_WriteByte2((saddr<<1)|WR);
if(s_ack == ACK_SUCCESS)
{
s_ack = 0;
s_ack = I2C_WriteByte2(RAM|cmd);
if(s_ack == ACK_SUCCESS)
{
s_ack = 0;
XLM99614_I2C_Start2();
s_ack = I2C_WriteByte2((saddr<<1)+1);
if(s_ack == ACK_SUCCESS)
{
s_ack = 0;
DataL = I2C_ReadByte2(1);
DataH = I2C_ReadByte2(1);
PEC = I2C_ReadByte2(1);
XLM99614_I2C_Stop2();
buf[5]=(saddr<<1);
buf[4]=EEPROM|cmd;
buf[3]=(saddr<<1)|RD;
buf[2]=DataL;
buf[1]=DataH;
buf[0]=0;
Pecreg=PEC_Cal(buf,6);
if(Pecreg == PEC)
{
break;
}
}
else goto stop_rr;
}
else goto stop_rr;
}
else goto stop_rr;
stop_rr:
XLM99614_I2C_Stop2();
}
PEC = PEC+1;
Data =(DataH<<8)+ DataL;
return Data;
}
static u8 PEC_Cal(u8 pec[],uint16_t 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;
crc[4]=0;
crc[3]=0;
crc[2]=0;
crc[1]=0x01;
crc[0]=0x07;
Bitposition=47;
shift=0;
i=5;
j=0;
while((pec[i]&(0x80>>j))==0 &&(i>0))
{
Bitposition--;
if(j<7)
{
j++;
}
else
{
j=0x00;
i--;
}
}
shift=Bitposition-8;
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;
}
shift--;
}
for(i=0; i<=5; i++)
{
pec[i]^=crc[i];
}
} while(Bitposition>8);
return pec[0];
}
float I2C_SetSlaveAddr(u8 x)
{
float OBJ1_Temp,OBJ_Temp_Old,OBJ_Temp_New;
OBJ_Temp_New=I2C_ReadRAM(0x00,0x07);
if((OBJ1_Temp>400)||(OBJ1_Temp<-40))
{
OBJ1_Temp=OBJ_Temp_Old;
}
else
OBJ1_Temp=OBJ_Temp_New;
OBJ_Temp_Old=OBJ1_Temp;
if(x==0)
{
OBJ1_Temp=(OBJ1_Temp*0.02)-273.15;
if(OBJ1_Temp>=40)
{
OBJ1_Temp=OBJ1_Temp*2.881-47.1782;
}
if(OBJ1_Temp<40)
{
OBJ1_Temp=OBJ1_Temp*2.576-48.788;
}
printf("\r\n OBJ1_Temp=%f \r\n",OBJ1_Temp);
Delay_us(100000);
}
if(x==1)
{
OBJ1_Temp=(OBJ1_Temp*0.02)-273.15;
OBJ1_Temp=OBJ1_Temp*2.7173-66.174;
printf("\r\n OBJ1_Temp=%f \r\n",OBJ1_Temp);
Delay_us(100000);
}
return OBJ1_Temp;
}
float I2C_SetSlaveAddr1(u8 x)
{
float OBJ1_Temp,OBJ_Temp_Old,OBJ_Temp_New;
OBJ_Temp_New=I2C_ReadRAM1(0x00,0x07);
if((OBJ1_Temp>400)||(OBJ1_Temp<-40))
{
OBJ1_Temp=OBJ_Temp_Old;
}
else
OBJ1_Temp=OBJ_Temp_New;
OBJ_Temp_Old=OBJ1_Temp;
if(x==0)
{
OBJ1_Temp=(OBJ1_Temp*0.02)-273.15;
if(OBJ1_Temp>=40)
{
OBJ1_Temp=OBJ1_Temp*2.881-47.1782;
}
if(OBJ1_Temp<40)
{
OBJ1_Temp=OBJ1_Temp*2.576-48.788;
}
printf("\r\n OBJ1_Temp=%f \r\n",OBJ1_Temp);
Delay_us(100000);
}
if(x==1)
{
OBJ1_Temp=(OBJ1_Temp*0.02)-273.15;
OBJ1_Temp=OBJ1_Temp*2.7173-66.174;
printf("\r\n OBJ1_Temp1=%f \r\n",OBJ1_Temp);
Delay_us(100000);
}
return OBJ1_Temp;
}
float I2C_SetSlaveAddr2(u8 x)
{
float OBJ1_Temp,OBJ_Temp_Old,OBJ_Temp_New;
OBJ_Temp_New=I2C_ReadRAM2(0x00,0x07);
if((OBJ1_Temp>400)||(OBJ1_Temp<-40))
{
OBJ1_Temp=OBJ_Temp_Old;
}
else
OBJ1_Temp=OBJ_Temp_New;
OBJ_Temp_Old=OBJ1_Temp;
if(x==0)
{
OBJ1_Temp=(OBJ1_Temp*0.02)-273.15;
if(OBJ1_Temp>=40)
{
OBJ1_Temp=OBJ1_Temp*OBJ1_Temp*0.0016+1.4343*OBJ1_Temp-33.824;
OBJ1_Temp=1.445*OBJ1_Temp-13.806-0.0015*OBJ1_Temp*OBJ1_Temp;
}
if(OBJ1_Temp<40)
{
OBJ1_Temp=OBJ1_Temp*2.576-48.788;
}
printf("\r\n OBJ1_Temp2=%f \r\n",OBJ1_Temp);
Delay_us(100000);
}
if(x==1)
{
OBJ1_Temp=OBJ1_Temp*OBJ1_Temp*0.0016+1.4343*OBJ1_Temp-33.824;
OBJ1_Temp=1.445*OBJ1_Temp-13.806-0.0015*OBJ1_Temp*OBJ1_Temp;
Delay_us(100000);
}
return OBJ1_Temp;
}
复制代码
主函数
#include "stm32f10x.h"
#include "sys_config.h"
#include "SysTick.h"
#include "led.h"
#include "usart1.h"
#include "iic.h"
#include "mlx90614.h"
#include "4422.h"
#include "HH_Handle.h"
#include "can.h"
__IO uint32_t flag = 0xff;
CanTxMsg TxMessage;
CanRxMsg RxMessage;
float Tempratrue=0;
float Tempratrue1=0;
float Tempratrue2=0;
u8 Alarm=0;
u16 Alarm_time=0;
u16 Normal_time=0;
u16 Temp_H=220;
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
int main(void)
{
RCC_Configuration();
SysTick_Init();
USART1_Config();
LED_GPIO_Config();
SMBus_Init();
CAN_Config();
printf("\r\n ζèèí¼t \r\n");
DCL_Select(0);
DCL_JDQ_PA4(OPEN);
while(1)
{
Tempratrue=I2C_SetSlaveAddr(0);
printf("\r\n %f\r\n ",Tempratrue);
Delay_us(500000);
Tempratrue1=I2C_SetSlaveAddr(0);
printf("\r\n %f\r\n ",Tempratrue1);
Delay_us(500000);
Tempratrue2=I2C_SetSlaveAddr(0);
printf("\r\n %f\r\n ",Tempratrue2);
if(Tempratrue>Tempratrue1)
{
if(Tempratrue>Tempratrue2)
{
if(Tempratrue1>Tempratrue2)
{
Tempratrue=Tempratrue1;
}
else
Tempratrue=Tempratrue2;
}
else
{
}
}
else
{
if(Tempratrue<Tempratrue2)
{
if(Tempratrue1>Tempratrue2)
{
Tempratrue=Tempratrue2;
}
}
}
if(Tempratrue>Temp_H)
{
Normal_time--;
if(Normal_time<0)
Normal_time=0;
Alarm_time++;
if(Alarm_time>200)
{
Alarm_time=0;
Alarm=1;
Beep(OPEN);
DCL_JDQ_PA4(OFF);
DCL_Select(0);
}
}
else
{
Alarm_time--;
if(Alarm_time<0)
Alarm_time=0;
Normal_time++;
if(Normal_time>200)
{
Normal_time=0;
Alarm=0;
Beep(OFF);
}
}
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
while (1)
{
}
}
#endif
复制代码
作者:
admin
时间:
2020-4-27 22:44
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1