• stm32f103+HC-SR04+ssd1306实现超声波测距


    🙌秋名山码民的主页
    😂oi退役选手,Java、大数据、单片机、IoT均有所涉猎,热爱技术,技术无罪
    🎉欢迎关注🔎点赞👍收藏⭐️留言📝
    获取源码,添加WX


    前言

    如果你经常做一些嵌入式设备,HC-SR04应该不陌生,一款便宜简单的超声波测距装置,可以应用在智能小车测距壁障,航模飞行器定高等。这篇文章简单讲解,通过一个示例来揉和。

    硬件模块:

    1. stm32f103
    2. HC-SR04
    3. oled 0.96寸显示屏

    HC-SR04讲解

    在这里插入图片描述
    工作原理:

    1. 发射器:HC-SR04模块的发射器会发射一系列的超声波脉冲信号。
    2. 接收器:当超声波信号遇到物体并被反射回来时,HC-SR04模块的接收器会接收到反射的超声波信号。
    3. 时间测量:HC-SR04模块通过测量从发送到接收超声波信号的时间差来计算距离。

    基本结构:

    1. 发射器(Transmitter):发射高频超声波脉冲信号。
    2. 接收器(Receiver):接收反射回来的超声波信号。
    3. 控制电路(Control Circuit):控制发射和接收的时序,并计算距离。
    4. 超声波传感器(Ultrasonic Sensor):包含发射器和接收器。

    使用步骤:

    1. 设置引脚:将HC-SR04模块的Trig引脚连接到单片机的一个GPIO输出引脚,将Echo引脚连接到单片机的一个GPIO输入引脚。
    2. 发射信号:通过将Trig引脚设置为高电平,持续10微秒,然后再将其拉低,来触发模块发射超声波信号。
    3. 接收信号:开始计时,等待Echo引脚由低电平变为高电平,记录时间。
    4. 计算距离:根据时间差和声速的关系,计算出测量到的距离。

    接口:
    VCC供5V电源,GND为地线,TRIG触发控制信号输入,ECHO回响信号

    时序触发图:
    在这里插入图片描述
    不难看出,先触发唤醒,然后其自动发射,8个40kHz脉冲,用定时器来获取其来回的时间,除以2就是其距离。

    代码编程

    #include "stm32f1xx_hal.h"
    #include "ssd1306.h"
    
    #define TRIG_PIN GPIO_PIN_0
    #define ECHO_PIN GPIO_PIN_1
    #define TRIG_PORT GPIOA
    #define ECHO_PORT GPIOA
    
    uint32_t distance = 0;
    char display_buffer[16];
    
    void SystemClock_Config(void);
    void GPIO_Init(void);
    void I2C_Init(void);
    void Ultrasonic_Init(void);
    void Ultrasonic_MeasureDistance(void);
    void OLED_DisplayDistance(void);
    void HAL_SYSTICK_Callback(void);
    
    int main(void)
    {
        HAL_Init();
        SystemClock_Config();
        GPIO_Init();
        I2C_Init();
        Ultrasonic_Init();
        ssd1306_Init();
    
        while (1)
        {
            Ultrasonic_MeasureDistance();
            OLED_DisplayDistance();
            HAL_Delay(1000);
        }
    }
    
    void SystemClock_Config(void)
    {
        RCC_OscInitTypeDef RCC_OscInitStruct;
        RCC_ClkInitTypeDef RCC_ClkInitStruct;
    
        __HAL_RCC_PWR_CLK_ENABLE();
        __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    
        RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
        RCC_OscInitStruct.HSIState = RCC_HSI_ON;
        RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
        RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
        if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
        {
            Error_Handler();
        }
    
        RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
        RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
        RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
        RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
        RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
        if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
        {
            Error_Handler();
        }
    
        HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
        HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
    
        HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
    }
    
    void GPIO_Init(void)
    {
        GPIO_InitTypeDef GPIO_InitStruct;
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
        GPIO_InitStruct.Pin = TRIG_PIN;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(TRIG_PORT, &GPIO_InitStruct);
    
        GPIO_InitStruct.Pin = ECHO_PIN;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
        HAL_GPIO_Init(ECHO_PORT, &GPIO_InitStruct);
    }
    
    void I2C_Init(void)
    {
        GPIO_InitTypeDef GPIO_InitStruct;
    
        __HAL_RCC_GPIOB_CLK_ENABLE();
        __HAL_RCC_AFIO_CLK_ENABLE();
    
        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
        __HAL_AFIO_REMAP_I2C1_ENABLE();
    
        __HAL_RCC_I2C1_CLK_ENABLE();
    
        I2C_HandleTypeDef hi2c1;
        hi2c1.Instance = I2C1;
        hi2c1.Init.ClockSpeed = 400000;
        hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
        hi2c1.Init.OwnAddress1 = 0;
        hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
        hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
        hi2c1.Init.OwnAddress2 = 0;
        hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
        hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
        if (HAL_I2C_Init(&hi2c1) != HAL_OK)
        {
            Error_Handler();
        }
    
        __HAL_RCC_GPIOB_CLK_ENABLE();
        GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    }
    
    void Ultrasonic_Init(void)
    {
        // 配置超声波传感器
        GPIO_InitTypeDef GPIO_InitStruct;
    
        __HAL_RCC_GPIOA_CLK_ENABLE();
    
        GPIO_InitStruct.Pin = TRIG_PIN;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(TRIG_PORT, &GPIO_InitStruct);
    
        GPIO_InitStruct.Pin = ECHO_PIN;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
        HAL_GPIO_Init(ECHO_PORT, &GPIO_InitStruct);
    }
    
    void Ultrasonic_MeasureDistance(void)
    {
        HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_SET);
        HAL_Delay(10);
        HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET);
    
        while (HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) == GPIO_PIN_RESET);
        uint32_t start = HAL_GetTick();
        while (HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN) == GPIO_PIN_SET);
        uint32_t end = HAL_GetTick();
    
        distance = (end - start) * 0.034 / 2;
    }
    
    void OLED_DisplayDistance(void)
    {
        sprintf(display_buffer, "%d cm", distance);
    
        ssd1306_Fill(Black);
        ssd1306_SetCursor(25, 25);
        ssd1306_WriteString(display_buffer, Font_11x18, White);
        ssd1306_UpdateScreen();
    }
    
    void HAL_SYSTICK_Callback(void)
    {
        HAL_IncTick();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170

    最后

    如果本文对你有所帮助,还请三连支持一下博主!
    请添加图片描述

  • 相关阅读:
    UWB学习——day4
    ivew button 使用自定义图标
    Lumion和Enscape渲染器有什么区别?哪个适合你
    基于j2ee的交通管理信息系统/交通管理系统
    springboot源码理解十、自定义starter改造
    奔赴山海之前,毕业季一定要做的那些事情
    LaTex排版系统:TeX Live+Visual Studio Code的配置
    利用拦截器加缓存完成接口防刷操作
    第一章《嵌入式系统原理与实践》--沈建华 王慈 清华大学出版社 课后部分习题个人答案
    对Java平台的理解
  • 原文地址:https://blog.csdn.net/weixin_45920495/article/details/134257398