ESP32 - ULP 協處理器在低功耗模式下讀片內霍爾傳感器 HALL SENSOR

ESP32 - ULP 協處理器在低功耗模式下讀片內霍爾傳感器 HALL SENSOR

本文提供了 ESP32 - ULP 協處理器如何在低功耗模式下讀片內霍爾傳感器的例子

1. 霍爾傳感器

根據霍爾效應,當電流垂直於磁場通過 N 型半導體時,會在垂直於電流和磁場的方向產生附加電場,從而在半導體兩端形成電勢差,具體高低與電磁場的強度和電流大小有關。當恆定電流穿過磁場或電流存在於恆定磁場時,霍爾效應傳感器可用於測量磁場強度。霍爾傳感器的應用場合非常廣泛,包括接近探測、定位、測速與電流檢測等。

2. 霍爾傳感器讀取示例

本例子 ULP 協處理器每隔 3 S 喚醒一次,喚醒後在低功耗模式下讀取霍爾傳感器值, 通過 hall phase shift 兩次,讀取 vp 和 vn 值 各兩次一共四個值,減去共模的部分可以得出 offset 值,這個值可以用來表徵環境對霍爾傳感器的影響。如圖,第一次打印的數值是周圍未有強磁場的情況下測得的霍爾傳感器數值;第二次打印的數值是使用了一枚釹鐵硼磁鐵的 N 極接近 ESP32 時獲取的數值;第三次打印的數值是釹鐵硼磁鐵的 S 極接近 ESP32 時獲取的數值,可以看出霍爾傳感器的數值發生了較大的變化。

hall_sensor

3. 系統連接

HALL SENSOR 和 SAR ADC 連接情況見下圖,HALL SENSOR 的 SENSOR_VP 和 SENSOR_VN 管腳分別連接到 SAR ADC1 的 SAR_MUX = 1 和 SAR_MUX = 4 上。

sar_adc

下表是 SAR ADC1 的輸入信號及 SAR_MUX 通道

信號名/GPIO SAR_ADC1,SAR_MUX
SENSOR_VP (GPIO36) 1
SENSOR_CAPP (GPIO37) 2
SENSOR_CAPN (GPIO38) 3
SENSOR_VN (GPIO39) 4
32K_XP (GPIO33) 5
32K_XN (GPIO32) 6
VDET_1 (GPIO34) 7
VDET_2 (GPIO35) 8

4. 編譯配置及燒錄程序

ESP32 的 C 語言編譯環境安裝和配置參照 鏈接地址,另外 ULP 協處理器目前只支持彙編編程,所以還需要安裝彙編工具鏈,下面介紹彙編工具鏈的安裝和配置。

4.1 彙編環境的配置

ULP 協處理器配置彙編編譯工具鏈,只需兩步即可安裝配置完畢,下面給出 ubuntu 操作系統下配置的步驟,或者點擊 鏈接地址 獲得更多 ULP 編程信息

  • 第一步, 下載工具鏈 binutils-esp32ulp toolchain 鏈接地址, 解壓到需要安裝的目錄
  • 第二步,添加工具鏈的 bin 目錄到系統環境變量 PATH 中。例如我的解壓目錄是 /opt/esp32ulp-elf-binutils 那麼添加 export PATH=/opt/esp32ulp-elf-binutils/bin:$PATH 這一行到 /home 目錄的隱藏文件 .bashrc 文件最後一行,保存關閉文件並使用命令 source .bashrc 使上述環境變量生效
4.2 配置編譯燒錄

至此,彙編編譯環境就安裝好了,在 esp-iot-solution /examples/ulp_hall_sensor/ 目錄下依次運行以下命令,進行 default config 配置並編譯、燒錄程序。

  • make defconfig
  • make all -j8 && make flash monitor

5. 軟件分析

ULP 協處理器沒有內置讀霍爾傳感器相關的彙編指令,所以我們需要設置相關寄存器來讀取片內霍爾傳感器。

void init_ulp_program() 函數中設置 ADC1 通道 1/2 輸入電壓衰減,用戶可以自己定義這個衰減值,較大的衰減將得到較小的 ADC 值。

    /* The ADC1 channel 0 input voltage will be reduced to about 1/2 */
    adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_6);
    /* The ADC1 channel 3 input voltage will be reduced to about 1/2 */
    adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_6);
    /* ADC capture 12Bit width */
    adc1_config_width(ADC_WIDTH_BIT_12);
    /* enable adc1 */
    adc1_ulp_enable();                 

