OpenEdv-开源电子网

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

请教:如何使用一个定时器实现多路频率可调PWM(占空比不要求可调)?

[复制链接]

33

主题

215

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2036
金钱
2036
注册时间
2017-12-11
在线时间
454 小时
发表于 2018-10-30 21:39:04 | 显示全部楼层 |阅读模式
1金钱
本帖最后由 bootblack 于 2018-10-31 13:46 编辑

如题,由于硬件上仅剩余一个硬件定时器(通用定时器),需要实现如下功能:
1、实现5路PWM
2、每路PWM频率都可调整(各路PWM频率都是独立的)
3、占空比没有要求,一般保持50%左右即可
4、每路频率都低于10KHz
5、要求频率误差小于等于1Hz

额,想请教下各路大神,有没有很好的思路,敬请指教!感谢!



最佳答案

查看完整内容[请看2#楼]

说干就干,用原子的MINI的TIM1的4个通道配置输出4路不同频率的方波,频率可调,提供源码附件 #include "led.h" #include "delay.h" #include "sys.h" #include "timer.h" //下次增量值 uint16_t TIM1_OC1_PulseAdd = 3600; //72M/10K/2=3600 uint16_t TIM1_OC2_PulseAdd = 3600; //72M/10K/2=3600 uint16_t TIM1_OC3_PulseAdd = 3600; //72M/10K/2=3600 uint16_t TIM1_OC4_PulseAdd = 3600; ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

32

主题

883

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4036
金钱
4036
注册时间
2015-11-14
在线时间
545 小时
发表于 2018-10-30 21:39:05 | 显示全部楼层
本帖最后由 Electronic 于 2018-11-8 17:37 编辑

说干就干,用原子的MINI的TIM1的4个通道配置输出4路不同频率的方波,频率可调,提供源码附件
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "timer.h"


//下次增量值
uint16_t TIM1_OC1_PulseAdd = 3600;        //72M/10K/2=3600
uint16_t TIM1_OC2_PulseAdd = 3600;        //72M/10K/2=3600
uint16_t TIM1_OC3_PulseAdd = 3600;        //72M/10K/2=3600
uint16_t TIM1_OC4_PulseAdd = 3600;        //72M/10K/2=3600
//比较捕获值
uint16_t TIM1_OC1_PulseVal = 0;
uint16_t TIM1_OC2_PulseVal = 0;
uint16_t TIM1_OC3_PulseVal = 0;
uint16_t TIM1_OC4_PulseVal = 0;


void TIM1_Init(void)
{
        GPIO_InitTypeDef GPIO_InitStruct;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        TIM_OCInitTypeDef TIM_OCInitStruct;
        NVIC_InitTypeDef NVIC_InitStructure;
        
        //使能时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        
        //PA8 PA9 PA10 PA11复用推挽输出
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;
        GPIO_Init(GPIOA, &GPIO_InitStruct);
        
        //配置定时器1
        TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
        TIM_TimeBaseStructure.TIM_Prescaler = 0;                //分频越小、精度越高、范围越小; 分频越大、精度越低、范围越大
        TIM_TimeBaseStructure.TIM_ClockDivision = 0;
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
        
        //清除比较捕获中断标志
        TIM_ClearFlag(TIM1, TIM_FLAG_CC1);
        TIM_ClearFlag(TIM1, TIM_FLAG_CC2);
        TIM_ClearFlag(TIM1, TIM_FLAG_CC3);
        TIM_ClearFlag(TIM1, TIM_FLAG_CC4);
        
        //配置比较捕获中断
        TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);
        TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);
        TIM_ITConfig(TIM1, TIM_IT_CC3, ENABLE);
        TIM_ITConfig(TIM1, TIM_IT_CC4, ENABLE);
        
        //比较捕获初值(必须设置,不然波形不对齐)
        TIM1_OC1_PulseVal = TIM1_OC1_PulseAdd;
        TIM1_OC2_PulseVal = TIM1_OC2_PulseAdd;
        TIM1_OC3_PulseVal = TIM1_OC3_PulseAdd;
        TIM1_OC4_PulseVal = TIM1_OC4_PulseAdd;
        
        //清除比较模式
        TIM1->CCMR1 &= ~((7<<4) | (7<<12));
        TIM1->CCMR2 &= ~((7<<4) | (7<<12));
        //强制为无效电平(不设置,边沿不能对其)
        TIM1->CCMR1 |= ((4<<4) | (4<<12));
        TIM1->CCMR2 |= ((4<<4) | (4<<12));
        
        //翻转模式
        TIM_OCStructInit(&TIM_OCInitStruct);
        TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;
        TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_Toggle;                //翻转
        TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;        //有效电平
        TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
        //比较捕获通道1
        TIM_OCInitStruct.TIM_Pulse = TIM1_OC1_PulseVal;
        TIM_OC1Init(TIM1, &TIM_OCInitStruct);
        //比较捕获通道2
        TIM_OCInitStruct.TIM_Pulse = TIM1_OC2_PulseVal;
        TIM_OC2Init(TIM1, &TIM_OCInitStruct);
        //比较捕获通道3
        TIM_OCInitStruct.TIM_Pulse = TIM1_OC3_PulseVal;
        TIM_OC3Init(TIM1, &TIM_OCInitStruct);
        //比较捕获通道4
        TIM_OCInitStruct.TIM_Pulse = TIM1_OC4_PulseVal;
        TIM_OC4Init(TIM1, &TIM_OCInitStruct);
        
        //使能中断线
        NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
        
        //主输出使能(高级定时器)
        TIM_CtrlPWMOutputs(TIM1, ENABLE);
        //使能定时器
        TIM_Cmd(TIM1, ENABLE);
}


int main(void)
{
        delay_init();                                                                        //延时函数初始化
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //设置中断优先级分组2
        LED_Init();                                                                                  //初始化与LED连接的硬件接口
        TIM1_Init();                                                                        //PA8被配置为复用功能
        
        //重新配置频率
        TIM1_OC1_PulseAdd = 2400;        //72M/15K/2=2400
        TIM1_OC2_PulseAdd = 3600;        //72M/10K/2=3600
        TIM1_OC3_PulseAdd = 7200;        //72M/ 5K/2=7200
        TIM1_OC4_PulseAdd = 36000;        //72M/ 1K/2=36000
           while(1)
        {
                LED1 = !LED1;
                delay_ms(300);
        }
}

//定时器1比较捕获中断
void TIM1_CC_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET)        //比较捕获通道1
        {
                TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
                TIM1_OC1_PulseVal += TIM1_OC1_PulseAdd;                //计算下次的比较捕获值
                TIM_SetCompare1(TIM1, TIM1_OC1_PulseVal);
        }
        
        if(TIM_GetITStatus(TIM1, TIM_IT_CC2) != RESET)        //比较捕获通道2
        {
                TIM_ClearITPendingBit(TIM1, TIM_IT_CC2);
                TIM1_OC2_PulseVal += TIM1_OC2_PulseAdd;                //计算下次的比较捕获值
                TIM_SetCompare2(TIM1, TIM1_OC2_PulseVal);
        }
        
        if(TIM_GetITStatus(TIM1, TIM_IT_CC3) != RESET)        //比较捕获通道3
        {
                TIM_ClearITPendingBit(TIM1, TIM_IT_CC3);
                TIM1_OC3_PulseVal += TIM1_OC3_PulseAdd;                //计算下次的比较捕获值
                TIM_SetCompare3(TIM1, TIM1_OC3_PulseVal);
        }
        
        if(TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET)        //比较捕获通道4
        {
                TIM_ClearITPendingBit(TIM1, TIM_IT_CC4);
                TIM1_OC4_PulseVal += TIM1_OC4_PulseAdd;                //计算下次的比较捕获值
                TIM_SetCompare4(TIM1, TIM1_OC4_PulseVal);
        }
}


不知道怎么上传代码,只能复制到上面

STM32 单定时器4路不同频率的方波-2018-11-08.rar (296.27 KB, 下载次数: 33)
回复

使用道具 举报

109

主题

5564

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10572
金钱
10572
注册时间
2017-2-18
在线时间
1914 小时
发表于 2018-10-30 22:42:51 | 显示全部楼层
帮顶!!
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
发表于 2018-10-31 08:46:58 | 显示全部楼层
帮顶!!!!!!!!!!!!!!!!!!!!
回复

使用道具 举报

6

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
164
金钱
164
注册时间
2017-3-6
在线时间
49 小时
发表于 2018-10-31 09:27:56 | 显示全部楼层
不嫌麻烦的话,初始化定时器,设置成一秒进入几十K次的中断,挨个设定翻转的时间。有点麻烦,但是可行。
回复

使用道具 举报

0

主题

49

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
317
金钱
317
注册时间
2018-3-21
在线时间
45 小时
发表于 2018-10-31 10:58:33 | 显示全部楼层
一个定时器硬件不能达到这些要求,软件模拟吧
回复

使用道具 举报

52

主题

334

帖子

0

精华

高级会员

Rank: 4

积分
560
金钱
560
注册时间
2016-4-12
在线时间
230 小时
发表于 2018-10-31 11:37:52 | 显示全部楼层
banxiafeixia 发表于 2018-10-31 09:27
不嫌麻烦的话,初始化定时器,设置成一秒进入几十K次的中断,挨个设定翻转的时间。有点麻烦,但是可行。

定时器翻转一路最快也就500K的频率,5路更低,要求不高的话确实可以。
回复

使用道具 举报

33

主题

215

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2036
金钱
2036
注册时间
2017-12-11
在线时间
454 小时
 楼主| 发表于 2018-10-31 13:44:25 | 显示全部楼层
banxiafeixia 发表于 2018-10-31 09:27
不嫌麻烦的话,初始化定时器,设置成一秒进入几十K次的中断,挨个设定翻转的时间。有点麻烦,但是可行。

感谢指教!

频率刷新不是特别快,小于10KHz以内,但是要求精度角度,最好相对误差低于1Hz。
回复

使用道具 举报

33

主题

215

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2036
金钱
2036
注册时间
2017-12-11
在线时间
454 小时
 楼主| 发表于 2018-10-31 13:44:47 | 显示全部楼层
wangmingwei093 发表于 2018-10-31 11:37
定时器翻转一路最快也就500K的频率,5路更低,要求不高的话确实可以。

感谢指教!

频率刷新不是特别快,小于10KHz以内,但是要求精度角度,最好相对误差低于1Hz。
回复

使用道具 举报

6

主题

44

帖子

0

精华

初级会员

Rank: 2

积分
154
金钱
154
注册时间
2018-8-23
在线时间
27 小时
发表于 2018-10-31 15:57:14 | 显示全部楼层
我知道的一个定时器只能同时出来4路吧可调吧,要想五路的话,你看看能不能用代码把一个IO口跟随一路pwm变化试试,而且这新的一路变化应该和上一路一样吧。 当然,这只是我的一个想法而已,可能有问题,你别介意哈。
回复

使用道具 举报

33

主题

215

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2036
金钱
2036
注册时间
2017-12-11
在线时间
454 小时
 楼主| 发表于 2018-10-31 17:31:56 | 显示全部楼层
十0二 发表于 2018-10-31 15:57
我知道的一个定时器只能同时出来4路吧可调吧,要想五路的话,你看看能不能用代码把一个IO口跟随一路pwm变化 ...

感谢回复!
请教下,如果产生4路可调PWM,能简单描述下思路吗?
回复

使用道具 举报

6

主题

44

帖子

0

精华

初级会员

Rank: 2

积分
154
金钱
154
注册时间
2018-8-23
在线时间
27 小时
发表于 2018-10-31 19:20:19 | 显示全部楼层
比如说用TIM3吧 这个时钟可以送给4个通道 然后你要找到这4个通道对应的io口具体步骤我也一下子说不完你看我的代码吧
#include "pwm.h"

// * 函数名:TIM3_PWM_Init()
// * 描述  :初始化
// * 输入  :无
// * 输出  :无
// * 调用  :内部调用数
void TIM3_PWM_Init(void)
{
        TIM3_GPIO_Config();
      TIM3_MODE_Config();       
}


// * 函数名:TIM3_GPIO_Config()
// * 描述  :配置TIM3输出的PWM信号的模式,如周期、极性、占空比初始化
// * 输入  :无
// * 输出  :无
// * 调用  :内部调用
static void  TIM3_GPIO_Config(void)
{

        GPIO_InitTypeDef GPIO_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);        //复用功能:使能定时器3;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);  

        //设置该引脚为复用输出功能,输出TIM3 CH1,CH2,CH3,CH4的PWM脉冲波形       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //TIM_CH3
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA
         
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
        GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB
}


// * 函数名:TIM3_MODE_Config()
// * 描述  :配置TIM3输出的PWM信号的模式,如周期、极性、
// * 输入  :无
// * 输出  :无
// * 调用  :内部调用数
static void TIM3_MODE_Config(void)
{
   //初始化TIM3
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
                       
        TIM_TimeBaseStructure.TIM_Period = 999; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
        TIM_TimeBaseStructure.TIM_Prescaler =0; //设置用来作为TIMx时钟频率除数的预分频值
        //TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
       

        //初始化TIM3 Channel234 PWM模式               
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
       
       
        TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC1
        TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR1上的预装载寄存器

        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2
        TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
       
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC3
        TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR3上的预装载寄存器

       
      TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
      TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC4
        TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR4上的预装载寄存器
       
        TIM_ARRPreloadConfig(TIM3, ENABLE); // 使能TIM3重载寄存器ARR
        TIM_Cmd(TIM3, ENABLE);  //使能TIM3
}


// * 函数名:TIM3_Set_pwm(u16 pwm1,u16 pwm2,u16 pwm3,u16 pwm4)
// * 描述  :设置TIM3的4个通道的pwm占空比
// * 输入  :u16 pwm1,u16 pwm2,u16 pwm3,u16 pwm4  
// * 输出  :无
// * 调用  :内部调用数
void TIM3_Set_pwm(u16 pwm1,u16 pwm2,u16 pwm3,u16 pwm4)
{
        TIM_SetCompare1(TIM3,pwm1);
        TIM_SetCompare2(TIM3,pwm2);
        TIM_SetCompare3(TIM3,pwm3);
        TIM_SetCompare4(TIM3,pwm4);
}


回复

使用道具 举报

33

主题

215

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2036
金钱
2036
注册时间
2017-12-11
在线时间
454 小时
 楼主| 发表于 2018-10-31 20:03:44 | 显示全部楼层
本帖最后由 bootblack 于 2018-10-31 20:05 编辑
十0二 发表于 2018-10-31 19:20
比如说用TIM3吧 这个时钟可以送给4个通道 然后你要找到这4个通道对应的io口具体步骤我也一下子说不完你看我 ...

额,非常感谢阁下
不过,我看你的程序,似乎这个改变的是各个通道的占空比,并不能独立改变各个通道的PWM的频率(其实我的程序是在msp430上跑的,但无奈msp430专题太冷清,所以你的程序我没有实际验证)。
不知道我的说法是否正确,还请指教!
回复

使用道具 举报

6

主题

44

帖子

0

精华

初级会员

Rank: 2

积分
154
金钱
154
注册时间
2018-8-23
在线时间
27 小时
发表于 2018-10-31 20:24:47 | 显示全部楼层
bootblack 发表于 2018-10-31 20:03
额,非常感谢阁下
不过,我看你的程序,似乎这个改变的是各个通道的占空比,并不能独立改变各个通道的PW ...

频率可以改的 你看一下相关的源码就知道了 花不了几分钟就能明白 或者你也可以去看相关的开发指南和技术手册 上面讲的很清楚 我的这个 在这里配置的就是周期和预分频值
TIM_TimeBaseStructure.TIM_Period = 999; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
        TIM_TimeBaseStructure.TIM_Prescaler =0; //设置用来作为TIMx时钟频率除数的预分
然后有了这两个就能确定频率了  假设我的时钟源是72mhz
那么频率=72000000/(999+1)=72KHZ
  而这个我一般都设为0       TIM_TimeBaseStructure.TIM_Prescaler =0;
但是我这是F1的代码 你如果用的是msp430那我就不清楚我说的这些可不可以帮到你了 因为我不了解你的板子。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-11-3 03:21:18 | 显示全部楼层
硬件只能4路。要输出5路,那就是在定时器中断里面,对IO取反了。。。
回复

使用道具 举报

32

主题

883

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4036
金钱
4036
注册时间
2015-11-14
在线时间
545 小时
发表于 2018-11-8 08:17:23 | 显示全部楼层
用输出比较模式,并开启中断,每次中断计算好下次的比较捕获值,翻转IO是硬件自动翻转,这样精度会比较高
回复

使用道具 举报

33

主题

215

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2036
金钱
2036
注册时间
2017-12-11
在线时间
454 小时
 楼主| 发表于 2018-11-8 17:15:18 | 显示全部楼层
感谢各位指教!
只是有人没有get到重点。
1、我要求每路通道频率单独可调,占空比不要求可调!
2、我目前已经实现,但是需要使用中断(最理想的方式是不用进入中断,这样根本就不占用CPU!)
再次感谢各位!
回复

使用道具 举报

32

主题

883

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4036
金钱
4036
注册时间
2015-11-14
在线时间
545 小时
发表于 2018-11-8 17:35:13 | 显示全部楼层
bootblack 发表于 2018-11-8 17:15
感谢各位指教!
只是有人没有get到重点。
1、我要求每路通道频率单独可调,占空比不要求可调!

我的代码就是频率可调啊,占空比固定是50%
回复

使用道具 举报

33

主题

215

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2036
金钱
2036
注册时间
2017-12-11
在线时间
454 小时
 楼主| 发表于 2018-11-8 22:00:26 | 显示全部楼层
Electronic 发表于 2018-11-8 17:35
我的代码就是频率可调啊,占空比固定是50%

有空我试试,最近需要有点忙。

感谢兄台,到时候过来汇报使用感受!

再次感谢兄台指教!
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-22 06:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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