⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iicxx.c

📁 TSL256源程序驱动!通过其IIC口采集环境光光强
💻 C
字号:
//**********************************************************
//**                     IIC驱动程序                   **
//**          单片机: STC12C5410AD 主频: 24MHz          **
//**              Jumping <2008.04.20>              **
//**********************************************************

//#include <REGx051.H>								// AT89C4051头文件
#include "../inc/STC12C5410AD.H"					// AT89C4051头文件
#include <INTRINS.H>								// 系统调令头文件
#include "def.h"									// 类型定义文件
#include "config.h"									// 配置头文件
#include "IIC.h"									// 配置头文件
#include "uart.h"									// 配置头文件


#define SomeNOP(); {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}

//*****变量声明****
INT CH0,CH1;     

// *** 函数声明 ***
void I2C_Start (void);
void I2C_Stop (void);
BOOL Send_Byte_I2C(BYTE tmData);
BYTE Read_Byte_I2C_ACK();
BYTE Read_Byte_I2C_NoACK();
uchar TSL2561_read_byte( uchar addr);
void InitTsl256x(void);
INT GetLux(void);
//BOOL Read_Data_I2C(BYTE iNum, unsigned int wAddr, BYTE tmData[64]);
//BOOL Write_Data_I2C(BYTE iNum, unsigned int wAddr, BYTE tmData[64]);

//***************************************************************************************
unsigned int CalculateLux(unsigned int iGain, unsigned int tInt, unsigned int ch0, unsigned int ch1, int iType);

//#pragma OPTIMIZE(5)

/*******************************************************************************
* 名    称: I2C_Start()
* 功    能: 启动I2C操作
* 入口参数: 无
* 出口参数: 无
*******************************************************************************/
void I2C_Start (void)
{

	SDA=0; 
	SCL=0; 
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始
	SDA=1; 
	SCL=1; 
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始

	SDA=0; 
	SCL=0; 
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始
	SDA=1; 
	SCL=1; 
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始
	SDA=0; 
	SCL=0; 
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始
	SDA=1; 
	SCL=1; 
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始

	SDA=0; 
	SCL=0; 
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始
	SDA=1; 
	SCL=1; 
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始

	SDA=1; 
	SCL=0; 
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始

	SDA=1; 
	SCL=1; 
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始

	SDA=0; 

	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始
	SomeNOP();//数据线保持高,时钟线从高到低一次跳变,I2C通信开始

}


/*******************************************************************************
* 名    称: I2C_Stop()
* 功    能: 结束I2C操作
* 入口参数: 无
* 出口参数: 无
*******************************************************************************/
void I2C_Stop (void)
{

	SDA=0; 
	SomeNOP(); //数据线保持低,时钟线从低到高一次跳变,I2C通信停止
	SCL=1; 
	SomeNOP(); 
	SDA=1; 
	SomeNOP(); 

								
}
/*******************************************************************************
* 名    称: I2C_Start()
* 功    能: 启动I2C操作
* 入口参数: 无
* 出口参数: 无
*******************************************************************************/
void SendAck(void)
{
	SDA=1; 
	SCL=0; 
	SomeNOP(); //数据线保持低,时钟线发生一次从高低的跳变 发送一个应答信号
	SCL=1; 
	SomeNOP();
//	SCL=0;
}
/*******************************************************************************
* 名    称: I2C_Start()
* 功    能: 启动I2C操作
* 入口参数: 无
* 出口参数: 无
*******************************************************************************/
void SendNotAck(void)
{
	SDA=1; 
	SCL=0;
	SomeNOP(); //数据线保持高,时钟线发生一次从高低的跳变 没有应答
	SCL=1; 
	SomeNOP();
//	SCL=0;
}
/*******************************************************************************
* 名    称: I2C_Start()
* 功    能: 启动I2C操作
* 入口参数: 无
* 出口参数: 无
*******************************************************************************/
BOOL Send_Byte_I2C(BYTE ch)
{
	unsigned char i=8;
	while (i--)
	{
		SCL=0;
		_nop_();
		SDA=(bit)(ch&0x80); 
		ch<<=1; 
		SomeNOP(); //时钟保持低可以发送数据
		SCL=1; 
		SomeNOP();
	}
	SCL=0;
	
	SendNotAck();

	return 0;
}


/*******************************************************************************
* 名    称: I2C_Start()
* 功    能: 启动I2C操作
* 入口参数: 无
* 出口参数: 无
*******************************************************************************/

BYTE Read_Byte_I2C_ACK(void)
{
	BYTE i,tdata;
	i=8;tdata=0;
	
	SDA=1;
	_nop_();_nop_();_nop_();
	while (i--)
	{
		tdata<<=1;
		SCL=0;
		SomeNOP();
		SCL=1;
		SomeNOP(); //时钟做一次从低到高的跳变 可以接收数据
		tdata|=SDA;
	}
	SCL=0;
	
	SendAck();
	
	return tdata;

}


