OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3187|回复: 2

求助STM32F1的TSL2561程序,时间紧迫!

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
6
金钱
6
注册时间
2018-5-29
在线时间
2 小时
发表于 2018-6-1 08:11:52 | 显示全部楼层 |阅读模式
15金钱
最近用到TSL2561做一个基于STM32F1的项目,调试了三天都没能正确读取数据,哪位大佬能分享一下自己的程序或者帮忙分析一下我的程序问题?非常感谢!IIC用的是原子哥的程序
//tsl2561.h
#ifndef TSL2561_H
#define TSL2561_H
  
#include "myiic.h"
   
#define uchar unsigned char
//命令控制寄存器  
#define TIMING  0x81  
#define DATA0LOW  0x8C
#define DATA0HIGH 0x8D
#define DATA1LOW  0x8E
#define DATA1HIGH 0x8F
void tsl2561_Init(void);

u8 TSL2561_ReadOneByte(u16 ReadAddr);                           //指定地址读取一个字节
void TSL2561_WriteOneByte(u16 WriteAddr,u8 DataToWrite);        //指定地址写入一个字节
unsigned  int Calculate_ch0( u8 DataLow0, u8 DataHigh0);
unsigned  int Calculate_ch1(u8 DataLow1, u8 DataHigh1);
unsigned int CalculateLux(unsigned int iGain, unsigned int tInt, unsigned int ch0, unsigned int ch1, int iType);
#endif


//tsl2561.c
#include "tsl2561.h"
#include "delay.h"

void tsl2561_Init(void)
{
     TSL2561_WriteOneByte(0x80,0x03); //设置TSL2561为开启状态
     TSL2561_WriteOneByte(0x81,0x02); //设置TSL2561的Timing寄存器--积分增益1x且积分时间402ms
}
  
//ReadAddr    :开始读数的寄存器地址  
//返回值temp  :读到的数据
uchar TSL2561_ReadOneByte(u16 ReadAddr)
{                 
    u8 temp=0;                                                                              
    IIC_Start();  
    IIC_Send_Byte(0x72);   //发送器件地址+Wr----float(0111 001_ + 0)--0X72   
     
    IIC_Wait_Ack();
    IIC_Send_Byte(ReadAddr);   //发送Command
     
    IIC_Wait_Ack();     
    IIC_Start();           
    IIC_Send_Byte(0X73);   //发送器件地址+Rd----float(0111 001_ + 1)--0X73   
     
    IIC_Wait_Ack();  
    temp=IIC_Read_Byte(1);  //发送ASK, 1字节存入temp
     
    IIC_Stop();//产生一个停止条件      
    return temp;
}


//WriteAddr  :写入数据的目的寄存器地址   
//DataToWrite:要写入目的寄存器的数据
void TSL2561_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{                                                                                            
    IIC_Start();  
    IIC_Send_Byte(0X72);   //发送器件地址0X72
     
    IIC_Wait_Ack();   
    IIC_Send_Byte(WriteAddr);   //发送Command
     
    IIC_Wait_Ack();                                                        
    IIC_Send_Byte(DataToWrite);     //发送字节                             
    IIC_Wait_Ack();                    
    IIC_Stop();//产生一个停止条件
    delay_ms(10);   
}


unsigned  int Calculate_ch0( u8 DataLow0, u8 DataHigh0)
  {
        unsigned long ch0;
        ch0 = 256*(u16)DataHigh0 + (u16)DataLow0;
        return ch0;
  }
   
unsigned   int Calculate_ch1(u8 DataLow1, u8 DataHigh1)
  {
        unsigned   long ch1;
        ch1 = 256*(u16)DataHigh1 +(u16)DataLow1;
        return ch1;
  }
   
   
//  int DataLow0 = TSL2561_ReadOneByte(DATA0LOW);  
//  DataHigh0 = TSL2561_ReadOneByte(DATA0HIGH);  
//  //ch0 = 256*DataHigh0 + DataLow0;
//  
//  DataLow1 = TSL2561_ReadOneByte(DATA1LOW);  
//  DataHigh1 = TSL2561_ReadOneByte(DATA1HIGH);  
//  ch1 = 256*DataHigh1 + DataLow1;
//  delay_ms(100);
   
//  //Ratio_Scale = Channel1/Channel0;
//   
//  if(0.0<Channel1/Channel0&&Channel1/Channel0<=0.50) Light=(0.0304*Channel0-0.062*Channel0*((Channel1/Channel0)^1.4));
//  if(0.50<Channel1/Channel0&&Channel1/Channel0<=0.61) Light=(0.0224*Channel0-0.031*Channel1);
//  if(0.61<Channel1/Channel0&&Channel1/Channel0<=0.80) Light=(0.0128*Channel0-0.0153*Channel1);
//  if(0.80<Channel1/Channel0&&Channel1/Channel0<=1.30) Light=(0.00146*Channel0-0.00112*Channel1);
//  if(Channel1/Channel0>1.30)Light=0;
//  delay_ms(100);
//


