OpenEdv-开源电子网

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

STM32使用模拟IIC控制BH1750实验程序,printf输出

[复制链接]

2

主题

6

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2018-1-2
在线时间
7 小时
发表于 2018-3-4 15:12:54 | 显示全部楼层 |阅读模式
本帖最后由 spl928 于 2018-3-4 15:12 编辑

一个小小的IIC程序整了好几天,从网上查了资料,终于调试好了,不过其中仍然有不懂得地方,以后再慢慢琢磨。
主要有两个地方:(有知道的帮忙释疑下啊)
(1)比如IIC.c文件中,IIC_Send_Byte()函数中有四句话(我自己加的,原子哥的IIC.c中没有),有或者没有会对程序造成很大的影响。
(2)读书只能读到54612.5lux,读不到65535,这是因为读完数据后除以1.2导致的。

先放上我已经调试ok的程序,IIC.c大部分跟原子哥的是一致的,但有些地方改了。
方法1和方法2,转换的数据一个用数组表示,一个用字符表示,差不多。
方法3,把转换数据的函数放到了外面。
这是main.c函数
[mw_shl_code=applescript,true]int main(void)
{
  //float data;
        delay_init();                     //延时函数初始化         
        uart_init(9600);
        BH1750_Init();
        
                /****方法一:使用此while循环****/
while(1)
{

          //Single_Write_BH1750(0x07);    //Power On
          BH1750_ReadContinuous1();
                 delay_ms(200);


                printf("light:");
                printf("%5.1f \r",lux);   
                printf("lux\r\n");    //注意此处的lux仅仅代表单位
                delay_ms(500);
                delay_ms(500);
        
}
        
        /****方法二:使用此while循环****/
// while(1)
// {

//           //Single_Write_BH1750(0x07);    //Power On
//           BH1750_ReadContinuous2();
//                  delay_ms(200);
//                  Conversion();         

//                 printf("light:");
//                 printf("%5.1f \r",lux);   
//                 printf("lux\r\n");    //注意此处的lux仅仅代表单位
//                 delay_ms(500);
//                 delay_ms(500);
//         
// }

        
        //方法三时使用此while循环
//         while(1)
//         {
//                 Single_Write_BH1750(0x01);    //Power On
//                 Single_Write_BH1750(0x10);    //连续H-Mode
//                 
//                 BH1750_Multiple_Read();
//                 delay_ms(200);
//                 Conversion();
//                 printf("light:");
//                 printf("%5.1f \r",lux);   
//                 printf("lux\r\n");    //注意此处的lux仅仅代表单位
//                 delay_ms(500);
//                 delay_ms(500);
//         }
//         
        
}

[/mw_shl_code]


下面是BH1750.c中的主要函数。
[mw_shl_code=applescript,true]/****向BH1750单次写命令****/
void Single_Write_BH1750(unsigned char Reg_Address)
{
        IIC_Start();
        IIC_Send_Byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
        //IIC_Wait_Ack();
        IIC_Send_Byte(Reg_Address);  
        //IIC_Wait_Ack();
        IIC_Stop();
}


/****BH1750初始化****/
void BH1750_Init(void)
{
        IIC_Config();
  Single_Write_BH1750(0x01);
        
}


/****从BH1750单次读Lux****/
/****
模式选择:H-Resolution Mode,分辨率1lux
单次读Opecode:0010 0000 ,即0x20
器件地址:0100011,ADDR接GND
****/
void BH1750_ReadOneTime(void)
{
        

        IIC_Start();
        IIC_Send_Byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
        IIC_Wait_Ack();
        IIC_Send_Byte(0x20);   //发送One time H-Resolution Mode的Opecode 0010 0000,分辨率为1lux
        IIC_Wait_Ack();
        IIC_Stop();
        delay_ms(200);
        IIC_Start();
        IIC_Send_Byte(0x47);  //
        IIC_Wait_Ack();
        BUF[0]=IIC_Read_Byte(1);
        //IIC_Ack();        //主机应答
        //temp1=temp<<8;
        BUF[1]=IIC_Read_Byte(0);
        //IIC_NAck();        //主机不应答        
        IIC_Stop();
        
        
//         temp2=BUF[0];
//         temp2=(temp2<<8)+BUF[1];
//         lux=(float)temp2/1.2;    //lux是float型
        
        //return lux;
        //delay_ms(200);
}

