搜索
bottom↓
回复: 28

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

[复制链接]

出0入0汤圆

发表于 2011-7-21 11:41:52 | 显示全部楼层 |阅读模式
第二次发代码,希望能帮助到有需要的朋友,花了我好久才搞通,其中各种错误呜呜~~
/******************************************
描述;模拟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 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分辨率模式

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;
       
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2011-7-22 11:49:35 | 显示全部楼层
请问这个程序能正常读取光照值么?最近也在调这块芯片,一直读到00FF,都想哭了。

出0入0汤圆

 楼主| 发表于 2011-7-25 11:00:32 | 显示全部楼层
回复【1楼】hefanghua
-----------------------------------------------------------------------

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

出0入0汤圆

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

出0入0汤圆

发表于 2011-12-19 15:30:13 | 显示全部楼层
MARK!

出0入0汤圆

发表于 2012-4-28 18:22:28 | 显示全部楼层
学习了 谢谢楼主

出0入0汤圆

发表于 2012-5-1 08:34:22 | 显示全部楼层
学习中,谢谢楼主

出0入0汤圆

发表于 2012-5-11 12:06:21 | 显示全部楼层
MARK!!!!!!!!!!!!!!!!!!1

出0入0汤圆

发表于 2012-7-5 21:56:03 | 显示全部楼层
学习了,谢谢LZ

出0入0汤圆

发表于 2012-10-31 10:23:28 | 显示全部楼层
楼主你好,我是一个zigbee的初学者,能发这份代码给我吗?我的邮箱是1179166553@qq.com.万分感谢。。。

出0入0汤圆

发表于 2012-12-23 21:38:57 | 显示全部楼层
mark……

出0入0汤圆

发表于 2013-3-1 20:54:29 | 显示全部楼层
感谢楼主,学习中。。。。

出0入0汤圆

发表于 2013-4-9 15:18:38 | 显示全部楼层
麻烦你发个源代码给我吧,非常感谢啊。。邮箱807052919@qq.com

出0入0汤圆

发表于 2013-4-10 08:49:51 | 显示全部楼层
谁有啊,大家帮个忙啊。。

出0入0汤圆

发表于 2013-4-10 10:14:48 | 显示全部楼层
听说这个单片机 可以做ZigBee

出0入0汤圆

发表于 2013-4-10 15:39:59 | 显示全部楼层
大神们,请赐教啊。。

出0入0汤圆

发表于 2013-4-21 20:34:02 | 显示全部楼层
谢谢楼主,这正是我需要的。

出0入0汤圆

发表于 2013-5-10 20:37:52 | 显示全部楼层
楼主啊楼主,我是用CC2530 COPY了你的程序 改了端口号。我怎么读起来还是跳不过去?ACK返回错误

出0入0汤圆

发表于 2013-6-4 01:27:15 | 显示全部楼层
感谢分享

出0入0汤圆

发表于 2013-6-4 15:02:22 | 显示全部楼层
感谢分享 留着再看以后用的

出0入53汤圆

发表于 2013-6-8 09:41:34 | 显示全部楼层
请问楼主一个很幼稚的问题   cc2530用什么软件编程?

出0入0汤圆

发表于 2013-8-28 20:15:25 | 显示全部楼层
本帖最后由 LBH 于 2013-8-29 11:08 编辑

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


出0入0汤圆

发表于 2013-8-30 01:15:59 | 显示全部楼层
请问你用的是什么编译软件

出0入0汤圆

发表于 2014-4-13 21:59:21 | 显示全部楼层
本帖最后由 cygnushan 于 2014-4-13 22:00 编辑
hefanghua 发表于 2011-7-30 16:56
十分感谢,参考您的程序找到问题了。时序里面的主机接收ACK响应原来理解为从机发出,结果就是之前那样的错 ...


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



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-7-15 15:12:51 | 显示全部楼层
楼主,我是zigbee初学者,希望能指导下QQ51262861

出0入0汤圆

发表于 2014-10-4 10:32:01 | 显示全部楼层
赞 谢楼主分享

出0入0汤圆

发表于 2015-1-16 16:52:18 | 显示全部楼层
之前做过,现在加上协议栈后,就不能读了,郁闷中...

出0入0汤圆

发表于 2018-5-9 14:39:43 | 显示全部楼层
cygnushan 发表于 2014-4-13 21:59
请问你调整是哪里的延时啊?我最近也在调BH1750的程序,读出来的数据一直是00FF,抓波形看时序也没问题

...

你好,我单个2530读取1750的数据没有问题,加入协议栈后始终是得到0xff,请问你的问题解决了吗?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 14:06

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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