您的位置:首页 > 其它

基于BBB的4轮移动轮式机器人系统设计与实现(四)--BeagleBone Black PWM 应用程序开发

2015-04-24 23:10 555 查看
在BBB开发板中,PWM的应用程序一共有三个类:PWM基类、PWM舵机类、PWM电机控制类

PWM基类表示PWM引脚的通用功能,如加载PWM引脚所对应的设备树、加载PWM定时器等

PWM基类定义

/*
* BeagleBonePWM.h
*
*  Created on: 2014-6-9
*      Author: sfe1012
*/

#ifndef BEAGLEBONEPWM_H_
#define BEAGLEBONEPWM_H_

#include <string>
#include <dirent.h>
#include <fstream>
#include <sstream>
#include <iostream>
#include <unistd.h>

const std::string PIN_MOTOR_FORWARD("P8_13");
const std::string PIN_MOTOR_BACK("P8_19");
const std::string PIN_SERVO_DERECTION("P9_14");
const std::string PIN_SERVO_SHOOK_HEAD("P9_16");
const std::string PIN_SERVO_NOD_HEAD("P9_21");

const int MICRSECONDS_TO_NANOSECONDS = 1000;//微秒 转换 纳秒
const int MILLISECONDS_TO_MICROSECONDS = 1000;//毫秒 转换 微妙
const int MILLISECONDS_TO_NANOSECONDS = MILLISECONDS_TO_MICROSECONDS * MICRSECONDS_TO_NANOSECONDS; //毫秒 转 纳秒
const long MODULE_DELAY_TIME_US = 100 * MILLISECONDS_TO_MICROSECONDS; //  Time to wait for module to be loaded and the sysfs interface setup

//#define DEBUG_VERBOSE_OUTPUT 1