//****************************************************************************
//****************************************************************************

#define LUX_SCALE 14 // scale by 2^14
#define RATIO_SCALE 9 // 比例系数----scale ratio by 2^9

//----------------------------------------------------
// Integration time scaling factors - 积分时间比例因子
//----------------------------------------------------

#define CH_SCALE 10 // scale channel values by 2^10
#define CHSCALE_TINT0 0x7517 // 322/11 * 2^CH_SCALE = 29975
#define CHSCALE_TINT1 0x0fe7 // 322/81 * 2^CH_SCALE = 4071

//----------------------------------------------------
// T, FN, and CL Package coefficients(系数)
//----------------------------------------------------
// For Ch1/Ch0=0.00 to 0.50
// Lux/Ch0=0.0304-0.062*((Ch1/Ch0)^1.4)
// piecewise approximation
// For Ch1/Ch0=0.00 to 0.125:
// Lux/Ch0=0.0304-0.0272*(Ch1/Ch0)
//
// For Ch1/Ch0=0.125 to 0.250:
// Lux/Ch0=0.0325-0.0440*(Ch1/Ch0)
//
// For Ch1/Ch0=0.250 to 0.375:
// Lux/Ch0=0.0351-0.0544*(Ch1/Ch0)
//
// For Ch1/Ch0=0.375 to 0.50:
// Lux/Ch0=0.0381-0.0624*(Ch1/Ch0)
//
// For Ch1/Ch0=0.50 to 0.61:
// Lux/Ch0=0.0224-0.031*(Ch1/Ch0)
//
// For Ch1/Ch0=0.61 to 0.80:
// Lux/Ch0=0.0128-0.0153*(Ch1/Ch0)
//
// For Ch1/Ch0=0.80 to 1.30:
// Lux/Ch0=0.00146-0.00112*(Ch1/Ch0)
//
// For Ch1/Ch0>1.3:
// Lux/Ch0=0
//----------------------------------------------------

#define K1T 0x0040 // 0.125 * 2^RATIO_SCALE
#define B1T 0x01f2 // 0.0304 * 2^LUX_SCALE
#define M1T 0x01be // 0.0272 * 2^LUX_SCALE

#define K2T 0x0080 // 0.250 * 2^RATIO_SCALE
#define B2T 0x0214 // 0.0325 * 2^LUX_SCALE
#define M2T 0x02d1 // 0.0440 * 2^LUX_SCALE

#define K3T 0x00c0 // 0.375 * 2^RATIO_SCALE
#define B3T 0x023f // 0.0351 * 2^LUX_SCALE
#define M3T 0x037b // 0.0544 * 2^LUX_SCALE

#define K4T 0x0100 // 0.50 * 2^RATIO_SCALE
#define B4T 0x0270 // 0.0381 * 2^LUX_SCALE
#define M4T 0x03fe // 0.0624 * 2^LUX_SCALE

#define K5T 0x0138 // 0.61 * 2^RATIO_SCALE
#define B5T 0x016f // 0.0224 * 2^LUX_SCALE
#define M5T 0x01fc // 0.0310 * 2^LUX_SCALE

#define K6T 0x019a // 0.80 * 2^RATIO_SCALE
#define B6T 0x00d2 // 0.0128 * 2^LUX_SCALE
#define M6T 0x00fb // 0.0153 * 2^LUX_SCALE

#define K7T 0x029a // 1.3 * 2^RATIO_SCALE
#define B7T 0x0018 // 0.00146 * 2^LUX_SCALE
#define M7T 0x0012 // 0.00112 * 2^LUX_SCALE

#define K8T 0x029a // 1.3 * 2^RATIO_SCALE
#define B8T 0x0000 // 0.000 * 2^LUX_SCALE
#define M8T 0x0000 // 0.000 * 2^LUX_SCALE

//---------------------------------------------------
// CS package coefficients
//---------------------------------------------------
// For 0 <= Ch1/Ch0 <= 0.52
// Lux/Ch0 = 0.0315-0.0593*((Ch1/Ch0)^1.4)
// piecewise approximation
// For 0 <= Ch1/Ch0 <= 0.13
// Lux/Ch0 = 0.0315-0.0262*(Ch1/Ch0)
// For 0.13 <= Ch1/Ch0 <= 0.26
// Lux/Ch0 = 0.0337-0.0430*(Ch1/Ch0)
// For 0.26 <= Ch1/Ch0 <= 0.39
// Lux/Ch0 = 0.0363?0.0529*(Ch1/Ch0)
// For 0.39 <= Ch1/Ch0 <= 0.52
// Lux/Ch0 = 0.0392-0.0605*(Ch1/Ch0)
// For 0.52 < Ch1/Ch0 <= 0.65
// Lux/Ch0 = 0.0229-0.0291*(Ch1/Ch0)
// For 0.65 < Ch1/Ch0 <= 0.80
// Lux/Ch0 = 0.00157-0.00180*(Ch1/Ch0)
// For 0.80 < Ch1/Ch0 <= 1.30
// Lux/Ch0 = 0.00338-0.00260*(Ch1/Ch0)
// For Ch1/Ch0 > 1.30
// Lux = 0
//---------------------------------------------------

