Gitee
https://gitee.com/WangXi_Chn/RttOs_ModuleLib
开发环境
CubeMX
MDK5 IDE
STM32F103C8T6 芯片
Stm32最小系统板
RT-Thread操作系统
面向对象模块接口设计
SG90舵机
硬件条件
- PWM驱动配置成功
- 定时器及通道对应正确
-
核心思想
将舵机模块封装(调用方式同前面的M3508电机)
- 以绝对角度为控制量(初始位置已知)
- 面向对象设计
Module_Steering.h
```c /*- Copyright (c) 2020 - ~, HIT_HERO Team *
- X-SPIDER APP HEAD FILE
- Used in RT-Thread Operate System *
- Change Logs:
- Date Author Notes Mail
- 2020-12-16 WangXi first version WangXi_chn@foxmail.com */
ifndef MODULE_STEERING_H
define MODULE_STEERING_H
include
include
include
enum TYPE_STEERING { SG90 = 0, TYPE_STEERING_END };
struct _MODULE_STEERING { / Property 初始化必要属性/ enum TYPE_STEERING Property_SteerType; //舵机类型(待扩充,决定了PWM参数配置) char * Property_PwmDevName; //pwm设备名,RTT配置所得 rt_uint8_t Property_PWM_CHANNEL; //pwm通道号,RTT配置所得
rt_uint32_t Property_PulseMINus; //舵机最小角度高电平时间
rt_uint32_t Property_PulseMAXus; //舵机最大角度高电平时间
rt_int16_t Property_AngleMAX; //舵机最大角度
rt_int16_t Property_InitAngle; //舵机初始角度
/* Value 变量值*/
rt_int16_t Value_Angle; //舵机角度
rt_uint32_t Value_PWM_PERIOD_NS; //pwm脉冲周期
rt_uint32_t Value_PWM_PULSE_NS; //pwm脉冲高电平时间
struct rt_device_pwm *pwm_dev; //RTT的Pwm设备
/* Method */
void (*Method_Init)(struct _MODULE_STEERING *module);
void (*Method_Enable)(struct _MODULE_STEERING *module);
void (*Method_Disable)(struct _MODULE_STEERING *module);
void (*Method_SetPulse)(struct _MODULE_STEERING *module,rt_uint32_t pwm_pulse_ns);
void (*Method_SetAngle)(struct _MODULE_STEERING *module,rt_int16_t angle);
}; typedef struct _MODULE_STEERING MODULE_STEERING;
/ Glodal Method / rt_err_t Module_Steering_Config(MODULE_STEERING *Dev_Steering);
endif
/** (C) COPYRIGHT 2020 WANGXI **END OF FILE**/
- 在使用前可单独编写代码段,调用Method_SetPulse方法
- 来获取舵机的转动范围,及其对应的脉冲参数来决定Property_PulseMINus,Property_PulseMAXus的数值大小
- Property_AngleMAX由舵机自身决定,一般为90、180、360
- 舵机的各项参数都确定后,即可调用Method_SetAngle方法,驱动舵机转到指定角度
<a name="WaQFh"></a>
# Module_Steering.c
```c
/*
* Copyright (c) 2020 - ~, HIT_HERO Team
*
* STEERING ENGINE MODULE SOUCE FILE
* Used in RT-Thread Operate System
*
* Change Logs:
* Date Author Notes Mail
* 2020-12-18 WangXi first version WangXi_chn@foxmail.com
*/
#include "Module_Steering.h"
/* Static Method */
static void Module_SteeringInit(MODULE_STEERING *module);
static void Module_SteeringEnable(MODULE_STEERING *module);
static void Module_SteeringDisable(MODULE_STEERING *module);
static void Module_SteeringSetPulse(MODULE_STEERING *module,rt_uint32_t pwm_pulse_ns);
static void Module_SteeringSetAngle(MODULE_STEERING *module,rt_int16_t angle);
/* Global Method */
rt_err_t Module_Steering_Config(MODULE_STEERING *Dev_Steering){
if( Dev_Steering->Method_Init == NULL &&
Dev_Steering->Method_SetPulse == NULL &&
Dev_Steering->Method_Enable == NULL &&
Dev_Steering->Method_Disable == NULL &&
Dev_Steering->Method_SetAngle == NULL
){
/* Link the Method */
Dev_Steering->Method_Init = Module_SteeringInit;
Dev_Steering->Method_Enable = Module_SteeringEnable;
Dev_Steering->Method_Disable = Module_SteeringDisable;
Dev_Steering->Method_SetPulse = Module_SteeringSetPulse;
Dev_Steering->Method_SetAngle = Module_SteeringSetAngle;
}
else{
rt_kprintf("Warning: Module Steering is Configed twice\n");
return RT_ERROR;
}
/* Device Init */
Dev_Steering->Method_Init(Dev_Steering);
return RT_EOK;
}
/* Static Method */
static void Module_SteeringInit(MODULE_STEERING *module)
{
module->pwm_dev = (struct rt_device_pwm *)rt_device_find(module->Property_PwmDevName);
if (module->pwm_dev == RT_NULL)
rt_kprintf("pwm init failed! can't find pwm device!\n");
switch(module->Property_SteerType){
case SG90:
module->Value_PWM_PERIOD_NS = 20000000;//20ms = 20000000 ns
break;
case TYPE_STEERING_END:
break;
default:
break;
}
module->Method_SetAngle(module,module->Property_InitAngle);
}
static void Module_SteeringSetPulse(MODULE_STEERING *module,rt_uint32_t pwm_pulse_ns){
module->Value_PWM_PULSE_NS = pwm_pulse_ns;
rt_pwm_set( module->pwm_dev, module->Property_PWM_CHANNEL,
module->Value_PWM_PERIOD_NS, module->Value_PWM_PULSE_NS);
}
static void Module_SteeringEnable(MODULE_STEERING *module){
rt_pwm_enable(module->pwm_dev, module->Property_PWM_CHANNEL);
}
static void Module_SteeringDisable(MODULE_STEERING *module){
rt_pwm_disable(module->pwm_dev, module->Property_PWM_CHANNEL);
}
static void Module_SteeringSetAngle(MODULE_STEERING *module,rt_int16_t angle){
angle = angle >= module->Property_AngleMAX ? module->Property_AngleMAX:angle;
angle = angle <= 0 ? 0:angle;
module ->Value_Angle = angle;
double k = (module->Property_PulseMAXus - module->Property_PulseMINus)
/module->Property_AngleMAX;
module->Value_PWM_PULSE_NS =
(k * module ->Value_Angle + module->Property_PulseMINus)*1000;
rt_pwm_set( module->pwm_dev, module->Property_PWM_CHANNEL,
module->Value_PWM_PERIOD_NS, module->Value_PWM_PULSE_NS);
}
/************************ (C) COPYRIGHT 2020 WANGXI **************END OF FILE****/
测试程序
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-06 SummerGift first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "Module_Steering.h"
#include <stdlib.h>
// Steer Param Test-Part------------------------------------------
MODULE_STEERING module_steering = {
.Property_SteerType = SG90,
.Property_PwmDevName = "pwm2",
.Property_PWM_CHANNEL = 1,
.Property_PulseMINus = 600,
.Property_PulseMAXus = 2500,
.Property_AngleMAX = 180,
.Property_InitAngle = 0
};
void SteerPulse(int argc,char **argv)
{
rt_uint32_t num = atoi(argv[1]);
module_steering.Method_SetPulse(&module_steering,num*1000);
}
MSH_CMD_EXPORT(SteerPulse , SteerPulseUs <pulse>(500-2500)us);
void SteerAngle(int argc,char **argv)
{
rt_uint16_t Angle = atoi(argv[1]);
module_steering.Method_SetAngle(&module_steering,Angle);
}
MSH_CMD_EXPORT(SteerAngle , SteerAngle <Angle>(0-MAX));
int main(void)
{
// Steer Param Test-Part------------------------------------------
Module_Steering_Config(&module_steering);
module_steering.Method_Enable(&module_steering);
return 0;
}