namespace PWM
{
template<class T> inline std::string ToString(const T & value) //模板函数 数据类型转换
{
std::stringstream ss;
ss << value;
return ss.str();
}

inline void WriteToFile(const std::string & filePath, const std::string & value)//命令字写入相应的 管脚 对应的 属性文件
{
#if DEBUG_VERBOSE_OUTPUT
std::cout << "Writing: " << value << " to: " << filePath << std::endl;
#endif
std::ofstream out;
out.open(filePath.c_str());
out.exceptions(std::ios::badbit);
out << value << std::endl;
out.close();
}
// A bunch of helper functions to get us locations in the file system.
// They are used so that we can manipulate the pwm driver through the /sys interface
//这个函数将会返回在 dirname目录下  文件名称为filenameTofind 文件名
std::string GetFullNameOfFileInDirectory(const std::string & dirName, const std::string & fileNameToFind);
std::string GetCapeManagerSlotsPath();//获得slots 目标名称
std::string GetOCPPath();//获得ocp的文件目录
int GetCapeManagerSlot(const std::string & moduleName);//获取设备模块 当得到的时候 就返回 设备号
void LoadDeviceTreeModule(const std::string & name);//加载设备模块 到 设备树
void UnloadDeviceTreeModule(const std::string name);//卸载设备模块 设备树

class Pin //管脚类
{
public:
enum RunStatus
{
Free = -2, WaitingForSetp, Disabled, Enabled,//-1、0、1
};
enum Polarity
{
PolaritryHigh = 0, PolarityLow, // 1
};

private:
std::string m_dutyFilePath;//管脚 占空比设置 文件位置
std::string m_periodFilePath;//管脚  周期设置 文件位置
std::string m_polarityFilePath;//管脚 输出占空比 极性  (BBB默认情况下,1表示占空比的输出为负,0表示为正)
std::string m_runFilePath;//管脚 运行 控制位
std::string m_pinName;//管脚 命名

long m_periodNS; // 周期  纳秒单位
long m_dutyNS; //占空比   纳秒单位
Polarity m_polarity; //极性
RunStatus m_runStatus;  //运行状态

public:
/*********SFE ADD*****************/
void LoadDeviceTreeModuleForEspecial(const std::string &strName)const
{
LoadDeviceTreeModule(strName);//加载设备模块 到 设备树
}
/************************************/
const std::string &GetDutyFilePath() const//获取占空比设置文件的位置
{
return m_dutyFilePath;
}
const std::string &GetPeriodFilePath() const//获取周期设置文件的位置
{
return m_periodFilePath;
}
const std::string &GetPolarityFilePath() const//获取极性设置文件的位置
{
return m_polarityFilePath;
}
const std::string &GetPinName() const//获取管脚的名字
{
return m_pinName;
}
const std::string &GetRunFilePath() const //获取管脚 运行管理的文件位置
{
return m_runFilePath;
}

const RunStatus &GetRunStatus() const  //获取管脚 运行状态
{
return m_runStatus;
}

const long &GetPeriodNS() const  //获取周期  纳秒为单位
{
return m_periodNS;
}
const Polarity &GetPolarity() const  //获取 管脚的极性
{
return m_polarity;
}
const long &GetDutyNS() const // 获取  管脚的占空比  纳秒为单位
{
return m_dutyNS;
}

private:
void WriteDutyNSToFile()  //向占空比 设置文件 写入命令
{
WriteToFile(GetDutyFilePath(), ToString(GetDutyNS()));
}
void WritePeriodNSToFile() // 向周期 设置文件 写入命令
{
WriteToFile(GetPeriodFilePath(), ToString(GetPeriodNS()));
}
void WritePolarityToFile() //向 极性控制 文件 写入命令
{
WriteToFile(GetPolarityFilePath(), GetPolarity() == PolaritryHigh ? std::string("0") : std::string("1"));
}

public:
//占空比设置
void SetDutyNS(const long & dutyNS)//纳秒
{
m_dutyNS = std::min(dutyNS, GetPeriodNS());
if (GetRunStatus() == Enabled)
WriteDutyNSToFile();
}
void SetDutyUS(const int &dutyUS)//微妙
{
SetDutyNS((long) dutyUS * MICRSECONDS_TO_NANOSECONDS);
}
void SetDutyMS(const int &dutyMS)//毫秒
{
SetDutyNS((long) dutyMS * MILLISECONDS_TO_NANOSECONDS);
}
void SetDutyPercent(const float &percent)
{
SetDutyNS(long(GetPeriodNS() * percent));
}
//周期设置
void SetPeriodNS(const long & periodNS)//纳秒
{
if (GetRunStatus() == Enabled || GetRunStatus() == Disabled)
{
std::cout << "Trying to set the period but we need to release the PWM module first!" << std::endl;
throw std::bad_exception();
return;
}
m_periodNS = periodNS;
if (GetRunStatus() == Enabled)
WritePeriodNSToFile();
}
void SetPeriodUS(const int &periodUS) //微妙
{
SetPeriodNS((long) periodUS * MICRSECONDS_TO_NANOSECONDS);
}
void SetPeriodMS(const int &periodMS) //毫秒
{
SetPeriodNS((long) periodMS * MILLISECONDS_TO_NANOSECONDS);
}

void SetPolarity(const Polarity & polarity)//设置极性
{
m_polarity = polarity;
if (GetRunStatus() == Enabled)
WritePolarityToFile();
}

private:
void SetRunStatus(const RunStatus & newRunStatus)  // 运行状态设置
{
if (newRunStatus != GetRunStatus())
{
if (newRunStatus == Disabled)
{
WriteToFile(GetRunFilePath(), std::string("0"));
}
else if (newRunStatus == Enabled)
{
if (GetRunStatus() == Free)
{
InitPinFS();
}
// Force write the file values out
WritePeriodNSToFile();
WriteDutyNSToFile();
WritePolarityToFile();

WriteToFile(GetRunFilePath(), std::string("1"));
}
else if (newRunStatus == Free)
{
if (GetRunStatus() != Disabled)
{
SetRunStatus(Disabled);
}
UnloadDeviceTreeModule(GetPinName());
}
}
m_runStatus = newRunStatus;
}
public:
void Enable()  //运行状态 设置为 开始运行
{
SetRunStatus(Enabled);
}
void Disable()
{
SetRunStatus(Disabled);
}
void Release()
{
SetRunStatus(Free);
}

public:
~Pin()
{
Release();
}
Pin()
{}
//默认构造函数中的  周期为20毫秒  占空比为 0 毫秒
Pin(const std::string & pinName, const long & periodNS = 20 * MILLISECONDS_TO_NANOSECONDS, const long & dutyNS = 0* MILLISECONDS_TO_NANOSECONDS) :
m_pinName(pinName)
{
// If the pin is already in use then we need to free it!
if (GetCapeManagerSlot(GetPinName()) != -1)
//查找当强的管脚是否已经被应用 ,yes:释放它
UnloadDeviceTreeModule(GetPinName());

m_runStatus = WaitingForSetp;

InitPinFS();

SetPeriodNS(periodNS);//周期
SetDutyNS(dutyNS);//占空比
SetPolarity(PolaritryHigh);//极性

//InitPinFS();
}

void InitPinFS() //设置BBB定时器  管脚命名  获取相应文件的位置 信息
{
//LoadDeviceTreeModule(std::string("am33xx_pwm"));//加入pwm定时器
std::string pinModule = std::string("sc_pwm_") + GetPinName();//
LoadDeviceTreeModule(pinModule);//加入pin
std::string pinInterfacePath = GetOCPPath() + GetFullNameOfFileInDirectory(GetOCPPath(), GetPinName()) + "/";
m_dutyFilePath = pinInterfacePath + "duty";
m_periodFilePath = pinInterfacePath + "period";
m_polarityFilePath = pinInterfacePath + "polarity";
m_runFilePath = pinInterfacePath + "run";

#if DEBUG_VERBOSE_OUTPUT
std::cout << GetDutyFilePath() << std::endl;
std::cout << GetPeriodFilePath() << std::endl;
std::cout << GetPolarityFilePath() << std::endl;
std::cout << GetRunFilePath() << std::endl;
#endif
}
};
}

