STC12驱动MLX90614红外测温模块在LCD1602显示

文章目录

  • 1、基本简介
  • 2、通信方式
  • 3、参考STC12例程
  • 参考文献

1、基本简介

STC12驱动MLX90614红外测温模块在LCD1602显示_第1张图片
STC12驱动MLX90614红外测温模块在LCD1602显示_第2张图片
STC12驱动MLX90614红外测温模块在LCD1602显示_第3张图片
STC12驱动MLX90614红外测温模块在LCD1602显示_第4张图片

2、通信方式

通过芯片手册我们可以了解到这个模块的输出有PWM和SMBus方式,PWM长期做嵌入式开发的已经很熟悉了,那么什么是SMBus呢?
SMBus(系统管理总线),最早由Intel提出,应用于移动PC和桌面PC系统中的低速率通信,是一种两线的接口。通过它,各设备之间以及系统的其他部分可以之间可以相互通信,它是基于IIC原理,接口和数据格式类似与IIC,同样有两个接口(1个时钟、一个数据),7位数据。可以说SMBus是IIC的一个子集
STC12驱动MLX90614红外测温模块在LCD1602显示_第5张图片
STC12驱动MLX90614红外测温模块在LCD1602显示_第6张图片
STC12驱动MLX90614红外测温模块在LCD1602显示_第7张图片

3、参考STC12例程

#include 
#include 
#include 

/*=================================================
 * 时钟宏定义
 *=================================================*/
#define MAIN_Fosc		11059200L			//宏定义主时钟HZ
//#define MAIN_Fosc		12000000L

/*=================================================
 * 自定义数据类型
 *=================================================*/
typedef unsigned char uchar;
typedef unsigned int uint;

//LCD1602硬件接口
#define LCD1602_DB P0			//LCD1602数据总线
sbit LCD1602_RS = P3^5;	 //RS端
sbit LCD1602_RW = P3^6;	 //RW端
sbit LCD1602_EN = P3^4;	 //EN端

//I2C模拟硬件接口定义
sbit SCL = P0^6;
sbit SDA = P0^7;

/*I2C常用变量宏定义*/
#define I2cRead 		1			//I2C读方向位
#define I2cWrite 		0			//I2C写方向

/*全局变量定义*/
uchar DataH,DataL,Pecreg;


/*============================自主适应时钟延时函数===========================================*/
//基于STC12单片机1us延时函数
//函数说明:内部调用
static void Delaym1us()
{
	# if MAIN_Fosc == 11059200L
	//晶振11.0592MHz
	_nop_();
	
	#elif MAIN_Fosc == 12000000L
	//晶振12.000000MHZ
	_nop_();
	_nop_();
	
	#endif
}

//基于STC12单片机us延时函数
//函数说明:外部调用
void Delay_us(uint time)
{
	int i;
	for(i=0; i<time; i++)
	{
		Delaym1us();
	}
}

//基于STC12单片机ms延时函数
//函数说明:外部调用
void Delay_ms(uint time)
{
	int i;
	for(i=0; i<time; i++)
	{
		Delay_us(1000);
	}
}

/*============================IIC===========================================*/
//I2C延时5us函数
void I2cDelay_5us(void)
{
	Delay_us(5);
}

//I2C总线起始信号
void I2cStart(void)
{
	SCL = 1;
	SDA = 1;
	I2cDelay_5us();//状态保持5us
	SDA = 0;
	I2cDelay_5us();//状态保持5us
}

//I2C总线停止信号
void I2cStop(void)
{
	SCL = 0;
	SDA = 0;
	SCL = 1;
	I2cDelay_5us();//状态保持5us
	SDA = 1;
	I2cDelay_5us();//状态保持5us
}

/********************************
 *函数名称:ReadACK(void)
 *函数输入:无
 *函数返回:1非应答,0应答
 *函数说明:I2C总线读从机应答信号
 ********************************/
bit ReadACK(void)
{
	uint i;
	
	SCL = 0;//拉低时钟总线,允许从机控制SDA
	SCL = 1;//拉高,读SDA
	I2cDelay_5us();
	while((SDA==1) && (i<250))//等待SDA应答,或者超过时间默认应答
		i++;
	SCL = 0;
	I2cDelay_5us();
	return(0);//返回0应答
}

/***************************************
 *函数名称:SendACK(bit i)
 *函数输入:1主机发送非应答,0发送应答
 *函数返回:无
 *函数说明:主机发送应答信号
 ***************************************/
void SendACK(bit i)
{
	SCL = 0;	//拉低时钟总线,允许主机控制SDA
	if(i)		//发送非应答
		SDA = 1;
	else
		SDA = 0;
	SCL = 1;	//拉高总线,让从机读SDA
	I2cDelay_5us();
	SCL = 0;	//拉低时钟总线,允许SDA释放
	SDA = 1;	//释放数据总线
}

/***************************************
 *函数名称:I2cSendByte(uchar DAT)
 *函数输入:DAT需要发送的数据
 *函数返回:无
 *函数说明:I2C发送一个字节数据
 ***************************************/
void I2cSendByte(uchar DAT)
{
	uchar i;
	for(i=0; i<8; i++)	//分别写8次,每次写1位
	{
		SCL = 0;		//拉低时钟总线,允许SDA变化
		_nop_();
		if(DAT & 0x80)	//先写数据最高位
		{
			SDA = 1;  	//写1
			_nop_();
		}
		else
		{
			SDA = 0;  	//写0
			_nop_();
		}
		SCL = 1;	  	//拉高时钟,让从机读SDA
		_nop_();
		DAT <<= 1;	  	//为发送下一位左移1位
	}
	SCL = 0;			//拉低时钟总线,允许SDA释放
	_nop_();
	SDA = 1;			//释放数据总线
	_nop_();
}

