一、项目介绍
本项目基于 SAM E51 Curiosity Nano评估板 制作了一款舵机测试仪。通过电位器调节舵机角度,线性控制舵机旋转角度(0°~180°)。并且通过串口实时数据监测与输出。
1.1 硬件介绍
- SAM E51 Curiosity Nano评估板:Microchip 公司推出的开发平台,基于ARM Cortex-M4架构,提供丰富的I/O接口和外围模块,适合快速原型开发。
- 舵机:常用的RC舵机,具有PWM控制接口。
- 电位器:用于手动调节并模拟舵机目标旋转角度输入。
- 电源模块:为系统提供稳定的电压和电流。
- UART接口:用于串口通信,实现数据的实时传输与调试。
1.2 功能概览
- 调节电位器改变舵机角度。
- 读取并处理电位器的模拟电压。
- 根据电位器输入产生相应的PWM信号输出。
- 通过UART串口接口输出各类调试信息,包括电压值、PWM参数、角度和状态。
- 使用开发板上的用户按键单击切换输出使能或失能。
- 开发板上的用户LED灯常亮表示输出使能,闪烁表示输出失能。
1.3 设计思路
- 电位器采样:使用ADC模块定期读取电位器的电压,转换得到舵机的目标角度。
- PWM信号生成:转换后的角度信息生成相应的PWM信号,以控制舵机的旋转。
- 串口通信:利用UART模块输出各项监控数据,用于调试和校验。
- 状态反馈:监测系统运行状态,提供实时反馈。
二、功能实现
2.1 软件流程图
系统初始化后完成外设及ADC、PWM定时器、UART配置,进入主循环。定时器中断触发时读取ADC值,计算舵机角度与PWM脉宽,动态更新占空比并通过串口输出电压、频率、脉宽、角度及状态信息,实现舵机角度闭环控制与实时监测。
2.2 PWM控制原理
舵机的控制通常采用PWM信号,例如需要一个周期为20ms的脉冲宽度调制(PWM), 脉冲宽度部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。 当脉冲宽度为1.5ms时,舵机旋转至中间角度,大于1.5ms时 舵机旋转角度增大,小于1.5ms时舵机旋转角度减小。舵机分90°、180°、270°、300°和360°舵机, 以180°的舵机为例来看看脉冲宽度与角度的关系,见下图所示。
上图中脉冲宽度与舵机旋转角度为线性关系,其他舵机控制脉冲也类似,0.5ms对应0度,2.5ms对应最大 旋转角度,脉冲宽度与旋转角度也是线性关系。
2.3 实现过程
2.3.1 硬件资源配置
- ADC采样:PA02引脚连接电位器,参考电压3.3V,12位分辨率
- PWM输出:PA09引脚输出50Hz信号,使用TC4硬件定时器
- 串口通信:PB16(TX)连接USB-CDC RX,PB17(RX) 连接USB-CDC TX,波特率115200
参考面包板接线示意图如下:
2.3.2 关键功能实现
- 采样电位器输出:通过配置和初始化ADC模块,以一定频率采样电位器输出电压。
if (ADC_PERIOD < (timestamp - last_adc_sample_timestamp)) {
last_adc_sample_timestamp = timestamp;
ADC0_ConversionStart();
uint16_t target_voltage = moving_average(ADC0_ConversionResultGet());
if(ADC_TOLERANCE_RANGE < abs(target_voltage - last_sample_voltage)) { // 电位器转动导致电压发生变化,需要更新输出
last_sample_voltage = target_voltage;
needChangePWMOutput = true;
}
}
- 电压到角度的转换:根据电位器输出电压范围和舵机工作范围(一般0-180度),进行线性转换。
if(true == needChangePWMOutput) { // 更新PWM输出
needChangePWMOutput = false;
uint16_t x = last_sample_voltage;
// 电位器两端留有余量
if(20 > x) {
x = 20;
}
if(4075 < x) {
x = 4075;
}
uint32_t match1vlaue = map(x, 20, 4075, 1875, 9375); // 根据电位器计数更新占空比,调整舵机输出角度
printf("Current counter value is: %lu\r\n", match1vlaue);
TC4_Compare32bitMatch1Set(match1vlaue);
}
- PWM信号生成:调用PWM模块,将目标角度转换成适当脉宽(通常为1ms到2ms对应0度到180度)。
uint32_t match1vlaue = map(x, 20, 4075, 1875, 9375); // 根据电位器计数更新占空比,调整舵机输出角度
last_output_angle = map(match1vlaue, 1875, 9375, 0, 180); // 计算输出角度
last_cc1_pulse_width = map(match1vlaue, 1875, 9375, 500, 2500); // 计算输出脉宽(单位:us)
TC4_Compare32bitMatch1Set(match1vlaue);
- 信息收集与输出:利用UART模块将当前电压值、PWM信号频率及脉宽、舵机角度和状态信息实时输出到串口。同时控制板载LED根据输出使能状状态常亮或闪烁。
if (LED_TOGGLE_PERIOD < (timestamp - last_led_toggle_timestamp)) {
last_led_toggle_timestamp = timestamp;
if(true == enableOutput) { // 输出使能,LED常亮
LED0_Clear();
} else { // 输出禁用,LED以1Hz闪烁
LED0_Toggle();
}
printf("%d,%lu,%lu,%lu,%d\r\n", last_sample_voltage,
TC4_CompareFrequencyGet() / TC4_Compare32bitPeriodGet(),
last_cc1_pulse_width, last_output_angle,
enableOutput ? 1 : 0
);
}
三、功能展示
调节效果展示
使用电位器调节产生的舵机动作,通过串口实时观察数据变化,确保动作与数据一致性。
输出使能切换
开发板上的用户按键可切换输出使能。当输出使能时,开发板上的用户LED常亮。输出关闭时,开发板上的用户LED以 1Hz 的频率闪烁。
串口监控界面
使用终端软件查看串口信息,捕捉系统状态和各项调试信息。使用图形化工具接收串口信息,图形化实时展示当前输出的数据。
四、总结
遇到的问题
- 经常在 Clean 项目之后,遇到错误:make[2]: *** No rule to make target 'dist/default/production/ServoTest.X.production.hex'. Stop. 目前不知道该如何解决,每次都是通过重启IDE解决,如有知道的小伙伴还请不吝赐教。详细错误信息如下:
- 参考官方教程配置串口时,无法生成DMA回调注册函数。这个问题一直没找到答案,最终放弃使用串口DMA,改用连接到标准输出使用串口功能。
心得体会
本项目成功实现了一个基于 SAM E51 Curiosity Nano评估板 的舵机测试仪,能够灵活调整和监控舵机行为。通过硬件的合理配置和软件的有效实现,可以适配单个舵机控制与调试场景,并为进一步的嵌入式系统开发打下基础。未来可以拓展更多功能,例如通过网络接口实现无线控制和监控等。