#define K1C 0x0043 // 0.130 * 2^RATIO_SCALE
#define B1C 0x0204 // 0.0315 * 2^LUX_SCALE
#define M1C 0x01ad // 0.0262 * 2^LUX_SCALE

#define K2C 0x0085 // 0.260 * 2^RATIO_SCALE
#define B2C 0x0228 // 0.0337 * 2^LUX_SCALE
#define M2C 0x02c1 // 0.0430 * 2^LUX_SCALE

#define K3C 0x00c8 // 0.390 * 2^RATIO_SCALE
#define B3C 0x0253 // 0.0363 * 2^LUX_SCALE
#define M3C 0x0363 // 0.0529 * 2^LUX_SCALE

#define K4C 0x010a // 0.520 * 2^RATIO_SCALE
#define B4C 0x0282 // 0.0392 * 2^LUX_SCALE
#define M4C 0x03df // 0.0605 * 2^LUX_SCALE

#define K5C 0x014d // 0.65 * 2^RATIO_SCALE
#define B5C 0x0177 // 0.0229 * 2^LUX_SCALE
#define M5C 0x01dd // 0.0291 * 2^LUX_SCALE

#define K6C 0x019a // 0.80 * 2^RATIO_SCALE
#define B6C 0x0101 // 0.0157 * 2^LUX_SCALE
#define M6C 0x0127 // 0.0180 * 2^LUX_SCALE

#define K7C 0x029a // 1.3 * 2^RATIO_SCALE
#define B7C 0x0037 // 0.00338 * 2^LUX_SCALE
#define M7C 0x002b // 0.00260 * 2^LUX_SCALE

#define K8C 0x029a // 1.3 * 2^RATIO_SCALE
#define B8C 0x0000 // 0.000 * 2^LUX_SCALE
#define M8C 0x0000 // 0.000 * 2^LUX_SCALE

// 无浮点计算的Lux近似计算方程----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 -- 通道0初值
// unsigned int ch1 - raw channel value from channel 1 of TSL2560 -- 通道1初值
// unsigned int iType - package type (T or CS) -- 封装类型
//
// Return: unsigned int - the approximate illuminance (lux) -- 返回近似的Lux
//
//////////////////////////////////////////////////////////////////////////////

unsigned int CalculateLux(unsigned int iGain, unsigned int tInt, unsigned int ch0, unsigned int ch1, int iType)
{
//----------------------------------------------------------------------------
// first, scale the channel values depending on the gain and integration time 16X, 402mS is nominal.
// scale if integration time is NOT 402 msec
// 首先,根据增益和积分时间,衡量通道值
    unsigned long chScale;
    unsigned long channel1;
    unsigned long channel0;
     
    unsigned long ratio;
    unsigned long ratio1;
     
    unsigned int b, m;
     
    unsigned long temp;
     
    unsigned long lux;
     
    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 ?
    //unsigned int b, m;
    switch (iType)
    {
        case 0: // T, FN and CL 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;

    }

    //unsigned long temp;
    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);
}


//主函数
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "tsl2561.h"


int main(void)
{      
     unsigned int ch0, ch1, lux;
    delay_init();      
  
    uart_init(115200);
      
    IIC_Init();
      
    tsl2561_Init();  
      
    IIC_Start();
    while(1)
    {
        delay_ms(1500);
         
        ch0=Calculate_ch0(TSL2561_ReadOneByte(DATA0LOW),TSL2561_ReadOneByte(DATA0HIGH));
         
        ch1=Calculate_ch1(TSL2561_ReadOneByte(DATA1LOW),TSL2561_ReadOneByte(DATA1HIGH));
         
                        lux = CalculateLux(1, 2, ch0, ch1, 1);//2:假定不缩放;
         
         //Read_Light();
        printf("Light:%ul lux\r\n",lux);      
        delay_ms(1500);
        
    }
}

TSL2561调试草稿.zip

2.88 MB, 下载次数: 75

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

109

主题

5564

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10570
金钱
10570
注册时间
2017-2-18
在线时间
1913 小时
发表于 2018-6-1 10:05:19 | 显示全部楼层
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2019-7-29
在线时间
4 小时
发表于 2019-7-31 15:11:38 | 显示全部楼层
老哥 我想问 你读取的ID是多少?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-30 22:10

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表