原创 McBSP用于查询方式的UART

2007-4-23 14:57 5478 11 11 分类: 处理器与DSP

以下部分内容来自spra633b "TMS320C6000 McBSP UART"颜色为兰色


 


<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /> 使用MCBSP的内部波特率进行同步,MCBSP可以被配置以16b字发送和接收每个UART位。软件必须将每个要发送的位扩展成16b,并将输入的16b数据压成单个 bit。同时要处理必要的同步数据,如起始位,停止位。


McBSP Setup: Serial Port Implementation<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


C6000将每个UART位当作16b数据。内部采样率发生器被配置为产生一个16倍于串口波特率的时钟。由于UART起始位是一个下降沿,因这个下降沿可心作为帧同步的输入,这就是为什么FSRDR都被连接到UART的输出。为了防止MCBSP被重复触发,在开始接收数据后需要忽略所有的帧同步信号。为了使用8N18数据位1停止位,无校验)方式发送UART数据,


MCBSP配置为UART输要设置几个参数。


Pin Control Register (PCR)        PCR = 0x00000B0C


Receive Control Registers (RCR) RCR = 0x81050840


Transmit Control Registers (XCR) XCR = 0x81040840


Sample Rate Generator Register (SRGR) SRGR = 0x2000006C


CLKGDV= (CPU Clock frequency) / (16 * baud rate) -1.


       MCBSP_SRGR_CLKGDV_OF(216) /* CLKGDV 57600  */


如果DSP时钟为200Mhz,当波特率为115200时,分频比为0x6C,实际波特率偏差为:0.4%。当分频比为216时,波特率为57600。没有办法使用更低频率的时钟,除非为MCBSP外接一个同步时钟。


Receiving/Transmitting UART Data


 


发送时,发送转换程序将需要被发送的数据按位转换16b。发送转换程序将扩展好的数据加上起始位0x0000及停止位0xFFFF放入发送缓冲器中。EDMA被设置为将数据从发送缓冲器传送到MCBSP,因为数据在发送缓冲区中已经是正确的UART格式,MCBSP帧同步产生器能连续地传送这些数据。void ProcessTransmitData(void);


 


 


接收时,EDMA将数据将被扩展的数据从MCBSP中读出,并写到接收缓冲区中,软件将禁止数据处理,直到EDMA完成一个段数据的传送。一个压缩程序被调用将数据还原成正确的数据。void ProcessReceiveData(void);


/* Open the McBSP channel 1 */


hMcbsp1 = MCBSP_open(MCBSP_DEV1, MCBSP_OPEN_RESET);


使用CLS库,如果使用上述函数将打开McBSP1


如果改为MCBSP_DEV0将打开McBSP0


 


 


C6x的多通道缓冲串行口(McBSP) 可以运行在不同的模式,由不同的应用要求,为了保证正确工作,串行口必须在特定的顺序进行初始化。


EDMACPU被用于处理McBSP数据,典型情况下,EDMA用于读/写数据从/McBSPEDMA传送是读/写同步的,McBSP提供这些同步状态。如可使用CPUDRR读数据,或向DXR写数据,查询或中断的方式都可以使用。


McBSP Introduction


发送器:发送器将写入DXR寄存器中的数据发送出去。DXR中的内容被拷贝XSR。当发送帧同步信号(FSX)被检测到时,传送立即开始。每一个CLKX时钟下,一个XSR中数据位将被传送。新的数据可以被写入DXR使用CPUDMA


接收器:在每个CLKR时钟下,DR引脚上的数据被移位至RSR寄存器。真正的数据移位开始于接收帧同步信号(FSR)RSR中的数据被拷贝至接收缓冲寄存器(RBR),然后到数据接收寄存器(DRR) DRR可以被CPUEDMA读取。


采样率产生器: As the name implies, 这个模块产生控制发送/接收的时钟信号以及必须的帧同步信号。时钟产生电路允许使用者通过CLKS选择CPU时钟或外部时钟作为源产生CLK(R/X)。帧同步信号的特性,如帧周期,帧宽也可编程。FS(R/X), CLK(R/X) 是双向引脚。


事件/中断产生: McBSP 产生为EDMA产生帧事件告知数据已经在DRR中准备好。或者DXR已经准备好接受新的数据。这些都是读同步事件REVT和写同步事件XEVT。同理CPU也可以通过中断(RINT and XINT)/写数据到McBSP


