加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權(quán)保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 01模塊來源
    • 02 規(guī)格參數(shù)
    • 03移植過程
    • ?04移植驗證
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

【CW32模塊使用】SR04超聲波測距傳感器

09/21 08:25
648
閱讀需 18 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

01模塊來源

資料下載鏈接:https://pan.baidu.com/s/1sSah9PvLBrmbA7So-6YcSw

資料提取碼:qq35

02 規(guī)格參數(shù)

工作電壓:3-5.5V

工作電流:5.3MA

感應(yīng)角度:小于15度

探測距離:2CM-600CM

探測精度:0.1CM+1%

輸出方式: GPIO

管腳數(shù)量:4 Pin

以上信息見廠家資料文件

03移植過程

我們的目標是將例程移植至CW32F030C8T6開發(fā)板上【能夠判斷前方障礙物距離的功能】。首先要獲取資料,查看數(shù)據(jù)手冊應(yīng)如何實現(xiàn)讀取數(shù)據(jù),再移植至我們的工程。

3.1查看資料

只需要在 Trig 管腳(觸發(fā)信號)輸入一個 10US 以上的高電平,系統(tǒng)便可發(fā)出 8 個 40KHZ 的超聲波脈沖,然后檢測回波信號。當檢測到回波信號后,通過 Echo 管腳輸出。根據(jù) Echo 管腳輸出高電平的持續(xù)時間可以計算距離值。即距離值為:(高電平時間*340m/s)/2。

當測量距離超過 HC-SR04 的測量范圍時,仍會通過 Echo管腳輸出高電平的信號,高電平的寬度約為 66ms。如圖所示:

測量周期:當接收到 HC-SR04 通過 Echo 管腳輸出的高電平脈沖后,便可進行下一次測量,所以測量周期取決于測量距離,當距離被測物體很近時,Echo 返回的脈沖寬度較窄,測量周期 就很短;當距離被測物體比較遠時,Echo 返回的脈沖寬度較寬,測量周期也就相應(yīng)的變長。最壞情況下,被測物體超出超聲波模塊的測量范圍,此時 返回的脈沖寬度最長,約為 66ms,所以最壞情況下的測量周期稍大于 66ms 即可(取 70ms 足夠)。

3.2引腳選擇

接線表

3.3移植至工程

工程模板參考入門手冊的工程模板

移植步驟中的導(dǎo)入.c和.h文件與【CW32模塊使用】DHT11溫濕度傳感器相同,只是將.c和.h文件更改為bsp_ultrasonic.c與bsp_ultrasonic.h。這里不再過多講述,移植完成后面修改相關(guān)代碼。

在文件bsp_ultrasonic.c中,編寫如下代碼。

/* * Change Logs: * Date           Author       Notes * 2024-06-20     LCKFB-LP    first version */
#include "bsp_ultrasonic.h"

