避障平衡车,陀螺仪的中断,加入超声波,无法测距,
![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/d72071356d5a4fde81
a70b76c3e1ecd6.png "#left")
避障平衡车,陀螺仪的中断,加入超声波,无法测距,
![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/d72071356d5a4fde81
引自免费微信小程序:皆我百晓生
在处理陀螺仪(MPU6050)和超声波传感器(HC-SR04)的中断时,我们需要确保它们能够在主循环中正确地工作并响应各自的任务。根据您提供的代码片段,这里有一些修改建议来优化中断处理。
首先,我们将把超声波传感器初始化和启动测量的函数封装到一个单独的函数中,这样可以简化代码结构,并且便于在其他地方调用。然后,我们可以设置两个不同的中断服务例程(Interrupt Service Routines, ISRs),分别用于陀螺仪和超声波传感器的中断处理。最后,在主循环中,我们处理这两个中断的结果。
以下是修改后的代码示例:
#include <STM32F10x.h> // 添加必要的头文件
#define TRIG_PIN GPIO_Pin_8 // 根据实际引脚定义TRIG和ECHO引脚
#define ECHO_PIN GPIO_Pin_9
#define TRIG_PORT GPIOB
#define ECHO_PORT GPIOB
volatile uint16_t time = 0;
// 超声波初始化
void HCSR04_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT_PP;
GPIO_InitStruct.GPIO_Pin = TRIG_PIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TRIG_PORT, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_PD;
GPIO_InitStruct.GPIO_Pin = ECHO_PIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ECHO_PORT, &GPIO_InitStruct);
GPIO_ResetBits(TRIG_PORT, TRIG_PIN);
}
// 超声波开始测量
void HCSR04_Start()
{
GPIO_SetBits(TRIG_PORT, TRIG_PIN);
delay_us(45);
GPIO_ResetBits(TRIG_PORT, TRIG_PIN);
}
// 超声波获取距离
uint16_t HCSR04_GetValue(void)
{
HCSR04_Start();
delay_ms(100);
return (time * 0.0001) * 34000 / 2;
}
// 陀螺仪中断服务程序
void MPU6050_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line5) != 0)
{
EXTI_ClearITPendingBit(EXTI_Line5);
// 在这里处理陀螺仪的数据,例如读取角度等
// ...
}
}
// 超声波中断服务程序
void HCSR04_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line9) != 0)
{
EXTI_ClearITPendingBit(EXTI_Line9);
// 获取超声波距离
uint16_t distance = HCSR04_GetValue();
// 在这里处理超声波数据,例如判断障碍物距离等
// ...
}
}
// 主循环
int main(void)
{
// 初始化系统、定时器、陀螺仪和超声波传感器
SystemInit();
// Timer_Init(); // 假设这个函数已经正确实现了定时器配置
HCSR04_Init();
// 设置中断优先级和使能中断
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// 配置EXTI线9和线5为下降沿触发
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line5 | EXTI_Line9;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
// 进入无限循环
while (1)
{
// 检查是否有中断发生
if (EXTI_GetITStatus(EXTI_Line5))
MPU6050_IRQHandler();
if (EXTI_GetITStatus(EXTI_Line9))
HCSR04_IRQHandler();
// 其他主循环任务,如更新电机控制、显示数据等
// ...
}
return 0;
}
这个示例代码中,我们创建了两个独立的中断服务程序:MPU6050_IRQHandler()
和 HCSR04_IRQHandler()
,分别对应陀螺仪和超声波传感器的中断。在主循环中,我们检查这两个中断是否发生,并调用相应的中断服务程序进行处理。
注意:这段代码没有包含完整的STM32F10x库函数,你需要根据你的具体开发环境添加相应的头文件和库函数实现。同时,这里的delay_us()
和delay_ms()
函数也需要你自己实现,通常这些函数可以通过延时循环或者定时器来完成。另外,记得调整EXTI中断线号(Line5和Line9)以匹配你的硬件连接情况。