ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

红牛stmf103原版例程红牛板_Touch(2.8和3.2寸)(2016.05.04)改硬spi

2022-09-14 01:00:47  阅读:181  来源: 互联网

标签:stmf103 temp Point 例程 SPI Pen InitStructure GPIO 红牛


原版的标准库触摸板用的是软件gpio模拟spi    但是读出来的值都是0无法使用。参考以前的官方bsp教程使用硬件spi读取触摸芯片的值。把用spi操作的部分改成硬spi

Touch.h

#ifndef __TOUCH_H
#define __TOUCH_H    

#include "stm32f10x.h"
#include "WB_LCD.h"
#include "stdlib.h"
#include "math.h"
#include "24c02.h"
#include "delay.h"

#define Key_Down   0x01  //触摸状态
#define Key_Up     0x00

#define READ_TIMES 15   //读取次数
#define LOST_VAL    5      //丢弃值
#define ERR_RANGE  10   //误差范围 

typedef struct 
{
    u16 X0;               //原始坐标
    u16 Y0;
    u16 X;                //最终/暂存坐标
    u16 Y;                                   
    u8  Key_Sta;          //笔的状态              
    
    float xfac;           //触摸屏校准参数
    float yfac;
    short xoff;
    short yoff;
}Pen_Holder;
extern Pen_Holder Pen_Point;


//触摸屏芯片连接引脚配置  
#define PEN           GPIOG->IDR&0x0080                                            //PG7   INT
#define DOUT         GPIOB->IDR&0x4000                                            //PB14  MISO

#define TDIN(x)   ((x) ? (GPIOB->BSRR = 0x00008000):(GPIOB->BSRR = 0x80000000)) //PB15  MOSI
#define TCLK(x)   ((x) ? (GPIOB->BSRR = 0x00002000):(GPIOB->BSRR = 0x20000000)) //PB13  SCLK
#define TCS(x)    ((x) ? (GPIOB->BSRR = 0x00001000):(GPIOB->BSRR = 0x10000000)) //PB12  CS 


//ADS7843/7846/UH7843/7846/XPT2046/TSC2046 指令集 
#define CMD_RDY 0x90  //0B10010000即用差分方式读X坐标
#define CMD_RDX    0xD0  //0B11010000即用差分方式读Y坐标  
  
void Touch_Init(void);
void Touch_Adjust(void);
void Convert_Pos(void);
void Pen_Int_Set(uint8_t en);
void Touch_Configuration(void);
uint8_t SPI_WriteByte(uint8_t data);
uint16_t ADS_Read_AD(uint8_t TOUCH_MSR_XY);
uint16_t ADS_Read_XY(uint8_t xy);
uint8_t Read_TP_Once(void);
uint8_t Read_ADS2(uint16_t *x,uint16_t *y);
uint8_t Read_ADS(uint16_t *x,uint16_t *y);
void Save_Adjdata(void);                                    //保存校准参数

void Drow_Touch_Point(uint8_t x,uint16_t y,uint16_t Color);
void Draw_Big_Point(uint8_t x,uint16_t y,uint16_t Color);   //打点
void Load_Drow_Dialog(void);
void Draw_Color_Box(void);
#endif

 

touch/c   修改了spi读写函数,spi初始化函数

/**
 * @file    Touch.c
 * @author  WB R&D Team - openmcu666
 * @version V1.0
 * @date    2016.05.05
 * @brief   Touch Driver
 */
#include "Touch.h"

Pen_Holder Pen_Point; //定义笔实体

/**
 * @brief  SPI写1byte数据
 * @param  写入的数据
 * @retval 接收到的字节
 */

 uint8_t SPI_WriteByte(uint8_t data)
{
     //Wait until the transmit buffer is empty
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
    // Send the byte
    SPI_I2S_SendData(SPI2, data);

    //Wait until a data is received
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
    // Get the received data
    data = SPI_I2S_ReceiveData(SPI2);

    // Return the shifted data
    return data;
}
/**
 * @brief  从7846/7843/XPT2046/UH7843/UH7846读取adc值
 * @param  命令
 * @retval 读取的数据
 */
