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;
} 请问这个程序能正常读取光照值么?最近也在调这块芯片,一直读到00FF,都想哭了。 回复【1楼】hefanghua
-----------------------------------------------------------------------
可以啊。这是调试成功了之后才发上来的,你看看你的代码细节问题,例如有没有少写了什么,然后就是延迟,适当的调节一下,很简单的其实 十分感谢,参考您的程序找到问题了。时序里面的主机接收ACK响应原来理解为从机发出,结果就是之前那样的错误。现在已能正常显示了,只是准不准有待检验。我用的是STC5A,汇编写的。keil的延时仿真不给力。时序的延时部分花了不少时间,后面干脆弄个变量,让它每秒自动增加才找到合适的延时时间。 MARK! 学习了 谢谢楼主 学习中,谢谢楼主 MARK!!!!!!!!!!!!!!!!!!1 学习了,谢谢LZ 楼主你好,我是一个zigbee的初学者,能发这份代码给我吗?我的邮箱是1179166553@qq.com.万分感谢。。。 mark…… 感谢楼主,学习中。。。。{:smile:} 麻烦你发个源代码给我吧,非常感谢啊。。邮箱807052919@qq.com 谁有啊,大家帮个忙啊。。 听说这个单片机 可以做ZigBee 大神们,请赐教啊。。 {:smile:} 谢谢楼主,这正是我需要的。 楼主啊楼主,我是用CC2530 COPY了你的程序 改了端口号。我怎么读起来还是跳不过去?ACK返回错误 感谢分享 感谢分享 留着再看以后用的 请问楼主一个很幼稚的问题 cc2530用什么软件编程? 本帖最后由 LBH 于 2013-8-29 11:08 编辑
编译时显示错误Fatal Error: cannot open source file<io.h>怎么解决
请问你用的是什么编译软件 本帖最后由 cygnushan 于 2014-4-13 22:00 编辑
hefanghua 发表于 2011-7-30 16:56
十分感谢,参考您的程序找到问题了。时序里面的主机接收ACK响应原来理解为从机发出,结果就是之前那样的错 ...
请问你调整是哪里的延时啊?我最近也在调BH1750的程序,读出来的数据一直是00FF,抓波形看时序也没问题
楼主,我是zigbee初学者,希望能指导下QQ51262861 赞 谢楼主分享 之前做过,现在加上协议栈后,就不能读了,郁闷中... cygnushan 发表于 2014-4-13 21:59
请问你调整是哪里的延时啊?我最近也在调BH1750的程序,读出来的数据一直是00FF,抓波形看时序也没问题
...
你好,我单个2530读取1750的数据没有问题,加入协议栈后始终是得到0xff,请问你的问题解决了吗?
页:
[1]