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

📄 iic.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"									// 配置头文件

//*****变量声明****
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)
{
	uchar i;

	SCL = 1;
	SDA = 1;

	for(i=0; i<12; i++)
	_nop_ ();

	SDA = 0;

	for(i=0; i<12; i++)
	_nop_ ();
	
	SCL = 0;
}


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

	SCL = 0;
	SDA = 0;

	for(i=0; i<12; i++)
	_nop_ ();
	SCL = 1;

	for(i=0; i<12; i++)
	_nop_ ();
	SDA = 1;
								
}
/*********************************************/
/*  name:  Send_Byte_I2C                     */
/*  input: BYTE tmData                         */
/*  output:	BOOL                             */
/*  function: Send one tmData to 24256         */
/*********************************************/
BOOL Send_Byte_I2C(BYTE tmData)
{
	BYTE i,temp;
	BOOL bSendOk;
	
	temp = tmData;

	SCL = 0;

	for(i=0; i<8; i++)
	_nop_ ();

	for(i=0; i<8; i++)
	{
		if(temp & 0x80)
			SDA = 1;
		else
			SDA = 0;

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

		SCL = 1;
		temp = _crol_(temp,1);

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

		SCL = 0;

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

	}
	
	for(i=0; i<5; i++)
	_nop_ ();
	
	SCL = 1;
	SDA = 1;	
	_nop_ ();//jp
	_nop_ ();//jp
	_nop_ ();//jp
	bSendOk = FALSE;
	for(i=0; i<10; i++)
	{
		_nop_ ();	
		if(!SDA) {bSendOk = TRUE;break;} //sda =0 应答信号
	}
 //   ACC = P1;
/*
	if(SDA)   //sda =0 应答信号
	{
		bSendOk = FALSE;
	}
	else
	bSendOk = TRUE;*/
	SCL = 0;
	return bSendOk;
}


/*********************************************/
/*  name:  Read_Byte_I2C_ACK                 */
/*  input: none                              */
/*  output:	BYTE tmData                         */
/*  function: Send one tmData to 24256         */
/*********************************************/
BYTE Read_Byte_I2C_ACK()
{
	BYTE i;
	BYTE tmData = 0;


	SDA=1;//
	_nop_ ();//jp
	_nop_ ();//jp
	_nop_ ();//jp
	_nop_ ();//jp

	for(i=0; i<8; i++)
	{
		//tmData *= 2;
		tmData <<= 1;
		SCL = 1;

		_nop_ ();
		_nop_ ();
		_nop_ ();
		
		_nop_ ();//jk
		_nop_ ();//jk
		_nop_ ();//jk

		if(SDA)
			tmData |= 0x01;

		_nop_ ();//jk
		_nop_ ();//jk
		_nop_ ();//jk

		SCL = 0;

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


	SDA = 0;	
	_nop_ ();
	_nop_ ();

	SCL = 1;
	for(i=0; i<8; i++)
	_nop_ ();
	SCL=0;

	SDA = 1;
        
 
	return tmData;
}


/*******************************************************************************
* 名    称: 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(0x01);              	  //写Byte Count 
    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(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_16X,ITIME_400MS,CH0,CH1,FootType_T);
	return (i);
}

⌨️ 快捷键说明

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