你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 HAL库BH1750光强检测器驱动代码

[复制链接]
STMCU小助手 发布时间:2022-4-11 10:16
  1. #ifndef __LIGHT_H
  2. #define __LIGHT_H

  3. #include "system.h"
  4. #include "delay.h"

  5. //IO方向设置
  6. #define SDA_IN()  {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)8<<4;}
  7. #define SDA_OUT() {IIC_SDA_GPIO_Port->CRH&=0XFFFFFF0F;IIC_SDA_GPIO_Port->CRH|=(u32)3<<4;}

  8. #define IIC_SCL    PCout(8) //SCL
  9. #define IIC_SDA    PCout(9) //SDA         
  10. #define READ_SDA   PCin(9)  //输入SDA
  11. #define ADDR 0x23                        //0100011

  12. #define BHAddWrite     0x46      // 从机地址+最后写方向位
  13. #define BHAddRead      0x47      // 从机地址+最后读方向位
  14. #define BHPowDown      0x00      // 关闭模块
  15. #define BHPowOn        0x01      // 打开模块等待测量指令
  16. #define BHReset        0x07      // 重置数据寄存器值在PowerOn模式下有效
  17. #define BHModeH1       0x10      // 高分辨率 单位1lx 测量时间120ms
  18. #define BHModeH2       0x11      // 高分辨率模式2 单位0.5lx 测量时间120ms
  19. #define BHModeL        0x13      // 低分辨率 单位4lx 测量时间16ms
  20. #define BHSigModeH     0x20      // 一次高分辨率 测量 测量后模块转到 PowerDown模式
  21. #define BHSigModeH2    0x21      // 同上类似
  22. #define BHSigModeL     0x23      // 上类似

  23. void Single_Write_BH1750(u8 REG_Address);
  24. void Light_Init(void);
  25. void bh_data_send(u8 command);
  26. u16 bh_data_read(void);

  27. //IIC所有操作函数
  28. void IIC_Init(void);                //初始化IIC的IO口
  29. void IIC_Start(void);                                //发送IIC开始信号
  30. void IIC_Stop(void);                                  //发送IIC停止信号
  31. void IIC_Send_Byte(u8 txd);                        //IIC发送一个字节
  32. u8 IIC_Read_Byte(u8 ack);                        //IIC读取一个字节
  33. u8 IIC_Wait_Ack(void);                                 //IIC等待ACK信号
  34. void IIC_Ack(void);                                        //IIC发送ACK信号
  35. void IIC_NAck(void);                                //IIC不发送ACK信号

  36. void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
  37. u8 IIC_Read_One_Byte(u8 daddr,u8 addr);

  38. #endif
