stm32超声波测距完整代码
时间: 2023-05-10 22:02:50 浏览: 142
由于STM32芯片在嵌入式系统中应用广泛,因此在控制与检测方面也被广泛使用。超声波测距系统作为一种实用的检测手段,也常常被应用于STM32芯片。下面将简要介绍STM32超声波测距的完整代码。
首先,我们需要准备一些基础设备,主要包括STM32开发板、超声波传感器、控制器等。接下来,需要做的是用C语言编写一个中断程序,来实现超声波测距的功能。具体的代码如下:
首先介绍程序的一个函数:void Init_TIM2(void)。该函数用于初始化定时器2,设置其为计数器模式,并设置时钟频率为SysClk/1000。该函数内的代码如下:
void Init_TIM2(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_DeInit(TIM2);
TIM_TimeBaseStructure.TIM_Period = 0xffff;
TIM_TimeBaseStructure.TIM_Prescaler = 72-1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
}
上述代码中,我们设置了定时器2的时钟频率为SysClk/1000,这里假设STM32芯片的时钟频率为72Mhz。同时,我们还设置了中断优先级等参数。
接下来,我们需要写一个函数来控制超声波传感器的触发信号。该函数如下:
void SendTrig(void)
{
GPIO_SetBits(GPIOA, GPIO_Pin_1);
delay_us(10);
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
在上述代码中,我们使用GPIO_SetBits和GPIO_ResetBits两个函数来控制超声波传感器的触发信号。我们的目的是在引脚1上输出一个10us的高电平脉冲波。
接下来,我们需要编写主函数,以便对上述函数进行调用。具体实现如下:
#include "stm32f10x.h"
#include "sys.h"
void Init_TIM2(void);
void delay_us(__IO uint32_t nTime);
void SendTrig(void);
volatile uint16_t Cnt;
volatile uint32_t CarValue = 0;
int main(void)
{
SysClockInit();
TIM_DeInit(TIM2);
Init_TIM2();
TIM_Cmd(TIM2, DISABLE);
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
while (1)
{
SendTrig();
TIM_SetCounter(TIM2, 0);
TIM_Cmd(TIM2, ENABLE);
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == RESET);
TIM_Cmd(TIM2, DISABLE);
CarValue = TIM_GetCounter(TIM2);
printf("distance:%d\r\n", CarValue/58);
delay_ms(200);
}
}
上述代码中,我们首先初始化系统时钟,并调用了前面提到的函数Initialize_TIM2来初始化定时器2。同时,我们还需要设置GPIO口的相关参数,如上述代码中的GPIO_InitStructure结构体。
在主函数中,我们需要周期性地向超声波传感器发送一个触发信号,并将定时器2计数清零,并开始计数。当超声波传感器捕捉到回波信号时,立即停止计数,并计算出测量的距离,最后输出到终端。以上过程通过while循环来实现,按照需要可以周期性地进行测距操作。
综上所述,上述代码可以实现超声波测距功能,且精准度较高。简化版代码如下:
```
#include "stm32f10x.h"
#include "sys.h"
void delay_us(__IO uint32_t nTime);
void SendTrig(void);
volatile uint16_t Cnt;
volatile uint32_t CarValue = 0;
int main(void)
{
SysClockInit();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
while (1)
{
SendTrig();
delay_us(10);
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == RESET);
TIM2->CNT=0;
TIM_Cmd(TIM2, ENABLE);
while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == SET);
TIM_Cmd(TIM2, DISABLE);
CarValue = TIM2->CNT;
printf("%d cm \r\n",CarValue/58);
delay_ms(200);
}
}
void SendTrig()
{
GPIO_SetBits(GPIOA,GPIO_Pin_1);
delay_us(10);
}
void delay_us(__IO uint32_t nTime)
{
u8 t;
while(nTime--)
{
t=7;
while(t--);
}
}
```
需要注意的是,在实际应用中,如何根据系统硬件特性和实时工作状态进行代码优化,是控制系统设计中需要考虑的因素之一。祝愿读者在工程实践中取得不断进步。