leon_wf 发表于 2011-7-21 11:41:52

CC2530 模拟I2C的BH1750FVI光照传感器的驱动程序

第二次发代码,希望能帮助到有需要的朋友,花了我好久才搞通,其中各种错误呜呜~~
/******************************************
描述;模拟I2C,光照传感器驱动代码
作者;leon_wf
时间;2011.7.21

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

#include <stdio.h>
#include <io.h>
#include "cc2530_sfr.h"




#define st(x)      do { x } while (__LINE__ == -1)
#define HAL_IO_SET(port, pin, val)      HAL_IO_SET_PREP(port, pin, val)
#define HAL_IO_SET_PREP(port, pin, val)   st( P##port##_##pin## = val; )
#define HAL_IO_GET(port, pin)   HAL_IO_GET_PREP( port,pin)
#define HAL_IO_GET_PREP(port, pin)   ( P##port##_##pin)

#define LIGHT_SCK_0()         HAL_IO_SET(1,4,0)
#define LIGHT_SCK_1()         HAL_IO_SET(1,4,1)
#define LIGHT_DTA_0()         HAL_IO_SET(1,3,0)
#define LIGHT_DTA_1()         HAL_IO_SET(1,3,1)

#define LIGHT_DTA()                HAL_IO_GET(1,3)
#define LIGHT_SCK()          HAL_IO_GET(1,4)

#define SDA_W() (P1DIR |=BV(3))
#define SDA_R() (P1DIR &=~BV(3) )
#define delay() {asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");}



                        /****command********/
#define DPOWR0X00         //断电
#define POWER0X01         //SHANG DIAN
#define RESET    0X07         //CHONG ZHI
#define CHMODE0X10      //连续H分辨率
#define CHMODE2 0X11         //连续H分辨率2
#define CLMODE   0X13         //连续低分辨
#define H1MODE   0X20         //一次H分辨率
#define H1MODE2 0X21          //一次H分辨率2
#define L1MODE    0X23         //一次L分辨率模式

void delay_nus(void)
{       
        int i;
        int n=100;
        for(i=0;i<n;i++)//延迟32NOP为1US
                {
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
}
}

void delay_nms(int n)
{
        while(n--)
                {
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
        asm("nop");asm("nop");asm("nop");asm("nop");
                }
}





/****************************
启动I2C
数据在时钟高电平的时候从高往低跃变

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

void start_i2c(void)
{
        SDA_W() ;
        //LIGHT_SCK_0() ;
        //delay_nus(20);
        LIGHT_DTA_1();
        //delay_nus();
        LIGHT_SCK_1() ;
        delay_nus() ;
        LIGHT_DTA_0() ;
        delay_nus();
        LIGHT_SCK_0() ;
        delay_nus();

        //delay();
}


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

结束I2C

数据在时钟高电平的时候从低往高跃变
********************************/

void stop_i2c(void)
{
        SDA_W() ;
        LIGHT_DTA_0() ;
        delay_nus();
        LIGHT_SCK_1() ;
        delay_nus();
        LIGHT_DTA_1() ;
        delay_nus();
        LIGHT_SCK_0() ;
        delay_nus();
       
}



