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

在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 
#include 
#include 
#include 
#include 
#include 

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 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:"<

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_lDrive || lCurrentDrive == 0)
//	{
//		lCurrentDriveTemp = m_lDrive;
//	}
//	if(lCurrentDrive < 0)
//	{
//		lCurrentDriveTemp = 0;
//	}
	#ifdef DEBUG_VERBOSE_OUTPUT
	std::cout<<"UpdateMotorPwmSignalBySetCurrentDrive : GetCurrentDrive()*m_lStep::"<


应用方法:

#include 
#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;
}

你可能感兴趣的:(嵌入式,4轮移动小型机器人开发)