#endif /* BEAGLEBONEPWM_H_ */


PWM基类实现

/*
* BeagleBonePWM.cpp
*
*  Created on: 2014-6-9
*      Author: sfe1012
*/
#include "BeagleBonePWM.h"

namespace PWM
{
// A bunch of helper functions to get us locations in the file system.
// They are used so that we can manipulate the pwm driver through the /sys interface

//这个函数将会返回在 dirname目录下  文件名称为filenameTofind 文件名
std::string GetFullNameOfFileInDirectory(const std::string & dirName, const std::string & fileNameToFind)
{
DIR *pDir;

dirent *pFile;
if ((pDir = opendir(dirName.c_str())) == NULL)
{
std::cout << "Directory name: " << dirName << " doesnt exist!" << std::endl;
throw std::bad_exception();
}
while ((pFile = readdir(pDir)) != NULL)
{
std::string currentFileName = (pFile->d_name);
if (currentFileName.find(fileNameToFind) != std::string::npos)//string  查找函数
{
return currentFileName;
}
}
return std::string("");
}

std::string GetCapeManagerSlotsPath()//获得slots 目标名称
{
static std::string g_capeManagerSlotsPath;
if (g_capeManagerSlotsPath.length() <= 0)
{
#if DEBUG_VERBOSE_OUTPUT
std::cout << "Setting up cape manager path" << std::endl;
#endif
std::string capeBasePath("/sys/devices/");
std::string fileName = GetFullNameOfFileInDirectory(capeBasePath, std::string("bone_capemgr."));
g_capeManagerSlotsPath = capeBasePath + fileName + "/slots";
}
return g_capeManagerSlotsPath;
}

std::string GetOCPPath()  //获得ocp的文件目录
{
static std::string g_ocpPath;
if (g_ocpPath.length() == 0)
{
std::string ocpBasePath("/sys/devices/");
std::string ocpName = GetFullNameOfFileInDirectory(ocpBasePath, std::string("ocp."));
g_ocpPath = ocpBasePath + ocpName + '/';
}
return g_ocpPath;
}

int GetCapeManagerSlot(const std::string & moduleName)
{
#if DEBUG_VERBOSE_OUTPUT
std::cout << "Trying to find slot for module: " << moduleName << std::endl;
#endif
std::ifstream in(GetCapeManagerSlotsPath().c_str());//找到 /sys/devices/bone_capemgr.9/slots
in.exceptions(std::ios::badbit);//读取slots 文件
int slot = -1;
while (in >> slot)
{
std::string restOfLine;
std::getline(in, restOfLine); //获取slots 中的一行
if (restOfLine.find(moduleName) != std::string::npos)//在这一行中查找是否有这个管脚
{
#if DEBUG_VERBOSE_OUTPUT
std::cout << "Found Module: " << moduleName << " at slot: " << slot << std::endl;
#endif
return slot;
}
}
#if DEBUG_VERBOSE_OUTPUT
std::cout << "Module: " << moduleName << " not found in cape manager!" << std::endl;
#endif
return -1;
}
void LoadDeviceTreeModule(const std::string & name)
{
int slot = GetCapeManagerSlot(name);//查找是否存在  不存在返回 -1
if (slot == -1)
{
#if DEBUG_VERBOSE_OUTPUT
std::cout << "Adding Module: " << name << std::endl;
std::cout << "Its going in: " << GetCapeManagerSlotsPath() << std::endl;
#endif
WriteToFile(GetCapeManagerSlotsPath(), name);//命令写入其中

usleep(MODULE_DELAY_TIME_US);
}
else
{
#if DEBUG_VERBOSE_OUTPUT
std::cout << "Module " << name << " is already in here!" << std::endl;
#endif
}
}
void UnloadDeviceTreeModule(const std::string name)
{
int currentSlot = GetCapeManagerSlot(name);
if (currentSlot == -1)
{
std::cout << "Why is the module " << name << " being unloaded when its not in use?" << std::endl;
throw std::bad_exception();
}
#if DEBUG_VERBOSE_OUTPUT
std::cout << "Unloading module: " << name << std::endl;
#endif
WriteToFile(GetCapeManagerSlotsPath(), std::string("-") + ToString(currentSlot));

usleep(MODULE_DELAY_TIME_US);
}
}


