OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5687|回复: 5

PID

[复制链接]

17

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2013-4-8
在线时间
0 小时
发表于 2013-7-19 13:41:11 | 显示全部楼层 |阅读模式
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-19 14:14:04 | 显示全部楼层
回复 支持 反对

使用道具 举报

17

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2013-4-8
在线时间
0 小时
 楼主| 发表于 2013-7-19 14:15:34 | 显示全部楼层
老师,你有木有?
回复 支持 反对

使用道具 举报

7

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
94
金钱
94
注册时间
2013-6-29
在线时间
0 小时
发表于 2013-7-19 14:42:57 | 显示全部楼层
之前做过pid。做的是控制电热棒。不知道你想控制什么。看你想拿程序应该是不懂什么叫pid吧?两张常见控制pid,利用da和pwm。我用的是da。
#include "ID.h"
void pid_out()
{
ek=rk-yk;
if(ek>10.0)duk=255;
else if(ek<0.0)duk=0;
else
{
sum=kp*ek+kd*(ek-ek1);
if(sum>0.0)
duk=(uchar)sum;
else duk=0;
if(duk>255)duk=255;
}
ek1=ek;
pcf8591_write_add(0x40,duk);     //输出量
}
以上程序是位置型PD,增量型也是大同小异。以上不完善的地方就是,超过期望值就释放控制,也就是等待降温,没有冷却处理。
自己用课本的某些方法凑出kp,ki,kd吧。
回复 支持 反对

使用道具 举报

17

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2013-4-8
在线时间
0 小时
 楼主| 发表于 2013-7-19 17:08:17 | 显示全部楼层
回复【4楼】hqr1021:
---------------------------------
做PID恒流恒压源
回复 支持 反对

使用道具 举报

15

主题

53

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
283
金钱
283
注册时间
2013-4-19
在线时间
0 小时
发表于 2013-7-20 16:32:58 | 显示全部楼层
PID 溫度控制 + PWM 輸出 測試實機OK

PID1 是加熱器  用 SSR PWM 輸出  加熱器可到 +_ 1 度內 (97.00度=9700)

PID2~PID4 是環境冷卻風扇 用 ULN2803AP驅動IC, PWM 輸出   冷卻環境控制溫度可到 +_ 3 度內 (61.00;度=6100)



/////////////////////////////////////////////////////////////////
pid.h
/////////////////////////////////////////////////////////////////


#ifndef __PID_H
#define __PID_H  
#include "sys.h"

struct PID
{
float Kp;   // 比例常數 Proportional Const
float Ki;    // 積分常數 Integral Const
float Kd;   // 微分常數 Derivative Const
float Keep; // 設定保持溫度 基本PWM 輸出量

float TargetTemp; //輸入設定溫度
float NowTemp; //現在量測到溫度 Temperature
float NowTemp1; //上次1量測到溫度 Temperature
float NowTemp2; //上次2量測到溫度 Temperature
float NowTemp3; //上次3量測到溫度 Temperature
float NowTemp4; //上次4量測到溫度 Temperature
float NowTemp5; //上次5量測到溫度 Temperature
u8 Flag; //升溫或降溫旗標 升溫=1; 降溫=0
u8 TempCount; //溫度取樣計數器
float TargetValue; //PID 控制 設定溫度
float NowValue; ///PID 控制 目前溫度
float Pre1Value; ///PID 控制 上次溫度記錄,
float Pre2Value; ///PID 控制 上上次溫度記錄,
float Error0;   //本次誤差值
float Error1; //上次誤差值
float Error2; //上上次誤差值
float SumError;   //累積誤差總合值
float vError0; //目前有變化 誤差溫度值
float vError1; //上1次有變化 誤差溫度值
float vError2; //上2次有變化 誤差溫度值
float vError3; //上3次有變化 誤差溫度值
float vError4; //上4次有變化 誤差溫度值
float vError5; //上5次有變化 誤差溫度值

float KpValue; //運算比例量暫存值
float KiValue; //運算積分量暫存值
float KdValue; //運算微分量暫存值

float ResultValue; //PID Kp+Ki+Kd 運算結果 暫存值
float OutputValue; //PID 運算後 輸出值 暫存值
float PWMResult; //PWM 輸出量 暫存值
float PWMOut; // PWM 輸出量 實際輸出值
};
extern struct PID PID1,PID2,PID3,PID4;


void PID1_Init( void); //PID1初始化程式
void PID1_Control(void); //PID1 控制程式
void PID1_Calculate(void);  //PID1 運算程式 (位置計算式)

void PID2_Init( void); //PID2初始化程式
void PID2_Control(void); //PID2 控制程式
void PID2_Calculate(void);  //PID2 運算程式 (位置計算式)

void PID3_Init( void); //PID3初始化程式
void PID3_Control(void); //PID3 控制程式
void PID3_Calculate(void);  //PID3 運算程式 (位置計算式)

void PID4_Init( void); //PID4初始化程式
void PID4_Control(void); //PID4 控制程式
void PID4_Calculate(void);  //PID4 運算程式 (位置計算式)

#endif

////////////////////////////////
pid.c
//////////////////////////////


#include "pid.h"
#include "stdio.h"
#include "lcd.h"
#include "s11059.h"
#include "max31855.h"
#include "myhmi.h"

/*
变量名
Pp(K) ;比例输出
Pi(K) ;积分输出
Pd(K) ;微分输出
Kp    ;比例系数
Ki    ;积分系数
Kd    ;微分系数
E(K)  ;本次误差值
R(K)  ;本次设定值
M(K)  ;本次测量值
E(K-1);上次误差值
E(K-2);上上次误差值
Pi(K-1);上次积分输出

;位置型PID算法:
E(K)=R(K)-M(K)         ;本次误差=本次设定值-本次测量值
Pp(K)=Kp*E(K)          ;本次比例输出=比例系数×本次误差值
Pi(K)=Ki*E(K)+Pi(K-1)  ;本次积分输出=积分系数×本次误差值+上次积分输出值
Pd(K)=Kd[E(K)-E(K-1)]  ;本次微分输出=微分系数×(本次误差值-上次误差值)
P(K)=Pp(K)+Pi(K)+Pd(K) ;输出值=本次比例输出+本次积分输出+本次微分输出
位置型PID计算公式


;增量型PID算法:
E(K)=R(K)-M(K)         ;本次误差=本次设定值-本次测量值
Pp(K)=Kp[E(K)-E(K-1)]  ;本次比例输出=比例系数×(本次误差值-上次误差值)
Pi(K)=Ki*E(K)          ;本次积分输出=积分系数×本次误差
Pd(K)=Kd[E(K)-2E(K-1)+E(K-2) ;本次微分输出=微分系数×(本次误差值-2×上次误差值+上上次误差值)
P(K)=Pp(K)+Pi(K)+Pd(K) ;输出值=本次比例输出+本次积分输出+本次微分输出

//增量法计算公式:
 //Pdt=Kp*[E(t)-E(t-1)]+Ki*E(t)+Kd*[E(t)-2*E(t-1)+E(t-2)]   
增量式PID算法的输出量为                   
ΔUn = Kp[(en-en-1)+(T/Ti)en+(Td/T)(en-2*en-1+en-2)] 
*/

/************************************************************************
**位置PID的 KP,KI,KD参数;
**在调试过程中,只对KP,KI,进行了调节,对KP,KI有了一点认识,但对KD仍然没有什么认识
**在本组参数中,只设置了KP。
**同时现在给定的理想值是实际的电机转动过程中输出的脉冲数。 
*************************************************************************/

struct PID PID1,PID2,PID3,PID4;
//////////////////////////////////////////////////////////////////////////////////////

