基于STC89C52RC的TSL2561调试程序.docx
《基于STC89C52RC的TSL2561调试程序.docx》由会员分享,可在线阅读,更多相关《基于STC89C52RC的TSL2561调试程序.docx(14页珍藏版)》请在冰豆网上搜索。
基于STC89C52RC的TSL2561调试程序
/////////////////////////////////////////////////
Config.h文件
////////////////////////////////////////////////////////
#ifndef_CONFIG_H
#define_CONFIG_H
/*通用头文件*/
#include
#include
/*数据类型定义*/
/*typedefsignedcharint8;//8位有符号整型数
typedefsignedintint16;//16位有符号整型数
typedefsignedlongint32;//32位有符号整型数*/
typedefunsignedcharu8;//8位无符号整型数
typedefunsignedintu16;//16位无符号整型数
typedefunsignedlongu32;//32位无符号整型数
/*全局运行参数定义*/
#defineSYS_MCLK(11059200/12)//系统主时钟频率,即振荡器频率÷12
/*IO引脚分配定义
sbitKEY_IN_1=P2^4;//矩阵按键的扫描输入引脚1
sbitKEY_IN_2=P2^5;//矩阵按键的扫描输入引脚2
sbitKEY_IN_3=P2^6;//矩阵按键的扫描输入引脚3
sbitKEY_IN_4=P2^7;//矩阵按键的扫描输入引脚4
sbitKEY_OUT_1=P2^3;//矩阵按键的扫描输出引脚1
sbitKEY_OUT_2=P2^2;//矩阵按键的扫描输出引脚2
sbitKEY_OUT_3=P2^1;//矩阵按键的扫描输出引脚3
sbitKEY_OUT_4=P2^0;//矩阵按键的扫描输出引脚4*/
sbitADDR0=P1^0;//LED位选译码地址引脚0
sbitADDR1=P1^1;//LED位选译码地址引脚1
sbitADDR2=P1^2;//LED位选译码地址引脚2
sbitADDR3=P1^3;//LED位选译码地址引脚3
sbitENLED=P1^4;//LED显示部件的总使能引脚
#defineLCD12864_DBP0//1602液晶数据端口
sbitLCD12864_RES=P1^0;//1602液晶指令/数据选择引脚
sbitLCD12864_RW=P1^1;//1602液晶读写引脚
sbitLCD12864_EN=P1^5;//1602液晶使能引脚
sbitDS1302_CE=P1^7;//DS1302片选引脚
sbitDS1302_CK=P3^5;//DS1302通信时钟引脚
sbitDS1302_IO=P3^4;//DS1302通信数据引脚
sbitI2C_SCL=P2^7;//I2C总线时钟引脚
sbitI2C_SDA=P2^6;//I2C总线数据引脚
sbitBUZZER=P1^6;//蜂鸣器控制引脚
sbitIO_18B20=P3^2;//DS18B20通信引脚
sbitIR_INPUT=P3^3;//红外接收引脚
#include"LCD12864.H"
#include"I2C.H"
#include"TSL2561.h"
#endif
///////////////////////////////////////////////
I2C通信协议
////////////////////////////////////////////////
#include"config.h"
#defineI2CDelay(){_nop_();_nop_();_nop_();_nop_();}
/*产生总线起始信号*/
voidI2CStart()
{
I2C_SDA=1;//首先确保SDA、SCL都是高电平
I2C_SCL=1;
I2CDelay();
I2C_SDA=0;//先拉低SDA
I2CDelay();
I2C_SCL=0;//再拉低SCL
}
/*产生总线停止信号*/
voidI2CStop()
{
I2C_SCL=0;//首先确保SDA、SCL都是低电平
I2C_SDA=0;
I2CDelay();
I2C_SCL=1;//先拉高SCL
I2CDelay();
I2C_SDA=1;//再拉高SDA
I2CDelay();
}
/*I2C总线写操作,dat-待写入字节,返回值-从机应答位的值*/
bitI2CWrite(unsignedchardat)
{
bitack;//用于暂存应答位的值
unsignedcharmask;//用于探测字节内某一位值的掩码变量
for(mask=0x80;mask!
=0;mask>>=1)//从高位到低位依次进行
{
if((mask&dat)==0)//该位的值输出到SDA上
I2C_SDA=0;
else
I2C_SDA=1;
I2CDelay();
I2C_SCL=1;//拉高SCL
I2CDelay();
I2C_SCL=0;//再拉低SCL,完成一个位周期
}
I2C_SDA=1;//8位数据发送完后,主机释放SDA,以检测从机应答
I2CDelay();
I2C_SCL=1;//拉高SCL
ack=I2C_SDA;//读取此时的SDA值,即为从机的应答值
I2CDelay();
I2C_SCL=0;//再拉低SCL完成应答位,并保持住总线
return(~ack);//应答值取反以符合通常的逻辑:
//0=不存在或忙或写入失败,1=存在且空闲或写入成功
}
/*I2C总线读操作,并发送非应答信号,返回值-读到的字节*/
unsignedcharI2CReadNAK()
{
unsignedcharmask;
unsignedchardat;
I2C_SDA=1;//首先确保主机释放SDA
for(mask=0x80;mask!
=0;mask>>=1)//从高位到低位依次进行
{
I2CDelay();
I2C_SCL=1;//拉高SCL
if(I2C_SDA==0)//读取SDA的值
dat&=~mask;//为0时,dat中对应位清零
else
dat|=mask;//为1时,dat中对应位置1
I2CDelay();
I2C_SCL=0;//再拉低SCL,以使从机发送出下一位
}
I2C_SDA=1;//8位数据发送完后,拉高SDA,发送非应答信号
I2CDelay();
I2C_SCL=1;//拉高SCL
I2CDelay();
I2C_SCL=0;//再拉低SCL完成非应答位,并保持住总线
returndat;
}
/*I2C总线读操作,并发送应答信号,返回值-读到的字节*
unsignedcharI2CReadACK()
{
unsignedcharmask;
unsignedchardat;
I2C_SDA=1;//首先确保主机释放SDA
for(mask=0x80;mask!
=0;mask>>=1)//从高位到低位依次进行
{
I2CDelay();
I2C_SCL=1;//拉高SCL
if(I2C_SDA==0)//读取SDA的值
dat&=~mask;//为0时,dat中对应位清零
else
dat|=mask;//为1时,dat中对应位置1
I2CDelay();
I2C_SCL=0;//再拉低SCL,以使从机发送出下一位
}
I2C_SDA=0;//8位数据发送完后,拉低SDA,发送应答信号
I2CDelay();
I2C_SCL=1;//拉高SCL
I2CDelay();
I2C_SCL=0;//再拉低SCL完成应答位,并保持住总线
returndat;
}*/
////////////////////////////////////////////////
LCD12864显示
//////////////////////////////////////////////////
#include"config.h"
u8zhbuf[]={"预览"};//中文数组
u8ehbuf[]={"yulan"};//英文字符数组
u8codeimbuf[]={//图片码128*64宽16,高32
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
/*写等待*/
voidWrite_Ready()
{
u8sta=0;
LCD12864_RES=0;
LCD12864_RW=1;
do{
LCD12864_EN=1;
sta=P0;
LCD12864_EN=0;
}while(sta&0x80);
}
/*读RAM中数据*/
u8Read_12864_RAM()
{
u8ram=0;
LCD12864_RES=1;
LCD12864_RW=1;
LCD12864_EN=1;
ram=P0;
LCD12864_EN=0;
returnram;
}
/*写指令*/
voidWrite_12864_Cmd(u8cmd)
{
Write_Ready();
LCD12864_RES=0;
LCD12864_RW=0;
P0=cmd;
LCD12864_EN=1;
LCD12864_EN=0;
}
/*写数据*/
voidWrite_12864_Dat(u8dat)
{
Write_Ready();
LCD12864_RES=1;
LCD12864_RW=0;
P0=dat;
LCD12864_EN=1;
LCD12864_EN=0;
}
/*设置起始坐标*/
voidSet_DDRAM_XY(u8x,u8y)
{
if(x>=7)
x=7;
if(y>=3)
y=3;
switch(y)
{
case0:
Write_12864_Cmd(0x80+x);break;
case1:
Write_12864_Cmd(0x90+x);break;
case2:
Write_12864_Cmd(0x88+x);break;
case3:
Write_12864_Cmd(0x98+x);break;
default:
break;
}
}
/*显示连续的2个字符*/
voidShow_Double_12864_Char(u8x,u8y,u8*c)
{
Set_DDRAM_XY(x,y);
Write_12864_Dat(*c);
Write_12864_Dat(*(c+1));
}
/*显示单个字符*/
voidShow_Single_12864_Char(u8x,u8y,u8*c)
{
Set_DDRAM_XY(x,y);
Write_12864_Dat(*c);
}
/*显示中文字符串*/
voidShow_12864_ZH(u8x,u8y,u8*zh)
{
u8*p=zh;
Set_DDRAM_XY(x,y);
while((*p)!
='\0')
{
Write_12864_Dat(*p++);
}
}
/*显示一串数值*/
/*u8dec小数位为0不显示小数*/
voidShow_12864_NUM(u8x,u8y,u8dec,u16num)
{
u8i;
u8numbuf[6];
for(i=0;num;i++)
{
numbuf[i]=num%10+'0';
num/=10;
}
Set_DDRAM_XY(x,y);
for(;i;i--)
{
if(i==dec)
{
Write_12864_Dat(0X2E);//显示小数点
}
Write_12864_Dat(*(numbuf+(i-1)));//显示数值
}
}
/*显示英文字符串*/
voidShow_12864_EH(u8x,u8y,u8*eh)
{
u8*p=eh;
Set_DDRAM_XY(x,y);
while((*p)!
='\0')
{
Write_12864_Dat(*p++);
}
}
/*显示图案*/
voidShow_12864_IM(u8code*im)
{
unsignedcharx,y,i;
unsignedinttmp=0;
for(i=0;i<9;)
{//分两屏,上半屏和下半屏,因为起始地址不同,需要分开
for(x=0;x<32;x++)
{//32行
Write_12864_Cmd(0x34);
Write_12864_Cmd(0x80+x);//列地址
Write_12864_Cmd(0x80+i);//行地址,下半屏,即第三行地址0X88
Write_12864_Cmd(0x30);
for(y=0;y<16;y++)
Write_12864_Dat(im[tmp+y]);//读取数据写入LCD
tmp+=16;
}
i+=8;
}
Write_12864_Cmd(0x36);//扩充功能设定
Write_12864_Cmd(0x30);
}
/*初始化12864*/
voidInit_Lcd12864()
{
Read_12864_RAM();
Show_Single_12864_Char(0,0,'A');
Show_Double_12864_Char(0,0,"AB");
Show_12864_NUM(0,0,1,123);
Show_12864_ZH(0,0,"预览");
Show_12864_EH(0,0,"yulan");
Show_12864_IM(imbuf);
Write_12864_Cmd(0X30);//8位数据,基本指令
Write_12864_Cmd(0X0C);//开显示,关游标
Write_12864_Cmd(0X01);//清屏
Write_12864_Cmd(0X02);//地址归位
Write_12864_Cmd(0X80);//设置DDRAM地址
}
////////////////////////////////////////////////////////////
TSL2561代码
//////////////////////////////////////////////////
#include"config.h"
/*初始化TSL2561*/
voidInit_TSL2561()
{
TSL2561_Write(0X80|TSL2561_CONTROL,0x03);//选择控制寄存器//工作模式
TSL2561_Write(0X80|TSL2561_TIME,0x01);//选择转换时间控制寄存器
}
/*读TSL2561寄存器中的数据,addr是寄存器地址*/
u8TSL2561_Read(u8addr)
{
u8lx=0;
I2CStart();
I2CWrite(TSL2561_WR);//选择TSL2561
I2CWrite(0X80|addr);//选择寄存器
I2CStart();
I2CWrite(TSL2561_RD);
lx=I2CReadNAK();//读取寄存器中的值
I2CStop();
returnlx;
}
/*写TSL2561命令或数据,addr是寄存器地址*/
voidTSL2561_Write(u8addr,u8cmd)
{
I2CStart();
I2CWrite(TSL2561_WR);//选择TSL2561写操作
I2CWrite(0X80|addr);//选择寄存器
I2CWrite(cmd);//写入命令或数据
I2CStop();
}
/*读取光强*/
u16TSL_Read_LX()
{
u8lxl=0,lxh=0,lxp=0;
doublelx=0;
u16ch0=0,ch1=0;
lxl=TSL2561_Read(TSL2561_DATA0_L);
lxh=TSL2561_Read(TSL2561_DATA0_H);
ch0=lxh*256+lxl;
lxh=0,lxl=0;
lxl=TSL2561_Read(TSL2561_DATA1_L);
lxh=TSL2561_Read(TSL2561_DATA1_H);
ch1=lxh*256+lxl;
lxp=(ch1*100)/ch0;
if((0{
lx=0.0304*ch0-0.062*ch0*((ch1/ch0)/4);
}
elseif((50{
lx=0.0224*ch0-0.031*ch1;
}
elseif((61{
lx=0.0128*ch0-0.0153*ch1;
}
elseif((80{
lx=0.00146*ch0-0.00112*ch1;
}
elseif(130{
lx=0;
}
return((u16)(lx*100));
}
///////////////////////////////////////////////////////////////
Main.c文件
///////////////////////////////////////////////////////////////
#include"config.h"
voiddelayms(u16ms)
{
while(ms>=30)
{
ms-=5;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
voidmain()
{
Init_Lcd12864();
Init_TSL2561();
while
(1)
{
Show_12864_NUM(0,0,0,TSL_Read_LX());
Show_12864_NUM(0,2,0,12345);
delayms(1000);
Write_12864_Cmd(0X01);
}
}
////////////////////////////////////////////////////
完
//////////////////////////////////////////////////////////