PWM舵机控制类定义

/*
* BeagleBonePwmServo.h
*
*  Created on: 2014-6-10
*      Author: sfe1012
*/
#ifndef BEAGLEBONEPWMSERVE_H_
#define BEAGLEBONEPWMSERVE_H_
#include "BeagleBonePWM.h"
#include "BeagleBonePwmMotor.h"
class BeagleBonePwmServo:public BeagleBonePwmMotor
{
public:
BeagleBonePwmServo(const std::string &strPinName,
const long &lPeriodTimeNs,
const long &lDutyTimeNs,
const long &lDrive,
const long &lServoRightLimitUs,
const long &lServoLeftLimitUs,
const long &lServoCenterUs);
~BeagleBonePwmServo();
public:
const long &GetCenterValue()const;
void  SetCenterValue(const long &lCenterValueUs);
public:
void EnableMotorPwm();
//void UpdateCurrentPwm();
void UpdateMotorPwmSignalByStep(const long &lTargetDrive);
void UpdateMotorPwmSignalBySetCurrentDriveNs(const long &lCurrentDrive);
private:
long m_lServoRightLimitUs;
long m_lServoLeftLimitUs;
long m_lServoCenterUS;
long m_lServoCurrentUS;
long m_lServoStep;
};
#endif /* BEAGLEBONEPWMSERVE_H_ */


PWM舵机控制类实现