/****方法一:****/
/****从BH1750连续读Lux****/
/****
模式选择:H-Resolution Mode,分辨率1lux
连续读Opecode:0001 0000
器件地址:0100011,ADDR接GND
****/
void  BH1750_ReadContinuous1(void)
{
        u16 temp=0,temp1=0;


        IIC_Start();
  IIC_Send_Byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
        IIC_Wait_Ack();
        IIC_Send_Byte(0x10);  //发送Continuous H-Resolution Mode的Opecode 0001 0000,分辨率为1lux
        IIC_Wait_Ack();
        IIC_Stop();
        delay_ms(200);
        IIC_Start();
  IIC_Send_Byte(0x47);  //此处严重失误,写成了IIC_Read_Byte,想当然的认为最后一位是1,就应该用IIC_Read_Byte,特别注意!!!
        IIC_Wait_Ack();
        
        
//         BUF[0]=IIC_Read_Byte(1);
//         BUF[1]=IIC_Read_Byte(0);        
        
        
        temp=IIC_Read_Byte(1);
        temp1=IIC_Read_Byte(0);


        IIC_Stop();
        
        temp2=temp1+(temp<<8);
        lux=(float)temp2/1.2;    //lux是float型


}


/****方法二:****/


void  BH1750_ReadContinuous2(void)
{
        //u16 temp=0,temp1=0;


        IIC_Start();
  IIC_Send_Byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
        IIC_Wait_Ack();
        IIC_Send_Byte(0x10);  //发送Continuous H-Resolution Mode的Opecode 0001 0000,分辨率为1lux
        IIC_Wait_Ack();
        IIC_Stop();
        delay_ms(200);
        IIC_Start();
  IIC_Send_Byte(0x47);  //此处严重失误,写成了IIC_Read_Byte,想当然的认为最后一位是1,就应该用IIC_Read_Byte,特别注意!!!
        IIC_Wait_Ack();
        
        
        BUF[0]=IIC_Read_Byte(1);
        BUF[1]=IIC_Read_Byte(0);        
        
        
//         temp=IIC_Read_Byte(1);
//         temp1=IIC_Read_Byte(0);

        IIC_Stop();
        
//         temp2=temp1+(temp<<8);
//         lux=(float)temp2/1.2;    //lux是float型


}



/****方法三****/
/****
利用函数BH1750_Multiple_Read()进行读
利用Conversion(void)函数进行转换
****/
void BH1750_Multiple_Read(void)
{
        IIC_Start();
  IIC_Send_Byte(0x47);  //此处严重失误,写成了IIC_Read_Byte,想当然的认为最后一位是1,就应该用IIC_Read_Byte,特别注意!!!

        BUF[0]=IIC_Read_Byte(1);
        BUF[1]=IIC_Read_Byte(0);         
        IIC_Stop();                          //停止信号  
        delay_us(5);
        delay_ms(200);
}

void Conversion(void)
{
        temp2=BUF[0];
        temp2=(temp2<<8)+BUF[1];
        lux=(float)temp2/1.2;    //lux是float型
        
}
[/mw_shl_code]



Program22_IIC_BH1750.zip

4.83 MB, 下载次数: 3722

BH1750工程文件

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2020-7-14
在线时间
19 小时
发表于 2020-7-31 17:12:27 | 显示全部楼层
批注 2020-07-31 170652.png 批注 2020-07-31 170601.png
请问一下上面两种发送数据的方式有何不同,为何使用第一种数据显示是正常。而第二种就一直是保持一个数据不变?
回复 支持 1 反对 0

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2018-1-2
在线时间
7 小时
 楼主| 发表于 2018-3-4 15:18:21 | 显示全部楼层
本帖最后由 spl928 于 2018-3-4 15:29 编辑

调试的过程中发现,
若是你输出的结果一直是255,有可能是你参数设置成u8了
若一直出现65535或者54612,或者某一个固定的值,大概率是IIC.c程序有问题。比如IIC_Send_Byte()函数,
反正一句话,多看几遍,跟别的比较,一定能调试出来,我自己这个程序整了三天,O(∩_∩)O~
下面是输出的结果:

输出结果

输出结果
回复 支持 反对

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2018-1-2
在线时间
7 小时
 楼主| 发表于 2018-3-4 15:20:03 | 显示全部楼层
原子哥,不要怪我啊,我明明写的是分享帖,怎么又成求助帖了啊
回复 支持 反对

使用道具 举报

7

主题

