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

2019-07-17 16:17发布

本帖最后由 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(" ",1);
    Delay_ms(2000);
    }
}

程序如上,但是无法读取数据,为什么呢?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
14条回答
dirtwillfly
1楼-- · 2019-07-17 17:36
观察过时序了吗?方便的话把时序波形贴出啦
xyz549040622
2楼-- · 2019-07-17 18:01
 精彩回答 2  元偷偷看……
裁定心生
3楼-- · 2019-07-17 23:29
 精彩回答 2  元偷偷看……
dongdong0071
4楼-- · 2019-07-18 05:20
我的2540的bh1750fvi的模拟iic调通了,可以给你看一下
豆腐块
5楼-- · 2019-07-18 08:48
对照datasheet,仔细查看看一下时序问题
迪卡
6楼-- · 2019-07-18 14:25
 精彩回答 2  元偷偷看……

一周热门 更多>