搜索
bottom↓
回复: 46

开源 新鲜出炉,16路串口接收模块

[复制链接]

出0入0汤圆

发表于 2013-11-16 15:25:40 | 显示全部楼层 |阅读模式
在坛子里面潜水多,看到很多大侠都发过一些串口模块,很多初学者最初学习也是从串口开始,但是找了很多资料发现大部分的串口接收都是单路的,或者说多路是由单路组成的,也就是每一路都要耗资源,这样如果是对于小规模的器件如果需要多几路串口,对资源影响还是挺大的,
目前的思路是做一个16通道的串口,资源尽量少,并且可扩展

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2013-11-16 15:29:50 | 显示全部楼层
上面是基本的框图,通过时钟分配器产生16路的串口处理时钟,最后把这16路时钟合成一个时钟,

16路最后合成一个时钟,通过时钟来生成通道 0~ 15

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-11-16 15:34:01 | 显示全部楼层
通过时钟和通道对输入进来的数据进行采样,采样以后就变成了一个带通道的数据如下图
输入的多路串口数据
attach://152457.jpg
采样得到的数据

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-11-16 15:35:21 | 显示全部楼层
状态机对多路进行处理

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-11-16 15:42:34 | 显示全部楼层
最终通过时分的方法吧多路的串口数据进行了接收解析
状态机做了几个事情
首先接收到了一个下降沿,然后如果发现下降沿后的一个采样点是低电平,就认为是一个正确的头,如果不是一个为低电平,就认为是一个错误的头,重新搜索下降沿,当接收到一个正确的起始位之后,字节计数器和比特计数器分别计数,比特计数器用了记录采样点,字节计数器用了记录是哪个字节,如果是字节接收完成,需要判断是不是校验成功,停止位是否正确,如果正确则将这一路的串口上送,否则就丢弃,
在接收数据的时候采用了多数判决,当采样点前一个和后一个以及采样点本身中有2个一样就认为是一个正确的采样,用了增强可靠性

出0入0汤圆

 楼主| 发表于 2013-11-16 15:44:54 | 显示全部楼层