41

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
366
金钱
366
注册时间
2017-4-11
在线时间
33 小时
发表于 2018-3-30 21:27:10 | 显示全部楼层
我的一直接收OXFF, 接收变量设置为U16的,不是U8,搞了3天了,还没好
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2018-7-25
在线时间
4 小时
发表于 2018-8-9 21:16:20 | 显示全部楼层
感谢感谢,实用
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2017-8-23
在线时间
1 小时
发表于 2018-11-17 15:49:02 | 显示全部楼层
太棒了,我在网上找了好久都没有比较好的程序,你这个我稍微改了一下就可以用了,棒棒1
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-2-24
在线时间
14 小时
发表于 2020-3-30 21:49:43 | 显示全部楼层
楼主~~请问BH1750五个引脚怎么连啊 我连上去用你的代码 串口没有信息(波特率也是9600)
我接的引脚是 VCC-5V
SCL-PB10
DAT-PB11
GND-地
ADDR-地
串口就是没有信息出来 很烦
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-2-24
在线时间
14 小时
发表于 2020-3-31 13:46:00 | 显示全部楼层
Helean 发表于 2018-11-17 15:49
太棒了,我在网上找了好久都没有比较好的程序,你这个我稍微改了一下就可以用了,棒棒1

请问你具体改了哪里呀?我一直显示54612.5
还有这个BH1750能用LCD显示吗?就是不用IIC驱动 直接驱动,显示在LCD上
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2019-5-27
在线时间
23 小时
发表于 2020-4-2 11:19:03 | 显示全部楼层
Yimmmm 发表于 2020-3-31 13:46
请问你具体改了哪里呀?我一直显示54612.5
还有这个BH1750能用LCD显示吗?就是不用IIC驱动 直接驱动, ...

你好,请问一下这个问题你解决了没,我也遇到了
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-2-24
在线时间
14 小时
发表于 2020-4-3 17:28:04 | 显示全部楼层
本帖最后由 Yimmmm 于 2020-5-11 10:50 编辑
jsxSEVEN 发表于 2020-4-2 11:19
你好,请问一下这个问题你解决了没,我也遇到了

11111111111
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2020-4-9
在线时间
10 小时
发表于 2020-4-17 12:49:17 | 显示全部楼层
Yimmmm 发表于 2020-4-3 17:28
哈哈哈我可以完美驱动啦 要不你加我QQ 399978996 我告诉你具体的 还有发文件给你

你们解决了吗?我的也是一直显示54612.5
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2020-4-17
在线时间
2 小时
发表于 2020-4-17 17:03:01 | 显示全部楼层
Yimmmm 发表于 2020-4-3 17:28
哈哈哈我可以完美驱动啦 要不你加我QQ 399978996 我告诉你具体的 还有发文件给你

请问方便加你qq吗,咨询一下程序代码
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-2-24
在线时间
14 小时
发表于 2020-4-17 22:38:49 | 显示全部楼层
其他人 发表于 2020-4-17 17:03
请问方便加你qq吗,咨询一下程序代码

你加吧我发工程给你
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2020-2-24
在线时间
14 小时
发表于 2020-4-17 22:39:12 | 显示全部楼层
嘀嗒321 发表于 2020-4-17 12:49
你们解决了吗?我的也是一直显示54612.5

你加我 我给你发工程
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2020-1-3
在线时间
2 小时
发表于 2020-4-28 16:32:27 | 显示全部楼层
Yimmmm 发表于 2020-4-17 22:39
你加我 我给你发工程

能把工程分享下吗?谢谢。
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2019-6-6
在线时间
24 小时
发表于 2020-5-29 21:11:34 | 显示全部楼层
十分感谢,F407可以使用
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2020-11-21
在线时间
5 小时
发表于 2020-12-11 14:17:04 | 显示全部楼层
感谢楼主,我用的是STM32F103ZET6,这边调了楼主的代码一整天,一开始出错,显示一个固定值不变,调试发现是bh1750没有接收到数据,于是没有应答ack,也就是IIC通信没有建立起来,终于发现有个地方需要改,一下就好了,就是PB7口,输入输出模式没有配好,在IIC头文件中改成如下设置就可以了。
//IO方向设置
#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}

总结:自己太菜,基础不牢,地动山摇。
回复 支持 反对

使用道具 举报

9

主题

91

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1849
金钱
1849
注册时间
2019-3-8
在线时间
324 小时
发表于 2022-8-8 18:02:51 | 显示全部楼层
shipship 发表于 2020-5-29 21:11
十分感谢,F407可以使用

你好 能否发一份程序,我现在用F407测试,使用PB89引脚,输出一直是54612.5。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-4-26 19:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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