/*
* BeagleBonePwmServo.cpp
*
*  Created on: 2014-6-13
*      Author: sfe1012
*/
#include"BeagleBonePwmServo.h"
BeagleBonePwmServo::BeagleBonePwmServo(const std::string &strPinName,
const long &lPeriodTimeNs,
const long &lDutyTimeNs,
const long &lDrive,
const long &lServoRightLimitUs,
const long &lServoLeftLimitUs,
const long &lServoCenterUs):
BeagleBonePwmMotor(strPinName,lPeriodTimeNs,lDutyTimeNs,lDrive){
m_lServoRightLimitUs = lServoRightLimitUs;//1000
m_lServoLeftLimitUs = lServoLeftLimitUs;//2000
m_lServoCenterUS = lServoCenterUs;//1500
m_lServoCurrentUS = 0;
m_lServoStep = (lServoLeftLimitUs - lServoRightLimitUs)/lDrive;
}
BeagleBonePwmServo::~BeagleBonePwmServo(){
}
const long &BeagleBonePwmServo::GetCenterValue()const{
return m_lServoCenterUS;
}
void BeagleBonePwmServo::SetCenterValue(const long &lCenterValueUs){
m_lServoCenterUS = lCenterValueUs;
}
void BeagleBonePwmServo::EnableMotorPwm(){
GetPwmPinClass().SetDutyUS(m_lServoCenterUS);
GetPwmPinClass().Enable();
m_lServoCurrentUS = m_lServoCenterUS;
}
void BeagleBonePwmServo::UpdateMotorPwmSignalByStep(const long &lTargetDrive){
m_lServoCurrentUS += lTargetDrive;
if(m_lServoCurrentUS > m_lServoLeftLimitUs){
m_lServoCurrentUS = m_lServoLeftLimitUs;
}
else if(m_lServoCurrentUS < m_lServoRightLimitUs){
m_lServoCurrentUS = m_lServoRightLimitUs;
}
GetPwmPinClass().SetDutyUS(m_lServoCurrentUS*m_lServoStep);// Write out to PWM GetCurrentDrive()
}
void BeagleBonePwmServo::UpdateMotorPwmSignalBySetCurrentDriveNs(const long &lCurrentDrive){
long lCurrentDriveTemp = 0 ;
if(lCurrentDrive > m_lServoLeftLimitUs*1000){
lCurrentDriveTemp = m_lServoLeftLimitUs*1000;
}
else if(lCurrentDrive < m_lServoRightLimitUs*1000){
lCurrentDriveTemp = m_lServoRightLimitUs*1000;
}
else
lCurrentDriveTemp = lCurrentDrive;
std::cout<<"lCurrentDriveTemp:"<<lCurrentDriveTemp<<std::endl;
GetPwmPinClass().SetDutyNS(lCurrentDriveTemp);// Write out to PWM GetCurrentDrive()
}


PWM电机控制类定义

/*
* BeagleBonePwmMotor.h
*
*  Created on: 2014-6-13
*      Author: sfe1012
*/

#ifndef BEAGLEBONEPWMMOTOR_H_
#define BEAGLEBONEPWMMOTOR_H_
#include "BeagleBonePWM.h"
class BeagleBonePwmMotor
{
public:
BeagleBonePwmMotor();
BeagleBonePwmMotor(const std::string &strPinName,
const long &lPeriodTimeNs,
const long &lDutyTimeNs,
const long &lDrive);
virtual ~BeagleBonePwmMotor();
public:
PWM::Pin &GetPwmPinClass();
const long &GetTargetDriveStep()const;
void SetTargetDriveStep(const long & lTargetDriveStep);
const long &GetCurrentDrive()const;
void SetCurrentDrive(const long & lCurrentPWM);
void LoadDeviceTreeModule(const std::string &strName)const;
public:
virtual void EnableMotorPwm();
virtual void UpdateCurrentPwm();
virtual void UpdateMotorPwmSignalByStep(const long &lTargetDrive);
virtual void UpdateMotorPwmSignalBySetCurrentDriveUs(const long &lCurrentDrive);
virtual void UpdateMotorPwmSignalBySetCurrentDriveNs(const long &lCurrentDrive);
private:
PWM::Pin m_Pin;
long m_lCurrentDrive;
long m_lTargetDriveStep;//在当前的档位上 加多少 还是 减掉 多少
long m_lDrive; //一共有多少个前进档位
long m_lStep; //每个档位代表多少个 微妙的占空比
};
#endif /* BEAGLEBONEPWMMOTOR_H_ */