Servicing the McBSP


C6000可以通过CPUEDMA操作McBSP。所有控制寄存器只能通过CPU编程。但DXRDRR可以通过CPUEDMA访问。通常EDMA通过用于读写数据,这样可以减轻CPU处理低速外围的压力。TMS320C6000 DMA Applications(SPRA529) and TMS320C6000 Enhanced DMA: Example Applications (SPRA636).


EDMA方式:EDMA使用写同步事件XEVTDXR,使用读同步事件REVTDRR。在每个EDMA在每个串口单元传送时读或写McBSP,当EDMA完成需要的单元数目后,如果需要可以产生一个通道结束中断。


CPU方式: CPU可以用中断或查询方式操作McBSP,查询时,SPCR中的(R/X)RDY位被查询检查McBSP是否可以发送新的数据或有新的数据需要接收。在中断方式,CPU处理McBSP产生的中断。中断模式寄存器(R/X)INTM = 00b 缺省值产生McBSP中断。当CPU中断允许时McBSP在每个数据单元发送/接收时通过(R/X)INT产生中断。其它中断模式用于诊断和跟踪功能。


Initialization Requirements


McBSP中的控制信号如:时钟、帧同步、时钟源都是可以编程。模块被编程激活的顺序对正确操作McBSP是非常重要的。


查询方式UART的实现:


需要实现下列函数


void ConfigMcBSP(void);


short* ProcessTransmitData(char xmitchar);


char ProcessReceiveData(short*);


short VoteLogic(unsigned short);


void McBSP_UART_OutChar(char);


char McBSP_UART_InChar(void);


 


初始化过程:


      CSL_init(); /* initialize the CSL library */


       IRQ_nmiEnable();/* enable NMI and GI */


       IRQ_globalEnable();


       hMcbsp1 = MCBSP_open(MCBSP_DEV0, MCBSP_OPEN_RESET); /* Open the McBSP channel 0 */


       ConfigMcBSP();/* Setup for McBSP */


       MCBSP_enableSrgr(hMcbsp1); /* Start Sample Rate Generator: set /GRST = 1 */


       /* inserted wait time for McBSP to get ready */


       for (waittime=0; waittime<0xF; waittime++);


       /* Wake up the McBSP as transmitter and receiver */


       MCBSP_enableRcv(hMcbsp1);


       MCBSP_enableXmt(hMcbsp1);


       /* Enable Frame Sync Generator for McBSP 1: set /FRST = 1 */


       MCBSP_enableFsync(hMcbsp1);


 


发送时不使用帧同步,直接将数据加上起始位和停止位,并将这10b数据按扩充为1016b的数据。扩充方式为当数据位为1时扩充为0xFFFF 数据位为0时扩充为0x0000。检测xrdy的状态将数据写入MCBSP即可。


接收时需要使用输入数据的起始位作为帧同步信号,启动接收。接收过程中数据的下降沿被忽略。


附:查询方式代码


/*******************************************************************/
/* Sinovee Microsystems */
/* Date Created: 03/31/2007 */
/* Date Last Modified: 03/31/2007 */
/* Source File: uart.c */
/* Original Author: Todd Hiers */
/* Author: 罗昊 */
/* */
/* 被始化C6000 McBSP 与UART通信 */
/* communicate with a . By modifying the CHIP definition, */
/* On 6x0x devices, DMA channels 1 and 2 are used to service */
/* McBSP 1 transmit and receive operations, respectively. On */
/* 6x1x/64x devices, EDMA channels 14 and 15 are used to service */
/* McBSP 1 transmit and receive operations, respectively. */
/* */
/* For this example, a data string is being transmitted from McBSP */
/* transmit (DX) to McBSP receive (DR). Each bit of the 8.bit */
/* ASCII character is expanded into 16.bit UART transmission word. */
/* Once being received, the 16.bit UART transmission words are */
/* compressed back to binary bits and ASCII form. */
/* */
/* For the code to work, DX, DR, and FSR of McBSP1 are shorted */
/* together. */
/* */
/* This code has been verified for functionality on 6711, 6202, */
/* and 6203 devices. */
/* */
/* This program is based on CSL 2.0. Please refer to the */
/* TMS320C6000 Chip Support Library API User’s Guide for further */
/* information. */
/*******************************************************************/
/* Chip definition . Please change this accordingly */
#define CHIP_6205 1


