stm32f103c8超声波测距代码
时间: 2024-05-18 07:09:34 浏览: 70
基于STM32F103C8T6超声波测距源码及接线(已调).zip
STM32F103C8是一款常见的32位微控制器,可以用于实现超声波测距功能。以下是一个基本的超声波测距代码,你可以根据自己的需求进行修改:
```
#include "stm32f10x.h"
#include "delay.h"
#include "usart.h"
#define TRIG_PORT GPIOA
#define TRIG_PIN GPIO_Pin_1
#define ECHO_PORT GPIOA
#define ECHO_PIN GPIO_Pin_2
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
//定时器TIM3初始化
TIM_TimeBaseStructure.TIM_Period = arr; //自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //定时器分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化定时器3
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //允许定时器3更新中断
TIM_Cmd(TIM3, ENABLE); //使能定时器3
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //定时器3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = ECHO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(ECHO_PORT, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource2);
EXTI_InitStructure.EXTI_Line=EXTI_Line2;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel=EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = TRIG_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TRIG_PORT, &GPIO_InitStructure);
}
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //判断是否发生了更新事件
{
TIM_Cmd(TIM3, DISABLE); //关闭定时器
TIM_SetCounter(TIM3,0); //清空定时器计数器的值
GPIO_ResetBits(TRIG_PORT, TRIG_PIN); //关闭超声波发射口
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除更新中断标志位
TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE); //禁止更新中断
}
}
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2) != RESET) //判断是否为线2发生的中断
{
while(GPIO_ReadInputDataBit(ECHO_PORT, ECHO_PIN)==1); //等待高电平结束
u16 dis=TIM_GetCounter(TIM3)*17/100; //计算距离,单位是厘米
USART_SendData(USART1,dis>>8);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
USART_SendData(USART1,dis&0xff);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
EXTI_ClearITPendingBit(EXTI_Line2); //清除LINE2上的中断标志位
TIM_SetCounter(TIM3,0); //计数器清零,为下次测距做准备
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //开启定时器更新中断
TIM_Cmd(TIM3, ENABLE); //使能定时器3
GPIO_SetBits(TRIG_PORT, TRIG_PIN); //触发超声波发射口
delay_us(10); //延时10us,保证发射口稳定输出
GPIO_ResetBits(TRIG_PORT, TRIG_PIN);
}
}
int main(void)
{
delay_init();
USART1_Init();
GPIO_Configuration();
EXTI_Init();
TIM3_Int_Init(65535,71);
while(1);
}
```
这段代码使用了STM32的GPIO口、定时器和外部中断功能,通过超声波模块的TRIG端口发送一定时间长度的高电平信号来触发超声波发射,并在ECHO端口检测回波信号的高低电平来计算出距离。
阅读全文