复制代码
  1. #include "bh1750.h"

  2. void Single_Write_BH1750(u8 REG_Address)
  3. {
  4.     IIC_Start();                  // 起始信号
  5.     IIC_Send_Byte(BHAddWrite);    // 发送设备地址+写信号
  6.     IIC_Send_Byte(REG_Address);   // 内部寄存器地址,
  7. //  BH1750_SendByte(REG_data);       // 内部寄存器数据,
  8.     IIC_Stop();                   // 发送停止信号
  9. }

  10. void Light_Init(void)
  11. {
  12.     GPIO_InitTypeDef GPIO_InitStruct = {0};

  13.     // 使能GPIOD时钟
  14.     __HAL_RCC_GPIOD_CLK_ENABLE();

  15.     // PD6和7引脚置高
  16.     HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_SET);

  17.     // 初始化引脚
  18.     GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
  19.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  20.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  21.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  22.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  23.     Single_Write_BH1750(0x01);
  24.     bh_data_send(BHPowOn);
  25.     bh_data_send(BHReset);
  26.     bh_data_send(BHModeL);                        //选择的是分辨率是4lx,测量时间是16ms的
  27.     delay_ms(180);
  28. }

  29. //产生IIC起始信号
  30. void IIC_Start(void)
  31. {
  32.     SDA_OUT();     //sda线输出
  33.     IIC_SDA=1;
  34.     IIC_SCL=1;
  35.     delay_us(4);
  36.     IIC_SDA=0;//START:when CLK is high,DATA change form high to low
  37.     delay_us(4);
  38.     IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
  39. }

  40. //产生IIC停止信号
  41. void IIC_Stop(void)
  42. {
  43.     SDA_OUT();//sda线输出
  44.     IIC_SCL=0;
  45.     IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
  46.     delay_us(4);
  47.     IIC_SCL=1;
  48.     IIC_SDA=1;//发送I2C总线结束信号
  49.     delay_us(4);
  50. }

  51. //等待应答信号到来
  52. //返回值:1,接收应答失败
  53. //        0,接收应答成功
  54. u8 IIC_Wait_Ack(void)
  55. {
  56.     u8 ucErrTime=0;
  57.     SDA_IN();      //SDA设置为输入
  58.     IIC_SDA=1;
  59.     delay_us(1);
  60.     IIC_SCL=1;
  61.     delay_us(1);
  62.     while(READ_SDA)
  63.     {
  64.         ucErrTime++;
  65.         if(ucErrTime>250)
  66.         {
  67.             IIC_Stop();
  68.             return 1;
  69.         }
  70.     }
  71.     IIC_SCL=0;//时钟输出0
  72.     return 0;
  73. }

  74. //产生ACK应答
  75. void IIC_Ack(void)
  76. {
  77.     IIC_SCL=0;
  78.     SDA_OUT();
  79.     IIC_SDA=0;
  80.     delay_us(2);
  81.     IIC_SCL=1;
  82.     delay_us(2);
  83.     IIC_SCL=0;
  84. }

  85. //不产生ACK应答
  86. void IIC_NAck(void)
  87. {
  88.     IIC_SCL=0;
  89.     SDA_OUT();
  90.     IIC_SDA=1;
  91.     delay_us(2);
  92.     IIC_SCL=1;
  93.     delay_us(2);
  94.     IIC_SCL=0;
  95. }

  96. //IIC发送一个字节
  97. //返回从机有无应答
  98. //1,有应答
  99. //0,无应答
  100. void IIC_Send_Byte(u8 txd)
  101. {
  102.     u8 t;
  103.     SDA_OUT();
  104.     IIC_SCL=0;//拉低时钟开始数据传输
  105.     for(t=0; t<8; t++)
  106.     {
  107.         //IIC_SDA=(txd&0x80)>>7;
  108.         if((txd&0x80)>>7)
  109.             IIC_SDA=1;
  110.         else
  111.             IIC_SDA=0;
  112.         txd<<=1;
  113.         delay_us(2);   //对TEA5767这三个延时都是必须的
  114.         IIC_SCL=1;
  115.         delay_us(2);
  116.         IIC_SCL=0;
  117.         delay_us(2);
  118.     }
  119. }

  120. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  121. u8 IIC_Read_Byte(unsigned char ack)
  122. {
  123.     unsigned char i,receive=0;
  124.     SDA_IN();//SDA设置为输入
  125.     for(i=0; i<8; i++ )
  126.     {
  127.         IIC_SCL=0;
  128.         delay_us(2);
  129.         IIC_SCL=1;
  130.         receive<<=1;
  131.         if(READ_SDA)receive++;
  132.         delay_us(1);
  133.     }
  134.     if (!ack)
  135.         IIC_NAck();//发送nACK
  136.     else
  137.         IIC_Ack(); //发送ACK
  138.     return receive;
  139. }

  140. void bh_data_send(u8 command)
  141. {
  142.     do
  143.     {
  144.         IIC_Start();                      //iic起始信号
  145.         IIC_Send_Byte(BHAddWrite);       //发送器件地址
  146.     }
  147.     while(IIC_Wait_Ack());            //等待从机应答
  148.     IIC_Send_Byte(command);          //发送指令
  149.     IIC_Wait_Ack();                   //等待从机应答
  150.     IIC_Stop();                       //iic停止信号
  151. }

  152. u16 bh_data_read(void)
  153. {
  154.     u16 buf;
  155.     IIC_Start();                       //iic起始信号
  156.     IIC_Send_Byte(BHAddRead);         //发送器件地址+读标志位
  157.     IIC_Wait_Ack();                     //等待从机应答
  158.     buf=IIC_Read_Byte(1);              //读取数据
  159.     buf=buf<<8;                        //读取并保存高八位数据
  160.     buf+=0x00ff&IIC_Read_Byte(0);      //读取并保存第八位数据
  161.     IIC_Stop();                        //发送停止信号
  162.     return buf;
  163. }


复制代码

收藏 评论0 发布时间:2022-4-11 10:16

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版