OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2793|回复: 8

光传感器程序不好用,求大神指正

[复制链接]

11

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2016-4-3
在线时间
41 小时
发表于 2016-4-14 10:40:52 | 显示全部楼层 |阅读模式
10金钱
最近在用stm32的I2C总线调光传感器的一个程序,实在调不好了,求大神指教。光传感器应该是BH1750,就是5个接口,有使能。程序如下
光传感器程序
#include "BH1750.h"
float result=0;

u8 BH1750_ReadOneByte(u8 addr)
{
        u8 temp=0;

        I2C_Start();
       
       
                I2C_Send_Byte(0x94);
                I2C_Wait_Ack();
                I2C_Send_Byte(addr);        //addr是内部寄存器地址
       
                I2C_Wait_Ack();


        I2C_Start();
        I2C_Send_Byte(0x95);
        I2C_Wait_Ack();

        temp=I2C_Read_Byte(0); //  0   ′ú±í NACK
        I2C_NAck();
        I2C_Stop();
       
        return temp;       
}

void BH1750_WriteOneByte(u8 addr,u8 dt)
{
        I2C_Start();


                I2C_Send_Byte(0x94);
                I2C_Wait_Ack();
                I2C_Send_Byte(addr);        //·¢Ëíêy¾YμØÖ·¸ßλ
       


        I2C_Wait_Ack();

        I2C_Send_Byte(dt);
        I2C_Wait_Ack();
        I2C_Stop();

        delay_ms(10);
}

void BH1750_WriteTwoByte(u8 addr,u16 dt)
{
        I2C_Start();

        I2C_Send_Byte(0x94);
                I2C_Wait_Ack();
                I2C_Send_Byte(addr);        //·¢Ëíêy¾YμØÖ·


        I2C_Wait_Ack();

        I2C_Send_Byte(dt>>8);
        I2C_Wait_Ack();

        I2C_Send_Byte(dt&0xFF);
        I2C_Wait_Ack();

        I2C_Stop();

        delay_ms(10);
}
void BH1750_INIT(void)
{
        I2C_INIT();
        I2C_Start();
        GPIOE->BSRR=GPIO_Pin_0;
  BH1750_WriteOneByte(0x04,0x00);
       
}
float BH1750_celiang(void)
{
        u8 i;
        u32 a;
  for(i=0;i<4;i++)
        {
                a|=BH1750_ReadOneByte(i);
                delay_ms(400);
                a<<=8;
        }
        a=78;
        result=a/1.2;
        return result;
}

I2c程序,这是我直接改的例程,应该没错
#include "I2C.h"

/****************************************************************************
* Function Name  : IIC_Config
* Description    : 3&#245;ê&#188;&#187;ˉGPIO.
* Input          : None
* Output         : None
* Return         : None
****************************************************************************/
void I2C_INIT()
{
        GPIO_InitTypeDef GPIO_InitStructure;       
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

        GPIO_InitStructure.GPIO_Pin=I2C_SCL|I2C_SDA;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB,&GPIO_InitStructure);

        I2C_SCL_H;
        I2C_SDA_H;
}

/*******************************************************************************
* oˉ êy &#195;&#251;         : I2C_SDA_OUT
* oˉêy1|&#196;ü                   : SDAê&#228;3&#246;&#197;&#228;&#214;&#195;          
* ê&#228;    è&#235;         : &#206;T
* ê&#228;    3&#246;         : &#206;T
*******************************************************************************/
void I2C_SDA_OUT()
{
    GPIO_InitTypeDef GPIO_InitStructure;       
       
        GPIO_InitStructure.GPIO_Pin=I2C_SDA;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB,&GPIO_InitStructure);
}

/*******************************************************************************
* oˉ êy &#195;&#251;         : I2C_SDA_IN
* oˉêy1|&#196;ü                   : SDAê&#228;è&#235;&#197;&#228;&#214;&#195;          
* ê&#228;    è&#235;         : &#206;T
* ê&#228;    3&#246;         : &#206;T
*******************************************************************************/
void I2C_SDA_IN(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;       
       
        GPIO_InitStructure.GPIO_Pin=I2C_SDA;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//&#207;&#194;à-ê&#228;3&#246;
        GPIO_Init(GPIOB,&GPIO_InitStructure);
}

//2úéú&#198;eê&#188;D&#197;o&#197;
void I2C_Start(void)
{
    I2C_SDA_OUT();
       
        I2C_SDA_H;
        I2C_SCL_H;
        delay_us(5);
        I2C_SDA_L;
        delay_us(6);
        I2C_SCL_L;
}

//2úéúí£&#214;1D&#197;o&#197;
void I2C_Stop(void)
{
   I2C_SDA_OUT();

   I2C_SCL_L;
   I2C_SDA_L;
   I2C_SCL_H;
   delay_us(6);
   I2C_SDA_H;
   delay_us(6);
}

//&#214;÷&#187;ú2úéúó|′eD&#197;o&#197;ACK
void I2C_Ack(void)
{
   I2C_SCL_L;
   I2C_SDA_OUT();
   I2C_SDA_L;
   delay_us(2);
   I2C_SCL_H;
   delay_us(5);
   I2C_SCL_L;
}