/* Include files */
#include
#include
#include


#define TRUE 1
#define FALSE 0
#define BUFFER_SIZE 30
/* Declare CSL objects */
MCBSP_Handle hMcbsp1; /* handle for McBSP1 */


volatile int receive_done = FALSE;
volatile int transmit_done = TRUE;
short xmitbuf[10];
short recvbuf[30];


char xmit_msg[BUFFER_SIZE] = "McBSP does UART on C6000!\r\n";
char recv_msg[BUFFER_SIZE];
/* Include the vector table to call the IRQ ISRs hookup */
//extern far void vectors();
/* Prototypes */
void ConfigMcBSP(void);
short* ProcessTransmitData(char xmitchar);
char ProcessReceiveData(short*);
short VoteLogic(unsigned short);
void McBSP_UART_OutChar(char);
char McBSP_UART_InChar(void);
/*******************************************************************/
/* void main(void) */
/*******************************************************************/
void main(void)
{
 int i;
 int waittime = 0;
 char temp;
 /* initialize the CSL library */
 CSL_init();
 /* enable NMI and GI */
 IRQ_nmiEnable();
 IRQ_globalEnable();
 /* point to the IRQ vector table */
 //IRQ_setVecs(vectors);
 /* Open the McBSP channel 1 */
 hMcbsp1 = MCBSP_open(MCBSP_DEV0, MCBSP_OPEN_RESET);
 /* Setup for McBSP */
 ConfigMcBSP();
 /* Start Sample Rate Generator: set /GRST = 1 */
 MCBSP_enableSrgr(hMcbsp1);
 /* inserted wait time for McBSP to get ready */
 for (waittime=0; waittime<0xF; waittime++);
 /* Wake up the McBSP as transmitter and receiver */
 MCBSP_enableRcv(hMcbsp1);
 MCBSP_enableXmt(hMcbsp1);
 /* Enable Frame Sync Generator for McBSP 1: set /FRST = 1 */
 MCBSP_enableFsync(hMcbsp1);
 for(i = 0;i {
  McBSP_UART_OutChar(xmit_msg);  
 } /*end of i */
 for(i = 0;i<30;i++)
 {
  temp = McBSP_UART_InChar();
  recv_msg = temp;
 }/*end of i */
 printf("String recieved: %s \r\n", recv_msg);
 MCBSP_close(hMcbsp1); /* close McBSP 1 */
} /* End of main() */



/*******************************************************************/
/* void ConfigMcBSP(void): Setup for McBSP Configuration */
/*******************************************************************/
void ConfigMcBSP(void)
{
 MCBSP_Config mcbspCfg1 = {
 /* SPCR Setup */
 MCBSP_SPCR_RMK(
 MCBSP_SPCR_FRST_DEFAULT, /* 0 */
 MCBSP_SPCR_GRST_DEFAULT, /* 0 */
 MCBSP_SPCR_XINTM_XRDY, /* 00 */
 MCBSP_SPCR_XSYNCERR_DEFAULT, /* 0 */
 MCBSP_SPCR_XRST_DEFAULT, /* 0 */
 MCBSP_SPCR_DLB_OFF, /* 0 */
 MCBSP_SPCR_RJUST_RZF, /* 00 */
 MCBSP_SPCR_CLKSTP_DISABLE, /* 0x */
 MCBSP_SPCR_RINTM_RRDY, /* 00 */
 MCBSP_SPCR_RSYNCERR_DEFAULT, /* 0 */
 MCBSP_SPCR_RRST_DEFAULT /* 0 */
 ),


 /* RCR Setup */
#if 0 //orignal
 MCBSP_RCR_RMK(
 MCBSP_RCR_RPHASE_DUAL, /* 1 */
 MCBSP_RCR_RFRLEN2_OF(1), /* 00010 */
 MCBSP_RCR_RWDLEN2_8BIT, /* 000 */
 MCBSP_RCR_RCOMPAND_MSB, /* 00 */
 MCBSP_RCR_RFIG_YES, /* 1 */
 MCBSP_RCR_RDATDLY_1BIT, /* 01 */
 MCBSP_RCR_RFRLEN1_OF(8), /* 01000 */
 MCBSP_RCR_RWDLEN1_16BIT /* 010 */
 ),
#else
 MCBSP_RCR_RMK(
 MCBSP_RCR_RPHASE_DUAL, /* 1 */
 MCBSP_RCR_RFRLEN2_OF(1), /* 00010 */
 MCBSP_RCR_RWDLEN2_8BIT, /* 000 */
 MCBSP_RCR_RCOMPAND_MSB, /* 00 */
 MCBSP_RCR_RFIG_YES, /* 1 */
 MCBSP_RCR_RDATDLY_1BIT, /* 01 */
 MCBSP_RCR_RFRLEN1_OF(7), /* 01000 */
 MCBSP_RCR_RWDLEN1_16BIT /* 010 */
 ),
#endif


/* XCR Setup */


 MCBSP_XCR_RMK(
 MCBSP_XCR_XPHASE_DUAL, /* 1 */
 MCBSP_XCR_XFRLEN2_OF(1), /* 00010 */
 MCBSP_XCR_XWDLEN2_8BIT, /* 000 */
 MCBSP_XCR_XCOMPAND_MSB, /* 00 */
 MCBSP_XCR_XFIG_YES, /* 1 */
 MCBSP_XCR_XDATDLY_0BIT, /* 00 */
 MCBSP_XCR_XFRLEN1_OF(8), /* 01000 */
 MCBSP_XCR_XWDLEN1_16BIT /* 010 */
 ),


 /* SRGR Setup */
 MCBSP_SRGR_RMK(
 MCBSP_SRGR_GSYNC_FREE, /* 0 */
 MCBSP_SRGR_CLKSP_RISING, /* 0 */
 MCBSP_SRGR_CLKSM_INTERNAL, /* 1 */
 MCBSP_SRGR_FSGM_DXR2XSR, /* 0 */
 MCBSP_SRGR_FPER_DEFAULT, /* 0 */
 MCBSP_SRGR_FWID_DEFAULT, /* 0 */
// MCBSP_SRGR_CLKGDV_OF(108) /* CLKGDV for 115200 */
 MCBSP_SRGR_CLKGDV_OF(216) /* CLKGDV for 57600  */
 ),
 /* MCR Setup */
 MCBSP_MCR_DEFAULT, /* default values */
 /* RCER Setup */
 MCBSP_RCER_DEFAULT, /* default values */
/* XCER Setup */
 MCBSP_XCER_DEFAULT, /* default values */
/* PCR Setup */
 MCBSP_PCR_RMK(
 MCBSP_PCR_XIOEN_SP, /* 0 */
 MCBSP_PCR_RIOEN_SP, /* 0 */
 MCBSP_PCR_FSXM_INTERNAL, /* 1 */
 MCBSP_PCR_FSRM_EXTERNAL, /* 0 */
 MCBSP_PCR_CLKXM_OUTPUT, /* 1 */
 MCBSP_PCR_CLKRM_OUTPUT, /* 1 */
 MCBSP_PCR_CLKSSTAT_0, /* 0 */
 MCBSP_PCR_DXSTAT_0, /* 0 */
 MCBSP_PCR_FSXP_ACTIVELOW, /* 1 */
 MCBSP_PCR_FSRP_ACTIVELOW, /* 1 */
 MCBSP_PCR_CLKXP_RISING, /* 0 */
 MCBSP_PCR_CLKRP_FALLING /* 0 */
// MCBSP_PCR_CLKRP_RISING  /* 0 */
 )
 };
 MCBSP_config(hMcbsp1, &mcbspCfg1);
} /* end of Config_McBSP(void) */


/*******************************************************************/
/* void ProcessTransmitData(void) */
/* */
/* This function expands each of the 8.bit ASCII characters in the */
/* transmit string ”xmit_msg” into UART transmission 16.bit word */
/* and place them in the transmit buffer ”xmitbuf”. In addition, */
/* 16.bit Start and 8.bit Stop framing words, respectively, are */
/* inserted before and after each of the ASCII characters in the */
/* buffer. */
/*******************************************************************/
short *ProcessTransmitData(char xmitchar)
{
 int i;
 short cnt;
 short *xmitbufptr;
 /* point to Transmit Buffer */
 xmitbufptr = xmitbuf;
 for (i=0; i<(sizeof(xmitbuf)/sizeof(short)); i++)
 {
  xmitbufptr = 0x0000; /* zero fill buffer */
 }
  /* Process BYTE of transmit character */
  for (cnt = -1; cnt < 10; cnt++)
  {
  if (cnt == -1)
   *xmitbufptr++ = 0x0000;
  else if (cnt == 8 || cnt ==9)
   *xmitbufptr++ = 0xFFFF;
  else if (xmitchar & (1 << cnt))
   *xmitbufptr++ = 0xFFFF;
  else
   *xmitbufptr++ = 0x0000;
  } /* end for cnt */
 return xmitbuf;
} /* end ProcessTransmitData */


/*******************************************************************/
/* void ProcessReceiveData(void) */
/* */
/* This function decodes the data in the receive buffer, ”recvbuf” */
/* and strips the framing start (0x0000) and Stop (0xFFFF) words. */
/* It calls the subroutine VoteLogic() to determine each bit of */
/* the ASCII character. It then puts the result in recv_msg. */
/*******************************************************************/
char ProcessReceiveData(short *recvbuf)
{
 unsigned char recv_char = 0;
 short cnt = -1;
 short recv_val;
 unsigned short raw_data;
 unsigned short *recvbufptr; /*receive buffer pointer*/
 /* Point to the receive buffer */
 recvbufptr = (unsigned short *)recvbuf;
 recv_char = 0;
  /* Process each UART frame */
  for (cnt = -1; cnt < 10; cnt++)
  {
   if(cnt == -1 || cnt == 8 || cnt == 9)
   {
    /* Ignore Start and Stop bits */
    *recvbufptr++;
   }
   else
   {
    /* Get 16.bit data from receive buffer */
    raw_data = *recvbufptr;
    recvbufptr++;
    /* get the value of the majority of the bits
    */
    recv_val = VoteLogic(raw_data);
    /* put received bit into proper place */
    recv_char += recv_val << cnt;
   }
  } /* end for cnt */
 return recv_char;
} /* end ProcessReceiveData() function */



/*******************************************************************/
/* short VoteLogic(unsigned short) */
/* */
/* This function decoded the received character by testing the */
/* center 4 bits of the baud. A majority rule is used for the */
/* decoding. */
/*******************************************************************/
short VoteLogic(unsigned short value)
{
 short returnvalue;
 switch ((value >> 6) & 0x0F)
 {
  case 0:
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
  case 6:
  case 8:
  case 9:
  case 10:
  returnvalue = 0;
  break;
  case 7:
  case 11:
  case 12:
  case 13:
  case 14:
  case 15:
  returnvalue = 1 ;
  break;
 } /* end switch */
 return (returnvalue);
} /* end VoteLogic() funciton */


void McBSP_UART_OutChar(char xmitchar)
{
 int cnt;
 short *xmitbufptr;
 xmitbufptr = ProcessTransmitData(xmitchar);
 for(cnt = 0;cnt < 10;cnt++)
 {
  while(!(MCBSP_xrdy(hMcbsp1))); //wait for transmitter ready
  MCBSP_write(hMcbsp1,xmitbufptr[cnt]);
 }/* end cnt */ 
}/* end McBSP_UART_OutChar() funciton */
 
char McBSP_UART_InChar(void)
{
 char charget;
 int cnt;
 short *recvbufptr;
 recvbufptr = recvbuf;
 for(cnt = 0;cnt < 10;cnt++)
 {
  while(!(MCBSP_rrdy(hMcbsp1))); //wait for reciev ready
  recvbufptr[cnt] = MCBSP_read(hMcbsp1);
 }/* end cnt */
 charget = ProcessReceiveData(recvbufptr); 
 return charget;
}


 

文章评论5条评论)