PWM电机控制类实现

/*
* BeagleBonePwmMotor.cpp
*
*  Created on: 2014-6-13
*      Author: sfe1012
*/
#include"BeagleBonePwmMotor.h"
BeagleBonePwmMotor::BeagleBonePwmMotor(const std::string &strPinName,
const long &lPeriodTimeNs,
const long &lDutyTimeNs,
const long &lDrive):
m_Pin(strPinName, lPeriodTimeNs,lDutyTimeNs){
m_lCurrentDrive = 0;
m_lTargetDriveStep = 0;
m_lDrive = lDrive;
m_lStep = lPeriodTimeNs / (m_lDrive*1000);
}
BeagleBonePwmMotor::BeagleBonePwmMotor()
{
}
BeagleBonePwmMotor::~BeagleBonePwmMotor(){
}
PWM::Pin &BeagleBonePwmMotor::GetPwmPinClass(){
return m_Pin;
}
const long &BeagleBonePwmMotor::GetTargetDriveStep()const{
return m_lTargetDriveStep;
}
void BeagleBonePwmMotor::SetTargetDriveStep(const long & lTargetDriveStep){
m_lTargetDriveStep = lTargetDriveStep;
}
const long &BeagleBonePwmMotor::GetCurrentDrive()const{
return m_lCurrentDrive;
}
void BeagleBonePwmMotor::SetCurrentDrive(const long & lCurrentDrive){
m_lCurrentDrive = lCurrentDrive;
}
void BeagleBonePwmMotor::EnableMotorPwm(){
GetPwmPinClass().Enable();
}
void BeagleBonePwmMotor::UpdateCurrentPwm(){
if(m_lTargetDriveStep > 0 || m_lTargetDriveStep == 0){
m_lCurrentDrive += m_lTargetDriveStep;
}
else if(m_lTargetDriveStep < 0){
m_lCurrentDrive += m_lTargetDriveStep;
}
if(m_lCurrentDrive > m_lDrive){
m_lCurrentDrive = m_lDrive;
}
else if(m_lCurrentDrive < 0){
m_lCurrentDrive = 0;
}
#ifdef DEBUG_VERBOSE_OUTPUT
std::cout<<"m_lCurrentDrive :"<<m_lCurrentDrive<<std::endl;
#endif
}
void BeagleBonePwmMotor::UpdateMotorPwmSignalByStep(const long &lTargetDriveStep){
SetTargetDriveStep(lTargetDriveStep);
UpdateCurrentPwm();
#ifdef DEBUG_VERBOSE_OUTPUT
std::cout<<"UpdateMotorPwmSignalByStep : GetCurrentDrive()*m_lStep::"<<GetCurrentDrive()*m_lStep<<std::endl;
#endif
GetPwmPinClass().SetDutyUS(GetCurrentDrive()*m_lStep);// Write out to PWM GetCurrentDrive()
}
void BeagleBonePwmMotor::UpdateMotorPwmSignalBySetCurrentDriveUs(const long &lCurrentDrive)
{
//	long lCurrentDriveTemp = 0;
//	if(lCurrentDrive > m_lDrive || lCurrentDrive == 0)
//	{
//		lCurrentDriveTemp = m_lDrive;
//	}
//	if(lCurrentDrive < 0)
//	{
//		lCurrentDriveTemp = 0;
//	}
#ifdef DEBUG_VERBOSE_OUTPUT
std::cout<<"UpdateMotorPwmSignalBySetCurrentDrive : GetCurrentDrive()*m_lStep::"<<lCurrentDrive*m_lStep<<std::endl;
#endif
GetPwmPinClass().SetDutyUS(lCurrentDrive*m_lStep);// Write out to PWM GetCurrentDrive()
}
void BeagleBonePwmMotor::UpdateMotorPwmSignalBySetCurrentDriveNs(const long &lCurrentDrive)
{
#ifdef DEBUG_VERBOSE_OUTPUT
std::cout<<"UpdateMotorPwmSignalBySetCurrentDrive :"<<lCurrentDrive<<std::endl;
#endif
GetPwmPinClass().SetDutyNS(lCurrentDrive);// Write out to PWM GetCurrentDrive()
}
void BeagleBonePwmMotor::LoadDeviceTreeModule(const std::string &strName)const
{
m_Pin.LoadDeviceTreeModuleForEspecial(strName);
}


应用方法:

#include <stdlib.h>
#include"GraduationHead.h"
#include"BeagleBonePwmMotor.h"
#include"BeagleBonePwmServo.h"
using namespace std;
int main(){

cout << "!!! Hello BeagleBone Black !!!" << endl; // prints !!!Hello World!!!
/***PIN_MOTOR_BACK***********PWM Init**********PIN_MOTOR_FORWARD*********/
BeagleBonePwmMotor PWMTimeLoad;
PWMTimeLoad.LoadDeviceTreeModule("am33xx_pwm");
BeagleBonePwmMotor MotorForward(PIN_MOTOR_FORWARD,20 * MILLISECONDS_TO_NANOSECONDS,0,100);//
BeagleBonePwmMotor MotorBack(PIN_MOTOR_BACK,20 * MILLISECONDS_TO_NANOSECONDS,0,100);
BeagleBonePwmServo ServoShookHead(PIN_SERVO_SHOOK_HEAD,20 * MILLISECONDS_TO_NANOSECONDS,0,100,1000,2000,1500);
BeagleBonePwmServo ServoNodHead(PIN_SERVO_NOD_HEAD,20 * MILLISECONDS_TO_NANOSECONDS,0,100,1000,2000,1500);
BeagleBonePwmServo ServoDerection(PIN_SERVO_DERECTION,20 * MILLISECONDS_TO_NANOSECONDS,0,100,1370,1650,1500);
MotorForward.EnableMotorPwm();
MotorBack.EnableMotorPwm();
ServoShookHead.EnableMotorPwm();
ServoNodHead.EnableMotorPwm();
ServoDerection.EnableMotorPwm();
usleep(MODULE_DELAY_TIME_US);;//等待PWM定时器设置成功
/****************Data Analaze*******************/
SerialDataAnalaze oSerialDataAnalaze;
/**********************PWM Data*****************/
long olMotorForward = 500; //ns
long olMotorBack = 0;//500; //ns
long olServoShookHead = 1500000; //ns
long olServoNodHead = 1500000; //ns
long olServoDerection = 1500000; //ns
long lButtonNum = 0;
while(1)
{
MotorForward.UpdateMotorPwmSignalBySetCurrentDriveNs(olMotorForward);
//usleep(MODULE_DELAY_TIME_US);;//等待设置成功
MotorBack.UpdateMotorPwmSignalBySetCurrentDriveNs(olMotorBack);
//usleep(MODULE_DELAY_TIME_US);;//等待设置成功
ServoShookHead.UpdateMotorPwmSignalBySetCurrentDriveNs(olServoShookHead);
//usleep(MODULE_DELAY_TIME_US);;//等待设置成功
ServoNodHead.UpdateMotorPwmSignalBySetCurrentDriveNs(olServoNodHead);
//usleep(MODULE_DELAY_TIME_US);;//等待设置成功
ServoDerection.UpdateMotorPwmSignalBySetCurrentDriveNs(olServoDerection);
//usleep(MODULE_DELAY_TIME_US);;//等待设置成功
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