找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4083|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

STM32f103RCT6+BH1750光照傳感器+IIC通信OLED顯示 源程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
需要的硬件:STM32f103rct6開發(fā)板、BH1750光照傳感器、IIC接口的0.96oled顯示屏
使用BH1750光照傳感器采集光照信息,然后通過oled顯示屏顯示光照值/lx
BH1750的硬件連接:
SCL——PC12
SDA——PC11
ADDR——GND (注:本程序AD地址為0x46為接地地址,如果把該引腳接VCC就需要修改bh1750.h文件中BH1750_Addr的值為0xB8,具體見數(shù)據(jù)手冊(cè)P13)
oled顯示屏的硬件連接:
SCL——PB0
SDA——PB1

電路原理圖如下:


代碼包含main.c、bh1750.h、bh1750.c、oled.h、oled.c、oledfont.h
制作出來(lái)的實(shí)物圖如下:


程序如下:
bh1750.h
  1. #ifndef __BH1750_H
  2. #define __BH1750_H
  3. #include "sys.h"
  4.         
  5. #define BH1750_OFF  0x00    //斷電
  6. #define BH1750_Addr 0x46    //ALT  ADDRESS引腳接地時(shí)地址為0x46,接電源時(shí)地址為0xB8
  7. #define BH1750_ON   0x01        //通電
  8. #define BH1750_CON  0x10        //連續(xù)H分辨率模式
  9. #define BH1750_ONE  0x20        //一次H分辨率模式
  10. #define BH1750_RSET 0x07        //重置
  11.                                  
  12. //IO方向設(shè)置
  13. #define SDA_IN()  {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}
  14. #define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}

  15. //IO操作函數(shù)         
  16. #define IIC_SCL    PCout(12) //SCL
  17. #define IIC_SDA    PCout(11) //SDA         
  18. #define READ_SDA   PCin(11)  //輸入SDA

  19. extern u32 result_lx;

  20. //IIC所有操作函數(shù)
  21. void IIC_Init(void);                //初始化IIC的IO口                                 
  22. void IIC_Start(void);                                //發(fā)送IIC開始信號(hào)
  23. void IIC_Stop(void);                                  //發(fā)送IIC停止信號(hào)
  24. void IIC_Send_Byte(u8 txd);                        //IIC發(fā)送一個(gè)字節(jié)
  25. u8 IIC_Read_Byte(unsigned char ack);//IIC讀取一個(gè)字節(jié)
  26. u8 IIC_Wait_Ack(void);                                 //IIC等待ACK信號(hào)
  27. void IIC_Ack(void);                                        //IIC發(fā)送ACK信號(hào)
  28. void IIC_NAck(void);                                //IIC不發(fā)送ACK信號(hào)

  29. void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
  30. u8 IIC_Read_One_Byte(u8 daddr,u8 addr);         


  31. void Start_BH1750(void);                        //上電,設(shè)置清除數(shù)據(jù)寄存器
  32. void Read_BH1750(void);                               //連續(xù)的讀取內(nèi)部寄存器數(shù)據(jù)
  33. void Convert_BH1750(void);

  34. #endif