下面是代码,仅仅供学习使用,请勿商用
  1. ////////////////////////////////////////////////////////////////////////////////
  2. // Company:
  3. // Engineer:
  4. // Create Date:    2013/11/16
  5. // Design Name:   
  6. // Module Name:    uart_rx
  7. // Project Name:   
  8. // Target Device:  
  9. // Tool versions:  
  10. // Description:
  11. //
  12. // Dependencies:
  13. //
  14. // Revision:
  15. // Revision 0.01 - File Created
  16. // Additional Comments:
  17. //
  18. ////////////////////////////////////////////////////////////////////////////////
  19. `timescale 1ns / 1ps
  20. module uart_rx
  21. (
  22.         input                   clk     ,
  23.         input                   rst_n   ,
  24.     input       [15    :0]  uart_rx , //16个通道的串口数据,这个是可以扩展的
  25.     output  reg [16*8-1:0]  uart_dat, // 接收到的串口并行数据 n通道数据 [8*n+7:8*n];
  26.     output  reg [16  -1:0]  uart_en   // 接收到的串口并行数据使能n通道使能 [n]       
  27. );
  28. parameter DELAY =1 ;
  29. parameter IDLE      = 2'b01; // 状态机IDLE状态
  30. parameter REC       = 2'b10; // 状态机正在接收数据状态
  31. parameter S_POINT   = 4'd7 ; // 采样点
  32. parameter [63:0] BAUD_RATE = 115200;//波特率设置
  33. parameter [63:0] CLK_FRE   = (10**8);//时钟频率设置,单位赫兹
  34. parameter [63:0] CLK_DIV_RATE = ((2**16)*(16)*BAUD_RATE)/CLK_FRE; //小数分频系数
  35. reg [15:0]  uart_rx_ff1    ;
  36. reg [15:0]  uart_rx_ff2    ;
  37. reg         uart_rx_ff3    ;
  38. reg [16:0]  div_cnt        ;
  39. reg [15:0]  clk_en         ;
  40. reg [3 :0]  ch_cnt         ;      
  41. reg         clk_en_ff1     ;
  42. reg         clk_en_ff2     ;
  43. reg [3:0]   ch_cnt_ff1     ;
  44. reg [3:0]   ch_cnt_ff2     ;
  45. wire        rx_dat_next    ;
  46. wire        rx_dat_curr    ;
  47. wire        rx_dat_curr_ff1;
  48. wire        rx_dat_curr_ff2;
  49. reg  [1:0]  sta_next       ;
  50. reg  [3:0]  bit_cnt_next   ;
  51. reg  [3:0]  byte_cnt_next  ;
  52. wire [1:0]  sta_curr       ;
  53. wire [3:0]  bit_cnt_curr   ;
  54. wire [3:0]  byte_cnt_curr  ;
  55. reg  [8:0]  shift_next     ;
  56. wire [8:0]  shift_curr     ;
  57. reg         sample_dat     ;
  58. reg  [8:0]  rx_dat         ;
  59. wire        get_dat        ;
  60. wire        sample_point   ;
  61. wire        dat_sta        ;
  62. wire        stop_sta       ;
  63. wire        start_sta      ;
  64. ram_infer
  65. #(
  66.         .DATA_WIDTH(22      ),
  67.         .ADDR_WIDTH(4       )
  68. )
  69. u_ram_state
  70. (
  71.         .data      ({shift_next,sta_next,bit_cnt_next,byte_cnt_next,rx_dat_next,rx_dat_curr,rx_dat_curr_ff1}    ),
  72.         .raddr     (ch_cnt                                     ),
  73.     .waddr     (ch_cnt_ff2                                ),
  74.         .wren      (clk_en_ff2                                ),
  75.         .clk       (clk                                        ),
  76.         .q         ({shift_curr,sta_curr,bit_cnt_curr,byte_cnt_curr,rx_dat_curr,rx_dat_curr_ff1,rx_dat_curr_ff2})
  77. );
  78. assign rx_dat_next   = uart_rx_ff3;         
  79. assign start_sig    = ~rx_dat_curr&rx_dat_curr_ff1;  //下降沿确定起始
  80. assign sample_point = (bit_cnt_curr == S_POINT)?1'b1:1'b0; //采样点
  81. assign start_sta    = (byte_cnt_curr == 4'd0)?1'b1:1'b0;   //起始状态
  82. assign stop_sta     = (byte_cnt_curr == 4'd10)?1'b1:1'b0;  //结束状态
  83. assign dat_sta      = (byte_cnt_curr >= 4'd1 &&byte_cnt_curr <= 4'd9)?1'b1:1'b0;
  84. always @(*)
  85. begin
  86.         case(sta_curr)
  87.                  IDLE:
  88.                  begin
  89.                             bit_cnt_next    = 4'd0;
  90.                             byte_cnt_next   = 4'd0;
  91.                         if(start_sig == 1'b1)           
  92.                                 sta_next        = REC;      //接收到下降沿,跳转到接收状态
  93.                         else
  94.                                 sta_next        = IDLE;
  95.                     end
  96.                  REC:
  97.              begin
  98.                          if(sample_point == 1'b1)   //在采样点处看状态
  99.                      begin
  100.                                 if(start_sta == 1'b1)      //如果是起始状态
  101.                                 begin
  102.                                    if(sample_dat == 1'b0)  //看采样数据是否为0,为0认为为真,否则假
  103.                                    begin
  104.                                                 sta_next        = REC;
  105.                                                bit_cnt_next    = bit_cnt_curr + 4'd1;
  106.                                                byte_cnt_next   = byte_cnt_curr +4'd1;
  107.                                    end
  108.                                    else
  109.                                    begin
  110.                                                 sta_next        = IDLE;
  111.                                                bit_cnt_next    = 4'd0;
  112.                                                byte_cnt_next   = 4'd0;
  113.                                    end
  114.                                 end
  115.                                 else if(stop_sta == 1'b1)  //停止位进入IDLE
  116.                                 begin
  117.                                            sta_next        = IDLE;
  118.                                        bit_cnt_next    = bit_cnt_curr + 4'd1;
  119.                                        byte_cnt_next   = 4'd0;
  120.                                 end
  121.                             else
  122.                                 begin       
  123.                                            sta_next        = REC;
  124.                                        bit_cnt_next    = bit_cnt_curr + 4'd1;
  125.                                        byte_cnt_next   = byte_cnt_curr +4'd1;
  126.                                 end       
  127.                         end
  128.                     else
  129.                     begin
  130.                                 sta_next        = REC;
  131.                                 bit_cnt_next    = bit_cnt_curr + 4'd1;
  132.                                 byte_cnt_next   = byte_cnt_curr ;
  133.                         end        
  134.                  end
  135.                  default:
  136.                  begin
  137.                                            sta_next        = IDLE;
  138.                                        bit_cnt_next    = 4'd0;
  139.                                        byte_cnt_next   = 4'd0;
  140.                  end  
  141.         endcase
  142. end

  143. always @(*) //多数判决,当采样点的前一个点和后一个点以及采样点有两个相同则去这个值
  144. begin
  145.         if(rx_dat_curr == rx_dat_curr_ff1)  
  146.                 sample_dat = rx_dat_curr;
  147.     else if(rx_dat_curr == rx_dat_curr_ff2)
  148.                 sample_dat = rx_dat_curr;
  149.     else  
  150.                 sample_dat = rx_dat_curr_ff1;
  151. end

  152. always @(*)
  153. begin
  154.         if(sta_curr == REC &&sample_point == 1'b1 && dat_sta == 1'b1) //数据接收移位
  155.                 shift_next = {shift_curr[7:0],sample_dat}; //这里把校验位也移入
  156.     else
  157.                 shift_next = shift_curr;
  158. end
  159. assign get_dat = (sta_curr == REC &&sample_point ==1'b1 &&stop_sta == 1'b1)?1'b1:1'b0;
  160. always @(*)
  161. begin
  162.         if(get_dat == 1'b1)
  163.            rx_dat = {sample_dat&(~(^shift_curr)),shift_curr[8:1]}; //如果校验错误数据丢弃
  164.     else
  165.            rx_dat = 2'd0;
  166. end

  167. generate
  168. genvar i;
  169. for (i=0;i<16;i=i+1)
  170. begin:TX_DAT
  171. always @(posedge clk or negedge rst_n)
  172. begin
  173.         if(rst_n==1'b0)
  174.         begin
  175.                 uart_dat <= 'd0;
  176.                 uart_en  <= 'd0;
  177.     end
  178.     else if(clk_en_ff2 == 1'b1&&(ch_cnt_ff2 == i)&&get_dat == 1'b1)
  179.     begin
  180.                 uart_dat[8*i+:8] <= #DELAY rx_dat[7:0];
  181.                 uart_en [i]      <= #DELAY rx_dat[8];
  182.     end  
  183.         else
  184.         begin
  185.                 uart_dat[8*i+:8] <= #DELAY 8'd0;
  186.                 uart_en [i]      <= #DELAY 1'd0;
  187.         end
  188. end
  189. end
  190. endgenerate


  191. always @(posedge clk or negedge rst_n)
  192. begin
  193.         if(rst_n==1'b0)
  194.                 div_cnt <= #DELAY 17'd0;
  195.     else
  196.                 div_cnt <= #DELAY {1'b0,div_cnt[15:0]} + CLK_DIV_RATE[16:0];
  197. end                

  198. always@(posedge clk or negedge rst_n)
  199. begin
  200.         if(rst_n ==1'b0)
  201.                 clk_en <= 16'd0;
  202.     else
  203.                 clk_en <= #DELAY {clk_en[14:0],div_cnt[16]};
  204. end

  205. always @(posedge clk or negedge rst_n)
  206. begin
  207.         if(rst_n == 1'b0)
  208.                 ch_cnt <= 4'd0;
  209.     else if((|clk_en) == 1'b1)
  210.                 ch_cnt <= #DELAY ch_cnt + 4'd1;
  211.     else
  212.                 ch_cnt <= #DELAY 4'd0;
  213. end

  214. always @(posedge clk or negedge rst_n)
  215. begin
  216.         if(rst_n == 1'b0)
  217.         begin
  218.                 clk_en_ff1 <=  1'b0;
  219.                 clk_en_ff2 <=  1'b0;
  220.                 ch_cnt_ff1 <=  4'd0;
  221.                 ch_cnt_ff2 <=  4'd0;
  222.         end
  223.         else
  224.         begin
  225.                 clk_en_ff1 <= #DELAY |clk_en;  
  226.                 clk_en_ff2 <= #DELAY clk_en_ff1;  
  227.                 ch_cnt_ff1 <= #DELAY ch_cnt;  
  228.                 ch_cnt_ff2 <= #DELAY ch_cnt_ff1;  
  229.         end
  230. end
  231. always @(posedge clk or negedge rst_n)
  232. begin
  233.         if(rst_n == 1'b0)
  234.         begin
  235.                 uart_rx_ff1 <= 16'd0;
  236.                 uart_rx_ff2 <= 16'd0;
  237.         end
  238.         else
  239.         begin
  240.                 uart_rx_ff1 <= #DELAY uart_rx  ;
  241.                 uart_rx_ff2 <= #DELAY uart_rx_ff1  ;
  242.         end
  243. end
  244. always @(posedge clk or negedge rst_n)
  245. begin
  246.         if(rst_n == 1'b0)
  247.                 uart_rx_ff3 <= 1'b0  ;
  248.         else if(clk_en_ff1 == 1'b1)       
  249.                 uart_rx_ff3 <= #DELAY uart_rx_ff2[ch_cnt_ff1]  ;
  250.         else
  251.                 uart_rx_ff3 <= #DELAY 1'b0;       
  252. end
  253. endmodule
复制代码

出0入0汤圆

 楼主| 发表于 2013-11-16 15:46:46 | 显示全部楼层
  1. //copyright all rights reserved
  2. //Author      :Sun-Technology
  3. //Data        :2013-11-2
  4. //Description :altera ram
  5. `timescale 1ns/1ns

  6. module ram_infer
  7. (
  8.         data      ,
  9.         raddr     ,
  10.     waddr     ,
  11.         wren      ,
  12.         clk       ,
  13.         q
  14. );
  15. parameter DATA_WIDTH =  1;
  16. parameter ADDR_WIDTH = 13;
  17. parameter DEPTH      = 2**ADDR_WIDTH;
  18. parameter U_DLY      = 1 ;
  19. input    [DATA_WIDTH-1:0]  data     ;
  20. input    [ADDR_WIDTH-1:0]  raddr    ;
  21. input    [ADDR_WIDTH-1:0]  waddr    ;
  22. input                           wren     ;
  23. input                           clk      ;
  24. output   [DATA_WIDTH-1:0]  q        ;
  25. reg      [DATA_WIDTH-1:0]  q        ;
  26. reg      [DATA_WIDTH-1:0]  inter_reg;   
  27. reg      [DATA_WIDTH-1:0]  ram_mem[DEPTH-1:0];

  28. always@(posedge clk)
  29. begin
  30.         if(wren== 1'b1)
  31.                 ram_mem[waddr] <=#U_DLY data;
  32. end

  33. always @(posedge clk)
  34. begin
  35.         inter_reg <= #U_DLY ram_mem[raddr];
  36.     q         <= #U_DLY inter_reg     ;       
  37. end
  38. endmodule
复制代码

出0入0汤圆

 楼主| 发表于 2013-11-16 15:53:41 | 显示全部楼层
modelsim 工程

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-11-16 16:03:15 | 显示全部楼层
不明觉厉  

出0入0汤圆

 楼主| 发表于 2013-11-16 20:35:22 | 显示全部楼层
没什么人感兴趣吗,多串口系统爱在FPGA上面应该还是很常用吧,还有就是现在我手头没有板子,所以没有上板测试过,误码率等指标还没用,如果谁有板子,又刚好要用到串口或者多串口系统,可以使用我的这个模块,我可以提供友情支持

出0入0汤圆

发表于 2013-11-16 21:12:18 | 显示全部楼层
不明觉厉!

出0入0汤圆

发表于 2013-11-16 21:44:22 | 显示全部楼层
市面上有串口扩展芯片,那怎在选择方案时用fpga做好还是串口扩展芯片好呢?

出0入0汤圆

发表于 2013-11-16 22:04:27 | 显示全部楼层
很不错的思路,作为串口服务器或网关是很好的。
我想知道的是,PC如何跟这些串口通讯?如何管理呢?

出0入0汤圆

发表于 2013-11-16 22:10:24 | 显示全部楼层
在看代码,感觉不错,看不懂啊,再学习学习

出0入0汤圆

发表于 2013-11-16 22:11:06 | 显示全部楼层
强贴!留名。感谢楼主分享。

出0入0汤圆

发表于 2013-11-16 22:42:09 | 显示全部楼层

不明觉厉!

出0入0汤圆

发表于 2013-11-16 22:57:04 | 显示全部楼层
很好,支持一下

出0入0汤圆

发表于 2013-11-16 23:31:03 | 显示全部楼层
先MARK一下

出0入0汤圆

发表于 2013-11-16 23:47:37 来自手机 | 显示全部楼层
595输出,165输入,同一个模块处理逻辑,更优哦,我就这么搞过

出0入0汤圆

发表于 2013-11-16 23:51:22 | 显示全部楼层
FPGA灵活,IO速度那么高,串口速度那么低

出0入0汤圆

发表于 2013-11-18 05:56:42 | 显示全部楼层
MARK 先收藏起来

出0入0汤圆

发表于 2013-11-18 09:20:17 | 显示全部楼层
谁手头有板子啊,速来一个小白鼠

出0入0汤圆

发表于 2013-11-18 09:22:38 | 显示全部楼层
SPI才是王道

出0入0汤圆

 楼主| 发表于 2013-11-20 21:43:04 | 显示全部楼层
sunocean 发表于 2013-11-18 09:20
谁手头有板子啊,速来一个小白鼠

同求

出0入0汤圆

 楼主| 发表于 2013-11-20 21:45:15 | 显示全部楼层
lnskngdc 发表于 2013-11-16 22:04
很不错的思路,作为串口服务器或网关是很好的。
我想知道的是,PC如何跟这些串口通讯?如何管理呢? ...

不太懂,这个是一个fpga的多串口解决方案,只负责接收,其他的可能要定义其他的协议来支持

出0入0汤圆

发表于 2013-11-20 21:49:23 | 显示全部楼层
刚想弄个40路串口的模块,芯片打算用XC6SLX9,淘宝大概35元 ,QFP封装。就是不知道资源够不够?

出0入0汤圆

 楼主| 发表于 2013-11-20 21:49:41 | 显示全部楼层
本帖最后由 Fourier00 于 2013-11-20 22:02 编辑
jm2011 发表于 2013-11-16 22:10
在看代码,感觉不错,看不懂啊,再学习学习


这个是有点麻烦,尤其是看波形基本没法看,但是弄懂了这个模块,我相信您在fpga设计技巧上一定会有所收获,这种技巧说不定哪天就可以帮上您的忙

出0入0汤圆

 楼主| 发表于 2013-11-20 22:00:40 | 显示全部楼层
jiangchun9981 发表于 2013-11-20 21:49
刚想弄个40路串口的模块,芯片打算用XC6SLX9,淘宝大概35元 ,QFP封装。就是不知道资源够不够?
...

我不知道你的波特率需要支持多少,还有就是 主时钟频率是多少,还有就是是不是发送和接收都需要做? 我看了一下X9的资源,如果用我的这个方案,接收方向肯定是没有问题的,发送方向还需要重新做一个省资源的方案

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-11-20 22:03:55 | 显示全部楼层
我对此有一定的兴趣 ,也愿 意提供一定的支持。
你还在吗?

出0入0汤圆

发表于 2013-11-20 22:05:01 | 显示全部楼层
SPI才是王道   请问SPI的优势 在哪里?

出0入0汤圆

 楼主| 发表于 2013-11-20 22:16:30 来自手机 | 显示全部楼层
lineling 发表于 2013-11-20 22:03
我对此有一定的兴趣 ,也愿 意提供一定的支持。
你还在吗?

你好,我在,不过现在是手机上的

出0入0汤圆

发表于 2013-11-20 22:31:52 | 显示全部楼层
大概要做一个串口上行收发(接上位机),然后下行40个左右收发的(通过上面的那个串口和上位机通讯)。
请LZ估算下资源情况。

出0入0汤圆

发表于 2013-11-20 22:33:07 | 显示全部楼层
下行的40个口波特率115200左右,因为要接的芯片已经固定这个速率不能调整。
上行那个可以别的。

出0入0汤圆

发表于 2013-11-20 23:06:44 | 显示全部楼层
不明觉厉  下载慢慢研究下~~

出0入0汤圆

发表于 2013-11-21 00:15:18 | 显示全部楼层
不明觉厉

出0入0汤圆

发表于 2013-11-21 11:04:47 | 显示全部楼层
看的一头雾水,不过还是觉得楼主牛比。

出0入0汤圆

发表于 2013-11-21 11:25:31 | 显示全部楼层
不明觉厉   貌似很厉害的样子

出0入0汤圆

发表于 2013-11-21 15:13:39 | 显示全部楼层
先收藏   回头慢慢研究

出0入0汤圆

 楼主| 发表于 2013-11-22 07:54:01 来自手机 | 显示全部楼层
jiangchun9981 发表于 2013-11-20 22:33
下行的40个口波特率115200左右,因为要接的芯片已经固定这个速率不能调整。
上行那个可以别的。 ...

这个速率,如果主时钟是100兆,或者更高,是没有问题的,我算了一下资源带fifo一路收发最多就50个lut,那个器件上万的资源,还有32快可以做成64块的ram,做上100路都没什么问题

出0入0汤圆

 楼主| 发表于 2013-11-22 08:00:38 来自手机 | 显示全部楼层
lineling 发表于 2013-11-20 22:05
SPI才是王道   请问SPI的优势 在哪里?

应用场景不一样,没有什么可比性

出0入0汤圆

发表于 2013-12-14 00:53:15 | 显示全部楼层
感谢楼主分享

出0入0汤圆

发表于 2013-12-14 11:22:13 | 显示全部楼层
关注多串口,希望有实物验证!

出0入0汤圆

发表于 2013-12-14 14:24:51 | 显示全部楼层

很好,支持一下

出0入0汤圆

 楼主| 发表于 2014-6-1 11:21:33 | 显示全部楼层
这么好的东西 没有人用?

出0入0汤圆

发表于 2014-6-1 11:40:07 | 显示全部楼层
十六路是统一波特率还是单独可配置的啊

出0入0汤圆

 楼主| 发表于 2014-6-1 12:05:33 | 显示全部楼层
linjpxt 发表于 2014-6-1 11:40
十六路是统一波特率还是单独可配置的啊

统一的阿,分开的不太好做

出0入0汤圆

发表于 2014-6-6 20:39:56 | 显示全部楼层
SPI转16路串口已经实现,可以在xc6slx9上实现,每路都是独立的设置波特率,没路收发至少256字节缓冲,没路都有485流向控制,另外没路还附带一个IO输出,可用于控制232与485的选择
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 03:29

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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