📄 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 + -