📄 tsl2561.c
字号:
#include <pic.h>
#include "tsl2561.h"
#define nop() asm("nop")
#define SCL TRISB1
#define SDA TRISB2
unsigned char no,ack,data;
void delay_xms(unsigned int delay_times)
{ unsigned int k;
for(k=delay_times;--k;) continue;
asm("clrwdt");
}
///////////////////////////////////////////////
void iic_initial()
{
TRISB=0X0F; //B口必须弱上拉有效
PORTB=0X00;
}
///起动总线函数
///函数原型: void start_i2c();
///Function: start on the I2C bus
void start_i2c()
{
SDA=1; //发送启始条件的数据信号
nop();
SCL=1;
nop();nop();nop();nop();nop();nop();nop();nop(); //24LC02要求建立时间大于4,7S
SDA=0; //发送起始信号
nop();nop();nop();nop();nop();nop();nop();nop();
SCL=0; //钳住I2C总线,准备发送数据或接收数据
nop();nop();
}
//停止总线函数
//函数原型: void stop_i2c();
///Function: stop the I2C bus
void stop_i2c()
{
SDA=0; //发送结束条件的数据信号
nop();
SCL=1;
nop();nop();nop();nop();nop();
SDA=1;
nop();nop();nop();nop();
}
/*=================================================================
//字节数据传送函数
//函数原型: void send_byte(uchar c);
//Function: 将数据C发送出去,可以是地址,也可以是数据,发完后等待回应,并对此状态
// 位进行操作(不应答或非应答都使ack=0 ),发送数据正常,ack=1;ack=0
// 表示被控器无应答或损坏。
==================================================================*/
void send_byte(unsigned char c)
{
unsigned char bit_count;
for (bit_count=0;bit_count<8;bit_count++)
{
if ((c<<bit_count)&0x80) {SDA=1;}
else {SDA=0;}
nop(); nop();
SCL=1;
nop();nop();nop();nop();nop();
SCL=0;
}
nop();nop(); nop(); nop();
SDA=1;
nop();nop(); nop(); nop();
SCL=1;
nop();nop(); //&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
if (RB2==1) ack=0; ///////////////////////////////////////////////
else ack=1; //用ASK=1为有应答信号
SCL=0;
nop();nop(); nop(); nop();
}
/*==================================================================
字节数据接收函数
函数原型:uchar receive_byte();
FUNCTION: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数。
===================================================================*/
unsigned char receive_byte()
{
unsigned char retc,bit_count;
retc=0;
SDA=1;
for (bit_count=0;bit_count<8;bit_count++)
{
nop();
SCL=0;
nop();nop();nop();nop();nop();
SCL=1;
nop();nop();
retc=retc<<1;
if (RB2==1) retc=retc+1; ////////////////////////////////////////
nop();nop();
}
SCL=0;
nop();nop();
return (retc);
}
///写tsl2561 byte
void WriteByte(unsigned char Command1,unsigned char Data) //
{
start_i2c();
send_byte(0x72); ////SlaveAddress=0x39<<1+1
if (ack==0) iic_error();
send_byte(Command1);
if (ack==0) iic_error();
send_byte(Data);
if (ack==0) iic_error();
stop_i2c();
}
///写tsl2561 word
void WriteWord(unsigned char Command2,unsigned char DataLow,unsigned char DataHigh) //
{
start_i2c();
send_byte(0x72); ////SlaveAddress=0x39<<1+1
if (ack==0) iic_error();
send_byte(Command2);
if (ack==0) iic_error();
send_byte(DataLow);
if (ack==0) iic_error();
send_byte(DataHigh);
if (ack==0) iic_error();
stop_i2c();
}
///读tsl2561 byte
unsigned char ReadByte(unsigned char Command3)
{ unsigned char receivedata;
start_i2c();
send_byte(0x72); ////SlaveAddress=0x39<<1+1写命令
if (ack==0) iic_error();
send_byte(Command3);
if (ack==0) iic_error();
start_i2c();
send_byte(0x73); ////SlaveAddress=0x39<<1+0读命令
if (ack==0) iic_error();
receivedata=receive_byte();
stop_i2c();
return(receivedata);
}
/////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
void iic_error()
{
unsigned char i;
for (i=0;i<8;i++)
{
RB6=0;
delay_xms(65535);
RB6=1;
delay_xms(65535);
}
}
/////////////////////////////////////////////////////////////////////
void Config(void) //配置tsl2561
{
WriteByte(0x81,0x02);//gain(1x),integration time of 402ms
WriteByte(0x86,0x00);//interrpt is level style, every ADC cycle generate one interrupt.
}
void start_tsl2561(void) ///开始转换
{
WriteByte(0x80,0x03);
}
void stop_tsl2561(void) //停止转换
{
WriteByte(0x80,0x00);
}
unsigned int ReadADCResult(void) //ADC结果是channel 0.
{
unsigned char datalow;
unsigned int ADCResult,datahigh;
datalow=ReadByte(0x8C);
datahigh=ReadByte(0x8D);
ADCResult=(datahigh<<8)+datalow;
return(ADCResult);
}
///////////////////////////////////////////////////////////
void I_byte_write(unsigned char slave_address,unsigned char byte_address,unsigned char datain)
{
start_i2c();
send_byte(slave_address);
if (ack==0) iic_error();
send_byte(byte_address);
if (ack==0) iic_error();
send_byte(datain);
if (ack==0) iic_error();
stop_i2c();
}
//////////////////////////////////////////
unsigned char I_random_read(unsigned char address) //随机读取
{
start_i2c();
send_byte(0xa0); //发送器件地址,即DEVICE ADDRESS。
if (ack==0) iic_error(); //如果24LC02无应答。则进入I2C ERROR错误指示。
send_byte(address); //发送字地址,即WORD ADDRESS。D口显示数组。
if (ack==0) iic_error();
start_i2c(); //重新启动总线。
send_byte(0xa1); //发送读命令和器件地址DEVICE ADDRESS。
if (ack==0) iic_error();
data=receive_byte();
stop_i2c();
return (data);
}
/////////////////////////////////////////////////////////////////
void SlaveWriteByte(unsigned char Slavedata) //
{
start_i2c();
send_byte(0x7E); ////SlaveAddress=0x7e
if (ack==0) iic_error();
send_byte(Slavedata);
if (ack==0) iic_error();
stop_i2c();
}
/////////////////////////////////////////////////////////////////
void SlaveWriteWord(unsigned char mastercommand,unsigned char masterdata)
{
start_i2c();
send_byte(0x7E);
if (ack==0) iic_error();
send_byte(mastercommand);
if (ack==0) iic_error();
send_byte(masterdata);
if (ack==0) iic_error();
stop_i2c();
}
///////////////////////////////////////////////////////
unsigned char slavereceive_byte()
{
unsigned char retc0,bit_count0;
retc0=0;
SDA=1;
for (bit_count0=0;bit_count0<8;bit_count0++)
{
nop();
SCL=0;
nop();nop();nop();nop();nop();
SCL=1;
while(RB1==0) //判断从机是否释放时钟.
{
;
}
// nop();nop();
retc0=retc0<<1;
if (RB2==1) retc0=retc0+1;
nop();nop();
}
SCL=0;
nop();nop();
return (retc0);
}
//////////////////////////////////////////////////////////////
unsigned char SlaveReadByte(unsigned char slavecommand)
{
unsigned char receiveslavedata;
start_i2c();
send_byte(0x7E); //写命令
if (ack==0) iic_error();
send_byte(slavecommand);
if (ack==0) iic_error();
start_i2c();
send_byte(0x7F); //读命令
if (ack==0) iic_error();
receiveslavedata=slavereceive_byte();
stop_i2c();
return(receiveslavedata);
}
////////////////////////////////////////////////////////////////////////////
unsigned char MastertestSlave()
{ unsigned char receivetestdata;
start_i2c();
send_byte(0x7F); //读命令
if (ack==0) iic_error();
receivetestdata=slavereceive_byte();
stop_i2c();
return(receivetestdata);
}
////////////////////////////////////////////////////////////////////////////
//Tempreture sensor of DS1631 ///////////////////////////////////
void StartConvert_DS1631() //Start DS1631 and bigan convert.
{
start_i2c();
send_byte(0x90); //Write Contral bite.
if (ack==0) iic_error();
send_byte(0x51); //51H is the Start Convert command.
if (ack==0) iic_error();
stop_i2c();
}
////////////////////////////////////////////////////////////////////////////
void StopConvert_DS1631() //Stop DS1631 and bigan convert.
{
start_i2c();
send_byte(0x90); //Write Contral bite.
if (ack==0) iic_error();
send_byte(0x22); //22H is the Stop Convert command.
if (ack==0) iic_error();
stop_i2c();
}
///////////////////////////////////////////////////////////////////////////
void Config_DS1631() //Config DS1631
{
start_i2c();
send_byte(0x90); //Write Contral bite.
if (ack==0) iic_error();
send_byte(0xAC); //ACH is the command of config DS1631
if (ack==0) iic_error();
send_byte(0x0C); //Continue Convertion Mode,Tout is active low.
if (ack==0) iic_error();
stop_i2c();
}
////////////////////////////////////////////////////////////////////
unsigned char ReadConfigRegister_DS1631()
{ unsigned char configdata;
start_i2c();
send_byte(0x90); //Write Contral bite.
if (ack==0) iic_error();
send_byte(0xAC); //ACH is the command of config DS1631
if (ack==0) iic_error();
start_i2c();
send_byte(0x91); //Read Contral bite.
if (ack==0) iic_error();
configdata=receive_byte();
stop_i2c();
return(configdata);
}
////////////////////////////////////////////////////////////////
void WriteThTl_Register(unsigned char Access_Command,unsigned char MS_Data,unsigned char LS_Data)
{ start_i2c();
send_byte(0x90); //Write Contral bite.
if (ack==0) iic_error();
send_byte(Access_Command); //Write command bite.
if (ack==0) iic_error();
send_byte(MS_Data); //Write Th MS Data bite.
if (ack==0) iic_error();
send_byte(LS_Data); //Write Th MS Data bite.
if (ack==0) iic_error();
stop_i2c();
}
////////////////////////////////////////////////////////////////
unsigned int Read_Temperature()
{ unsigned int Temperature;
unsigned char MSdata,LSdata;
Temperature=0x0000;
start_i2c();
send_byte(0x90); //Write Contral bite.
if (ack==0) iic_error();
send_byte(0xAA); //AAH is the command of Read Temperature
if (ack==0) iic_error();
start_i2c();
send_byte(0x91); //Read command
if (ack==0) iic_error();
MSdata=receive_byte(); //Receive MS data
//////////////////////////产生 ACK 信号
SDA=0;
nop();nop();nop();
SCL=1;
nop();nop();nop();
SCL=0;
nop();nop();nop();
SDA=1;
/////////////////
LSdata=receive_byte(); //Receive MS data
stop_i2c();
Temperature=Temperature + MSdata;
Temperature=Temperature << 8;
Temperature=Temperature + LSdata;
return(Temperature);
}
///////////////////////////////////////////////////////////////////////////
void Set_TunerUser(unsigned char freqhigh,unsigned char freqlow)
{ unsigned int temp1;
unsigned char temp3;
temp1=freqhigh;
temp1=temp1<<8 + freqlow;
temp3=0x00;
if(temp1>0x06A7) temp3=0x01;
if(temp1>0x1007) temp3=0x02;
if(temp1>0x2533) temp3=0x03;
start_i2c();
send_byte(0xC2);
if (ack==0) iic_error();
send_byte(freqhigh); //设置频率
if (ack==0) iic_error();
send_byte(freqlow); //
if (ack==0) iic_error();
send_byte(0x8A); //步长31.25k,CP=0,OS=0 IC工作状态
if (ack==0) iic_error();
send_byte(temp3); //波段设置
if (ack==0) iic_error();
stop_i2c();
}
//////////////////////////////////////////////////////////////////
void Set_Tuner(unsigned int freq)
{ unsigned char temp1,temp2;
unsigned char temp3;
temp3=0x00;
if(freq>0x06A7) temp3=0x01;
if(freq>0x1007) temp3=0x02;
if(freq>0x2533) temp3=0x03;
temp1=freq;
temp2=freq>>8;
start_i2c();
send_byte(0xC2);
if (ack==0) iic_error();
send_byte(temp1); //设置频率
if (ack==0) iic_error();
send_byte(temp2); //
if (ack==0) iic_error();
send_byte(0x8A); //步长31.25k,CP=0,OS=0 IC工作状态
if (ack==0) iic_error();
send_byte(temp3); //波段设置
if (ack==0) iic_error();
stop_i2c();
}
///////////////////////////////////////////////////////////
void Write_9886()
{
start_i2c();
send_byte(0x86);
if (ack==0) iic_error();
send_byte(0x00); //
if (ack==0) iic_error();
send_byte(0x54); //
if (ack==0) iic_error();
send_byte(0x30); //
if (ack==0) iic_error();
send_byte(0x08); //
if (ack==0) iic_error();
stop_i2c();
}
////////////////////////////////////////
unsigned char Read_9886(void)
{
unsigned char rec_data;
start_i2c();
send_byte(0x87);
if (ack==0) iic_error();
rec_data=receive_byte();
stop_i2c();
return(rec_data);
}
////////////////////////////////////////////////////////
unsigned int Lock_Channel_DOWN(unsigned int Curr_Freq)
{
unsigned char temp,f,count,count1,rData;
unsigned int freq,i;
f=0;
count=0;
for(i=Curr_Freq;i>1300;i--)
{
Set_Tuner(i);
delay_xms(10000);
rData=Read_9886();
temp=(rData>>1)&0x0f;
if(temp==7) {f|=1,count=count1;count1=0;}
if(temp>0&&temp<7) f|=0x02;
if(temp==0||temp==15) {f|=0x04;freq=i;}
if(temp>8&&temp<15) f|=0x08;
if(temp==8) {f=0x10;count1++;}
if((rData&0xc0)!=0xc0)
{
f=0;
count=0;
}
if(f==0x1f&&count>3)
{
Set_Tuner(freq);
delay_xms(10000);
return freq;
}
}
return 1; //Not Find Channel
}
//////////////////
unsigned int Lock_Channel_UP(unsigned int Curr_Freq)
{
unsigned char temp,f,count,rData;
unsigned int freq,i;
f=0;
count=0;
for(i=Curr_Freq;i<18083;i++)
{
Set_Tuner(i);
delay_xms(10000);
rData=Read_9886();
temp=(rData>>1)&0x0f;
if(temp==7) {f=1;count=0;}
if(temp>0&&temp<7) f|=0x02;
if(temp==0||temp==15) {f|=0x04;freq=i;}
if(temp>8&&temp<15) f|=0x08;
if(temp==8) {f|=0x10;count++;}
if((rData&0xc0)!=0xc0)
{
f=0;
count=0;
}
if(f==0x1f&&count>3)
{
Set_Tuner(freq);
delay_xms(10000);
return freq;
}
}
return 1; //Not Find Channel
}
/////////////////////////
unsigned char TV_AutoScan()
{
unsigned char number;//
unsigned int freq;
char up=0;
number=0;
if(up)
freq=1300;
else
freq=15300;
while(1)
{
if(up)
freq=Lock_Channel_UP(freq+20);
else
freq=Lock_Channel_DOWN(freq-20);
if(freq<2) break;
number++;
}
return(number);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -