PID<->Port

本文提供了一种在Windows平台上通过端口查询进程ID的方法,同时也能根据进程ID查询其打开的所有端口。代码适用于从XP到Windows 7等多个版本的操作系统。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前几天在网上找到了个通过端口获得进程ID,和通过进程ID获取端口的例子,先存下来,有空细研究。。。。


上传个VC下能编译运行的工程,所需头文件也放在了工程里,不用再找了。。。

http://download.youkuaiyun.com/detail/change518/4236155


//Netstat -anb

#include <Windows.h>
#include "Psapi.h"
#include <Iprtrmib.h>

#pragma  comment(lib,"Psapi.lib")
#pragma  comment(lib,"Iphlpapi.Lib")
#pragma  comment(lib,"WS2_32.lib")

 
#include <iostream>
#include <vector>

using namespace std;
using std::vector;


enum TcpOrUdp
{
	TcpType, 
	UdpType
};


typedef struct
{
  DWORD dwState;      //连接状态
  DWORD dwLocalAddr;  //本地地址
  DWORD dwLocalPort;  //本地端口
  DWORD dwRemoteAddr; //远程地址
  DWORD dwRemotePort; //远程端口
  DWORD dwProcessId;  //进程标识

}MIB_TCPEXROW,*PMIB_TCPEXROW;


typedef struct
{
  DWORD dwLocalAddr;  //本地地址
  DWORD dwLocalPort;  //本地端口
  DWORD dwProcessId;  //进程标识

}MIB_UDPEXROW,*PMIB_UDPEXROW;


typedef struct
{
  DWORD dwState;      //连接状态
  DWORD dwLocalAddr;  //本地地址
  DWORD dwLocalPort;  //本地端口
  DWORD dwRemoteAddr; //远程地址
  DWORD dwRemotePort; //远程端口
  DWORD dwProcessId;  //进程标识
  DWORD Unknown;      //待定标识

}MIB_TCPEXROW_VISTA,*PMIB_TCPEXROW_VISTA;


typedef struct
{
  DWORD dwNumEntries;
  MIB_TCPEXROW table[ANY_SIZE];

}MIB_TCPEXTABLE,*PMIB_TCPEXTABLE;


typedef struct
{
  DWORD dwNumEntries;
  MIB_TCPEXROW_VISTA table[ANY_SIZE];

}MIB_TCPEXTABLE_VISTA,*PMIB_TCPEXTABLE_VISTA;


typedef struct
{
  DWORD dwNumEntries;
  MIB_UDPEXROW table[ANY_SIZE];

}MIB_UDPEXTABLE,*PMIB_UDPEXTABLE;


//=====================================================================================//
//Name: DWORD AllocateAndGetTcpExTableFromStack()								       //
//                                                                                     //
//Descripion: 该函数仅仅只在 Windows XP,Windows Server 2003 下有效						   //
//            				                            						       //
//=====================================================================================//
typedef DWORD (WINAPI *PFNAllocateAndGetTcpExTableFromStack)(
	PMIB_TCPEXTABLE *pTcpTabel,
	bool bOrder,
	HANDLE heap,
	DWORD zero,
	DWORD flags
	);

//=====================================================================================//
//Name: DWORD AllocateAndGetUdpExTableFromStack()								       //
//                                                                                     //
//Descripion: 该函数仅仅只在 XP,Windows Server 2003 下有效						       	   //
//            				                            						       //
//=====================================================================================//
typedef DWORD (WINAPI *PFNAllocateAndGetUdpExTableFromStack)(
	PMIB_UDPEXTABLE *pUdpTable,
	bool bOrder,
	HANDLE heap,
	DWORD zero,
	DWORD flags
	);

//=====================================================================================//
//Name: DWORD InternalGetTcpTable2()												   //
//                                                                                     //
//Descripion: 该函数在 Windows Vista 以及 Windows 7 下面效								   //
//            				                            						       //
//=====================================================================================//
typedef DWORD (WINAPI *PFNInternalGetTcpTable2)(
	PMIB_TCPEXTABLE_VISTA *pTcpTable_Vista,
	HANDLE heap,
	DWORD flags
	);

//=====================================================================================//
//Name: DWORD InternalGetUdpTableWithOwnerPid()										   //
//                                                                                     //
//Descripion: 该函数在 Windows Vista 以及 Windows 7 下面效								   //
//            				                            						       //
//=====================================================================================//
typedef DWORD (WINAPI *PFNInternalGetUdpTableWithOwnerPid)(
	PMIB_UDPEXTABLE *pUdpTable,
	HANDLE heap,
	DWORD flags
	);


//=====================================================================================//
//Name: DWORD GetProcessIdByPort()													   //
//                                                                                     //
//Descripion: 根据端口号求出打开该端口号的进程 ID(支持 XP,Server 2003,Vista,Win7)			   //
//            				                            						       //
//=====================================================================================//
DWORD GetProcessIdByPort(TcpOrUdp type, DWORD dwPort)
{
	HMODULE hModule = LoadLibraryW(L"iphlpapi.dll");
	if (hModule == NULL)
	{
		return 0;
	}

	if(type == TcpType)
	{
		// 表明查询的是 TCP 信息
		PFNAllocateAndGetTcpExTableFromStack pAllocateAndGetTcpExTableFromStack;
		pAllocateAndGetTcpExTableFromStack = 
			(PFNAllocateAndGetTcpExTableFromStack)GetProcAddress(hModule, "AllocateAndGetTcpExTableFromStack");
		if (pAllocateAndGetTcpExTableFromStack != NULL)
		{
			// 表明为 XP 或者 Server 2003 操作系统
			PMIB_TCPEXTABLE pTcpExTable = NULL;
			if (pAllocateAndGetTcpExTableFromStack(&pTcpExTable, TRUE, GetProcessHeap(), 0, AF_INET) != 0)
			{
				if (pTcpExTable)
				{
					HeapFree(GetProcessHeap(), 0, pTcpExTable);
				}

				FreeLibrary(hModule);
				hModule = NULL;

				return 0;
			}

			for (UINT i = 0; i < pTcpExTable->dwNumEntries; i++)
			{
				// 过滤掉数据,只查询我们需要的进程数据
				if(dwPort == ntohs(0x0000FFFF & pTcpExTable->table[i].dwLocalPort))
				{
					DWORD dwProcessId = pTcpExTable->table[i].dwProcessId;
					if (pTcpExTable)
					{
						HeapFree(GetProcessHeap(), 0, pTcpExTable);
					}

					FreeLibrary(hModule);
					hModule = NULL;

					return dwProcessId;
				}
			}

			if (pTcpExTable)
			{
				HeapFree(GetProcessHeap(), 0, pTcpExTable);
			}

			FreeLibrary(hModule);
			hModule = NULL;

			return 0;
		}
		else
		{
			// 表明为 Vista 或者 7 操作系统
			PMIB_TCPEXTABLE_VISTA pTcpExTable = NULL;
			PFNInternalGetTcpTable2 pInternalGetTcpTable2 = 
				(PFNInternalGetTcpTable2)GetProcAddress(hModule, "InternalGetTcpTable2");
			if (pInternalGetTcpTable2 == NULL)
			{
				if (pTcpExTable)
				{
					HeapFree(GetProcessHeap(), 0, pTcpExTable);
				}

				FreeLibrary(hModule);
				hModule = NULL;

				return 0;
			}

			if (pInternalGetTcpTable2(&pTcpExTable, GetProcessHeap(), 1))
			{
				if (pTcpExTable)
				{
					HeapFree(GetProcessHeap(), 0, pTcpExTable);
				}

				FreeLibrary(hModule);
				hModule = NULL;

				return 0;
			}

			for (UINT i = 0;i < pTcpExTable->dwNumEntries; i++)
			{
				// 过滤掉数据,只查询我们需要的进程数据
				if(dwPort == ntohs(0x0000FFFF & pTcpExTable->table[i].dwLocalPort))
				{
					DWORD dwProcessId = pTcpExTable->table[i].dwProcessId;
					if (pTcpExTable)
					{
						HeapFree(GetProcessHeap(), 0, pTcpExTable);
					}

					FreeLibrary(hModule);
					hModule = NULL;

					return dwProcessId;
				}
			}

			if (pTcpExTable)
			{
				HeapFree(GetProcessHeap(), 0, pTcpExTable);
			}

			FreeLibrary(hModule);
			hModule = NULL;

			return 0;
		}
	}
	else if(type == UdpType)
	{
		// 表明查询的是 UDP 信息
		PMIB_UDPEXTABLE pUdpExTable = NULL;
		PFNAllocateAndGetUdpExTableFromStack pAllocateAndGetUdpExTableFromStack;
		pAllocateAndGetUdpExTableFromStack = 
			(PFNAllocateAndGetUdpExTableFromStack)GetProcAddress(hModule,"AllocateAndGetUdpExTableFromStack");
		if (pAllocateAndGetUdpExTableFromStack != NULL)
		{
			// 表明为 XP 或者 Server 2003 操作系统
			if (pAllocateAndGetUdpExTableFromStack(&pUdpExTable, TRUE, GetProcessHeap(), 0, AF_INET) != 0)
			{
				if (pUdpExTable)
				{
					HeapFree(GetProcessHeap(), 0, pUdpExTable);
				}

				FreeLibrary(hModule);
				hModule = NULL;

				return 0;
			}

			for (UINT i = 0; i < pUdpExTable->dwNumEntries; i++)
			{
				// 过滤掉数据,只查询我们需要的进程数据
				if (dwPort == ntohs(0x0000FFFF & pUdpExTable->table[i].dwLocalPort))
				{
					DWORD dwProcessId = pUdpExTable->table[i].dwProcessId;
					if (pUdpExTable)
					{
						HeapFree(GetProcessHeap(), 0, pUdpExTable);
					}

					FreeLibrary(hModule);
					hModule = NULL;

					return dwProcessId;
				}
			}

			if (pUdpExTable)
			{
				HeapFree(GetProcessHeap(), 0, pUdpExTable);
			}

			FreeLibrary(hModule);
			hModule = NULL;

			return 0;
		}
		else
		{
			// 表明为 Vista 或者 7 操作系统
			PFNInternalGetUdpTableWithOwnerPid pInternalGetUdpTableWithOwnerPid;
			pInternalGetUdpTableWithOwnerPid = 
				(PFNInternalGetUdpTableWithOwnerPid)GetProcAddress(hModule, "InternalGetUdpTableWithOwnerPid");
			if (pInternalGetUdpTableWithOwnerPid != NULL)
			{
				if (pInternalGetUdpTableWithOwnerPid(&pUdpExTable, GetProcessHeap(), 1))
				{
					if (pUdpExTable)
					{
						HeapFree(GetProcessHeap(), 0, pUdpExTable);
					}

					FreeLibrary(hModule);
					hModule = NULL;

					return 0;
				}

				for (UINT i = 0; i < pUdpExTable->dwNumEntries; i++)
				{
					// 过滤掉数据,只查询我们需要的进程数据
					if (dwPort == ntohs(0x0000FFFF & pUdpExTable->table[i].dwLocalPort))
					{
						DWORD dwProcessId = pUdpExTable->table[i].dwProcessId;
						if (pUdpExTable)
						{
							HeapFree(GetProcessHeap(), 0, pUdpExTable);
						}

						FreeLibrary(hModule);
						hModule = NULL;

						return dwProcessId;
					}
				}
			}

			if (pUdpExTable)
			{
				HeapFree(GetProcessHeap(), 0, pUdpExTable);
			}

			FreeLibrary(hModule);
			hModule = NULL;

			return 0;
		}
	}
	else
	{
		FreeLibrary(hModule);
		hModule = NULL;

		return -1;
	}
}


