LiteOS基於Sensorhub的超聲波模組移植

摘要:本文爲你帶來LiteOS基於Sensorhub的超聲波模組移植的應用。

一、Sensor Hub

LiteOS傳感框架即Sensor Hub,是一個基於Huawei LiteOS物聯網操做系統的傳感器管理框架。面試

隨着物聯網的發展,物聯網終端愈來愈智能化,例如在我的穿戴、智能家居、家用醫療等終端上將配置愈來愈多的傳感器,來獲取更多傳感數據,使終端更加智能,使得開發和維護變得複雜和困難。LiteOS傳感框架將物聯網終端設備上例如加速計(Accelerometer)、陀螺儀(Gyroscope)、氣壓儀(Barometer)、溫溼度計(Humidometer)等不一樣類型的傳感器統一管理,經過抽象不一樣類型傳感器接口,屏蔽其硬件細節,作到「硬件」無關性,很是方便於物聯網設備的開發、維護和功能擴展。算法

LiteOS傳感框架主要包括了Sensor Manager、BSP manager,Converged Algorithms。segmentfault

  • Sensor Manager:統一的傳感器交互管理,如Sensor的配置、採樣、上報和管理。
  • BSP Manager:統一的驅動接口,負責Sensor驅動管理、電源管理、Sensor交互管理,如Sensor的打開、關閉、讀寫、數據更新等。
  • Converged Algorithms:融合算法庫(算法基於具體的業務模型),根據具體業務模型,在端側MCU進行算法融合,例如環境監測算法、計步算法等,從傳統、簡單採集算法升級到智能算法,應用直接調用,提高傳感數據的業務精準度,下降數據採集時延。

二、SR04超聲波模組

HC-SR04超聲波測距模塊可提供2cm-400cm的非接觸式距離感測功能,測距精度可達高到3mm;模塊包括超聲波發射器、接收器與控制電路。基本工做原理:(1)採用IO口TRIG觸發測距,給至少10us的高電平信號;(2)模塊自動發送8個40khz的方波,自動檢測是否有信號返回;(3)有信號返回,經過IO口ECHO輸出一個高電平,高電平持續的時間就是超聲波從發射到返回的時間。測試距離=(高電平時間聲速(340M/S))/2;二、實物圖:如右圖接線,VCC供5V電源,GND爲地線,TRIG觸發控制信號輸入,ECHO迴響信號輸出等四支線。圖一實物圖三、電氣參數:電氣參數HC-SR04超聲波模塊工做電壓DC 5 V工做電流15mA工做頻率40Hz最遠射程4m最近射程2cm測量角度15度輸入觸發信號10uS的TTL脈衝輸出迴響信號輸出TTL電平信號,與射程成比例規格尺寸4520*15mm。框架

從時序圖代表你只須要提供一個10uS以上脈衝觸發信號,該模塊內部將發出8個40kHz週期電平並檢測回波。一旦檢測到有回波信號則輸出迴響信號。迴響信號的脈衝寬度與所測的距離成正比。由此經過發射信號到收到的迴響信號時間間隔能夠計算獲得距離。公式:uS/58=釐米或者uS/148=英寸;或是:距離=高電平時間*聲速(340M/S)/2;建議測量週期爲60ms以上,以防止發射信號對迴響信號的影響。dom

三、sensorhub的HC-SR04驅動

經過時序圖能夠完成一個簡單的讀取傳感器的接收程序:(這裏用GPIOA1和GPIOA4舉例)測試

uint32_t hcsr04_read (void)
{
 local_time=0;
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);  // pull the TRIG pin HIGH
 delay(2);  // wait for 2 us


 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);  // pull the TRIG pin HIGH
 delay(10);  // wait for 10 us
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);  // pull the TRIG pin low

 // read the time for which the pin is high

 while (!(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)));  // wait for the ECHO pin to go high
 while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4))    // while the pin is high
  {
  local_time++;   // measure time for which the pin is high
  delay (1);
  }
 return local_time * .034/2; 
}

四、將驅動註冊到SensorHub上

先寫iO操做,初始化、打開、關閉和讀取數據的操做ui

STATIC INT32 SR04Init(SensorType *sensor)
{
    (VOID)(sensor);
 
  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin : PD11 */
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PD12 PD13 PD14 PD15 */
  GPIO_InitStruct.Pin = GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    return LOS_OK;
}
STATIC INT32 SR04ReadData(SensorType *sensor)
{
    PRINTK("read datan");
    INT32 *data = (INT32 *)sensor->sensorData;
    data[0] =  hcsr04_read();
     return LOS_OK;
}
STATIC INT32 SR04Open(SensorType *sensor, OpenParam *para)
{
    UINT32 ret;
    (VOID)(para);

    SR04 *SR04 = (SR04 *)sensor->priv;

    if ((sensor->sensorStat == SENSOR_STAT_OPEN) && (sensor->interval == SR04Period)) {
        return LOS_OK;
    }

    if (SR04->gyroTimerId != INVALID_TIMER_ID) {
        ret = LOS_SwtmrDelete(SR04->gyroTimerId);
        SR04->gyroTimerId = INVALID_TIMER_ID;
        if (ret != LOS_OK) {
            PRINT_ERR("delete a timer failed!n");
            return LOS_NOK;
        }
    }

    // creat a timer, first parameter is ticks.
    ret = LOS_SwtmrCreate(sensor->interval, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)GypoTimerFunc, &SR04->gyroTimerId, (UINT32)sensor);
    if (ret != LOS_OK) {
        PRINT_ERR("creat a timer failed!n");
        return LOS_NOK;
    }

    ret = LOS_SwtmrStart(SR04->gyroTimerId);
    if (ret != LOS_OK) {
        PRINT_ERR("start timer errn");
    }

    SR04Period = sensor->interval;

    PRINTK("SR04 on.n");
    return LOS_OK;
}

STATIC INT32 SR04Close(SensorType *sensor)
{
    UINT32 ret;

    if (sensor->sensorStat == SENSOR_STAT_CLOSE) {
        PRINT_DEBUG("sr04 has been closedn");
        return LOS_OK;
    }

    __HAL_RCC_GPIOA_CLK_DISABLE();

    PRINTK("SR04 off.n");
    return LOS_OK;
}

而後將設計的驅動註冊到框架上spa

STATIC struct SensorOperation Sr04Ops = {
    .Init = SR04Init,
    .Open = SR04Open,
    .Close = SR04Close,
    .ReadData = SR04ReadData,
};

STATIC SensorType g_sensorSR04 = {
    .sensorOp = &Sr04Ops,
    .sensorData = &g_SR04Data,
    .sensorDataLen = sizeof(g_SR04Data),
    .priv = &g_SR04Priv,
    .tag = TAG_BEGIN,
    .cmd = CMD_CMN_INTERVAL_REQ,
    .interval = DEFAULT_INTERVAL,

};
VOID SR04Register(VOID)
{
    SensorRegister(&g_sensorSR04);
}

將驅動註冊到通用sensor驅動模塊上。今天的代碼移植基本完成,後續有傳感器和板子進行驗證操作系統

總結

這個驅動是有問題,就是這個是讀取時阻塞的程序,後面試過,須要設計時採用定時器和外部中斷完成,能夠將這個阻塞的程序改爲非阻塞的,效率大大提高,後續講解如何用定時器和外部觸發中斷完成這個驅動設計。設計

點擊關注,第一時間瞭解華爲雲新鮮技術~

相關文章
相關標籤/搜索