E18-D80NK红外避障传感器作为传感器搭配stm32f103c8t6控制两个舵机旋转,当有遮挡物时舵机一二同时旋转90度,然后延时5s,接着舵机回到初始位置
时间: 2025-06-11 17:14:30 浏览: 29
<think>好的,我现在需要帮助用户解决关于使用STM32F103C8T6控制红外避障传感器E18-D80NK来驱动两个舵机的问题。用户的具体需求是当检测到遮挡物时,舵机旋转90度,延时5秒后回到初始位置,并请求示例代码。首先,我需要理清整个系统的硬件连接和逻辑流程。
首先,用户使用的硬件包括STM32F103C8T6微控制器、E18-D80NK红外避障传感器和两个舵机。舵机通常使用PWM信号来控制角度,所以需要确认STM32的定时器配置,以生成适当的PWM波形。E18-D80NK是数字输出的传感器,检测到障碍物时输出低电平或高电平,需要查阅其数据手册确认具体信号类型。
接下来,需要确定舵机的控制参数。舵机的控制信号通常是周期为20ms的PWM波,占空比对应角度,比如0.5ms到2.5ms的脉宽对应0到180度。换算成占空比的话,0.5ms对应2.5%(0.5/20),2.5ms对应12.5%。因此,对于90度的位置,可能需要中间值,比如1.5ms脉宽,即7.5%的占空比。
然后,考虑STM32的定时器配置。假设使用定时器TIM2和TIM3的通道1和通道2来生成两个PWM信号。需要配置定时器的预分频器和自动重装载值,以产生正确的PWM频率。STM32F103C8T6的时钟频率是72MHz,预分频器设置为72-1,这样定时器时钟为1MHz,自动重装载值设为20000-1,这样周期为20ms,符合舵机要求。
接下来是舵机初始位置的设置。初始化时,两个舵机的PWM占空比应设置为初始角度对应的值,比如0度,即0.5ms脉宽,对应的比较寄存器值为50(0.5ms/20ms * 20000)。
然后处理红外传感器的输入。E18-D80NK的输出需要连接到GPIO输入引脚,配置为上拉输入,这样当检测到障碍物时,传感器输出低电平。通过轮询或中断的方式检测该引脚的状态变化。当检测到低电平时,触发舵机转动。
一旦检测到障碍物,舵机需要旋转到90度位置,即比较寄存器值设置为1500(1.5ms脉宽),然后延时5秒。这里需要注意,延时函数不能使用阻塞式的,而应该使用HAL_Delay(),或者配置定时器中断来实现非阻塞延时,但用户示例中可能更倾向于简单实现,所以暂时使用HAL_Delay(),尽管在实际应用中可能需要优化。
5秒后,舵机需要回到初始位置,即将比较寄存器值重新设置为初始角度对应的值。此外,需要确保在舵机转动过程中,系统能够响应其他操作,或者处理可能的多次触发,例如在延时期间忽略新的障碍物检测,避免重复触发。
代码结构方面,主循环中应不断检测传感器状态。当检测到障碍物时,改变PWM占空比,延时,再恢复。需要注意,舵机的控制可能需要一定的时间来稳定,但HAL_Delay()已经可以满足基本需求。
可能的问题包括:GPIO配置是否正确,PWM信号是否稳定,中断处理是否会影响PWM输出,以及延时是否会导致系统无法及时响应其他事件。用户可能需要添加去抖动处理,防止传感器误触发。此外,两个舵机的控制需要分别配置不同的定时器和通道,或者同一定时器的不同通道,但需要确保它们不会冲突。
最后,示例代码需要包含必要的初始化部分,如系统时钟、GPIO、定时器和PWM的配置,以及主循环中的逻辑。用户可能需要根据实际接线调整引脚和定时器设置。此外,代码的注释和可读性也很重要,方便用户理解和修改。</think>根据需求提供基于STM32F103C8T6的示例代码框架,以下是实现逻辑和关键步骤:
### 硬件配置
1. **E18-D80NK接线**
- OUT引脚接PA0(外部中断模式)
- VCC接3.3V,GND接地
2. **舵机接线**
- 舵机1信号线接PA6(TIM3_CH1)
- 舵机2信号线接PA7(TIM3_CH2)
- 供电需外接5V电源
### 核心代码实现
```c
// PWM配置(TIM3通道1/2)
void PWM_Init(void)
{
TIM_OC_InitTypeDef sConfigOC = {0};
htim3.Instance = TIM3;
htim3.Init.Prescaler = 71; // 72MHz/(71+1)=1MHz
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 19999; // 20ms周期
HAL_TIM_PWM_Init(&htim3);
// 舵机1配置(初始0度)
sConfigOC.Pulse = 500; // 0.5ms脉宽
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);
// 舵机2配置(初始0度)
sConfigOC.Pulse = 500;
HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
}
// 外部中断回调函数
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN_0)
{
// 设置舵机到90度位置(1.5ms脉宽)
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 1500);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 1500);
HAL_Delay(5000); // 保持5秒
// 返回初始位置
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 500);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 500);
}
}
```
### 关键参数说明
- **PWM周期计算**:
$$ T = \frac{(Prescaler+1) \times (Period+1)}{Clock} = \frac{72 \times 20000}{72MHz} = 20ms $$
- **角度换算公式**:
$$ Pulse = 500 + \frac{Angle}{90} \times 1000 $$
其中$Angle$取值范围0-90度[^2]
### 优化建议
1. 使用硬件定时器替代`HAL_Delay`避免阻塞
2. 添加软件消抖处理(建议10-20ms检测间隔)
3. 采用DMA方式控制多路PWM信号同步
阅读全文
相关推荐


