/*******************************************************************************
* 名    称: I2C_Start()
* 功    能: 启动I2C操作
* 入口参数: 无
* 出口参数: 无
*******************************************************************************/
BYTE Read_Byte_I2C_NoACK()
{
	BYTE i;
	BYTE tmData = 0;
	SDA=1;
	for(i=0; i<8; i++)
	{
		tmData *= 2;
		SCL = 1;

		if(SDA)
			tmData |= 0x01;
		SCL = 0;

		_nop_ ();
		_nop_ ();
		_nop_ ();
		_nop_ ();
		_nop_ ();
	}

/*	SCL = 0;*/

	return tmData;
}
/*******************************************************************************
* 名    称: TSL2561_write_byte()
* 功    能: 启动I2C操作
* 入口参数: 无
* 出口参数: 无
*******************************************************************************/
uchar TSL2561_write_byte( unsigned char addr, unsigned char dat) 
{ 

    uchar status=0; 
    I2C_Start();                           		  //开始 
    status=Send_Byte_I2C(TSL2561_ADDR|TSL2561_WR);//写TSL2561地址 
    status=Send_Byte_I2C(0x80|addr);              //写命令 
    status=Send_Byte_I2C(dat);                    //写数据 
    I2C_Stop( );                                  //停止 
    delay_1ms(2);                                //延时2 ms 
    return 0; 

} 
/*******************************************************************************
* 名    称: TSL2561_read_byte()
* 功    能: 启动I2C操作
* 入口参数: 无
* 出口参数: 无
*******************************************************************************/
uchar TSL2561_read_byte( uchar addr) 
{ 

    uchar status=0; 

    I2C_Start();                           		  //开始 
    status=Send_Byte_I2C(TSL2561_ADDR|TSL2561_WR);//写TSL2561地址 
	status=Send_Byte_I2C(0x80|addr);              //写命令 

    I2C_Start();                           			 //Re开始 
    status=Send_Byte_I2C(TSL2561_ADDR|TSL2561_RD);  //写TSL2561地址     
    status=Read_Byte_I2C_ACK();                      //读数据 
	I2C_Stop( );                                     //停止 

    delay_1ms(10); 

    return status; 

} 

/*******************************************************************************
* 名    称: InitTsl256x()
* 功    能: 启动I2C操作
* 入口参数: 无
* 出口参数: 无
*******************************************************************************/
void InitTsl256x(void)
{
	uchar status;
	status=TSL2561_write_byte(0x00,PWUP);	  //寄存器00H
	//status=TSL2561_write_byte(0x01,0x12);	  //寄存器00H	
	status=TSL2561_write_byte(0x01,0x02);	  //寄存器00H	//jumping080522 change the gain To 1x
	status=TSL2561_write_byte(0x02,0x00);	  //寄存器00H
	status=TSL2561_write_byte(0x03,0x00);	  //寄存器00H
	status=TSL2561_write_byte(0x04,0x00);	  //寄存器00H
	status=TSL2561_write_byte(0x05,0x00);	  //寄存器00H
	status=TSL2561_write_byte(0x06,0x00);	  //寄存器00H
 /*
    I2C_Start();                           		   //开始 

    status=Send_Byte_I2C(TSL2561_ADDR|TSL2561_WR); //写TSL2561地址 
//jumpingtest
while(!status)//test the Tsl2561 ack 
LED=0;
LED=1;
    status=Send_Byte_I2C(0x90|REG_CTR);            //写命令 
//    I2C_Start();                                   //开始 
//    status=Send_Byte_I2C(TSL2561_ADDR|TSL2561_RD);//写TSL2561地址 

    status=Send_Byte_I2C(0x07);//写n ge ????????

    status=Send_Byte_I2C(PWUP);                    //寄存器00H
	status=Send_Byte_I2C(0x12);                    //寄存器01H  -the gain=1 16x -the timer=10 401ms
	
	status=Send_Byte_I2C(0x00);                    //寄存器02H
	status=Send_Byte_I2C(0x00);                    //寄存器03H
	status=Send_Byte_I2C(0x00);                    //寄存器04H
	status=Send_Byte_I2C(0x00);                    //寄存器05H

	status=Send_Byte_I2C(0x00);                    //寄存器06H   no interrupt
    I2C_Stop( );                                   //停止 */
    delay_1ms(10);                                 //延时10 ms 

}