unsigned char msHcCount = 0;//ms計數(shù)float distance = 0;
/****************************************************************** * 函 數(shù) 名 稱:bsp_ultrasonic * 函 數(shù) 說 明:超聲波初始化 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:TRIG引腳負責發(fā)送超聲波脈沖串******************************************************************/void Ultrasonic_Init(void){        GPIO_InitTypeDef  GPIO_InitStructure;        BTIM_TimeBaseInitTypeDef BTIM_TimeBaseInitStruct; // 定時器基本初始化結(jié)構(gòu)體
        RCC_SR04_ENABLE();        // 使能GPIO時鐘        RCC_TIMER_ENABLE(); // 使能定時器時鐘
        // GPIO配置參數(shù)        GPIO_InitStructure.Pins = GPIO_TRIG;        GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; // 推挽輸出        GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
        GPIO_Init(PORT_SR04, &GPIO_InitStructure);

        GPIO_InitStructure.Pins = GPIO_ECHO;        GPIO_InitStructure.Mode = GPIO_MODE_INPUT_PULLUP; // 上拉輸入
        GPIO_Init(PORT_SR04, &GPIO_InitStructure);
        // 禁止中斷,以安全地配置NVIC        __disable_irq();
        // 開啟BTIM1中斷,并關(guān)聯(lián)到NVIC        NVIC_EnableIRQ(TIMER_IRQ);
        // 允許中斷,恢復(fù)中斷狀態(tài)        __enable_irq();
        // 配置定時器模式、周期和預(yù)分頻器        BTIM_TimeBaseInitStruct.BTIM_Mode = BTIM_Mode_TIMER; // 設(shè)置為定時器模式        BTIM_TimeBaseInitStruct.BTIM_Period = 1000 - 1;   // 設(shè)置周期,使得定時器每1ms產(chǎn)生一次溢出中斷        BTIM_TimeBaseInitStruct.BTIM_Prescaler = BTIM_PRS_DIV64; // 預(yù)分頻器設(shè)置為64,以降低時鐘頻率
    // 使用上述配置初始化定時器BTIM1        BTIM_TimeBaseInit(PORT_TIMER, &BTIM_TimeBaseInitStruct);
        // 使能BTIM1的溢出中斷        BTIM_ITConfig(PORT_TIMER, BTIM_IT_OV, ENABLE);
//        // 啟動定時器BTIM1//        BTIM_Cmd(PORT_TIMER, ENABLE);

}/****************************************************************** * 函 數(shù) 名 稱:Open_Timer * 函 數(shù) 說 明:打開定時器 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:******************************************************************/void Open_Timer(void){    BTIM_SetCounter(PORT_TIMER, 0);   // 清除定時器計數(shù)
    msHcCount = 0;
    BTIM_Cmd(PORT_TIMER, ENABLE);   // 使能定時器}
/****************************************************************** * 函 數(shù) 名 稱:Get_TIMER_Count * 函 數(shù) 說 明:獲取定時器定時時間 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:數(shù)據(jù) * 作       者:LC * 備       注:******************************************************************/uint32_t Get_TIMER_Count(void){    uint32_t time  = 0;    time   = msHcCount*1000;              // 得到us    time  += BTIM_GetCounter(PORT_TIMER); // 得到ms
    BTIM_SetCounter(PORT_TIMER, 0);   // 清除定時器計數(shù)    delay_ms(10);    return time ;}
/****************************************************************** * 函 數(shù) 名 稱:Close_Timer * 函 數(shù) 說 明:關(guān)閉定時器 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:******************************************************************/void Close_Timer(void){        BTIM_Cmd(PORT_TIMER, DISABLE);   // 關(guān)閉定時器}
/****************************************************************** * 函 數(shù) 名 稱:TIMER_IRQHandler * 函 數(shù) 說 明:定時器中斷服務(wù)函數(shù) * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:無 * 作       者:LC * 備       注:1ms進入一次******************************************************************/void TIMER_IRQHandler(void){    if (BTIM_GetITStatus(CW_BTIM1, BTIM_IT_OV))   // 檢查定時器中斷發(fā)生    {                msHcCount++;
        BTIM_ClearITPendingBit(PORT_TIMER, BTIM_IT_OV);  // 清除中斷標志    }}

/****************************************************************** * 函 數(shù) 名 稱:Hcsr04GetLength * 函 數(shù) 說 明:獲取測量距離 * 函 數(shù) 形 參:無 * 函 數(shù) 返 回:測量距離 * 作       者:LC * 備       注:無******************************************************************/float Hcsr04GetLength(void){        /*測5次數(shù)據(jù)計算一次平均值*/        float length = 0;        float t = 0;        float sum = 0;        unsigned int  i = 0;        while(i != 10)        {
                SR04_TRIG(1);//trig拉高信號,發(fā)出高電平                delay_1us(20);//持續(xù)時間超過10us                SR04_TRIG(0);//trig拉低信號,發(fā)出低電平                /*Echo發(fā)出信號 等待回響信號*/                /*輸入方波后,模塊會自動發(fā)射8個40KHz的聲波,與此同時回波引腳(echo)端的電平會由0變?yōu)?;                (此時應(yīng)該啟動定時器計時);當超聲波返回被模塊接收到時,回波引 腳端的電平會由1變?yōu)?;                (此時應(yīng)該停止定時器計數(shù)),定時器記下的這個時間即為                                                                                超聲波由發(fā)射到返回的總時長;*/
                while(SR04_ECHO() == GPIO_Pin_RESET);//echo等待回響
                Open_Timer();   //打開定時器
                i++;
                while(SR04_ECHO() == GPIO_Pin_SET);
                Close_Timer();   // 關(guān)閉定時器
                t = Get_TIMER_Count();   // 獲取時間,分辨率為1us                length = (float)t / 58.0f;   // cm                sum += length;        }
        length = sum/10;//五次平均值        distance = length;        return length;}

?

在文件bsp_ultrasonic.h中,編寫如下代碼。

/* * Change Logs: * Date           Author       Notes * 2024-06-20     LCKFB-LP    first version */#ifndef _BSP_ULTRASONIC_H_#define _BSP_ULTRASONIC_H_
#include "board.h"
#define RCC_SR04_ENABLE()     __RCC_GPIOA_CLK_ENABLE()
#define PORT_SR04             CW_GPIOA
#define GPIO_TRIG             GPIO_PIN_1#define GPIO_ECHO             GPIO_PIN_2
#define RCC_TIMER_ENABLE()    __RCC_BTIM_CLK_ENABLE()#define PORT_TIMER            CW_BTIM1
#define TIMER_IRQ             BTIM1_IRQn#define TIMER_IRQHandler      BTIM1_IRQHandler
#define SR04_TRIG(x)          GPIO_WritePin( PORT_SR04, GPIO_TRIG, x?GPIO_Pin_SET:GPIO_Pin_RESET)#define SR04_ECHO()           GPIO_ReadPin( PORT_SR04, GPIO_ECHO )
void Ultrasonic_Init(void);//超聲波初始化float Hcsr04GetLength(void );//獲取超聲波測距的距離
#endif

?04移植驗證

在自己工程中的main主函數(shù)中,編寫如下。

/* * Change Logs: * Date           Author       Notes * 2024-06-20     LCKFB-LP    first version */#include "board.h"#include "stdio.h"#include "bsp_uart.h"#include "bsp_ultrasonic.h"
int32_t main(void){    board_init();        // 開發(fā)板初始化
    uart1_init(115200);        // 串口1波特率115200
    Ultrasonic_Init();    printf("Start.......rn");
    while(1)    {        printf((const char *)"距離為 = %.2fCMrn",Hcsr04GetLength() );        delay_ms(500);    }}

移植現(xiàn)象:距離20CM處擺放障礙物,輸出換算后的實際距離。

模塊移植成功案例代碼:

鏈接:https://pan.baidu.com/s/1AwXOFbLryUoYPW-ueRZ_qA?pwd=LCKF

提取碼:LCKF

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

以開放、共享、互助為理念,致力于構(gòu)建武漢芯源半導(dǎo)體CW32系列MCU生態(tài)社區(qū)。無論是嵌入式MCU小自還是想要攻破技術(shù)難題的工程師,亦或是需求解決方案的產(chǎn)品經(jīng)理都可在CW32生態(tài)社區(qū)汲取營養(yǎng)、共同成長。

B站