/******************************
发送字节并且判断是否收到ACK
当收到ACK返回为0,否则返回为1

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


char i2c_send(unsigned char val)               
{
        int i;
        int ack;
        char error=0;
        SDA_W();
        for(i=0x80;i>0;i/=2)
                {
                        if(val&i)
                                LIGHT_DTA_1();
                        else
                                LIGHT_DTA_0();
                        delay_nus();
                        LIGHT_SCK_1() ;
                        delay_nus();
                        LIGHT_SCK_0() ;
                        delay_nus();
                               
                }
       
        LIGHT_DTA_1();
        SDA_R();
        //delay_nus();
        LIGHT_SCK_1() ;
        delay_nus();
        if(LIGHT_DTA())
                error=1;
        delay_nus();
        LIGHT_SCK_0() ;
        return error;
       
}

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

读取I2C的字节,并且发送ACK
当参数为1的时候发送一个ACK(低电平)


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

char i2c_read(char ack)
{
        int i;
        char val=0;
        LIGHT_DTA_1();
        //SDA_R();
        for(i=0x80;i>0;i/=2)
                {
                       
                        LIGHT_SCK_1() ;
                        delay_nus();
                        SDA_R();
                        if(LIGHT_DTA())
                                val=(val|i);
                        delay_nus();
                        LIGHT_SCK_0() ;
                        delay_nus();
                       
                       
                }
        SDA_W();
        if(ack)
                LIGHT_DTA_0();
        else
                LIGHT_DTA_1();
        delay_nus();
        LIGHT_SCK_1() ;
        delay_nus();
        LIGHT_SCK_0() ;
        LIGHT_DTA_1();
        return val;
       
}






/**************************
测量光张强度

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


unsigned char
get_light(void)
{       
        unsigned char ack1=1;
        unsigned char ack2=1;
        unsigned char ack3=1;
        unsigned char ack4=1;
        unsigned char ack5=1;
        unsigned char ack6=1;
        unsigned char ack7=1;
        unsigned char ack8=1;
       
        unsigned char t0;
        unsigned char t1;
        unsigned char t;
        int i;
        P1DIR|=BV(4);
        delay_nms(200);

                start_i2c();
                ack1=i2c_send(0x46);
                if(ack1)
                        return 255;
                ack2=i2c_send(0x01);
                if(ack2)
                        return 254;
                stop_i2c();         //init
                start_i2c();
                ack3=i2c_send(0x46);
                if(ack3)
                        return 253;
                ack4=i2c_send(0x01);
                if(ack4)
                        return 252;
                stop_i2c();//power
                start_i2c();
                ack5=i2c_send(0x46);
                if(ack5)
                        return 251;
                ack6=i2c_send(0x10);
                if(ack6)
                        return 250;
                stop_i2c();//发送测量命令
                       
       
        delay_nms(1500);
        start_i2c();
       
                        ack7=i2c_send(0x47);   //发送地址
                       
                                if(ack7)
                                        return 249;
                       
        t0=i2c_read(1);
        t1=i2c_read(0);
        stop_i2c();
        t=(((t0<<8)|t1)/1.2);
        return t;
       
}

hefanghua 发表于 2011-7-22 11:49:35

请问这个程序能正常读取光照值么?最近也在调这块芯片,一直读到00FF,都想哭了。

leon_wf 发表于 2011-7-25 11:00:32

回复【1楼】hefanghua
-----------------------------------------------------------------------

可以啊。这是调试成功了之后才发上来的,你看看你的代码细节问题,例如有没有少写了什么,然后就是延迟,适当的调节一下,很简单的其实

hefanghua 发表于 2011-7-30 16:56:52

十分感谢,参考您的程序找到问题了。时序里面的主机接收ACK响应原来理解为从机发出,结果就是之前那样的错误。现在已能正常显示了,只是准不准有待检验。我用的是STC5A,汇编写的。keil的延时仿真不给力。时序的延时部分花了不少时间,后面干脆弄个变量,让它每秒自动增加才找到合适的延时时间。

changhui0222 发表于 2011-12-19 15:30:13

MARK!

dreamfly625 发表于 2012-4-28 18:22:28

学习了 谢谢楼主

ksh84222 发表于 2012-5-1 08:34:22

学习中,谢谢楼主

linhui2012 发表于 2012-5-11 12:06:21

MARK!!!!!!!!!!!!!!!!!!1

ksh84222 发表于 2012-7-5 21:56:03

学习了,谢谢LZ

xuzijian 发表于 2012-10-31 10:23:28

楼主你好,我是一个zigbee的初学者,能发这份代码给我吗?我的邮箱是1179166553@qq.com.万分感谢。。。

风浪 发表于 2012-12-23 21:38:57

mark……

bm6520 发表于 2013-3-1 20:54:29

感谢楼主,学习中。。。。{:smile:}

liujianbo688 发表于 2013-4-9 15:18:38

麻烦你发个源代码给我吧,非常感谢啊。。邮箱807052919@qq.com

liujianbo688 发表于 2013-4-10 08:49:51

谁有啊,大家帮个忙啊。。

电子爱好者_MCU 发表于 2013-4-10 10:14:48

听说这个单片机 可以做ZigBee

liujianbo688 发表于 2013-4-10 15:39:59

大神们,请赐教啊。。

YIZEDXL 发表于 2013-4-21 20:34:02

{:smile:} 谢谢楼主,这正是我需要的。

122108323 发表于 2013-5-10 20:37:52

楼主啊楼主,我是用CC2530 COPY了你的程序 改了端口号。我怎么读起来还是跳不过去?ACK返回错误

lidreamer 发表于 2013-6-4 01:27:15

感谢分享

jesse2012 发表于 2013-6-4 15:02:22

感谢分享 留着再看以后用的

zhcj66 发表于 2013-6-8 09:41:34

请问楼主一个很幼稚的问题   cc2530用什么软件编程?

LBH 发表于 2013-8-28 20:15:25

本帖最后由 LBH 于 2013-8-29 11:08 编辑

编译时显示错误Fatal Error: cannot open source file<io.h>怎么解决


LBH 发表于 2013-8-30 01:15:59

请问你用的是什么编译软件

cygnushan 发表于 2014-4-13 21:59:21

本帖最后由 cygnushan 于 2014-4-13 22:00 编辑

hefanghua 发表于 2011-7-30 16:56
十分感谢,参考您的程序找到问题了。时序里面的主机接收ACK响应原来理解为从机发出,结果就是之前那样的错 ...

请问你调整是哪里的延时啊?我最近也在调BH1750的程序,读出来的数据一直是00FF,抓波形看时序也没问题



慢慢懂 发表于 2014-7-15 15:12:51

楼主,我是zigbee初学者,希望能指导下QQ51262861

yangxx 发表于 2014-10-4 10:32:01

赞 谢楼主分享

Samzzt 发表于 2015-1-16 16:52:18

之前做过,现在加上协议栈后,就不能读了,郁闷中...

liude2006 发表于 2018-5-9 14:39:43

cygnushan 发表于 2014-4-13 21:59
请问你调整是哪里的延时啊?我最近也在调BH1750的程序,读出来的数据一直是00FF,抓波形看时序也没问题

...

你好,我单个2530读取1750的数据没有问题,加入协议栈后始终是得到0xff,请问你的问题解决了吗?
页: [1]
查看完整版本: CC2530 模拟I2C的BH1750FVI光照传感器的驱动程序