登录后参与讨论

用户377235 2012-5-8 12:59

很好啊,学习了

用户1381176 2009-9-29 16:04

地弹:当电路中有大的电流涌起时,在真正的地平面上(0V)会有电压的波动和变化!

用户191304 2009-6-2 10:43

不错,谢谢

southcreek 2007-5-30 21:06

确实是UART模式,GPIO模式我也试过,也是可以用的。

southcreek 2007-5-30 21:04

我想 6000系列的MCBSP硬件应该都是一样的吧。如果确实是一样,那么还是可以用上述公式计算出225M主频下,波特率为115200,所需要的分频比为CLKDV = 121。

用户389537 2007-5-29 08:57

请问southcreek,我还有一事不明。你这边说

CLKGDV= (CPU Clock frequency) / (16 * baud rate) -1.

       MCBSP_SRGR_CLKGDV_OF(216) /* CLKGDV 57600  */

而我有在其它资料上看到

CLKGDV=(McBSP的时钟频率)/(16倍的波特率)-1。

时钟频率必须进行适当的配置,以便产生 16倍波特率的频率。对于 6711,CPU的时钟频率为150MHZ,McBSP的时钟频率为75MHZ,波特率为115200bps,此时通过上式计算得CLKGDV=41.

请问如果是6713的话该如何算呢?6713的主频是225MHZ。