/*====================================
函数	:I2cReadByte()
参数	:无
返回值	:返回读出的一字节数据
描述	:I2C总线读一字节数据
====================================*/
uchar I2cReadByte(void)
{
	uchar i, DAT;

	SCL = 0;
	_nop_();
	SDA = 1;
	_nop_();
	for(i=0; i<8; i++)//分别读8次,每次读一位
	{
		DAT <<= 1; //数据左移1位,准备接收一位
		SCL = 0;   //拉低时钟总线,允许从机控制SDA变化
		_nop_();
		SCL = 1;   //拉高时钟总线,读取SDA上的数据
		_nop_();
		if(SDA)
			DAT |= 0X01;//为1则写1,否则不行执行写1,通过左移补0
		_nop_();
	}
	return(DAT); //返回读出的数据
}

//读取温度数据
uint temperatureRead(void)
{
	I2cStart();
	I2cSendByte(0xB4);//Send SlaveAddress(写从设备地址)
	ReadACK();
	I2cSendByte(0x07);//Send Command(写命令)
	ReadACK();
	
	I2cStart();
	I2cSendByte(0x01);
	DataL = I2cReadByte();
	SendACK(0);
	DataH = I2cReadByte();
	SendACK(0);
	Pecreg = I2cReadByte();
	I2cStop();
	return(DataH*256+DataL);
}

//读取到最终温度
//程序涉及到温度计算,详细参考芯片手册
float SMBus_ReadTemp(void)
{
	float temp;
	temp = temperatureRead();
	temp = temp * 0.02 - 273.15;
	return temp;
}

/*============================LCD1206===========================================*/
/*=================================================
*函数名称:Read_Busy
*函数功能:判断1602液晶忙,并等待
=================================================*/
void Read_Busy()
{
	uchar busy;
	LCD1602_DB = 0xff;//复位数据总线
	LCD1602_RS = 0;	  //拉低RS+
	LCD1602_RW = 1;	  //拉高RW读
	do
	{
		LCD1602_EN = 1;//使能EN
		busy = LCD1602_DB;//读回数据
		LCD1602_EN = 0;	 //拉低使能以便于下一次产生上升沿
	}while(busy & 0x80); //判断状态字BIT7位是否为1,为1则表示忙,程序等待
}
/*=================================================
*函数名称:LCD1602_Write_Cmd
*函数功能:写LCD1602命令
*调用:Read_Busy();
*输入:cmd:要写的命令
=================================================*/
void LCD1602_Write_Cmd(uchar cmd)
{
	Read_Busy();	 //判断忙,忙则等待
	LCD1602_RS = 0;
	LCD1602_RW = 0;	//拉低RS、RW操作时序情况1602课件下中文使用说明基本操作时序章节
	LCD1602_DB = cmd;//写入命令
	LCD1602_EN = 1;	 //拉高使能端 数据被传输到LCD1602内
	LCD1602_EN = 0;	 //拉低使能以便于下一次产生上升沿
}
/*=================================================
*函数名称:LCD1602_Write_Dat
*函数功能:写LCD1602数据
*调用:Read_Busy();
*输入:dat:需要写入的数据
=================================================*/
void LCD1602_Write_Dat(uchar dat)
{
	Read_Busy();
	LCD1602_RS = 1;
	LCD1602_RW = 0;
	LCD1602_DB = dat;
	LCD1602_EN = 1;
	LCD1602_EN = 0;
}

/*=================================================
*函数名称:LCD1602_Dis_Str
*函数功能:在指定位置显示字符串
*调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();
*输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行)
		*str:需要显示的字符串
=================================================*/
void LCD1602_Dis_Str(uchar x, uchar y, uchar *str)
{
	if(y) x |= 0x40;
	x |= 0x80;
	LCD1602_Write_Cmd(x);
	while(*str != '\0')
	{
		LCD1602_Write_Dat(*str++);
	}
}
/*=================================================
*函数名称:Init_LCD1602
*函数功能:1602初始化
*调用:	LCD1602_Write_Cmd();
=================================================*/
void Init_LCD1602()
{
	LCD1602_Write_Cmd(0x38); //	设置16*2显示,5*7点阵,8位数据接口
	LCD1602_Write_Cmd(0x0c); //开显示
	LCD1602_Write_Cmd(0x06); //读写一字节后地址指针加1
	LCD1602_Write_Cmd(0x01); //清除显示
}

void main()
{
	float Temperature = 0;			//温度数据变量(浮点型)
	char TempValue[10] = {0};		//温度值(字符串)
	
	uchar TestStr[] = {"Temp:"};
	Init_LCD1602();							//1602初始化
	LCD1602_Dis_Str(0, 0, &TestStr[0]);		//显示字符串
	
	while(1)
	{
		Temperature = SMBus_ReadTemp();
		Delay_ms(100);
		sprintf(TempValue, "%.1f", Temperature);//浮点型转换字符串
		LCD1602_Dis_Str(6, 0, &TempValue[0]);
	}
}

STC12驱动MLX90614红外测温模块在LCD1602显示_第8张图片

参考文献

[1] MLX90614中文资料

你可能感兴趣的:(STC12C5A60S2库,单片机,嵌入式硬件,物联网)