stm32hal库超声波测距OLED
时间: 2024-12-27 19:27:24 浏览: 1
### 使用 STM32 HAL 库进行超声波测距并在 OLED 上显示
为了实现这一功能,需要完成几个主要部分的工作:初始化硬件资源、编写控制逻辑以及处理数据显示。
#### 初始化硬件资源
对于 STM32F103C8T6 板子而言,需先配置 GPIO 和定时器来驱动 HC-SR04 超声波传感器,并通过 IIC 接口连接 SSD1306 OLED 显示屏[^2]。具体来说:
- **GPIO 配置**: 设置触发脉冲 (TRIG) 输出端口和回响信号 (ECHO) 输入捕捉通道。
- **TIM 定时器配置**: 利用 TIM 的输入捕获特性测量 ECHO 信号宽度,从而计算距离[^3]。
- **IIC 总线配置**: 对于 OLED 屏幕通信,通常采用 IIC 协议传输数据给显示屏控制器。
```c
// 初始化函数声明
void MX_GPIO_Init(void);
void MX_TIM2_Init(void); // 假设使用 TIM2 进行输入捕获
void MX_I2C1_Init(void);
int main(void){
/* Reset of all peripherals, Initializes the Flash interface and Systick. */
HAL_Init();
SystemClock_Config();
// 初始化外设
MX_GPIO_Init(); // 初始化 GPIO
MX_TIM2_Init(); // 初始化用于输入捕获的定时器
MX_I2C1_Init(); // 初始化 IIC
while(1){
Measure_Distance(); // 测量距离
Display_On_OLED(); // 将结果展示到 OLED 屏幕上
HAL_Delay(500); // 添加适当延时减少刷新频率
}
}
```
#### 编写控制逻辑
当一切准备就绪之后,在 `Measure_Distance` 函数内部发送 TRIG 信号激活一次测量周期;随后等待直到收到完整的 ECHO 返回值,再利用这些信息推算实际的距离数值[^4]。
```c
#define SOUND_SPEED 34000 // 声音速度 cm/s * 1e6 us^-1
float Measure_Distance(){
uint32_t Time;
// 发送 10us 的高电平触发信号
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_SET);
__HAL_TIM_SetCounter(&htim2, 0); // 清零计数器
HAL_DelayMicroseconds(10); // 等待 10 微秒
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET);
// 启动输入捕获中断获取时间差
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
// ... 中断服务程序中读取并保存时间戳 ...
// 计算往返时间为 t = T/2; d = v*t / 2
float Distance = ((Time / 2.0) / 1000000.0) * SOUND_SPEED;
return Distance;
}
extern "C" void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){
static uint32_t IC_Val[2];
static uint8_t Index = 0;
if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1){
IC_Val[Index++] = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
if(Index >= 2){ // 当两次边沿都被记录下来后...
Time = abs(IC_Val[1]-IC_Val[0]);
// 关闭输入捕获模式防止重复触发
HAL_TIM_IC_Stop_IT(htim, TIM_CHANNEL_1);
Index=0;
}
}
}
```
#### 处理数据显示
最后一步是在 OLED 屏幕上调用相应的 API 绘制文本框或图形表示当前检测到的目标位置。这可以通过调用特定库中的绘图命令轻松达成。
```c
#include "ssd1306.h"
void Display_On_OLED(float distance){
char buffer[16];
sprintf(buffer,"Distance:%.2fcm",distance);
ssd1306_clearScreen();
ssd1306_setCursor(0, 0);
ssd1306_writeString((uint8_t*)buffer,strlen(buffer), Font_7x10, White);
ssd1306_updateScreen();
}
```
阅读全文