QQ:357448476

或者这边回答也可,谢谢!

用户389537 2007-5-29 08:44

你好:

请问一下,你这测试代码对应的硬件电路是UART模式还是GPIO模式呢?我想是UART的吧?

QQ:3574489476

邮箱:huaeast@163.com


   This diagram shows that DX, DR, FSX, and FSR
   of McBSP1 are all connected together.

                ___________________
                |2                                 1|
                |                                     |
                |                                     |
                |                                     |
                |                                     |
                |                                     |
                |CLK0                  FSX0|
                |DX0                             |
                |DR0                    FSR0|
                |                                     |
        +----|DX1 36          35 FSX1|     
           |    |                                     |     
        +----|DR1 42          41 FSR1|----+
           |    |                                     |    |
           |    |                                     |    |
           |    |                                     |    |
           |    |                                     |    |
           |    |                                     |    |
           |    |                                     |    |
           |    |                                     |    |
           |    |____________ ______|    |
           |                                              |
           +---------------------------------+

southcreek 2007-5-28 16:47

我做完了原理图,样例程序,烧写程序。

调通了串口。现在交给做软件的了。

wang1jin 2006-11-10 00:59

这个要顶下.HE HE...

用户1318081 2006-10-12 08:29

不好意思啊

 

相关推荐阅读
southcreek 2024-07-08 11:38
接地不良导致的故障分析
这个电路的控制板需要连接显示板和识别板。5V 供电和串行控制连到显示板,显示板再连接到识别板。识别板上电位器使用一个LDO供电,将输入的5V转成3.3V。当电位器滑动时,输出电压在0~3.3V之间。...
southcreek 2024-06-26 09:15
【EMC整改】带辅助加热的滴速控制器辐射抗扰整改
这个滴速式的输液泵使用一个红外线发射和接收装置,当有液滴通过时,会扰动检测信号,识别这个扰动检测到液滴滴下,获得滴壶中的液滴速度,调整阀门大小,实现输液速度控制。控制器还配备一根加热条,用于输液时对药...
southcreek 2024-06-06 08:52
QT 使用QSettings 操作ini文件配合表格操作
这个项目可以演示 使用QSetting 读取或写入 ini文件。并使用tablewidget 显示。Ini文件的格式如下,这个文件可以事先编写。也可以在程序中生成。有一个大类,下面有一个小类使用等号设...
southcreek 2024-05-27 16:18
差分输入ADC的单端到差分转换器驱动设计
单端信号需要转换成差分信号,以便使用ADC进行转换。这个就所谓的ADC驱动电路。需要的结果为Vp = Vcm + Vi/2Vn = Vcm – Vi/2这样 Vp – Vn = Vi使用简单的加法器和...
southcreek 2024-05-10 15:12
QT 使用 customplot实现绘图
从customPlot 官网下载需要的源文件。将qcustomplot类中的源文件加入到工程里。在工程文件中增加greaterThan(QT_MAJOR_VERSION, 4): QT += widg...
southcreek 2024-04-19 12:15
步进电机运动控制
这个项目使用步进电机高速启停并换向。需要在尽可能短时间完成相应的圈数。常用的线性加速启停的时候有很大的噪声。需要做一点运动控制。达到加速度变化连续的效果。7段加减速控制策略分t1~t7 7个阶段,A...
我要评论
5
11
关闭 站长推荐上一条 /2 下一条