打印

有关CC2530 模拟I2C读取bh1750数据的问题

[复制链接]
3794|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
JAWN|  楼主 | 2015-10-12 19:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 JAWN 于 2015-10-12 19:55 编辑

#include "iocc2530.h"
#include "UART.h"
//------------------------------------
#define uint unsigned int
#define uchar unsigned char   //数据类型宏定义

void BH1750_Start(void);      //起始信号
void BH1750_Stop(void);       //停止信号
void BH1750_SendACK(void);    //发送应答ACK
uchar BH1750_SendNCK(void) ;   //接收应答ACK
uchar RcvByte();              //I2C读
void  SendByte(unsigned char c);  //IIC单个字节写
uchar ISendByte(uchar sla,uchar c);
uchar IRcvStrExt(uchar sla,uchar *s,uchar no);        //连续的读取内部寄存器数据
void Init_BH1750();          //初始化
void conversion(uint temp_data) ;    //数据
void Delay_us(uint timeout);
void Delay_ms(uint Time);//n ms延时


#define DPOWR  0X00         //断电
#define POWER  0X01         //SHANG DIAN
#define RESET    0X07       //CHONG ZHI
#define CHMODE  0X10        //连续H分辨率
#define CHMODE2 0X11        //连续H分辨率2
#define CLMODE   0X13       //连续低分辨
#define H1MODE   0X20       //一次H分辨率
#define H1MODE2 0X21        //一次H分辨率2
#define L1MODE    0X23      //一次L分辨率模式
#define  SCL P1_6      //IIC时钟引脚定义
#define  SDA P1_5     //IIC数据引脚定义
#define         SlaveAddress   0x46 //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
                              //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A
typedef   unsigned char BYTE;
typedef   unsigned short WORD;
uchar ack;
uchar buf[2];                         //接收数据缓存区  
uint sun;
uchar ge,shi,bai,qian,wan;            //显示变量
float s;

//-----------------------------------

void Initial() //系统初始化
{
  CLKCONCMD = 0x80;      //选择32M振荡器
  while(CLKCONSTA&0x40); //等待晶振稳定
  InitUart();         //串口初始化
  //P1SEL &= 0xfb;         //DS18B20的io口初始化
}

/****************************
        延时函数
*****************************/
void Delay_us(uint timeout) //1 us延时uint16 timeout )
{
  while (timeout--)
  {
    asm("NOP");
    asm("NOP");
    asm("NOP");
  }
}


void Delay_ms(uint Time)//n ms延时
{
  unsigned char i;
  while(Time--)
  {
    for(i=0;i<100;i++)
     Delay_us(10);
  }
}
//*********************************************************

/**************************************
起始信号
**************************************/
void BH1750_Start()                    //起始信号
{
    P1DIR|=0X60;
    SDA = 1;                    //拉高数据线
    SCL = 1;                    //拉高时钟线
    Delay_us(5);                 //延时
    SDA = 0;                    //产生下降沿
    Delay_us(5);                 //延时
    SCL = 0;                    //拉低时钟线
}
/**************************************
停止信号
**************************************/
void BH1750_Stop()
{
    P1DIR|=0X60;
    SDA = 0;                    //
    SCL = 1;                    //拉高时钟线
    Delay_us(5);               //延时
    SDA = 1;                    //产生上升沿
    Delay_us(5);                //延时
}

/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void BH1750_SendACK()
{
    P1DIR|=0X60;
    SDA = ack;                  //写应答信号
    SCL = 1;                    //拉高时钟线
    Delay_us(5);                //延时
    SCL = 0;                    //拉低时钟线
    Delay_us(5);                //延时
}
uchar BH1750_SendNCK()
{
    P1DIR|=0X60;
    SCL = 1;                    //拉高时钟线
    Delay_us(5);                //延时
    CY = SDA;                   //读应答信号
    SCL = 0;                    //拉低时钟线
    Delay_us(5);                 //延时
    return CY;
}


/*----------------------------------------------------------------              
I2C写入一个8位二进制数,高位在前低位在后
------------------------------------------------------------------*/
void  SendByte(unsigned char c)
{
unsigned char BitCnt;
P1DIR|=0X60;
for(BitCnt=0;BitCnt<8;BitCnt++)  //要传送的数据长度为8位
    {
     if((c<<BitCnt)&0x80) SDA=CY;   //判断发送位
       else  SDA=0;               
     SCL=1;               //置时钟线为高,通知被控器开始接收数据位
     Delay_us(5);         //保证时钟高电平周期大于4μ      
     SCL=0;
    }   
    P1DIR&=0Xdf;          //8位发送完后释放数据线,准备接收应答位
    SCL=1;
    Delay_us(2);
    if(SDA==1)ack=0;     
       else ack=1;        //判断是否接收到应答信号,"1":没有
    SCL=0;
}


/*******************************************************************
I2C读取一个8位二进制数,也是高位在前低位在后  
****************************************************************/        
uchar RcvByte()
{
  unsigned char retc;
  unsigned char BitCnt;
   retc=0;
   P1DIR&=0Xdf;         //置数据线为输入方式
  for(BitCnt=0;BitCnt<8;BitCnt++)
      {      
        SCL=0;       //置时钟线为低,准备接收数据
        Delay_us(5); //时钟低电平周期大于4.7us
        SCL=1;
      Delay_us(2);
        retc=retc<<1;
        if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中
  Delay_us(2);
      }
  SCL =0;   
  return(retc);
}
/*******************************************************************
                 向无子地址器件发送字节数据函数               
函数原型: bit  ISendByte(uchar sla,ucahr c);  
功能:     从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.
          如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
uchar ISendByte(uchar sla,uchar c)
{
   BH1750_Start();               //起始信号
   SendByte(sla);             //发送设备地址+写信号
   if(ack==0)return(0);
   SendByte(c);               //发送数据
   if(ack==0)return(0);
   BH1750_Stop();                //结束总线
   return(1);
}
//*********************************************************
//连续读出BH1750内部数据
//*********************************************************
uchar IRcvStrExt(uchar sla,uchar *s,uchar no)
{   uchar i;        
    BH1750_Start();                         //起始信号
    SendByte(sla+1);        //发送设备地址+读信号
    if(ack==0)return(0);
      for (i=0; i<5; i++)                      //连续读取6个地址数据,存储中BUF
      {
        buf=RcvByte();      
        if(i==5)
        {
           BH1750_SendNCK();              //最后一个数据需要回NOACK
        }
        else
        {               
          BH1750_SendACK();               //回应ACK
        }
      }
    BH1750_Stop();                           //停止信号
    Delay_ms(5);
    return(1);
}



//初始化BH1750,根据需要请参考pdf进行修改****
void Init_BH1750()
{
   P1DIR|=0X00;
   ISendByte(0x46,0x01);  
}

//*********************************************************
void conversion(uint temp_data)  //  数据转换出 个,十,百,千,万
{  
    wan=temp_data/10000+0x30 ;
    temp_data=temp_data%10000;   //取余运算
     qian=temp_data/1000+0x30 ;
    temp_data=temp_data%1000;    //取余运算
     bai=temp_data/100+0x30  ;
    temp_data=temp_data%100;     //取余运算
     shi=temp_data/10+0x30 ;
    temp_data=temp_data%10;     //取余运算
     ge=temp_data+0x30;         
}

/****************************************************************************
* 程序入口函数
****************************************************************************/
void main()
{   
    uchar light[5];
    uchar *p=buf;
    Delay_ms(100);            //延时100ms        
    Init_BH1750();       //初始化BH1750
    InitUart();              //串口初始化
   
    while(1)
    {
      memset(light, 0, 5);
      
      ISendByte(0x46,0x01);   // power on
      ISendByte(0x46,0X10);   // H- resolution mode
      Delay_ms(180);              //延时180ms
      IRcvStrExt(0x46,p,2);       //连续读出数据,存储在BUF中
      sun=buf[0];
      sun=(sun<<8)+buf[1];//合成数据,即光照数据  
      s=(float)sun/1.2;   
      conversion((uint)s);         //计算数据和显示
      light[0]=wan;
      light[1]=qian;
      light[2]=bai;
      light[3]=shi;
      light[4]=ge;
      UartSendString(light,5);
    /*UartSendString(qian,1);
    UartSendString(bai,1);
    UartSendString(shi,1);
    UartSendString(ge,1);*/
    UartSendString("\n",1);
    Delay_ms(2000);
    }
}

程序如上,但是无法读取数据,为什么呢?

相关帖子

沙发
dirtwillfly| | 2015-10-12 22:41 | 只看该作者
观察过时序了吗?方便的话把时序波形贴出啦

使用特权

评论回复
板凳
xyz549040622| | 2015-10-14 19:27 | 只看该作者
楼主不是找了好几个例程么,照着例程改吧。注意延时函数的准确率,IO的初始化,实在不行,对着datasheet看你的模拟时序的问题。

使用特权

评论回复
地板
裁定心生| | 2015-10-31 14:40 | 只看该作者
对着时序图,延时加大点试试。

使用特权

评论回复
5
dongdong0071| | 2015-11-8 19:33 | 只看该作者
我的2540的bh1750fvi的模拟iic调通了,可以给你看一下

使用特权

评论回复
6
豆腐块| | 2015-11-9 20:02 | 只看该作者
对照datasheet,仔细查看看一下时序问题

使用特权

评论回复
7
迪卡| | 2015-11-10 18:56 | 只看该作者
IIC通信出问题一般都是时钟和时序问题

使用特权

评论回复
8
可可球| | 2015-11-12 19:33 | 只看该作者
楼主应该参照着例程改

使用特权

评论回复
9
举个小栗子i| | 2017-4-26 11:06 | 只看该作者
楼主在么,我也遇到这个问题,请问最后是怎么解决的呢

使用特权

评论回复
10
dirtwillfly| | 2017-4-27 08:07 | 只看该作者
举个小栗子i 发表于 2017-4-26 11:06
楼主在么,我也遇到这个问题,请问最后是怎么解决的呢

楼主很久没出现了。建议重新发帖

使用特权

评论回复
11
tongbu2015| | 2017-4-27 22:53 | 只看该作者
这个归根到底的还是i2c总线的控制问题

使用特权

评论回复
12
chuntian2016| | 2017-4-29 11:46 | 只看该作者
I2C总线的注意时钟源的配置的

使用特权

评论回复
13
vibra2016| | 2017-4-29 13:24 | 只看该作者
这个分辨率的设计还是蛮重要的

使用特权

评论回复
14
angerbird| | 2017-4-29 15:03 | 只看该作者
这个用逻辑分析仪调试看下的

使用特权

评论回复
15
comeon201208| | 2017-4-30 11:40 | 只看该作者
这个关于I2C总线操作的很不错的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

38

主题

110

帖子

1

粉丝