//=====================================================================================//
//Name: DWORD GetAllPortByProcessId()												   //
//                                                                                     //
//Descripion: 根据进程 ID 来求出该进程所打开的所有的端口号,并且在 dwAllPort 数组中返回所有端口号	   //
//			  其中 dwMaxLen 为数组的长度,函数的返回值为进程所打开的端口的数目					   //
//			  (支持 XP,Server 2003,Vista,Win7)										   //
//            				                            						       //
//=====================================================================================//
DWORD GetAllPortByProcessId(TcpOrUdp type, DWORD dwProcessId, DWORD * dwAllPort, DWORD dwMaxLen)
{
	DWORD dwPortCount = 0;
	HMODULE hModule = LoadLibraryW(L"iphlpapi.dll");
	if (hModule == NULL)
	{
		return dwPortCount;
	}

	if(type == TcpType)
	{
		// 表明查询的是 UDP 信息
		PFNAllocateAndGetTcpExTableFromStack pAllocateAndGetTcpExTableFromStack;
		pAllocateAndGetTcpExTableFromStack = (PFNAllocateAndGetTcpExTableFromStack)GetProcAddress(hModule, "AllocateAndGetTcpExTableFromStack");
		if (pAllocateAndGetTcpExTableFromStack != NULL)
		{
			// 表明为 XP 或者 Server 2003 操作系统
			PMIB_TCPEXTABLE pTcpExTable = NULL;
			if (pAllocateAndGetTcpExTableFromStack(&pTcpExTable, TRUE, GetProcessHeap(), 0, AF_INET) != 0)
			{
				if (pTcpExTable)
				{
					HeapFree(GetProcessHeap(), 0, pTcpExTable);
				}

				FreeLibrary(hModule);
				hModule = NULL;

				return dwPortCount;
			}

			for (UINT i = 0; i < pTcpExTable->dwNumEntries; i++)
			{
				// 过滤掉数据,只获取我们要查询的进程的 Port 信息
				if(dwProcessId == pTcpExTable->table[i].dwProcessId)
				{
					if(dwPortCount < dwMaxLen)
					{
						dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pTcpExTable->table[i].dwLocalPort);
						dwPortCount++;
					}
				}
			}

			if (pTcpExTable)
			{
				HeapFree(GetProcessHeap(), 0, pTcpExTable);
			}

			FreeLibrary(hModule);
			hModule = NULL;

			return dwPortCount;
		}
		else
		{
			// 表明为 Vista 或者 7 操作系统
			PMIB_TCPEXTABLE_VISTA pTcpExTable = NULL;
			PFNInternalGetTcpTable2 pInternalGetTcpTable2 = (PFNInternalGetTcpTable2)GetProcAddress(hModule, "InternalGetTcpTable2");
			if (pInternalGetTcpTable2 == NULL)
			{
				if (pTcpExTable)
				{
					HeapFree(GetProcessHeap(), 0, pTcpExTable);
				}

				FreeLibrary(hModule);
				hModule = NULL;

				return dwPortCount;
			}

			if (pInternalGetTcpTable2(&pTcpExTable, GetProcessHeap(), 1))
			{
				if (pTcpExTable)
				{
					HeapFree(GetProcessHeap(), 0, pTcpExTable);
				}

				FreeLibrary(hModule);
				hModule = NULL;

				return dwPortCount;
			}

			for (UINT i = 0;i < pTcpExTable->dwNumEntries; i++)
			{
				// 过滤掉数据,只获取我们要查询的进程的 TCP Port 信息
				if(dwProcessId == pTcpExTable->table[i].dwProcessId)
				{
					if(dwPortCount < dwMaxLen)
					{
						dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pTcpExTable->table[i].dwLocalPort);
						dwPortCount++;
					}
				}
			}

			if (pTcpExTable)
			{
				HeapFree(GetProcessHeap(), 0, pTcpExTable);
			}

			FreeLibrary(hModule);
			hModule = NULL;

			return dwPortCount;
		}
	}
	else if(type == UdpType)
	{
		// 表明查询的是 UDP 信息
		PMIB_UDPEXTABLE pUdpExTable = NULL;
		PFNAllocateAndGetUdpExTableFromStack pAllocateAndGetUdpExTableFromStack;
		pAllocateAndGetUdpExTableFromStack = (PFNAllocateAndGetUdpExTableFromStack)GetProcAddress(hModule,"AllocateAndGetUdpExTableFromStack");
		if (pAllocateAndGetUdpExTableFromStack != NULL)
		{
			// 表明为 XP 或者 Server 2003 操作系统
			if (pAllocateAndGetUdpExTableFromStack(&pUdpExTable, TRUE, GetProcessHeap(), 0, AF_INET) != 0)
			{
				if (pUdpExTable)
				{
					HeapFree(GetProcessHeap(), 0, pUdpExTable);
				}

				FreeLibrary(hModule);
				hModule = NULL;

				return dwPortCount;
			}

			for (UINT i = 0; i < pUdpExTable->dwNumEntries; i++)
			{
				// 过滤掉数据,只获取我们要查询的进程的 UDP Port信息
				if(dwProcessId == pUdpExTable->table[i].dwProcessId)
				{
					if(dwPortCount < dwMaxLen)
					{
						dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pUdpExTable->table[i].dwLocalPort);
						dwPortCount++;
					}
				}
			}

			if (pUdpExTable)
			{
				HeapFree(GetProcessHeap(), 0, pUdpExTable);
			}

			FreeLibrary(hModule);
			hModule = NULL;

			return dwPortCount;
		}
		else
		{
			// 表明为 Vista 或者 7 操作系统
			PFNInternalGetUdpTableWithOwnerPid pInternalGetUdpTableWithOwnerPid;
			pInternalGetUdpTableWithOwnerPid = (PFNInternalGetUdpTableWithOwnerPid)GetProcAddress(hModule, "InternalGetUdpTableWithOwnerPid");
			if (pInternalGetUdpTableWithOwnerPid != NULL)
			{
				if (pInternalGetUdpTableWithOwnerPid(&pUdpExTable, GetProcessHeap(), 1))
				{
					if (pUdpExTable)
					{
						HeapFree(GetProcessHeap(), 0, pUdpExTable);
					}

					FreeLibrary(hModule);
					hModule = NULL;

					return dwPortCount;
				}

				for (UINT i = 0; i < pUdpExTable->dwNumEntries; i++)
				{
					// 过滤掉数据,只获取我们要查询的进程的 UDP Port信息
					if(dwProcessId == pUdpExTable->table[i].dwProcessId)
					{
						if(dwPortCount < dwMaxLen)
						{
							dwAllPort[dwPortCount] = ntohs(0x0000FFFF & pUdpExTable->table[i].dwLocalPort);
							dwPortCount++;
						}
					}
				}
			}

			if (pUdpExTable)
			{
				HeapFree(GetProcessHeap(), 0, pUdpExTable);
			}

			FreeLibrary(hModule);
			hModule = NULL;

			return dwPortCount;
		}
	}
	else
	{
		FreeLibrary(hModule);
		hModule = NULL;

		return dwPortCount;
	}
}