//****************************************************************************
//
// Copyright -Handson Jumping, Inc.
//
// lux equation approximation without floating point calculations
//////////////////////////////////////////////////////////////////////////////
// Routine: unsigned int CalculateLux(unsigned int ch0, unsigned int ch0, int iType)
//
// Description: Calculate the approximate illuminance (lux) given the raw
// channel values of the TSL2560. The equation if implemented
// as a piece.wise linear approximation.
//
// Arguments: unsigned int iGain . gain, where 0:1X, 1:16X
// unsigned int tInt . integration time, where 0:13.7mS, 1:100mS, 2:402mS,
// 3:Manual
// unsigned int ch0 . raw channel value from channel 0 of TSL2560
// unsigned int ch1 . raw channel value from channel 1 of TSL2560
// unsigned int iType . package type (T or CS)
//
// Return: unsigned int . the approximate illuminance (lux)
//
//////////////////////////////////////////////////////////////////////////////
unsigned int CalculateLux(unsigned int iGain, unsigned int tInt, unsigned int ch0, unsigned int ch1, int iType)
{
	unsigned long ratio1;
	unsigned long ratio;
	unsigned long temp;
	unsigned long lux;
	unsigned long chScale;    //TSL2561
	unsigned long channel1;   //TSL2561
	unsigned long channel0;   //TSL2561
	unsigned int b, m;
	//........................................................................
	// first, scale the channel values depending on the gain and integration time
	// 16X, 402mS is nominal.
	// scale if integration time is NOT 402 msec
	switch (tInt)
	{
		case 0: // 13.7 msec
			chScale = CHSCALE_TINT0;
			break;
		case 1: // 101 msec
			chScale = CHSCALE_TINT1;
			break;
		default: // assume no scaling
			chScale = (1 << CH_SCALE);
			break;
	}
	// scale if gain is NOT 16X
	if (!iGain) chScale = chScale << 4; // scale 1X to 16X
	// scale the channel values
	channel0 = (ch0 * chScale) >> CH_SCALE;
	channel1 = (ch1 * chScale) >> CH_SCALE;
	//........................................................................
	// find the ratio of the channel values (Channel1/Channel0)
	// protect against divide by zero
	ratio1 = 0;
	if (channel0 != 0) ratio1 = (channel1 << (RATIO_SCALE+1)) / channel0;
	// round the ratio value
	ratio = (ratio1 + 1) >> 1;
	// is ratio <= eachBreak ?
	switch (iType)
	{
		case 0: // T package
			if ((ratio >= 0) && (ratio <= K1T))
				{b=B1T; m=M1T;}
			else if (ratio <= K2T)
				{b=B2T; m=M2T;}
			else if (ratio <= K3T)
				{b=B3T; m=M3T;}
			else if (ratio <= K4T)
				{b=B4T; m=M4T;}
			else if (ratio <= K5T)
				{b=B5T; m=M5T;}
			else if (ratio <= K6T)
				{b=B6T; m=M6T;}
			else if (ratio <= K7T)
				{b=B7T; m=M7T;}
			else if (ratio > K8T)
				{b=B8T; m=M8T;}
			break;
		case 1:// CS package
/*
			if ((ratio >= 0) && (ratio <= K1C))
			{b=B1C; m=M1C;}
			else if (ratio <= K2C)
			{b=B2C; m=M2C;}
			else if (ratio <= K3C)
			{b=B3C; m=M3C;}
			else if (ratio <= K4C)
			{b=B4C; m=M4C;}
			else if (ratio <= K5C)
			{b=B5C; m=M5C;}
			else if (ratio <= K6C)
			{b=B6C; m=M6C;}
			else if (ratio <= K7C)
			{b=B7C; m=M7C;}
			else if (ratio > K8C)
			{b=B8C; m=M8C;}
*/
			break;
	}

	temp = ((channel0 * b)- (channel1 * m));
	// do not allow negative lux value
	if (temp < 0) temp = 0;
	// round lsb (2^(LUX_SCALE.1))
	temp += (1 << (LUX_SCALE-1));
	// strip off fractional portion
	lux = temp >> LUX_SCALE;
	return(lux);
}

/*******************************************************************************
* 名    称: GetLux()
* 功    能: 启动I2C操作
* 入口参数: 无
* 出口参数: 无
*******************************************************************************/
INT GetLux(void)
{
	INT i;
	i=0;	
	CH0=TSL2561_read_byte(REG_CH0_L);
	CH0=CH0+TSL2561_read_byte(REG_CH0_H)*256;
	
	CH1=TSL2561_read_byte(REG_CH1_L);
	CH1=CH1+TSL2561_read_byte(REG_CH1_H)*256;

	i=CalculateLux(GAIN_1X,ITIME_400MS,CH0,CH1,FootType_T);
	return (i);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -