#include<REG51.H>
#include<math.h>//Keillibrary
#include<stdio.h>//Keillibrary
#include<INTRINS.H>
#defineucharunsignedchar
#defineuintunsignedint
#defineDataPortP0//LCD1602數據端口
sbitSCL=P1^0;//IIC時鐘引腳定義
sbitSDA=P1^1;//IIC數據引腳定義
sbitLCM_RS=P3^5;//LCD1602命令端口
sbitLCM_RW=P3^6;//LCD1602命令端口
sbitLCM_EN=P3^4;//LCD1602命令端口
#defineSlaveAddress0x46//定義器件在IIC總線中的從地址,根據ALTADDRESS地址引腳不同修改
//ALTADDRESS引腳接地時地址為0xA6,接電源時地址為0x3A
typedefunsignedcharBYTE;
typedefunsignedshortWORD;
BYTEBUF[8];//接收數據緩存區
ucharge,shi,bai,qian,wan;//顯示變量
intdis_data;//變量
voiddelay_nms(unsignedintk);
voidInitLcd();
voidInit_BH1750(void);
voidWriteDataLCM(uchardataW);
voidWriteCommandLCM(ucharCMD,ucharAttribc);
voidDisplayOneChar(ucharX,ucharY,ucharDData);
voidconversion(uinttemp_data);
voidSingle_Write_BH1750(ucharREG_Address);//單個寫入數據
ucharSingle_Read_BH1750(ucharREG_Address);//單個讀取內部寄存器數據
voidMultiple_Read_BH1750();//連續的讀取內部寄存器數據
//------------------------------------
voidDelay5us();
voidDelay5ms();
voidBH1750_Start();//起始信號
voidBH1750_Stop();//停止信號
voidBH1750_SendACK(bitack);//應答ACK
bitBH1750_RecvACK();//讀ack
voidBH1750_SendByte(BYTEdat);//IIC單個字節寫
BYTEBH1750_RecvByte();//IIC單個字節讀
//-----------------------------------
//*********************************************************
voidconversion(uinttemp_data)//數據轉換出個,十,百,千,萬
{
wan=temp_data/10000+0x30;
temp_data=temp_data%10000;//取余運算
qian=temp_data/1000+0x30;
temp_data=temp_data%1000;//取余運算
bai=temp_data/100+0x30;
temp_data=temp_data%100;//取余運算
shi=temp_data/10+0x30;
temp_data=temp_data%10;//取余運算
ge=temp_data+0x30;
}
//毫秒延時**************************
voiddelay_nms(unsignedintk)
{
unsignedinti,j;
for(i=0;i<k;i++)
{
for(j=0;j<121;j++)
{;}}
}
/*******************************/
voidWaitForEnable(void)
{
DataPort=0xff;
LCM_RS=0;LCM_RW=1;_nop_();
LCM_EN=1;_nop_();_nop_();
while(DataPort&0x80);
LCM_EN=0;
}
/*******************************/
voidWriteCommandLCM(ucharCMD,ucharAttribc)
{
if(Attribc)WaitForEnable();
LCM_RS=0;LCM_RW=0;_nop_();
DataPort=CMD;_nop_();
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}
/*******************************/
voidWriteDataLCM(uchardataW)
{
WaitForEnable();
LCM_RS=1;LCM_RW=0;_nop_();
DataPort=dataW;_nop_();
LCM_EN=1;_nop_();_nop_();LCM_EN=0;
}
/***********************************/
voidInitLcd()
{
WriteCommandLCM(0x38,1);
WriteCommandLCM(0x08,1);
WriteCommandLCM(0x01,1);
WriteCommandLCM(0x06,1);
WriteCommandLCM(0x0c,1);
}
/***********************************/
voidDisplayOneChar(ucharX,ucharY,ucharDData)
{
Y&=1;
X&=15;
if(Y)X|=0x40;
X|=0x80;
WriteCommandLCM(X,0);
WriteDataLCM(DData);
}
/**************************************
延時5微秒(STC90C52RC@12M)
不同的工作環境,需要調整此函數,注意時鐘過快時需要修改
當改用1T的MCU時,請調整此延時函數
**************************************/
voidDelay5us()
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
}
/**************************************
延時5毫秒(STC90C52RC@12M)
不同的工作環境,需要調整此函數
當改用1T的MCU時,請調整此延時函數
**************************************/
voidDelay5ms()
{
WORDn=560;
while(n--);
}
/**************************************
起始信號
**************************************/
voidBH1750_Start()
{
SDA=1;//拉高數據線
SCL=1;//拉高時鐘線
Delay5us();//延時
SDA=0;//產生下降沿
Delay5us();//延時
SCL=0;//拉低時鐘線
}
/**************************************
停止信號
**************************************/
voidBH1750_Stop()
{
SDA=0;//拉低數據線
SCL=1;//拉高時鐘線
Delay5us();//延時
SDA=1;//產生上升沿
Delay5us();//延時
}
/**************************************
發送應答信號
入口參數:ack(0:ACK1:NAK)
**************************************/
voidBH1750_SendACK(bitack)
{
SDA=ack;//寫應答信號
SCL=1;//拉高時鐘線
Delay5us();//延時
SCL=0;//拉低時鐘線
Delay5us();//延時
}
/**************************************
接收應答信號
**************************************/
bitBH1750_RecvACK()
{
SCL=1;//拉高時鐘線
Delay5us();//延時
CY=SDA;//讀應答信號
SCL=0;//拉低時鐘線
Delay5us();//延時
returnCY;
}
/**************************************
向IIC總線發送一個字節數據
**************************************/
voidBH1750_SendByte(BYTEdat)
{
BYTEi;
for(i=0;i<8;i++)//8位計數器
{
dat<<=1;//移出數據的最高位
SDA=CY;//送數據口
SCL=1;//拉高時鐘線
Delay5us();//延時
SCL=0;//拉低時鐘線
Delay5us();//延時
}
BH1750_RecvACK();
}
/**************************************
從IIC總線接收一個字節數據
**************************************/
BYTEBH1750_RecvByte()
{
BYTEi;
BYTEdat=0;
SDA=1;//使能內部上拉,準備讀取數據,
for(i=0;i<8;i++)//8位計數器
{
dat<<=1;
SCL=1;//拉高時鐘線
Delay5us();//延時
dat|=SDA;//讀數據
SCL=0;//拉低時鐘線
Delay5us();//延時
}
returndat;
}
//*********************************
voidSingle_Write_BH1750(ucharREG_Address)
{
BH1750_Start();//起始信號
BH1750_SendByte(SlaveAddress);//發送設備地址+寫信號
BH1750_SendByte(REG_Address);//內部寄存器地址,請參考中文pdf22頁
//BH1750_SendByte(REG_data);//內部寄存器數據,請參考中文pdf22頁
BH1750_Stop();//發送停止信號
}
//********單字節讀取*****************************************
/*
ucharSingle_Read_BH1750(ucharREG_Address)
{ucharREG_data;
BH1750_Start();//起始信號
BH1750_SendByte(SlaveAddress);//發送設備地址+寫信號
BH1750_SendByte(REG_Address);//發送存儲單元地址,從0開始
BH1750_Start();//起始信號
BH1750_SendByte(SlaveAddress+1);//發送設備地址+讀信號
REG_data=BH1750_RecvByte();//讀出寄存器數據
BH1750_SendACK(1);
BH1750_Stop();//停止信號
returnREG_data;
}
*/
//*********************************************************
//
//連續讀出BH1750內部數據
//
//*********************************************************
voidMultiple_read_BH1750(void)
{uchari;
BH1750_Start();//起始信號
BH1750_SendByte(SlaveAddress+1);//發送設備地址+讀信號
for(i=0;i<3;i++)//連續讀取6個地址數據,存儲中BUF
{
BUF[i]=BH1750_RecvByte();//BUF[0]存儲0x32地址中的數據
if(i==3)
{
BH1750_SendACK(1);//最后一個數據需要回NOACK
}
else
{
BH1750_SendACK(0);//回應ACK
}
}
BH1750_Stop();//停止信號
Delay5ms();
}
//初始化BH1750,根據需要請參考pdf進行修改****
voidInit_BH1750()
{
Single_Write_BH1750(0x01);
}
//*********************************************************
//主程序********
//*********************************************************
voidmain()
{
floattemp;
delay_nms(200);//延時200ms
InitLcd();//初始化LCD
Init_BH1750();//初始化BH1750
while(1)//循環
{
Single_Write_BH1750(0x01);//poweron
Single_Write_BH1750(0x10);//H-resolutionmode
delay_nms(180);//延時180ms
Multiple_Read_BH1750();//連續讀出數據,存儲在BUF中
dis_data=BUF[0];
dis_data=(dis_data<<8)+BUF[1];//合成數據
temp=(float)dis_data/1.2;
conversion(temp);//計算數據和顯示
DisplayOneChar(0,0,'L');
DisplayOneChar(1,0,'i');
DisplayOneChar(2,0,'g');
DisplayOneChar(3,0,'h');
DisplayOneChar(4,0,'t');
DisplayOneChar(5,0,':');
DisplayOneChar(7,0,wan);//顯示數據
DisplayOneChar(8,0,qian);
DisplayOneChar(9,0,bai);
DisplayOneChar(10,0,shi);
DisplayOneChar(11,0,ge);
DisplayOneChar(13,0,'l');////顯示數單位
DisplayOneChar(14,0,'x');