int main()
{
	DWORD dwAllPort[50];
	DWORD dwMaxLen = 50;

	DWORD dwPort;
	DWORD dwProcessId;

	DWORD dwResult = 0;

	DWORD dwInput = 0;
	while(dwInput != 5)
	{
		cout<<"Input 1: Query TCP Port By Process ID;"<<endl;
		cout<<"Input 2: Query UDP Port By Process ID;"<<endl;
		cout<<"Input 3: Query Process ID By TCP Port;"<<endl;
		cout<<"Input 4: Query Process ID By UDP Port;"<<endl;
		cout<<"Input 5: Exit Application;"<<endl<<endl;
		cout<<"Please Input Your Select Option:   ";
		cin>>dwInput;
		system("cls");

		memset(dwAllPort, 0, sizeof(DWORD) * dwMaxLen);

		switch(dwInput)
		{
		case 1:
			{
				cout<<"Please Input The Process ID:  ";
				cin>>dwProcessId;
				dwResult = GetAllPortByProcessId(TcpType, dwProcessId, dwAllPort, dwMaxLen);
				cout<<endl<<"=========Query TCP Port By Process ID Result : ========="<<endl;
				for(int i=0;i<dwResult;i++)
				{
					cout<<"第 "<<i + 1<<" 条:  "<<dwAllPort[i]<<endl;
				}
				cout<<"========================================================"<<endl<<endl<<endl;
				break;
			}
		case 2:
			{
				cout<<"Please Input The Process ID:  ";
				cin>>dwProcessId;
				dwResult = GetAllPortByProcessId(UdpType, dwProcessId, dwAllPort, dwMaxLen);
				cout<<endl<<"=========Query UDP Port By Process ID Result : ========="<<endl;
				for(int i=0;i<dwResult;i++)
				{
					cout<<"第 "<<i + 1<<" 条:  "<<dwAllPort[i]<<endl;
				}
				cout<<"========================================================"<<endl<<endl<<endl;
				break;
			}
		case 3:
			{
				cout<<"Please Input The Port:  ";
				cin>>dwPort;
				dwResult = GetProcessIdByPort(TcpType, dwPort);
				cout<<endl<<"=========Query Process ID By TCP Port Result : ========="<<endl;
				cout<<"结果为:  "<<dwResult<<endl;
				cout<<"========================================================"<<endl<<endl<<endl;
				break;
			}
		case 4:
			{
				cout<<"Please Input The Port:  ";
				cin>>dwPort;
				dwResult = GetProcessIdByPort(UdpType, dwPort);
				cout<<endl<<"=========Query Process ID By UDP Port Result : ========="<<endl;
				cout<<"结果为:  "<<dwResult<<endl;
				cout<<"========================================================"<<endl<<endl<<endl;
				break;
			}
		case 5:
			{
				return 0;
			}
		default:
			{
				break;
			}
		}
	}

	return 0;
}

