網(wǎng)站建設(shè)項(xiàng)目經(jīng)理考題怎么seo網(wǎng)站關(guān)鍵詞優(yōu)化
上節(jié)我們學(xué)的是溫濕傳感器,這節(jié)我們學(xué)的是姿態(tài)傳感器,雖然都是傳感器,但是它們還是有很大的區(qū)別的,這節(jié)的傳感器我們通過(guò)學(xué)習(xí)可知,開(kāi)發(fā)板上的姿態(tài)傳感器型號(hào)是QMI8658C,內(nèi)部集成3軸加速度傳感器和3軸陀螺儀傳感器,支持SPI和I2C通信,在我們的開(kāi)發(fā)板上使用的是I2C通信,ESP32-C3只有1個(gè)I2C外設(shè),我們開(kāi)發(fā)板上的所有I2C設(shè)備,都使用一個(gè)I2C通信接口,通過(guò)I2C設(shè)備的地址,來(lái)決定和誰(shuí)通信,QMI8658C的I2C地址是0x6A,這個(gè)項(xiàng)目,我們將最終完成測(cè)量XYZ三個(gè)軸的角度,把角度數(shù)據(jù)通過(guò)串口傳輸?shù)浇K端
接著,我們要進(jìn)行編寫QMI8658C驅(qū)動(dòng)程序
這個(gè)和溫濕傳感器大致相似,也是使用sample project作為模板,們復(fù)制esp-idf-v5.1.3\examples\get-started\sample_project這個(gè)工程到我們的實(shí)驗(yàn)文件夾,然后把這個(gè)文件夾的名稱修改為attitude,attitude是姿態(tài)的意思。
接著,進(jìn)行我們經(jīng)常的操作,在vscode中打開(kāi)attitude文件夾,我們先點(diǎn)擊打開(kāi)attitude工程目錄下的CMakeList.txt文件,修改工程的名稱為attitude,然后保存關(guān)閉此文件(這步一般來(lái)說(shuō)是我們的第一步,也就是我們的文件名)
project(attitude)
我們這個(gè)項(xiàng)目需要用到I2C通信,現(xiàn)在我們把溫濕度例程里面的myi2c.h和myi2c.c文件復(fù)制到attitude工程中的main目錄下,然后我們點(diǎn)開(kāi)main目錄下的CMakeLists.txt文件,可以看到myi2c.c文件已經(jīng)添加到編譯路徑
idf_component_register(SRCS "myi2c.c" "main.c"INCLUDE_DIRS ".")
點(diǎn)擊打開(kāi)qmi8658c.h文件,在最上面添加#pragma once
#pragma once
點(diǎn)擊打開(kāi)qmi8658c.c文件,在最上面添加包含qmi8658c.h文件
#include "qmi8658c.h"
點(diǎn)擊打開(kāi)main.c文件,添加頭文件
#include "myi2c.h"
#include "qmi8658c.h"
在app_main函數(shù)中,先調(diào)用I2C初始化函數(shù)
void app_main(void)
{ESP_ERROR_CHECK(i2c_master_init());ESP_LOGI(TAG, "I2C initialized successfully");
}
函數(shù)里使用到了ESP_LOGI,需要包含esp_log.h頭文件
#include "esp_log.h"
還需要給ESP_LOGI里面的TAG定義一下
static const char *TAG = "MAIN";
接下來(lái),開(kāi)始寫qmi8658c的驅(qū)動(dòng)函數(shù),通過(guò)課程視頻學(xué)習(xí),我們先寫兩個(gè)讀取qmi8658c寄存器的函數(shù)和寫入qmi8658c寄存器的函數(shù),寫入函數(shù)用于配置傳感器的參數(shù),讀取函數(shù)用于讀取傳感器的寄存器數(shù)據(jù),例如ID號(hào),狀態(tài)等,這兩個(gè)函數(shù)放入qmi8658c.c文件中
esp_err_t qmi8658c_register_read(uint8_t reg_addr, uint8_t *data, size_t len)
{return i2c_master_write_read_device(I2C_MASTER_NUM, QMI8658C_SENSOR_ADDR, ®_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
}esp_err_t qmi8658c_register_write_byte(uint8_t reg_addr, uint8_t data)
{uint8_t write_buf[2] = {reg_addr, data};return i2c_master_write_to_device(I2C_MASTER_NUM, QMI8658C_SENSOR_ADDR, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
}
然后我們?cè)趒mi8658c.c文件中添加這兩個(gè)函數(shù)需要的頭文件
#include "driver/i2c.h"
#include "myi2c.h"
函數(shù)里面用到了QMI8658C_SENSOR_ADD,我們?cè)趒mi8658c.h文件中定義一下
#define QMI8658C_SENSOR_ADDR 0x6A
接下來(lái),我們需要寫一個(gè)qmi8658c初始化函數(shù),用于讀取ID號(hào),配置加速度、陀螺儀范圍等參數(shù)。這個(gè)函數(shù)涉及到了qmi8658c的寄存器,所以我們先用枚舉類型定義寄存器,放到qmi8658c.h文件中
enum qmi8658c_reg
{QMI8658C_WHO_AM_I,QMI8658C_REVISION_ID,QMI8658C_CTRL1,QMI8658C_CTRL2,QMI8658C_CTRL3,QMI8658C_CTRL4,QMI8658C_CTRL5,QMI8658C_CTRL6,QMI8658C_CTRL7,QMI8658C_CTRL8,QMI8658C_CTRL9,QMI8658C_CATL1_L,QMI8658C_CATL1_H,QMI8658C_CATL2_L,QMI8658C_CATL2_H,QMI8658C_CATL3_L,QMI8658C_CATL3_H,QMI8658C_CATL4_L,QMI8658C_CATL4_H,QMI8658C_FIFO_WTM_TH,QMI8658C_FIFO_CTRL,QMI8658C_FIFO_SMPL_CNT,QMI8658C_FIFO_STATUS,QMI8658C_FIFO_DATA,QMI8658C_I2CM_STATUS = 44,QMI8658C_STATUSINT,QMI8658C_STATUS0,QMI8658C_STATUS1,QMI8658C_TIMESTAMP_LOW,QMI8658C_TIMESTAMP_MID,QMI8658C_TIMESTAMP_HIGH,QMI8658C_TEMP_L,QMI8658C_TEMP_H,QMI8658C_AX_L,QMI8658C_AX_H,QMI8658C_AY_L,QMI8658C_AY_H,QMI8658C_AZ_L,QMI8658C_AZ_H,QMI8658C_GX_L,QMI8658C_GX_H,QMI8658C_GY_L,QMI8658C_GY_H,QMI8658C_GZ_L,QMI8658C_GZ_H,QMI8658C_MX_L,QMI8658C_MX_H,QMI8658C_MY_L,QMI8658C_MY_H,QMI8658C_MZ_L,QMI8658C_MZ_H,QMI8658C_dQW_L = 73,QMI8658C_dQW_H,QMI8658C_dQX_L,QMI8658C_dQX_H,QMI8658C_dQY_L,QMI8658C_dQY_H,QMI8658C_dQZ_L,QMI8658C_dQZ_H,QMI8658C_dVX_L,QMI8658C_dVX_H,QMI8658C_dVY_L,QMI8658C_dVY_H,QMI8658C_dVZ_L,QMI8658C_dVZ_H,QMI8658C_AE_REG1,QMI8658C_AE_REG2,QMI8658C_RESET = 96
};
結(jié)合QMI8658C的數(shù)據(jù)手冊(cè)中的寄存器定義表格,寫出這個(gè)枚舉定義。枚舉類型的第一個(gè)值默認(rèn)是0,和寄存器WHO_AM_I的地址一樣,所以不用標(biāo)出,然后依次遞增,遇到地址不連續(xù)的寄存器地址時(shí),單獨(dú)標(biāo)出,最后的結(jié)果如上代碼所示
接下來(lái)寫qmi8658c初始化函數(shù)到qmi8658c.c文件
void qmi8658c_init(void)
{uint8_t id = 0;qmi8658c_register_read(QMI8658C_WHO_AM_I, &id ,1);while (id != 0x05){vTaskDelay(1000 / portTICK_PERIOD_MS);qmi8658c_register_read(QMI8658C_WHO_AM_I, &id ,1);}ESP_LOGI(TAG, "QMI8658C OK!");qmi8658c_register_write_byte(QMI8658C_RESET, 0xb0); // 復(fù)位vTaskDelay(10 / portTICK_PERIOD_MS);qmi8658c_register_write_byte(QMI8658C_CTRL1, 0x40); // CTRL1 設(shè)置地址自動(dòng)增加qmi8658c_register_write_byte(QMI8658C_CTRL7, 0x03); // CTRL7 允許加速度和陀螺儀qmi8658c_register_write_byte(QMI8658C_CTRL2, 0x95); // CTRL2 設(shè)置ACC 4g 250Hzqmi8658c_register_write_byte(QMI8658C_CTRL3, 0xd5); // CTRL3 設(shè)置GRY 512dps 250Hz
}
初始化函數(shù)里面,首先讀取qmi8658c的ID號(hào),如果不正確,就繼續(xù)讀,如果正確,往下執(zhí)行。確定qmi8658c沒(méi)有問(wèn)題,先復(fù)位芯片,然后進(jìn)行配置。CTRL1,配置地址自動(dòng)增加后,我們讀取一連串的加速度和陀螺儀數(shù)據(jù),只寫個(gè)首地址就可以連續(xù)讀了。CTRL2配置加速度的量程和輸出速率,CTRL3配置陀螺儀的量程和輸出速率,CTRL7配置允許加速度和陀螺儀
函數(shù)里面用到了ESP_LOGI,用來(lái)輸出信息,這里的TAG,需要定義。我們把這個(gè)TAG定義,放到qmi8658c.c文件中的包含頭文件的下面
static const char *TAG = "QMI8658C";
函數(shù)里面使用了freeRTOS的延時(shí)函數(shù),所以需要包含freeRTOS頭文件
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
函數(shù)中也用到了ESP_LOGI宏,所以需要再添加它的頭文件
#include "esp_log.h"
現(xiàn)在我們把這個(gè)函數(shù)的聲明寫到qmi8658c.h文件
extern void qmi8658c_init(void);
接下來(lái)我們?cè)趍ain.c文件中的app_main函數(shù)中調(diào)用這個(gè)初始化函數(shù)
void app_main(void)
{ESP_ERROR_CHECK(i2c_master_init());ESP_LOGI(TAG, "I2C initialized successfully");qmi8658c_init();
}
我們可以試編譯一下,看看運(yùn)行結(jié)果,依次配置VSCode左下角的配置選項(xiàng),串口號(hào)、目標(biāo)芯片、下載方式、menuconfig里面,把FLASH大小修改為8MB,其它不做修改。
好了,到這兒我們的姿態(tài)傳感器上半部分結(jié)束!