在超低功耗模式下,需要預先設置相關的寄存器之後纔可以通過 SAR ADC1 來讀取 HALL SENSOR 值。

    /* SENS_XPD_HALL_FORCE = 1, hall sensor force enable, XPD HALL is controlled by SW */
    WRITE_RTC_REG(SENS_SAR_TOUCH_CTRL1_REG, SENS_XPD_HALL_FORCE_S, 1, 1)

    /* RTC_IO_XPD_HALL = 1, xpd hall, Power on hall sensor and connect to VP and VN */
    WRITE_RTC_REG(RTC_IO_HALL_SENS_REG, RTC_IO_XPD_HALL_S, 1, 1)

    /* SENS_HALL_PHASE_FORCE = 1, phase force, HALL PHASE is controlled by SW */
    WRITE_RTC_REG(SENS_SAR_TOUCH_CTRL1_REG, SENS_HALL_PHASE_FORCE_S, 1, 1)

    /* RTC_IO_HALL_PHASE = 0, phase of hall sensor */
    WRITE_RTC_REG(RTC_IO_HALL_SENS_REG, RTC_IO_HALL_PHASE_S, 1, 0)

    /* SENS_FORCE_XPD_SAR, Force power up */
    WRITE_RTC_REG(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR_S, 2, SENS_FORCE_XPD_SAR_PU)

之後,使用 ADC 指令多次讀取片內霍爾傳感器 phase_vp 和 phase_vn 的值,累加並計算平均值後,將霍爾傳感器值保存到 Sens_Vp0Sens_Vn0 這兩變量中。

    /* do measurements using ADC */
    /* r2, r3 will be used as accumulator */
    move r2, 0
    move r3, 0  
    /* initialize the loop counter */
    stage_rst
measure0:
    /* measure Sar_Mux = 1 to get vp0   */
    adc r0, 0, 1
    add r2, r2, r0

    /* measure Sar_Mux = 4 to get vn0 */
    adc r1, 0, 4
    add r3, r3, r1

    /* increment loop counter and check exit condition */
    stage_inc 1
    jumps measure0, adc_oversampling_factor, lt

    /* divide accumulator by adc_oversampling_factor.
       Since it is chosen as a power of two, use right shift */
    rsh r2, r2, adc_oversampling_factor_log

    /* averaged value is now in r2; store it into Sens_Vp0 */
    move r0, Sens_Vp0
    st r2, r0, 0

    /* r3 divide 4 which means rsh 2 bits */
    rsh r3, r3, adc_oversampling_factor_log
    /* averaged value is now in r3; store it into Sens_Vn0 */
    move r1, Sens_Vn0
    st r3, r1, 0

接下來,需要 shift 霍爾傳感器的 phase,設置寄存器 RTC_IO_HALL_SENS_REGRTC_IO_HALL_PHASE 位置 1 , 並再次讀取片內霍爾傳感器 phase_vp 和 phase_vn 的值,同上,累加並計算平均值後,保存到 Sens_Vp1Sens_Vn1 中。

    /* RTC_IO_HALL_PHASE = 1, phase of hall sensor */
    WRITE_RTC_REG(RTC_IO_HALL_SENS_REG, RTC_IO_HALL_PHASE_S, 1, 1)

最後,在喚醒主 CPU 後,通過以上四個數值計算出 offset 的值並打印出來。

static void print_hall_sensor()
{
    printf("ulp_hall_sensor:Sens_Vp0:%d,Sens_Vn0:%d,Sens_Vp1:%d,Sens_Vn1:%d\r\n",
        (uint16_t)ulp_Sens_Vp0,(uint16_t)ulp_Sens_Vn0,(uint16_t)ulp_Sens_Vp1,(uint16_t)ulp_Sens_Vn1);  
    printf("offset:%d\r\n",  ((uint16_t)ulp_Sens_Vp0 - (uint16_t)ulp_Sens_Vp1) - ((uint16_t)ulp_Sens_Vn0 - (uint16_t)ulp_Sens_Vn1));
}

6. 總結

ESP32 中的霍爾傳感器經過專門設計,可向低噪放大器和 SAR ADC 提供電壓信號,實現磁場傳感功能。在超低功耗模式下,該傳感器可由 ULP 協處理器控制。ESP32 內置了霍爾傳感器在位置傳感、接近檢測、測速以及電流檢測等應用場景下成爲一種極具吸引力的解決方案。

7. 參考文檔

  1. esp32_technical_reference_manual_cn.pdf 文檔的 27.5 霍爾傳感器
  2. esp32_technical_reference_manual_cn.pdf 文檔的 27.3 逐次逼近數字模擬轉換器
發佈了55 篇原創文章 · 獲贊 72 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章