uint16_t ADS_Read_AD(uint8_t TOUCH_MSR_XY)
{


    uint16_t usAdc;

    TCS(0); /* 使能TS2046的片选 */

    SPI_WriteByte(TOUCH_MSR_XY);
     usAdc =  (SPI_WriteByte(0x00) & 0x7F) << 5;
    usAdc |= (SPI_WriteByte(0x00) >> 3) & 0x1F;

    TCS(1); /* 禁能片选 */

    //printf("%d ", TOUCH_MSR_XY); //测试用
    //printf("%d ", usAdc);        //测试用

    return (usAdc);
}

/**
  * @brief  连续读取READ_TIMES次数据,对这些数据升序排列,
            然后去掉最低和最高LOST_VAL个数,取平均值
  * @param  读坐标命令
  * @retval 坐标值
  */
uint16_t ADS_Read_XY(uint8_t xy)
{
    uint16_t i, j;
    uint16_t buf[READ_TIMES];
    uint16_t sum = 0;
    uint16_t temp;
    for (i = 0; i < READ_TIMES; i++)
    {
        buf[i] = ADS_Read_AD(xy);
    }
    for (i = 0; i < READ_TIMES - 1; i++) //排序
    {
        for (j = i + 1; j < READ_TIMES; j++)
        {
            if (buf[i] > buf[j]) //升序排列
            {
                temp = buf[i];
                buf[i] = buf[j];
                buf[j] = temp;
            }
        }
    }
    sum = 0;
    for (i = LOST_VAL; i < READ_TIMES - LOST_VAL; i++)
        sum += buf[i];
    temp = sum / (READ_TIMES - 2 * LOST_VAL);
    return temp;
}

/**
 * @brief  带滤波的坐标读取  最小值不能少于200.
 * @param  xy首地址
 * @retval return 1读数成功
 */
uint8_t Read_ADS(uint16_t *x, uint16_t *y)
{
    uint16_t xtemp, ytemp;
    xtemp = ADS_Read_XY(CMD_RDX);
    ytemp = ADS_Read_XY(CMD_RDY);
    if (xtemp < 200 || ytemp < 200)
        return 0; //读数失败
    *x = xtemp;
    *y = ytemp;
    return 1; //读数成功
}

/**
  * @brief  2次读取ADS7846,连续读取2次有效的AD值,且这两次的偏差不能超过
            ERR_RANGE,满足条件,则认为读数正确,否则读数错误.
  * @param  xy首地址
  * @retval return 1读数成功
  */
uint8_t Read_ADS2(uint16_t *x, uint16_t *y)
{
    uint16_t x1, y1;
    uint16_t x2, y2;
    uint8_t flag;
    flag = Read_ADS(&x1, &y1);
    if (flag == 0)
        return (0);
    flag = Read_ADS(&x2, &y2);
    if (flag == 0)
        return (0);
    if (((x2 <= x1 && x1 < x2 + ERR_RANGE) || (x1 <= x2 && x2 < x1 + ERR_RANGE)) //前后两次采样在+-50内
        && ((y2 <= y1 && y1 < y2 + ERR_RANGE) || (y1 <= y2 && y2 < y1 + ERR_RANGE)))
    {
        *x = (x1 + x2) / 2;
        *y = (y1 + y2) / 2;
        return 1;
    }
    else
        return 0;
}

/**
 * @brief  读取一次坐标值,直到PEN松开才返回!
 * @param  None
 * @retval return 1读数成功
 */
uint8_t Read_TP_Once(void)
{
    uint8_t t = 0;
    Pen_Int_Set(0); //关闭中断
    Pen_Point.Key_Sta = Key_Up;
    Read_ADS2(&Pen_Point.X, &Pen_Point.Y);
    while (!(PEN & 0x80) && t <= 250)
    {
        t++;
        Delay(10);
    }
    Pen_Int_Set(1); //开启中断
    if (t >= 250)
        return 0; //按下2.5s 认为无效
    else
        return 1;
}

/**
 * @brief  画一个触摸点,用来校准用的
 * @param  x,y:TFT坐标
 * @retval None
 */
void Drow_Touch_Point(uint8_t x, uint16_t y, uint16_t Color)
{
    LCD_DrawLine(x - 12, y, x + 13, y, Color); //横线
    LCD_DrawLine(x, y - 12, x, y + 13, Color); //竖线
    LCD_DrawPoint(x + 1, y + 1, Color);
    LCD_DrawPoint(x - 1, y + 1, Color);
    LCD_DrawPoint(x + 1, y - 1, Color);
    LCD_DrawPoint(x - 1, y - 1, Color);
    LCD_DrawCircle(x, y, 6, Color); //画中心圈
}

/**
 * @brief  画一个2*2的点
 * @param  x,y:TFT坐标 Color 打点颜色
 * @retval None
 */
void Draw_Big_Point(uint8_t x, uint16_t y, uint16_t Color)
{
    LCD_DrawPoint(x, y, Color); //中心点
    LCD_DrawPoint(x + 1, y, Color);
    LCD_DrawPoint(x, y + 1, Color);
    LCD_DrawPoint(x + 1, y + 1, Color);
}

/**
 * @brief  根据触摸屏的校准参数来决定转换后的结果,保存在X0,Y0中
 * @param  None
 * @retval None
 */
void Convert_Pos(void)
{
    if (Read_ADS2(&Pen_Point.X, &Pen_Point.Y))
    {
        Pen_Point.X0 = Pen_Point.xfac * Pen_Point.X + Pen_Point.xoff;
        Pen_Point.Y0 = Pen_Point.yfac * Pen_Point.Y + Pen_Point.yoff;
    }
}

/**
 * @brief  获取校准值
 * @param  None
 * @retval return 1 读数成功
 */
u8 Get_Adjdata(void)
{
    s32 temp_data;
    u16 temp[8], i;
    temp_data = AT24CXX_Read(0x20, temp, 8);
    if (temp[0] == 0xff)
    {
        for (i = 0; i < 8; i++)
        {
            temp[i] = 0;
        }
        AT24CXX_Read(0x00, temp, 8);
        temp_data = (s32)((temp[3] << 24) | (temp[2] << 16) | (temp[1] << 8) | temp[0]);
        Pen_Point.xfac = (float)temp_data / 100000000;

        AT24CXX_Read(0x08, temp, 8);
        temp_data = (s32)((temp[3] << 24) | (temp[2] << 16) | (temp[1] << 8) | temp[0]);
        Pen_Point.yfac = (float)temp_data / 100000000;

        AT24CXX_Read(0x10, temp, 8);
        temp_data = (s32)((temp[1] << 8) | temp[0]);
        Pen_Point.xoff = temp_data;

        AT24CXX_Read(0x18, temp, 8);
        temp_data = (s32)((temp[1] << 8) | temp[0]);
        Pen_Point.yoff = temp_data;
        return 1;
    }

    return 0;
}

/**
 * @brief  得到四个校准参数
 * @param  None
 * @retval None
 */