/*====================================================================================================/
 ID1 PWM1 TIM4 CH1 PB6 Temp.13~17 Heater
=====================================================================================================*/
void PID1_Init(void)
{ //PID=100000 PWM=1000 =1/100
PID1.TargetTemp =9700; //設定目標溫度值
PID1.Keep=1000; //設定保持最低輸出值 //[100/1000 (0.1)]
PID1.Kp=100; // 比例常数Proportional Const  //[100x100=10000 /100=100  (0.15)]
PID1.Ki=3; // 积分常数Integral Const //[2000*5=10000/100=100 (0.1)]  (0.5 20=10s )
PID1.Kd=50; // 微分常数Derivative Const  //[25*200=5000 /100=50  (+_0.05)]  Max=0.1
PID1.Error0=0.0; //目前誤差值
PID1.Error1=0.0;   // Error[-1] 上次误差
PID1.Error2=0.0; // Error[-2]  上上次误差
PID1.SumError =0.0; //累積誤差總合值
PID1.OutputValue=0.0 ; //实际输出量
PID1.TargetValue =PID1.TargetTemp ; // 设定目标值Desired value Target
}


void PID1_Control(void) //Temp.13~17 Heater
{
//PID1.NowValue=PID1.NowTemp; //控制現在溫度值
PID1.TargetValue=PID1.TargetTemp; //控制目標溫度值
PID1_Calculate();     // float PID_calculate( struct PID *pid_1,float NowValue ); //位置PID计算
if (PID1.NowTemp<ID1.TargetTemp-1000) PID1.PWMResult=10000; //(0~1000) 溫度過低 PID運算範圍外 , PWM 輸出量 暫存值
else if (PID1.NowTemp<ID1.TargetTemp-500) PID1.PWMResult=7000; //溫度過低 PID運算範圍外 , PWM 輸出量 暫存值
else if (PID1.NowTemp<ID1.TargetTemp -200) PID1.PWMResult=5000; //溫度過低 PID運算範圍外 , PWM 輸出量 暫存值
else if (PID1.NowTemp>ID1.TargetTemp +100) PID1.PWMResult=0; //溫度過高 PID運算範圍外 , PWM 輸出量 暫存值
else  ID1.PWMResult=(PID1.OutputValue/10)+PID1.Keep; //溫度上升中; PID 運算 (0~100000/0~1000)=100 //PID 運算範圍內 輸出值 // PID運算範圍內
PID1.PWMOut=PID1.PWMResult; // PWM 輸出量 實際輸出值
}

/*====================================================================================================/
 ID1计算部分
=====================================================================================================*/
/*
位置型PID算法:
E(K)=R(K)-M(K)         ;本次误差=本次设定值-本次测量值
Pp(K)=Kp*E(K)          ;本次比例输出=比例系数×本次误差值
Pi(K)=Ki*E(K)+Pi(K-1)  ;本次积分输出=积分系数×本次误差值+上次积分输出值
Pd(K)=Kd[E(K)-E(K-1)]  ;本次微分输出=微分系数×(本次误差值-上次误差值)
P(K)=Pp(K)+Pi(K)+Pd(K) ;输出值=本次比例输出+本次积分输出+本次微分输出
*/

void PID1_Calculate(void) //位置PID计算
{  
PID1.Error0 = PID1.TargetValue-PID1.NowValue ; //目前誤差值 本次误差=本次设定值-本次测量值

/*===PID1比例項 計算式===*/
//PID1.KpValue = PID1.Kp*PID1.Error0 ; //比例項  本次比例输出=比例系数×本次误差值  pError=Error-pp->LastError;
PID1.KpValue = PID1.Kp*(PID1.Error0+50) ; //比例項  本次比例输出=比例系数×本次误差值  pError=Error-pp->LastError;
/*===PID1 積分項 計算式===*/
PID1.SumError += PID1.Error0; //累積誤差總合值   本次积分输出=积分系数×本次误差值+上次积分输出值  
if(PID1.SumError>2000) PID1.SumError=2000; //累積誤差總合最大值
if(PID1.SumError<-200) PID1.SumError=-200; //累積誤差總合最小值
if((PID1.NowTemp>ID1.TargetTemp+25)&&(PID1.SumError>1000)) PID1.SumError=0; //升溫超過正誤差設定值 累積誤差歸零
if((PID1.NowTemp<ID1.TargetTemp)&&(PID1.SumError<-25)) PID1.SumError=0; //降溫超過負誤差設定值 累積誤差歸零
PID1.KiValue = PID1.Ki*PID1.SumError;  //積分項  本次积分输出=积分系数×本次误差值+上次积分输出值 E(t)  //pp->SumError += Error
/*===PID1 微分項 計算式===*/ 
if(PID1.NowValue!=PID1.Pre1Value) //檢查溫度有無變化
{
if(PID1.NowValue<ID1.Pre1Value) PID1.Flag=0; //降溫=目前溫度 <上次溫度記錄,
if(PID1.NowValue>PID1.Pre1Value) PID1.Flag=1; //升溫=目前溫度 >上次溫度記錄,
PID1.vError5=PID1.vError4; //上5次有變化 誤差溫度值
PID1.vError4=PID1.vError3; //上4次有變化 誤差溫度值
PID1.vError3=PID1.vError2; //上3次有變化 誤差溫度值
PID1.vError2=PID1.vError1; //上2次有變化 誤差溫度值 
PID1.vError1=PID1.vError0; //上1次有變化 誤差溫度值 
PID1.vError0=PID1.Error0; //目前有變化 誤差溫度值 
PID1.Pre2Value=PID1.Pre1Value;
PID1.Pre1Value=PID1.NowValue; //目前溫度記錄=上次溫度
}
//PID1.KdValue = PID1.Kd*(PID1.Error0 - PID1.Error1  ); //微分项  本次微分输出=微分系数×(本次误差值-上次误差值)dError = pp->LastError - pp->PrevError
PID1.KdValue = PID1.Kd*(3*((PID1.vError0-PID1.vError1))+(2*(PID1.vError1-PID1.vError2))+(PID1.vError2-PID1.vError3)+(PID1.vError3-PID1.vError4)+(PID1.vError4-PID1.vError5)); //微分項  本次微分输出=微分系数×(本次误差值-上次误差值)dError = pp->LastError - pp->PrevError
/*===PID1 誤差值儲存===*/
PID1.Error2 = PID1.Error1;//保存上2次誤差
PID1.Error1 = PID1.Error0;//保存上1次誤差
/*===PID1 輸出值 ===*/
PID1.ResultValue = PID1.KpValue + PID1.KiValue + PID1.KdValue; //Kp+Ki+Kd 運算結果暫存值
PID1.OutputValue=PID1.ResultValue; //PID 運算後 輸出值
if( PID1.OutputValue>100000) PID1.OutputValue=100000; //PWM 實際輸出最大值限幅
if (PID1.OutputValue<0) PID1.OutputValue=0; //PWM 實際輸出最最小值限幅
}


/*====================================================================================================/
 PID2 PWM2 TIM3 CH1 PC6  Temp. 1~6  Fan1,2
=====================================================================================================*///////////////////////////////////////////////////////////////////////////////
void PID2_Init(void)
{
PID2.TargetTemp =6100; //設定目標溫度值
PID2.Keep=100; //設定保持最低輸出值
PID2.Kp=100; // 比例常数Proportional Const
PID2.Ki=1; // 积分常数Integral Const
PID2.Kd=1; // 微分常数Derivative Const
PID2.Error0=0.0; //目前誤差值
PID2.Error1=0.0;   // Error[-1] 上次误差
PID2.Error2=0.0; // Error[-2]  上上次误差
PID2.SumError =0.0; //累積誤差總合值
PID2.OutputValue=0.0 ; //实际输出量
PID2.TargetValue =PID2.TargetTemp ; // 设定目标值Desired value Target
}


void PID2_Control(void) //Temp. 1~6  Fan1,2
{
PID2.NowValue=PID2.NowTemp; //控制現在溫度值
PID2.TargetValue=PID2.TargetTemp; //控制目標溫度值
PID2_Calculate(); // float PID_calculate( struct PID *pid_1,float NowValue );      //位置PID计算
if(PID2.NowTemp>PID2.TargetTemp+500) PID2.PWMResult=1000;                  //PWMResult
else if(PID2.NowTemp<PID2.TargetTemp-500) PID2.PWMResult=0;
else PID2.PWMResult=PID2.OutputValue/100; //0~100000
PID2.PWMOut=PID2.PWMResult+PID2.Keep;
TIM_SetCompare1(TIM3,PID2.PWMOut); // TIM3_CH1 PB6 PWM2 PWM2.OutValue Rate = 0~1000


/*====================================================================================================/
 PID2计算部分
=====================================================================================================*/
 
void PID2_Calculate(void)//位置PID计算
{
PID2.Error0 =PID2.NowValue-PID2.TargetValue; //目前誤差值     
PID2.KpValue = PID2.Kp*PID2.Error0 ;   //比例项   本次比例输出=比例系数×本次误差值  pError=Error-pp->LastError; 
PID2.SumError += PID2.Error0; //累積誤差總合值    
if(PID2.SumError>2000) PID2.SumError=2000;
if(PID2.SumError<-2000) PID2.SumError=-2000;
PID2.KiValue = PID2.Ki*PID2.SumError; //积分项  本次积分输出=积分系数×本次误差值+上次积分输出值 E(t)  //pp->SumError += Error
 
PID2.KdValue = PID2.Kd*(PID2.Error0 - PID2.Error1); //微分项  本次微分输出=微分系数×(本次误差值-上次误差值)dError = pp->LastError - pp->PrevError
PID2.Error2 = PID2.Error1;//保存二次谐波
PID2.Error1 = PID2.Error0;//保存一次谐波
PID2.ResultValue = PID2.KpValue + PID2.KiValue + PID2.KdValue;//输出值计算,注意加减
PID2.OutputValue=PID2.ResultValue;
if( PID2.OutputValue>100000) PID2.OutputValue=100000; //限幅
if (PID2.OutputValue<0) PID2.OutputValue=0;
}


//////////////////////////////////////////////////////////////////////////////////////

/*====================================================================================================/
 PID3 PWM3 TIM4 CH1 PB8  Temp. 13~17
=====================================================================================================*/

void PID3_Init(void)
{
PID3.TargetTemp =6100; //設定目標溫度值
PID3.Keep=100; //設定保持最低輸出值
PID3.Kp=100; // 比例常数Proportional Const
PID3.Ki=1; // 积分常数Integral Const
PID3.Kd=1; // 微分常数Derivative Const
PID3.Error0=0.0; //目前誤差值
PID3.Error1=0.0;   // Error[-1] 上次误差
PID3.Error2=0.0; // Error[-2]  上上次误差
PID3.SumError =0.0; //累積誤差總合值
PID3.OutputValue=0.0 ; //实际输出量
PID3.TargetValue =PID3.TargetTemp ; // 设定目标值Desired value Target
}


void PID3_Control(void)
{
PID3.NowValue=PID3.NowTemp; //控制現在溫度值
PID3.TargetValue=PID3.TargetTemp; //控制目標溫度值
PID3_Calculate();     // float PID_calculate( struct PID *pid_1,float NowValue );      //位置PID计算
if (PID3.NowTemp>PID3.TargetTemp +500) PID3.PWMResult=1000;                  //PWMResult
else if (PID3.NowTemp<PID3.TargetTemp -500) PID3.PWMResult=0;
else PID3.PWMResult=PID3.OutputValue/100;
PID3.PWMOut=PID3.PWMResult+PID3.Keep;
TIM_SetCompare2(TIM3,PID3.PWMOut); // TIM3_CH2 PC7 PWM3  PWM3.OutValue Rate = 0~1000


/*====================================================================================================/
 PID3计算部分
=====================================================================================================*/

void PID3_Calculate(void)//位置PID计算
{
PID3.Error0 = PID3.NowValue-PID3.TargetValue  ; //目前誤差值 
PID3.KpValue = PID3.Kp*PID3.Error0 ; //比例项   本次比例输出=比例系数×本次误差值  pError=Error-pp->LastError; 
PID3.SumError += PID3.Error0;    
if(PID3.SumError>2000) PID3.SumError=2000;
if(PID3.SumError<-2000) PID3.SumError=-2000;
PID3.KiValue = PID3.Ki*PID3.SumError; //积分项  本次积分输出=积分系数×本次误差值+上次积分输出值 E(t)  //pp->SumError += Error
PID3.KdValue = PID3.Kd*(PID3.Error0 - PID3.Error1); //微分项  本次微分输出=微分系数×(本次误差值-上次误差值)dError = pp->LastError - pp->PrevError
PID3.Error2 = PID3.Error1;//保存二次谐波
PID3.Error1 = PID3.Error0;//保存一次谐波
PID3.ResultValue = PID3.KpValue + PID3.KiValue + PID3.KdValue;//输出值计算,注意加减
PID3.OutputValue=PID3.ResultValue;
if( PID3.OutputValue>100000) PID3.OutputValue=100000; //限幅
if (PID3.OutputValue<0) PID3.OutputValue=0;
}


//////////////////////////////////////////////////////////////////////////////////////
void PID4_Init(void)
{
PID4.TargetTemp =4000; //設定目標溫度值
PID4.Keep=300; //設定保持最低輸出值
PID4.Kp=10; // 比例常数Proportional Const
PID4.Ki=0; // 积分常数Integral Const
PID4.Kd=0; // 微分常数Derivative Const
PID4.Error0=0.0; //目前誤差值
PID4.Error1=0.0;   // Error[-1] 上次误差
PID4.Error2=0.0; // Error[-2]  上上次误差
PID4.SumError =0.0; //累積誤差總合值
PID4.OutputValue=0.0 ; //实际输出量
PID4.TargetValue =PID4.TargetTemp ; // 设定目标值Desired value Target
}


void PID4_Control(void)
{
PID4.NowValue=PID4.NowTemp; //控制現在溫度值
PID4.TargetValue=PID4.TargetTemp; //控制目標溫度值
PID4_Calculate();     // float PID_calculate( struct PID *pid_4,float NowValue );      //位置PID计算
if (PID4.NowTemp>PID4.TargetTemp +500) PID4.PWMResult=1000;                  //PWMResult
else if (PID4.NowTemp<PID4.TargetTemp-500) PID4.PWMResult=0;
else PID4.PWMResult=PID4.OutputValue/100;
PID4.PWMOut=PID4.PWMResult+PID4.Keep;
TIM_SetCompare3(TIM3,PID4.PWMOut); // TIM3_CH3 PC8 PWM4.OutValue Rate = 0~1000
}


/*====================================================================================================/
 PID4计算部分
=====================================================================================================*/  

void PID4_Calculate(void)//位置PID计算
{
PID4.Error0 = PID4.NowValue-PID4.TargetValue ; //目前誤差值
PID4.KpValue = PID4.Kp*PID4.Error0 ;   //比例项   本次比例输出=比例系数×本次误差值  pError=Error-pp->LastError;  
PID4.SumError += PID4.Error0; //累積誤差總合值  
if(PID4.SumError>2000) PID4.SumError=2000;
if(PID4.SumError<-2000) PID4.SumError=-2000;
PID4.KiValue = PID4.Ki*PID4.SumError; //积分项  本次积分输出=积分系数×本次误差值+上次积分输出值 E(t)  //pp->SumError += Error

PID4.KdValue = PID4.Kd*(PID4.Error0 - PID4.Error1); //微分项  本次微分输出=微分系数×(本次误差值-上次误差值)dError = pp->LastError - pp->PrevError
PID4.Error2 = PID4.Error1;//保存二次谐波
PID4.Error1 = PID4.Error0;//保存一次谐波
PID4.ResultValue = PID4.KpValue + PID4.KiValue + PID4.KdValue;//输出值计算,注意加减
PID4.OutputValue=PID4.ResultValue;
if( PID4.OutputValue>100000) PID4.OutputValue=100000; //限幅
if (PID4.OutputValue<0) PID4.OutputValue=0;
}
























pid.c




pwm.c

11.01 KB, 下载次数: 169

pwm.h

753 Bytes, 下载次数: 166

pid.c

14.21 KB, 下载次数: 166

pid.h

2.05 KB, 下载次数: 175

戰艦 2.8 吋螢幕 如換成 3.5 吋螢幕 請教問題1: 戰鑑库函数版本3.5吋觸控螢幕無法設成橫式顯示
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-18 05:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表