復(fù)制代碼
bh1750.c
  1. #include "bh1750.h"
  2. #include "delay.h"

  3. u8 BUF[2]={0};
  4. u16 result=0;
  5. u32 result_lx;

  6. //初始化IIC引腳
  7. void IIC_Init(void)
  8. {                                             
  9.         GPIO_InitTypeDef GPIO_InitStructure;
  10.         
  11.         RCC_APB2PeriphClockCmd(        RCC_APB2Periph_GPIOC, ENABLE );        
  12.            
  13.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_11;
  14.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;                   //推挽輸出
  15.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  16.         GPIO_Init(GPIOC, &GPIO_InitStructure);

  17.         IIC_SCL=1;
  18.         IIC_SDA=1;

  19. }
  20. //產(chǎn)生IIC起始信號(hào)
  21. void IIC_Start(void)
  22. {
  23.         SDA_OUT();      //sda線輸出
  24.         IIC_SDA=1;                    
  25.         IIC_SCL=1;
  26.         delay_us(4);
  27.          IIC_SDA=0;                //START:when CLK is high,DATA change form high to low
  28.         delay_us(4);
  29.         IIC_SCL=0;                //鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù)
  30. }         
  31. //產(chǎn)生IIC停止信號(hào)
  32. void IIC_Stop(void)
  33. {
  34.         SDA_OUT();                //sda線輸出
  35.         IIC_SCL=0;
  36.         IIC_SDA=0;                //STOP:when CLK is high DATA change form low to high
  37.          delay_us(4);
  38.         IIC_SCL=1;
  39.         IIC_SDA=1;                //發(fā)送I2C總線結(jié)束信號(hào)
  40.         delay_us(4);                                                                  
  41. }
  42. //等待應(yīng)答信號(hào)到來(lái)
  43. //返回值:1,接收應(yīng)答失敗
  44. //        0,接收應(yīng)答成功
  45. u8 IIC_Wait_Ack(void)
  46. {
  47.         u8 ucErrTime=0;
  48.         SDA_IN();              //SDA設(shè)置為輸入  
  49.         IIC_SDA=1;delay_us(1);           
  50.         IIC_SCL=1;delay_us(1);         
  51.         while(READ_SDA)
  52.         {
  53.                 ucErrTime++;
  54.                 if(ucErrTime>250)
  55.                 {
  56.                         IIC_Stop();
  57.                         return 1;
  58.                 }
  59.         }
  60.         IIC_SCL=0;                //時(shí)鐘輸出0            
  61.         return 0;  
  62. }
  63. //產(chǎn)生ACK應(yīng)答
  64. void IIC_Ack(void)
  65. {
  66.         IIC_SCL=0;
  67.         SDA_OUT();
  68.         IIC_SDA=0;
  69.         delay_us(2);
  70.         IIC_SCL=1;
  71.         delay_us(2);
  72.         IIC_SCL=0;
  73. }
  74. //不產(chǎn)生ACK應(yīng)答                    
  75. void IIC_NAck(void)
  76. {
  77.         IIC_SCL=0;
  78.         SDA_OUT();
  79.         IIC_SDA=1;
  80.         delay_us(2);
  81.         IIC_SCL=1;
  82.         delay_us(2);
  83.         IIC_SCL=0;
  84. }                                                                              
  85. //IIC發(fā)送一個(gè)字節(jié)
  86. //返回從機(jī)有無(wú)應(yīng)答
  87. //1,有應(yīng)答
  88. //0,無(wú)應(yīng)答                          
  89. void IIC_Send_Byte(u8 txd)
  90. {                        
  91.     u8 t;   
  92.         SDA_OUT();            
  93.     IIC_SCL=0;                        //拉低時(shí)鐘開始數(shù)據(jù)傳輸
  94.     for(t=0;t<8;t++)
  95.     {              
  96.         IIC_SDA=(txd&0x80)>>7;
  97.         txd<<=1;           
  98.                 delay_us(2);          //對(duì)TEA5767這三個(gè)延時(shí)都是必須的
  99.                 IIC_SCL=1;
  100.                 delay_us(2);
  101.                 IIC_SCL=0;        
  102.                 delay_us(2);
  103.     }         
  104. }            
  105. //讀1個(gè)字節(jié),ack=1時(shí),發(fā)送ACK,ack=0,發(fā)送nACK   
  106. u8 IIC_Read_Byte(unsigned char ack)
  107. {
  108.         unsigned char i,receive=0;
  109.         SDA_IN();                     //SDA設(shè)置為輸入
  110.     for(i=0;i<8;i++ )
  111.         {
  112.         IIC_SCL=0;
  113.         delay_us(2);
  114.                 IIC_SCL=1;
  115.         receive<<=1;
  116.         if(READ_SDA)receive++;   
  117.                 delay_us(1);
  118.     }                                         
  119.     if (!ack)
  120.         IIC_NAck();                //發(fā)送nACK
  121.     else
  122.         IIC_Ack();                 //發(fā)送ACK   
  123.     return receive;
  124. }

  125. void Cmd_Write_BH1750(u8 cmd)
  126. {
  127.     IIC_Start();                    //起始信號(hào)
  128.     IIC_Send_Byte(BH1750_Addr+0);   //發(fā)送設(shè)備地址+寫信號(hào)
  129.         while(IIC_Wait_Ack());
  130.     IIC_Send_Byte(cmd);        //內(nèi)部寄存器地址
  131.         while(IIC_Wait_Ack());
  132.     //BH1750_SendByte(REG_data);       //內(nèi)部寄存器數(shù)據(jù),
  133.     IIC_Stop();                        //發(fā)送停止信號(hào)
  134.         delay_ms(5);
  135. }

  136. void Start_BH1750(void)                        //上電,設(shè)置清除數(shù)據(jù)寄存器
  137. {
  138.         Cmd_Write_BH1750(BH1750_OFF);         //power off
  139.         Cmd_Write_BH1750(BH1750_ON);         //power on
  140.         Cmd_Write_BH1750(BH1750_RSET);         //reset
  141.         Cmd_Write_BH1750(BH1750_ONE);    //在1lx分辨率下開始測(cè)量,測(cè)量時(shí)間一般為120ms
  142.         delay_ms(200);
  143. }

  144. void Read_BH1750(void)               //讀取內(nèi)部寄存器數(shù)據(jù)
  145. {
  146.         IIC_Start();                        //起始信號(hào)
  147.     IIC_Send_Byte(BH1750_Addr+1);       //發(fā)送設(shè)備地址+讀信號(hào)
  148.         while(IIC_Wait_Ack());
  149.         BUF[0]=IIC_Read_Byte(1);  //發(fā)送ACK
  150.         BUF[1]=IIC_Read_Byte(0);  //發(fā)送nACK

  151.     IIC_Stop();               //停止信號(hào)
  152.     delay_ms(5);
  153. }

  154. void Convert_BH1750(void)
  155. {
  156.         
  157.         result=BUF[0];
  158.         result=(result<<8)+BUF[1];            //合成兩個(gè)字節(jié)的數(shù)據(jù),即光照數(shù)據(jù)
  159.         
  160.         result_lx=(u32)((float)result/1.2);
  161. }