void Touch_Adjust(void)
{
    uint16_t pos_temp[4][2]; //坐标缓存值
    uint8_t cnt = 0;
    uint16_t d1, d2;
    uint32_t tem1, tem2;
    float fac;
    cnt = 0;
    LCD_Clear(WHITE);              //清屏
    Drow_Touch_Point(20, 20, RED); //画点1
    Pen_Point.Key_Sta = Key_Up;    //消除触发信号
    Pen_Point.xfac = 0;            // xfac用来标记是否校准过,所以校准之前必须清掉!以免错误
    while (1)
    {
        if (Pen_Point.Key_Sta == Key_Down) //按键按下了
        {
            if (Read_TP_Once()) //得到单次按键值
            {
                pos_temp[cnt][0] = Pen_Point.X;
                pos_temp[cnt][1] = Pen_Point.Y;
                cnt++;
            }
            switch (cnt)
            {
            case 1:
                LCD_Clear(WHITE);               //清屏
                Drow_Touch_Point(220, 20, RED); //画点2
                break;
            case 2:
                LCD_Clear(WHITE);               //清屏
                Drow_Touch_Point(20, 300, RED); //画点3
                break;
            case 3:
                LCD_Clear(WHITE);                //清屏
                Drow_Touch_Point(220, 300, RED); //画点4
                break;
            case 4:                                          //全部四个点已经得到
                                                             //对边相等
                tem1 = abs(pos_temp[0][0] - pos_temp[1][0]); // x1-x2
                tem2 = abs(pos_temp[0][1] - pos_temp[1][1]); // y1-y2
                tem1 *= tem1;
                tem2 *= tem2;
                d1 = sqrt(tem1 + tem2); //得到1,2的距离

                tem1 = abs(pos_temp[2][0] - pos_temp[3][0]); // x3-x4
                tem2 = abs(pos_temp[2][1] - pos_temp[3][1]); // y3-y4
                tem1 *= tem1;
                tem2 *= tem2;
                d2 = sqrt(tem1 + tem2); //得到3,4的距离
                fac = (float)d1 / d2;
                if (fac < 0.95 || fac > 1.05 || d1 == 0 || d2 == 0) //不合格
                {
                    cnt = 0;
                    LCD_Clear(WHITE); //清屏
                    Drow_Touch_Point(20, 20, RED);
                    continue;
                }
                tem1 = abs(pos_temp[0][0] - pos_temp[2][0]); // x1-x3
                tem2 = abs(pos_temp[0][1] - pos_temp[2][1]); // y1-y3
                tem1 *= tem1;
                tem2 *= tem2;
                d1 = sqrt(tem1 + tem2); //得到1,3的距离

                tem1 = abs(pos_temp[1][0] - pos_temp[3][0]); // x2-x4
                tem2 = abs(pos_temp[1][1] - pos_temp[3][1]); // y2-y4
                tem1 *= tem1;
                tem2 *= tem2;
                d2 = sqrt(tem1 + tem2); //得到2,4的距离
                fac = (float)d1 / d2;
                if (fac < 0.95 || fac > 1.05) //不合格
                {
                    cnt = 0;
                    LCD_Clear(WHITE); //清屏
                    Drow_Touch_Point(20, 20, RED);
                    continue;
                } //正确了

                //对角线相等
                tem1 = abs(pos_temp[1][0] - pos_temp[2][0]); // x1-x3
                tem2 = abs(pos_temp[1][1] - pos_temp[2][1]); // y1-y3
                tem1 *= tem1;
                tem2 *= tem2;
                d1 = sqrt(tem1 + tem2); //得到1,4的距离

                tem1 = abs(pos_temp[0][0] - pos_temp[3][0]); // x2-x4
                tem2 = abs(pos_temp[0][1] - pos_temp[3][1]); // y2-y4
                tem1 *= tem1;
                tem2 *= tem2;
                d2 = sqrt(tem1 + tem2); //得到2,3的距离
                fac = (float)d1 / d2;
                if (fac < 0.95 || fac > 1.05) //不合格
                {
                    cnt = 0;
                    LCD_Clear(WHITE); //清屏
                    Drow_Touch_Point(20, 20, RED);
                    continue;
                }                                                                                //正确了
                                                                                                 //计算结果
                Pen_Point.xfac = (float)200 / (pos_temp[1][0] - pos_temp[0][0]);                 //得到xfac
                Pen_Point.xoff = (240 - Pen_Point.xfac * (pos_temp[1][0] + pos_temp[0][0])) / 2; //得到xoff

                Pen_Point.yfac = (float)280 / (pos_temp[2][1] - pos_temp[0][1]);                 //得到yfac
                Pen_Point.yoff = (320 - Pen_Point.yfac * (pos_temp[2][1] + pos_temp[0][1])) / 2; //得到yoff

                LCD_Clear(WHITE);                                                                //清屏
                LCD_DisplayStr(35, 110, (unsigned char *)"Touch Screen Adjust OK!", RED, WHITE); //显示校正完成
                Delay(1000);
                LCD_Clear(WHITE); //清屏
                return;           //校正完成
            }
        }
    }
}

/**
 * @brief  保存校准参数
 * @param  None
 * @retval None
 */
void Save_Adjdata(void)
{
    s32 temp_data;
    u16 temp[8];
    temp_data = Pen_Point.xfac * 100000000;   //保存x校正因素
    temp[0] = (u8)(temp_data & 0xff);         //保存x校正因素
    temp[1] = (u8)((temp_data >> 8) & 0xff);  //保存x校正因素
    temp[2] = (u8)((temp_data >> 16) & 0xff); //保存x校正因素
    temp[3] = (u8)((temp_data >> 24) & 0xff); //保存x校正因素
    AT24CXX_Write(0x00, temp, 8);

    temp_data = Pen_Point.yfac * 100000000;   //保存y校正因素
    temp[0] = (u8)(temp_data & 0xff);         //保存x校正因素
    temp[1] = (u8)((temp_data >> 8) & 0xff);  //保存x校正因素
    temp[2] = (u8)((temp_data >> 16) & 0xff); //保存x校正因素
    temp[3] = (u8)((temp_data >> 24) & 0xff); //保存x校正因素
    AT24CXX_Write(0x08, temp, 8);

    temp_data = Pen_Point.xoff;
    temp[0] = (u8)(temp_data & 0xff);
    temp[1] = (u8)((temp_data >> 8) & 0xff);
    AT24CXX_Write(0x10, temp, 8);

    temp_data = Pen_Point.yoff;
    temp[0] = (u8)(temp_data & 0xff);
    temp[1] = (u8)((temp_data >> 8) & 0xff);
    AT24CXX_Write(0x18, temp, 8);

    temp[0] = 0xff;
    AT24CXX_Write(0x20, temp, 8);
}

/**
 * @brief  SPI引脚配置(x模拟SPIx)    使能硬件SPI2, 片选由软件控制
 * @param  None
 * @retval None
 */
void Touch_Configuration() //把模拟spi改成硬件spi
{

      



    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef SPI_InitStructure;
     NVIC_InitTypeDef NVIC_InitStructure;

 

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOG | RCC_APB2Periph_AFIO, ENABLE); //重要!!

    //下面是SPI相关GPIO初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //通用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // Configure PB12 pin: TP_CS pin    PB12片选
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);


    // Configure PC5??? pin: TP_INT pin
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;     // TOUCH_INT   PG7触摸中断
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
    GPIO_Init(GPIOG, &GPIO_InitStructure);



    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组2

    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;        //配置中断线7
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        //次占优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* SPI1总线 配置 */
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //全双工
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;                       //主模式
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;                   // 8位
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;                          //时钟极性 空闲状态时,SCK保持低电平
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;                        //时钟相位 数据采样从第一个时钟边沿开始
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;                           //软件产生NSS
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; //波特率控制 SYSCLK/64
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;                  //数据高位在前
    SPI_InitStructure.SPI_CRCPolynomial = 7;                            // CRC多项式寄存器初始值为7
    SPI_Init(SPI2, &SPI_InitStructure);

    /* SPI2 使能 */
    SPI_Cmd(SPI2, ENABLE);
}

/**
 * @brief  触摸初始化
 * @param  None
 * @retval None
 */
void Touch_Init()
{
    EXTI_InitTypeDef EXTI_InitStructure;

    Touch_Configuration();
    Read_ADS(&Pen_Point.X, &Pen_Point.Y); //第一次读取初始化

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能IO复用功能,使用中断功能重要!!!
    /* Connect PEN EXTI Line to Key Button GPIO Pin */
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOG, GPIO_PinSource7);

    /* Configure PEN EXTI Line to generate an interrupt on falling edge */
    EXTI_InitStructure.EXTI_Line = EXTI_Line7;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /* Generate software interrupt: simulate a falling edge applied on PEN EXTI line */
    EXTI_GenerateSWInterrupt(EXTI_Line7);

    LCD_Clear(WHITE); //清屏
    if (Get_Adjdata())
    {
        return;
    }    //已经校准
    else //未校准
    {
        Touch_Adjust(); //屏幕校准
        Save_Adjdata(); //保存校准值
    }

    Get_Adjdata(); //获取校准值
}

/**
 * @brief  中断开关
 * @param  1开中断 0关中断
 * @retval None
 */
void Pen_Int_Set(uint8_t en)
{
    if (en)
        EXTI->IMR |= 1 << 7; //开启line7上的中断
    else
        EXTI->IMR &= ~(1 << 7); //关闭line7上的中断
}

/**
 * @brief  清除画图区域
 * @param  None
 * @retval None
 */
void Load_Drow_Dialog(void)
{
    LCD_Fill(50, 0, 240, 320, WHITE);
    LCD_DrawCircle(230, 10, 10, RED);
}

/**
 * @brief  显示画笔颜色选择框
 * @param  None
 * @retval None
 */
void Draw_Color_Box(void)
{
    LCD_Fill(20, 30, 50, 60, RED);
    LCD_Fill(20, 70, 50, 100, GREEN);
    LCD_Fill(20, 110, 50, 140, BLUE);
    LCD_Fill(20, 150, 50, 180, YELLOW);
    LCD_Fill(20, 190, 50, 220, MAGENTA);
    LCD_DrawCircle(230, 10, 10, RED);
}

 

标签:stmf103,temp,Point,例程,SPI,Pen,InitStructure,GPIO,红牛
来源: https://www.cnblogs.com/kyo413/p/16691565.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有