【RT-Thread筆記】BH1750軟體包的使用

BH1750簡介

BH1750是一種用於兩線制串列匯流排介面的16位數字型光強度感測器積體電路。利用它的高解析度可以探測較大範圍的光強度變化。(1lx~65535lx)。

twfd76.png

創建工程、驗證

在RT-Thread中讀取BH1750數據有兩種方法:一種方法是藉助bh1750軟體包;另一種方法是直接使用i2c驅動框架讀取BH1750數據。

關於直接使用i2c驅動框架讀取BH1750數據的方法可以閱讀Mculover666兄的這篇:

//blog.csdn.net/Mculover666/article/details/104675712

本次實驗我們藉助bh1750軟體包來讀取BH1750感測器數據,使用RT-Thread Studio V1.1.0來創建工程。

1、添加bh1750軟體包

twfDhD.png
twf0AK.png
twfBtO.png

2、打開i2c設備驅動

twfa0x.png

目前只有軟體i2c驅動。保存RT-Thread Settings文件。編譯報錯:

twfcjA.png

那是因為我們沒有打開I2C相關的宏,drv_soft_i2c.c中模擬了幾個i2c,我們要確認我們使用哪一個i2c與bh1750感測器相連。

twf2nI.png

這裡可以看到bh1750的示例的初始化函數中使用了i2c2,所以相應的我們需要在board.h中打開i2c2相關的宏,需要打開、修改哪些宏可以看相關注釋:

twfo9g.png

這裡我們使用的是小熊派開發板,bh1750與MCU通過PB6、PB7引腳相連:

twf6cd.png

雖然PB6、PB7可以配置為硬體i2功能,但是我們這裡使用的是軟體i2c,所以這裡的PB6、PB7是當做gpio來用的。然後我們根據注釋的說明把程式碼改為:

twfy1H.png

然後編譯報錯,錯誤提示這幾個宏有問題。反反覆複檢查,好像沒什麼問題,為啥就會瘋狂報錯。隱約記得有些常式常式中表示引腳好像不是這麼表示的,而是類似這樣的:

twfRBt.png

每個引腳都有一個新的代號,而這些引腳與代號的關係可以在drv_gpio.c中查看:

twfhAf.png

可以看到我們的PB6、PB7引腳的代號分別是22、23。然後嘗試著把上面的i2c宏程式碼改為:

twfWHP.png

編譯成功!然後試著讀取感測器數據,也成功了。所以,這大概是RT-Thread Studio V1.1.0的一個小bug,模板工程的board.h里關於i2c的注釋有問題,嚴重誤導了我們。。

3、下載、驗證

twf54S.png

若執行sensor read命令無數據輸出時,需要打開\components\drivers\sensors\sensor_cmd.c,在sensor_show_data函數後面自行增加環境光照強度列印程式碼:

case RT_SENSOR_CLASS_LIGHT:
        LOG_I("num:%3d, light:%4d.%d, timestamp:%5d", num, sensor_data->data.light / 10, sensor_data->data.light % 10, sensor_data->timestamp);
        break;

4、編寫應用

上面能輸入那些命令對bh1750進行測試的前提是官方已經給我們寫好了相關應用demo,在sensor_cmd.c中,如:

(1)測試函數

twf4N8.png

(2)顯示數據

twf7cj.png

除此之外還有其它幾個應用相關的函數。

我們也可以模仿sensor_cmd.c裡面的程式碼來寫我們自己的應用程式碼:

static void bh1750_thread_entry(void *parameter)
{
    rt_device_t dev = RT_NULL;
    struct rt_sensor_data data;
    rt_size_t res;

    /* 查找bh1750感測器  */
    dev = rt_device_find("li_bh1750");
    if (dev == RT_NULL)
    {
        rt_kprintf("Can't find device:li_bh1750\n");
        return;
    }

    /* 以只讀模式打開bh1750 */
    if (rt_device_open(dev, RT_DEVICE_FLAG_RDONLY) != RT_EOK)
    {
        rt_kprintf("open device failed!");
        return;
    }

    while(1)
    {
        /* 從感測器讀取一個數據 */
        res = rt_device_read(dev, 0, &data, 1);
        if (1 != res)
        {
            rt_kprintf("read data failed!size is %d", res);
        }
        else
        {
            rt_kprintf("light:%4d.%d lux\n", data.data.light / 10, data.data.light % 10);
        }
        rt_thread_mdelay(1000);
    }
}

int bh1750_example(void)
{
    rt_thread_t tid;    /* 執行緒句柄 */

    tid = rt_thread_create("bh1750_thread",
                            bh1750_thread_entry,
                            RT_NULL,
                            1024,
                            20,
                            10);
   if(tid != RT_NULL)
   {
        /* 執行緒創建成功,啟動執行緒 */
        rt_thread_startup(tid);
   }

   return 0;
}

/* 導出到 msh 命令列表中 */
MSH_CMD_EXPORT(bh1750_example, bh1750 example);

運行結果:

twfLBq.png

使用RT-Thread提供給我的I/O設備管理介面rt_device_find、rt_device_open、rt_device_read、rt_device_close來編寫應用。相關框圖:

twfT3Q.png

twfHjs.png
twfqun.png

關於RT-Thread的I/O設備模型可查看往期筆記:【RT-Thread筆記】IO設備模型

以上就是本次的分享,如有錯誤,歡迎指出!


我的個人部落格://www.lizhengnian.cn/

我的微信公眾號:嵌入式大雜燴

我的CSDN部落格://blog.csdn.net/zhengnianli