float Speed_Low_Filter(float new_Spe,encoder_t *encoder) { float sum = 0.0f; uint32_t test_Speed = new_Spe; for(uint8_t i=SPEED_RECORD_NUM-1;i>0;i--) { encoder->speed_Record[i] = encoder->speed_Record[i-1]; sum += encoder->speed_Record[i-1]; } encoder->speed_Record[0] = new_Spe; sum += new_Spe; test_Speed = sum/SPEED_RECORD_NUM; return sum/SPEED_RECORD_NUM; } motor_t motor_l; motor_t motor_r; void motor_Init() { DL_TimerG_startCounter(PWM_0_INST); //pwm初始化 /*使能编码器输入捕获中断*/ NVIC_EnableIRQ(ENCODER1A_INST_INT_IRQN); DL_TimerA_startCounter(ENCODER1A_INST); NVIC_EnableIRQ(ENCODER2A_INST_INT_IRQN); DL_TimerG_startCounter(ENCODER2A_INST); /*使能时钟定时器中断*/ NVIC_EnableIRQ(CLOCK_INST_INT_IRQN); DL_TimerA_startCounter(CLOCK_INST); /*motor_l init*/ motor_l.pwmDuty=0; motor_l.speed=0; motor_l.timer_index=DL_TIMER_CC_0_INDEX; motor_l.forward_GPIO_PORT=GPIO_MOTOR_AIN1_PORT; motor_l.reverse_GPIO_PORT=GPIO_MOTOR_AIN2_PORT; motor_l.forward_GPIO_PIN=GPIO_MOTOR_AIN1_PIN; motor_l.reverse_GPIO_PIN=GPIO_MOTOR_AIN2_PIN; motor_l.speed_pid.kp=0; motor_l.speed_pid.ki=0; motor_l.speed_pid.kd=0; motor_l.speed_pid.max_integral=1000; motor_l.speed_pid.maxoutput=1000; motor_l.speed_pid.dead_zone=0; motor_l.pos_pid.kp=0; motor_l.pos_pid.ki=0; motor_l.pos_pid.kd=0; motor_l.pos_pid.max_integral=1000; motor_l.pos_pid.maxoutput=1000; motor_l.pos_pid.dead_zone=0; /*motor_r init*/ motor_r.pwmDuty=0; motor_r.speed=0; motor_r.timer_index=DL_TIMER_CC_1_INDEX; motor_r.forward_GPIO_PORT=GPIO_MOTOR_BIN1_PORT; motor_r.reverse_GPIO_PORT=GPIO_MOTOR_BIN2_PORT; motor_r.forward_GPIO_PIN=GPIO_MOTOR_BIN1_PIN; motor_r.reverse_GPIO_PIN=GPIO_MOTOR_BIN2_PIN; motor_r.speed_pid.kp=0; motor_r.speed_pid.ki=0; motor_r.speed_pid.kd=0; motor_r.speed_pid.max_integral=1000; motor_r.speed_pid.maxoutput=1000; motor_r.speed_pid.dead_zone=0; motor_r.pos_pid.kp=0; motor_r.pos_pid.ki=0; motor_r.pos_pid.kd=0; motor_r.pos_pid.max_integral=1000; motor_r.pos_pid.maxoutput=1000; motor_r.pos_pid.dead_zone=0; } /*左电机的编码器测速*/ void TIMA0_IRQHandler(void) { switch (DL_TimerA_getPendingInterrupt(ENCODER1A_INST)) { case DL_TIMERA_IIDX_CC0_DN: motor_l.encoder.dierct = DL_GPIO_readPins(GPIO_ENCODER_PORT, GPIO_ENCODER_ENCODER1B_PIN);//读取IO电平获取电机旋转方向 motor_l.encoder.countnum= motor_l.encoder.dierct? (motor_l.encoder.countnum + 1) : (motor_l.encoder.countnum - 1);//通过判断旋转方向来决定countnum增加还是减少 break; default: break; } } /*右电机的编码器测速*/ void TIMG6_IRQHandler(void) { switch (DL_TimerG_getPendingInterrupt(ENCODER2A_INST)) { case DL_TIMERG_IIDX_CC0_DN: motor_r.encoder.dierct= DL_GPIO_readPins(GPIO_ENCODER_PORT, GPIO_ENCODER_ENCODER2B_PIN);//读取IO电平获取电机旋转方向 motor_r.encoder.countnum = motor_r.encoder.dierct ? ( motor_r.encoder.countnum + 1) : ( motor_r.encoder.countnum- 1);//通过判断旋转方向来决定countnum增加还是减少 break; default: break; } } /*period 100Hz*/ void CLOCK_INST_IRQHandler(void) { DL_TimerA_clearInterruptStatus(CLOCK_INST, DL_TIMER_IIDX_ZERO); motor_l.encoder.speed = (float)(motor_l.encoder.countnum - motor_l.encoder.lastcount) * 6000 / PULSE_PER_CYCLE; // rpm motor_r.encoder.speed = (float)(motor_r.encoder.countnum - motor_r.encoder.lastcount) * 6000 / PULSE_PER_CYCLE; // rpm motor_l.encoder.speed = Speed_Low_Filter(motor_l.encoder.speed, &motor_l.encoder); motor_r.encoder.speed = Speed_Low_Filter(motor_r.encoder.speed, &motor_r.encoder); motor_l.encoder.lastcount = motor_l.encoder.countnum; motor_r.encoder.lastcount = motor_r.encoder.countnum; } float PID_Realize(pid_t* pid,float target,float feedback) { pid->err = target - feedback; if(pid->err < pid->dead_zone && pid->err > -pid->dead_zone) pid->err = 0;//pid死区 pid->integral += pid->err; if(pid->ki * pid->integral < -pid->max_integral) pid->integral = -pid->max_integral / pid->ki;//积分限幅 else if(pid->ki * pid->integral > pid->max_integral) pid->integral = pid->max_integral / pid->ki; pid->output = (pid->kp * pid->err) + (pid->ki * pid->integral) + (pid->kd * (pid->err - pid->last_err)); //输出限幅 if(pid->output > pid->maxoutput) pid->output = pid->maxoutput; else if(pid->output < -pid->maxoutput) pid->output = -pid->maxoutput; pid->last_err = pid->err; return pid->output; } void Motor_Set_Duty(motor_t *motor){ if (motor->pwmDuty>=0){//正转 DL_TimerG_setCaptureCompareValue(PWM_0_INST,motor->pwmDuty,motor->timer_index); DL_GPIO_setPins(motor->forward_GPIO_PORT, motor->forward_GPIO_PIN); DL_GPIO_clearPins(motor->reverse_GPIO_PORT, motor->reverse_GPIO_PIN); } else if(motor->pwmDuty<0){//反转 DL_TimerG_setCaptureCompareValue(PWM_0_INST,-motor->pwmDuty,motor->timer_index); DL_GPIO_setPins(motor->reverse_GPIO_PORT, motor->reverse_GPIO_PIN); DL_GPIO_clearPins(motor->forward_GPIO_PORT, motor->forward_GPIO_PIN); } } void Motor_Set_Speed(motor_t *motor){ motor->pwmDuty=PID_Realize(&motor->speed_pid,motor->speed,motor->encoder.speed); Motor_Set_Duty(motor); } void Motor_Set_Position(motor_t *motor){ motor->pos_pulse=(int)((motor->pos*PULSE_PER_CYCLE)/(LINE_SPEED_C)); motor->speed=PID_Realize(&motor->pos_pid, motor->pos_pulse, motor->encoder.countnum); Motor_Set_Speed(motor); } void Motor_Stop(motor_t *motor){ motor->speed=0; Motor_Set_Speed(motor); if(motor->encoder.speed==0){ motor->encoder.countnum=0; motor->encoder.lastcount=0; motor->speed_pid.integral=0; } }解释一下这些代码
最新发布
07-17
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值