//&#214;÷&#187;ú2&#187;2úéúó|′eD&#197;o&#197;NACK
void I2C_NAck(void)
{
   I2C_SCL_L;
   I2C_SDA_OUT();
   I2C_SDA_H;
   delay_us(2);
   I2C_SCL_H;
   delay_us(5);
   I2C_SCL_L;
}
//μè′y′ó&#187;úó|′eD&#197;o&#197;
//·μ&#187;&#216;&#214;μ£o1 &#189;óê&#213;ó|′eê§°ü
//                  0 &#189;óê&#213;ó|′e3é1|
u8 I2C_Wait_Ack(void)
{
        u8 tempTime=0;

        I2C_SDA_IN();

        I2C_SDA_H;
        delay_us(1);
        I2C_SCL_H;
        delay_us(1);

        while(GPIO_ReadInputDataBit(GPIO_I2C,I2C_SDA))
        {
                tempTime++;
                if(tempTime>250)
                {
                        I2C_Stop();
                        return 1;
                }         
        }

        I2C_SCL_L;
        return 0;
}
//I2C ·¢&#203;íò&#187;&#184;&#246;×&#214;&#189;ú
void I2C_Send_Byte(u8 txd)
{
        u8 i=0;

        I2C_SDA_OUT();
        I2C_SCL_L;//à-μíê±&#214;ó&#191;aê&#188;êy&#190;Y′&#171;ê&#228;

        for(i=0;i<8;i++)
        {
                if((txd&0x80)>0) //0x80  1000 0000
                        I2C_SDA_H;
                else
                        I2C_SDA_L;

                txd<<=1;
                I2C_SCL_H;
                delay_us(2); //·¢&#203;íêy&#190;Y
                I2C_SCL_L;
                delay_us(2);
        }
}

//I2C &#182;áè&#161;ò&#187;&#184;&#246;×&#214;&#189;ú

u8 I2C_Read_Byte(u8 ack)
{
   u8 i=0,receive=0;

   I2C_SDA_IN();
   for(i=0;i<8;i++)
   {
                   I2C_SCL_L;
                delay_us(2);
                I2C_SCL_H;
                receive<<=1;
                if(GPIO_ReadInputDataBit(GPIO_I2C,I2C_SDA))
                   receive++;
                delay_us(1);       
   }

           if(ack==0)
                   I2C_NAck();
        else
                I2C_Ack();

        return receive;
}
主程序

void GPIO_Config(void);
int main(void)
{
        float a;

       
        GPIO_Config();//&#182;&#203;&#191;ú3&#245;ê&#188;&#187;ˉ
        BH1750_INIT();//i2c3&#245;ê&#188;&#187;ˉ
       
        delay_ms(5);
        while(1)
        {
        a=BH1750_celiang();
                if(a>0)
                {
                        GPIO_SetBits(GPIOE,GPIO_Pin_13);
                        delay_ms(500);
                        GPIO_SetBits(GPIOE,GPIO_Pin_14);
                        delay_ms(500);
                }

}

最佳答案

查看完整内容[请看2#楼]

求大神解答,第一次做东西,这个程序已经搞了一天了,要炸了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

11

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2016-4-3
在线时间
41 小时
 楼主| 发表于 2016-4-14 10:40:53 | 显示全部楼层
求大神解答,第一次做东西,这个程序已经搞了一天了,要炸了
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11553
金钱
11553
注册时间
2014-4-1
在线时间
1317 小时
发表于 2016-4-14 11:21:45 | 显示全部楼层

按照通信过程,一步步查时序。

比如:
主机连续发送第一个字节,然后用示波器看波形,是否符合;
然后一步步往后走。

程序搞一天,很正常。


回复

使用道具 举报

15

主题

317

帖子

0

精华

高级会员

Rank: 4

积分
863
金钱
863
注册时间
2015-2-12
在线时间
354 小时
发表于 2016-4-14 11:23:53 | 显示全部楼层
“难调”是指程序调不通?还是检测的数据差距太大?
回复

使用道具 举报

11

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2016-4-3
在线时间
41 小时
 楼主| 发表于 2016-4-14 11:48:07 | 显示全部楼层
csmjmcc 发表于 2016-4-14 11:23
“难调”是指程序调不通?还是检测的数据差距太大?

是指读不出数来,一直返回的是0
回复

使用道具 举报

11

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2016-4-3
在线时间
41 小时
 楼主| 发表于 2016-4-14 11:50:17 | 显示全部楼层
xuande 发表于 2016-4-14 11:21
按照通信过程,一步步查时序。

比如:

可是这个没办法吧,这个东西不会弄啊
回复

使用道具 举报

11

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2016-4-3
在线时间
41 小时
 楼主| 发表于 2016-4-14 11:54:28 | 显示全部楼层
zhuri 发表于 2016-4-14 10:40
求大神解答,第一次做东西,这个程序已经搞了一天了,要炸了

这个帖子不好,调程序的东西也发上来了,我另外发了一个,期待大神的解答
回复

使用道具 举报

0

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2015-6-23
在线时间
10 小时
发表于 2016-4-14 12:47:44 | 显示全部楼层
按照我调温度传感器的经验,这样子的传感器一般读数都比较慢,上电后,要加延时,设置 以后也要加延时。读数的时候最好也加。
回复

使用道具 举报

11

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2016-4-3
在线时间
41 小时
 楼主| 发表于 2016-4-14 14:58:41 | 显示全部楼层
pldjn 发表于 2016-4-14 12:47
按照我调温度传感器的经验,这样子的传感器一般读数都比较慢,上电后,要加延时,设置 以后也要加延时。读 ...

我在读数时加了180ms的延时,在上电之后也加了2us的延时啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 01:16

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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