找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8109|回复: 14
收起左侧

STM32 BH1750光线感应源程序

  [复制链接]
ID:345364 发表于 2018-6-5 13:46 | 显示全部楼层 |阅读模式
基于BH1750模块实现的光强度检测,使用的是STM32F103C8T6

单片机源程序如下:
  1. #include  "bh1750.h"
  2. #include "delay.h"
  3. #include "timer.h"

  4. u8 BUF[8];
  5. u16 temp2=0;
  6. float lux=0;


  7. void bh1750_iic_init(void)
  8. {
  9.         GPIO_InitTypeDef GPIO_InitStructure;
  10.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOB, ENABLE );        //使能GPIOB时钟
  11.            
  12.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6;
  13.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
  14.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  15.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  16.         GPIO_SetBits(GPIOB,GPIO_Pin_5|GPIO_Pin_6);         //PB6,PB7 输出高

  17. }

  18. /****向BH1750单次写命令****/
  19. void Single_Write_bh1750(unsigned char Reg_Address)
  20. {
  21.         bh1750_iic_start();
  22.         bh1750_send_byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
  23.         //IIC_Wait_Ack();
  24.         bh1750_send_byte(Reg_Address);  
  25.         //IIC_Wait_Ack();
  26.         bh1750_iic_stop();
  27. }

  28. /****BH1750初始化****/
  29. void bh1750_Init(void)
  30. {
  31.         char dir=0;
  32.         unsigned char value=0;
  33.         TIM3_PWM_Init(899,0);
  34.         bh1750_iic_init();
  35.         TIM_SetCompare3(TIM3,0);
  36.         
  37.         while(1)
  38.         {        
  39.                 Single_Write_bh1750(0x01);
  40.                 Single_Write_bh1750(0x10);
  41.                 delay_ms(200);
  42.                 bh1750_ReadContinuous1();
  43.                 temp2=BUF[0];
  44.                 temp2=(temp2<<8)+BUF[1];
  45.                 lux=(float)temp2/1.2;    //lux是float型        
  46.                 if((lux>0)&&(lux<50))
  47.                         value=10;
  48.                 else if(lux<75)
  49.                         value=20;
  50.                 else if(lux<100)
  51.                         value=40;
  52.                 else if(lux<125)
  53.                         value=50;
  54.                 else if(lux<150)
  55.                         value=60;
  56.                 else if(lux<175)
  57.                         value=70;
  58.                 else if(lux<200)
  59.                         value=80;
  60.                 else if(lux<250)
  61.                         value=90;
  62.                 else if(lux<280)
  63.                         value=110;
  64.                 else if(lux<300)
  65.                         value=120;
  66.                 else if(lux<320)
  67.                         value=130;
  68.                 else if(lux<340)
  69.                         value=140;
  70.                 else if(lux<360)
  71.                         value=150;
  72.                 else if(lux<380)
  73.                         value=160;
  74.                 else if(lux<400)
  75.                         value=170;
  76.                 else if(lux<410)
  77.                         value=180;
  78.                 else if(lux<450)
  79.                         value=190;        
  80.                 else if(lux<800)
  81.                         value=240;
  82.                 printf("光照强度:%f   value:%d\r\n",lux,value);
  83.                 TIM_SetCompare3(TIM3,value);
  84.                
  85.                 //delay_ms(1000);
  86.         }
  87.         
  88.         
  89. }

  90. /****从BH1750单次读Lux****/
  91. /****
  92. 模式选择:H-Resolution Mode,分辨率1lux
  93. 单次读Opecode:0010 0000 ,即0x20
  94. 器件地址:0100011,ADDR接GND
  95. ****/
  96. void bh1750_ReadOneTime(void)
  97. {
  98.         

  99.         bh1750_iic_start();
  100.         bh1750_send_byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
  101.         bh1750_recv_ack();
  102.         bh1750_send_byte(0x20);   //发送One time H-Resolution Mode的Opecode 0010 0000,分辨率为1lux
  103.         bh1750_recv_ack();
  104.         bh1750_iic_stop();
  105.         delay_ms(200);
  106.         bh1750_iic_start();
  107.         bh1750_send_byte(0x47);  //
  108.         bh1750_recv_ack();
  109.         BUF[0]=bh1750_recv_byte(1);
  110.         //IIC_Ack();        //主机应答
  111.         //temp1=temp<<8;
  112.         BUF[1]=bh1750_recv_byte(0);
  113.         //IIC_NAck();        //主机不应答        
  114.         bh1750_iic_stop();
  115.         
  116.         
  117. //         temp2=BUF[0];
  118. //         temp2=(temp2<<8)+BUF[1];
  119. //         lux=(float)temp2/1.2;    //lux是float型
  120.         
  121.         //return lux;
  122.         //delay_ms(200);
  123. }

  124. /****从BH1750连续读Lux****/
  125. /****
  126. 模式选择:H-Resolution Mode,分辨率1lux
  127. 连续读Opecode:0001 0000
  128. 器件地址:0100011,ADDR接GND
  129. ****/
  130. void  bh1750_ReadContinuous1(void)
  131. {
  132. //        u16 temp=0,temp1=0;
  133.         bh1750_iic_start();
  134.   bh1750_send_byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
  135.         bh1750_recv_ack();
  136.         bh1750_send_byte(0x10);  //发送Continuous H-Resolution Mode的Opecode 0001 0000,分辨率为1lux
  137.         bh1750_recv_ack();
  138.         bh1750_iic_stop();
  139.         delay_ms(200);
  140.         bh1750_iic_start();
  141.   bh1750_send_byte(0x47);  
  142.         bh1750_recv_ack();
  143.         
  144.         
  145.          BUF[0]=bh1750_recv_byte(1);
  146.         BUF[1]=bh1750_recv_byte(0);        
  147.         
  148.         
  149.         //temp=bh1750_recv_byte(1);
  150.         //temp1=bh1750_recv_byte(0);


  151.         bh1750_iic_stop();
  152.         
  153.         //temp2=temp1+(temp<<8);
  154.         //lux=(float)temp2/1.2;    //lux是float型


  155. }

  156. void Conversion(void)
  157. {
  158.         temp2=BUF[0];
  159.         temp2=(temp2<<8)+BUF[1];
  160.         lux=(float)temp2/1.2;    //lux是float型
  161.         
  162. }






  163. /**************************************
  164. 起始信号
  165. **************************************/
  166. void bh1750_iic_start(void)
  167. {
  168.                 BH1750_SDA_OUT()       //设置SDA线为输出
  169.         //在开始数据传输前,先让SDA和SCL都拉高
  170.                 BH1750_IIC_SDA=1;    //发送起始条件的数据信号,释放总线
  171.           delay_us(2);
  172.                 BH1750_IIC_SCL=1;   

  173.                 delay_us(5);   //Tsu;STA:起始条件的建立时间大于4.7us。
  174.         
  175.                 BH1750_IIC_SDA=0;    //SDA由高变为低表示开始信号
  176.                 delay_us(4);   //起始条件的保持时间大于4us
  177.                 BH1750_IIC_SCL=0;    //钳住IIC总线,准备发送或者接收数据
  178.                 delay_us(2);
  179. }

  180. /**************************************
  181. 停止信号
  182. **************************************/
  183. void bh1750_iic_stop(void)
  184. {
  185.         BH1750_SDA_OUT()       //设置SDA线为输出
  186.         
  187.         //IIC_SCL=0;    //此句是调试BH1750时加,2018.03.03
  188.         
  189.         BH1750_IIC_SDA=0;   //发送停止信号的数据信号
  190.         delay_us(2);
  191.         BH1750_IIC_SCL=1;   //发送停止信号的时钟信号
  192.         delay_us(5);  //停止信号的建立时间大于4us
  193.         BH1750_IIC_SDA=1;   //发送停止信号
  194.         delay_us(4);    //;
  195. }

  196. /**************************************
  197. 发送应答信号
  198. 入口参数:ack (0:ACK 1:NAK)
  199. **************************************/
  200. void bh1750_send_ack(char ack)
  201. {
  202.         BH1750_IIC_SCL=0;
  203.         BH1750_SDA_OUT();
  204.         BH1750_IIC_SDA=ack;   //主器件应答
  205.         delay_us(2);
  206.         BH1750_IIC_SCL=1;
  207.         delay_us(4);        //SCL高电平周期大于4us
  208.         BH1750_IIC_SCL=0;         //清时钟线,钳住IIC总线以便继续接收
  209.         delay_us(2);

  210. }

  211. /**************************************
  212. 接收应答信号
  213. **************************************/
  214. char bh1750_recv_ack(void)
  215. {
  216.         u8 ucErrorTime=0;
  217.         BH1750_SDA_IN();     //SDA设置成输入
  218.         BH1750_IIC_SDA=1;
  219.         delay_us(2);
  220.         BH1750_IIC_SCL=1;
  221.         delay_us(2);
  222.         while(BH1750_READ_SDA)
  223.         {
  224.                 ucErrorTime++;
  225.                 if(ucErrorTime>=250)
  226.                 {
  227.                         bh1750_iic_stop();
  228.                         return 1;               
  229.                 }
  230.         }
  231.         BH1750_IIC_SCL=0;
  232.         return 0;
  233. }

  234. /**************************************
  235. 向IIC总线发送一个字节数据
  236. **************************************/
  237. void bh1750_send_byte(char dat)
  238. {
  239.         u8 i;
  240.         BH1750_SDA_OUT();  

  241.         for(i=0;i<8;i++)
  242.         {
  243.                 if((dat<<i)&0x80)  BH1750_IIC_SDA=1;   //判断发送位
  244.                 else BH1750_IIC_SDA=0;

  245.                 delay_us(2);
  246.                 BH1750_IIC_SCL=1;     //拉高SCL,通知被控器开始接收数据位
  247.                 delay_us(4);   //保证SCL高电平周期大于4us
  248.                 BH1750_IIC_SCL=0;    //拉低SCL,允许SDA传输下一位数据。因为只有在SCL=0时才允许SDA的状态发生变化
  249.           delay_us(2);
  250.    }
  251.          //以下四句是调试BH1750时添加的,2018.03.03
  252.          //特别注意;用方法三时,以下四句不可去掉,去掉后得到的数有问题
  253.          //用方法二时,以下四句需注释掉,否则也会有问题,至于原因暂时还不清楚。
  254. //          IIC_SDA=0;
  255. //          delay_us(2);
  256. //          IIC_SCL=1;
  257. //          delay_us(2);
  258.          
  259.          BH1750_IIC_SCL=0;      //拉低SCL,为下次数据传输做好准备
  260.          delay_us(2);
  261. }

  262. /**************************************
  263. 从IIC总线接收一个字节数据
  264. 用来接收从器件传来的数据,ack为1时,发送Ack(产生应答);ack为0时,发送NAck(不产生应答)
  265. **************************************/
  266. char bh1750_recv_byte(unsigned char ack)
  267. {
  268.         unsigned char i,receive=0;
  269.         BH1750_SDA_IN();   
  270.         for(i=0;i<8;i++)
  271.         {
  272.                 BH1750_IIC_SCL=0;    //置SCL为低,准备接收数据位
  273.                 delay_us(5);  //时钟低电平周期大于4.7us
  274.                 BH1750_IIC_SCL=1;   //置SCL为高,使SDA上数据有效
  275.                 delay_us(2);
  276.                 receive=receive<<1;
  277.                 if(BH1750_READ_SDA) receive=receive+1;    //读取SDA,把接收的数据位放入receve中,若此处写成IIC_SDA==1,会失败,思考原因?        
  278.                 delay_us(2);
  279.   }
  280.         if(!ack)
  281. ……………………

  282. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

Keil代码下载:
bh1750.rar (275.76 KB, 下载次数: 434)

评分

参与人数 2黑币 +51 收起 理由
pdd708 + 1 赞一个!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:95072 发表于 2018-7-26 17:21 | 显示全部楼层
非常感谢
回复

使用道具 举报

ID:382687 发表于 2018-8-3 20:29 | 显示全部楼层
下载来学习学习,感谢楼主
回复

使用道具 举报

ID:219315 发表于 2018-11-17 14:31 | 显示全部楼层
感谢楼主,
非常感谢
回复

使用道具 举报

ID:489605 发表于 2019-3-12 23:23 | 显示全部楼层
jach09 发表于 2018-11-17 14:31
感谢楼主,
非常感谢

非常感谢,很好
回复

使用道具 举报

ID:489675 发表于 2019-3-13 09:20 | 显示全部楼层
非常感谢,太好了
回复

使用道具 举报

ID:275634 发表于 2019-3-30 20:46 | 显示全部楼层
学习学习
回复

使用道具 举报

ID:306124 发表于 2019-4-1 15:02 | 显示全部楼层
非常感谢
回复

使用道具 举报

ID:579624 发表于 2019-10-26 10:31 | 显示全部楼层
编译的时候出现问题,说无法打开.\core_cm3.o 这是什么问题呀,烦请楼主解答一下
回复

使用道具 举报

ID:648623 发表于 2019-12-29 01:17 | 显示全部楼层
感谢楼主
回复

使用道具 举报

ID:391164 发表于 2020-3-16 19:46 | 显示全部楼层
我测试了一下不行,数据一致不更新
回复

使用道具 举报

ID:543372 发表于 2020-6-6 12:33 | 显示全部楼层
感谢楼主
回复

使用道具 举报

ID:425175 发表于 2020-7-11 23:40 | 显示全部楼层
测试通过,谢谢楼主!
回复

使用道具 举报

ID:1068392 发表于 2023-3-27 21:30 | 显示全部楼层
有大佬能根据楼主的资料画个仿真图吗?
回复

使用道具 举报

ID:982617 发表于 2023-4-18 13:31 | 显示全部楼层
求问 实物怎么连接
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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