復(fù)制代碼

main.c
  1. #include "led.h"
  2. #include "oled.h"
  3. #include "bh1750.h"
  4. #include "sys.h"
  5. #include "delay.h"

  6. int main(void)
  7. {
  8.         delay_init();
  9.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  10.         OLED_Init();
  11.         IIC_Init();
  12.         LED_Init();
  13.         OLED_Clear();
  14.         OLED_Refresh();
  15.         //Start_BH1750();
  16.         while(1)
  17.         {
  18.                 Start_BH1750();
  19.                 Read_BH1750();
  20.                 Convert_BH1750();
  21.                 Convert_BH1750();
  22.                 OLED_ShowString(0,2,"lightval:",12);
  23.                 OLED_ShowNum(60,2,result_lx,6,12);
  24.                 OLED_ShowString(110,2,"lx",12);
  25.                 OLED_Refresh();
  26.                 LED0=!LED0;
  27.                 delay_ms(200);
  28.         }
  29. }

復(fù)制代碼
由于oled相關(guān)程序過長(zhǎng),限于篇幅此處沒有粘貼出來(lái),如果需要可以下載以下工程文件。
工程文件夾如下:


Keil代碼下載: STM32f103RCT6+BH1750光照傳感器+IIC通信oled顯示.7z (605.07 KB, 下載次數(shù): 134)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:689054 發(fā)表于 2022-3-11 08:30 | 只看該作者
光太強(qiáng)的話會(huì)不會(huì)出現(xiàn)超量程?
回復(fù)

使用道具 舉報(bào)

板凳
ID:473377 發(fā)表于 2022-3-11 13:14 | 只看該作者
bbc10808 發(fā)表于 2022-3-11 08:30
光太強(qiáng)的話會(huì)不會(huì)出現(xiàn)超量程?

最大值的情況下就是讀取的數(shù)據(jù)結(jié)果為高八位和低八位都為11111111 11111111,通過公式計(jì)算(1+2^1+2^2+2^3+2^4+...+2^14+2^15)/1.2=65535/1.2=54612.5 lx(參考數(shù)據(jù)手冊(cè)p7),本程序中oled有6位數(shù)顯示區(qū)域,所以不會(huì)超出量程。
回復(fù)

使用道具 舉報(bào)

地板
ID:504404 發(fā)表于 2022-4-23 15:38 | 只看該作者
IIC初始化不能通過,不知道為啥
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表