IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 学习记录:FSMC—扩展外部SRAM -> 正文阅读

[嵌入式]学习记录:FSMC—扩展外部SRAM

目录

一、SRAM控制原理

????????1.1、型号为IS62WV51216的SRAM芯片外观:

? ? ? ? 1.2、SRAM芯片的内部功能框架:

? ? ? ? 1.2.1、SRAM的存储矩阵:

????????1.2.2、地址译码器、列I/O及I/O数据电路

? ? ? ? 1.2.3、控制电路?

? ? ? ? 1.3、SRAM的读写流程?

? ? ? ? 1.3.1、SRAM的读写时序参数?

?二、STM32的FSMC特性及架构

? ? ? ? 2.1、FSMC简介

? ? ? ? 2.2、FSMC框图剖析?

? ? ? ? 2.2.1、通讯引脚

? ? ? ? 2.2.2、存储器控制器?

? ? ? ? 2.2.3、时钟控制逻辑?

? ? ? ? 2.3、FSMC的地址映射?

? ? ? ? 2.4、FSMC控制SRAM的时序

三、FSMC控制SRAM的相关结构体

? ? ? ? 3.1、FSMC结构体?

? ? ? ? 3.1.1、FSMC时序结构体?

? ? ? ? 3.1.2、FSMC的SRAM初始化结构体?


本文主要介绍了SRAM的原理介绍,从0到1的跨进。介绍FSMC是什么,怎么用。

本文主要参考资料:《野火STM32视频教程》


一、SRAM控制原理

????????STM32控制器芯片内部有一定大小的SRAM及FLASH作为内存和程序存储空间,但当程序较大,内存和程序空间不足时,就需要在STM32 芯片的外部扩展存储器了。

????????STM32F103ZE系列芯片可以扩展外部SRAM用作内存。

????????1.1、型号为IS62WV51216的SRAM芯片外观:

? ? ? ? 1.2、SRAM芯片的内部功能框架:

SRAM信号线
信号线类型说明
A0-A18I地址输入
I/O0-I/O7I/O数据输入输出信号,低字节
I/O8-I/O15I/O数据输入输出信号,高字节
CS2和CS1#I片选信号,CS2高电平有效,CS1#低电平有效,部分芯片只有 其中一个引脚
OE#I输出使能信号,低电平有效
WE#I写入使能,低电平有效
UB#I数据掩码信号Upper Byte,高位字节允许访问,低电平有效
LB#I数据掩码信号Lower Byte,低位字节允许访问,低电平有效

????????SRAM的控制比较简单,只要控制信号线使能了访问,从地址线输入要访问的地址,即可从I/O数据线写入或读出数据。

? ? ? ? 1.2.1、SRAM的存储矩阵:

?????????SRAM内部包含的存储阵列,可以把它理解成一张表格,数据就填在这张表格上和表格查找一样,指定一个行地址和列地址,就可以精确地找到目标单元格。这是SRAM芯片寻址的基本原理。这样的每个单元格被称为存储单元,而这样的表则被称为存储矩阵。

????????1.2.2、地址译码器、列I/O及I/O数据电路

????????地址译码器把N根地址线转换成2^{N}根信号线,每根信号线对应一行或一列存储单元,通过地址线找到具体的存储单元,实现寻址。访问时,使用UB#或LB#线控制数据宽度。

? ? ? ? 1.2.3、控制电路?

????????控制电路主要包含了片选、读写使能以及上面提到的宽度控制信号UB#和LB#。利用CS2或CS1#片选信号,可以把多个SRAM芯片组成一个大容量的内存条。 OE#和WE#可以控制读写使能,防止误操作。

? ? ? ? 1.3、SRAM的读写流程?

????????对SRAM进行数据时,它各个信号线的时序流程如下:?

????????对SRAM进行数据时,它各个信号线的时序流程如下:

????????读写时序的流程很类似,过程如下:

(1) 主机使用地址信号线发出要访问的存储器目标地址;

(2) 控制片选信号CS1#及CS2#使能存储器芯片;

(3) 若是要进行读操作,则控制读使能信号OE#表示要读数据,若进行写操作则控制写使能信号WE#表示要写数据;

(4) 使用掩码信号LB#与UB#指示要访问目标地址的高、低字节部分;

(5) 若是读取过程,存储器会通过数据线向主机输出目标数据,若是写入过程,主要使用数据线向存储器传输目标数据。

? ? ? ? 1.3.1、SRAM的读写时序参数?

时间参数IS62WV51216BLL-55ns 型号要求的最短时间说明
t_{RC}55ns读操作周期
t_{AA}0ns地址访问时间
t_{WC}55ns写操作周期
t_{SA}0ns地址建立时间
t_{SD}25ns数据建立至写结束的时间
t_{HD}0ns数据写结束后的保持时间

?二、STM32的FSMC特性及架构

? ? ? ? 2.1、FSMC简介

????????STM32F1系列芯片使用FSMC外设来管理扩展的存储器,FSMC是Flexible Static Memory Controller的缩写,译为灵活的静态存储控制器。

????????它可以用于驱动包括SRAMNOR FLASH?以及NAND FLSAH类型的存储器,不能驱动如SDRAM这种动态的存储器,而在STM32F429系列的控制器中,它具有FMC外设,支持控制SDRAM存储器。?

? ? ? ? 2.2、FSMC框图剖析?

? ? ? ? 2.2.1、通讯引脚

????????由于控制不同类型存储器的时候会有一些不同的引脚,看起来有非常多,其中地址线FSMC_A和数据线FSMC_D是所有控制器都共用的。?

FSMC引脚名称对 应 SRAM 引 脚 名说明
FSMC_NBL[1:0]LB#、UB#数据掩码信号
FSMC_A[18:0]A[18:0]行地址线
FSMC_D[15:0]I/O[15:0]数据线
FSMC_NWEWE#写入使能
FSMC_NOEOE#输出使能(读使能)
FSMC_NE[1:4]CE#片选信号

?????????其中比较特殊的FSMC_NE是用于控制SRAM芯片的控制信号线, STM32具有FSMC_NE1/2/3/4号引脚,不同的引脚对应STM32内部不同的地址区域。

????????例如,当STM32访问0x68000000-0x6BFFFFFF地址空间时,FSMC_NE3引脚会自动设置为低电平,由于它连接到SRAM的CE#引脚,所以SRAM的片选被使能,而访问0x60000000-0x63FFFFFF地址时,FSMC_NE1会输出低电平。当使用不同的FSMC_NE引脚连接外部存储器时,STM32访问SRAM的地址不一样,从而达到控制多块SRAM芯片的目的。?

? ? ? ? 2.2.2、存储器控制器?

????????上面不同类型的引脚是连接到FSMC内部对应的存储控制器中的。 NOR/PSRAM/SRAM设备使用相同的控制器,NAND/PC卡设备使用相同的控制器,不同的控制器有专用的寄存器用于配置其工作模式。?

????????控制SRAM的有FSMC_BCR1/2/3/4控制寄存器、 FSMC_BTR1/2/3/4片选时序寄存器以及FSMC_BWTR1/2/3/4写时序寄存器。 每种寄存器都有4个,分别对应于4个不同的存储区域,各种寄存器介绍如下:?

????????? FSMC_BCR控制寄存器可配置要控制的存储器类型、数据线宽度以及信号有效极性能参数。

????????? FSMC_BTR时序寄存器用于配置SRAM访问时的各种时间延迟,如数据保持时间、地址保持时间等。

????????? FSMC_BWTR写时序寄存器与FMC_BTR寄存器控制的参数类似,它专门用于控制写时序的时间参数。

? ? ? ? 2.2.3、时钟控制逻辑?

????????FSMC外设挂载在AHB总线上,时钟信号来自于HCLK(默认72MHz),控制器的同步时钟输出就是由它分频得到。

????????例如,NOR控制器的FSMC_CLK 引脚输出的时钟,它可用于与同步类型的SRAM芯片进行同步通讯,它的时钟频率可通过FSMC_BTR寄存器的CLKDIV位配置,可以配置为HCLK的1/2 或1/3,也就是说若它与同步类型的SRAM通讯时,同步时钟最高频率为36MHz。本示例中的SRAM为异步类型的存储器,不使用同步时钟信号,所以时钟分频配置不起作用。?

? ? ? ? 2.3、FSMC的地址映射?

????????FSMC连接好外部的存储器并初始化后,就可以直接通过访问地址来读写数据。?

????????FSMC访问存储器的方式与I2C EEPROM、SPI FLASH的不一样, 后两种方式都需要控制I2C或SPI总线给存储器发送地址,然后获取数据;在程序里,这个地址和数据都需要分开使用不同的变量存储,并且访问时还需要使用代码控制发送读写命令。?

????????而使用FSMC外接存储器时,其存储单元是映射到STM32的内部寻址空间的;在程序里,定义一个指向这些地址的指针,然后就可以通过指针直接修改该存储单元的内容,FSMC外设会自动完成数据访问过程,读写命令之类的操作不需要程序控制。?

?????????图中左侧的是Cortex-M3内核的存储空间分配,右侧是STM32 FSMC外设的地址映射。可以看到FSMC的NOR/PSRAM/SRAM/NAND FLASH以及PC卡的地址都在External RAM地址空间内。

????????正是因为存在这样的地址映射,使得访问FSMC控制的存储器时,就跟访问STM32的片上外设寄存器一样(片上外设的地址映射即图中左侧的 “Peripheral”区域)。?

????????FSMC把整个External RAM存储区域分成了4个Bank区域,并分配了地址范围及适用的存储器类型,如NOR及SRAM存储器只能使用Bank1的地址。?

????????在NOR及SRAM区域,每个Bank的内部又分成了4个小块,每个小块有相应的控制引脚用于连接片选信号,如FSMC_NE[4:1]信号线可用于选择 BANK1内部的4小块地址区域,当STM32访问0x68000000-0x6BFFFFFF地址空间时,会访问到Bank1的第3小块区域,相应的FSMC_NE3信号线会输出控制信号。?

? ? ? ? 2.4、FSMC控制SRAM的时序

?????????FSMC外设支持输出多种不同的时序以便于控制不同的存储器,它具有ABCD四种模式,下面我们仅针对控制SRAM使用的模式A进行讲解。

读时序

?????????当内核发出访问某个指向外部存储器地址时,FSMC外设会根据配置控制信号线产生时序访问存储器,上图中的是访问外部SRAM时FSMC外设的读写时序。

????????以读时序为例,该图表示一个存储器操作周期由地址建立周期 (ADDSET)、数据建立周期(DATAST)以及2个HCLK周期组成。在地址建立周期中,地址线发出要访问的地址,数据掩码信号线指示出要读取地址的高、 低字节部分,片选信号使能存储器芯片;地址建立周期结束后读使能信号线发出读使能信号,接着存储器通过数据信号线把目标数据传输给FSMC, FSMC把它交给内核。?

写时序

????????写时序类似,区别是它的一个存储器操作周期仅由地址建立周期 (ADDSET)和数据建立周期(DATAST)组成,且在数据建立周期期间写使能信号线发出写信号,接着FSMC把数据通过数据线传输到存储器中。?

三、FSMC控制SRAM的相关结构体

? ? ? ? 3.1、FSMC结构体?

????????控制FSMC使用SRAM存储器时主要是配置时序寄存器以及控制寄存 器,利用ST标准库的SRAM时序结构体以及初始化结构体可以很方便地写入参数。?

?????????? 时序结构体:FSMC_NORSRAMTimingInitTypeDef

????????? 初始化结构体:FSMC_NORSRAMInitTypeDef

? ? ? ? 3.1.1、FSMC时序结构体?

????????FSMC的SRAM时序结构体成员定义的都是SRAM读写时序中的各项时间参数,这些成员的参数都与FSMC_BRT及FSMC_BWTR寄存器配置对应。?

typedef struct
{
  uint32_t FSMC_AddressSetupTime;       /*!< Defines the number of HCLK cycles to configure
                                             the duration of the address setup time. 
                                             This parameter can be a value between 0 and 0xF.
                                             @note: It is not used with synchronous NOR Flash memories. */

  uint32_t FSMC_AddressHoldTime;        /*!< Defines the number of HCLK cycles to configure
                                             the duration of the address hold time.
                                             This parameter can be a value between 0 and 0xF. 
                                             @note: It is not used with synchronous NOR Flash memories.*/

  uint32_t FSMC_DataSetupTime;          /*!< Defines the number of HCLK cycles to configure
                                             the duration of the data setup time.
                                             This parameter can be a value between 0 and 0xFF.
                                             @note: It is used for SRAMs, ROMs and asynchronous multiplexed NOR Flash memories. */

  uint32_t FSMC_BusTurnAroundDuration;  /*!< Defines the number of HCLK cycles to configure
                                             the duration of the bus turnaround.
                                             This parameter can be a value between 0 and 0xF.
                                             @note: It is only used for multiplexed NOR Flash memories. */

  uint32_t FSMC_CLKDivision;            /*!< Defines the period of CLK clock output signal, expressed in number of HCLK cycles.
                                             This parameter can be a value between 1 and 0xF.
                                             @note: This parameter is not used for asynchronous NOR Flash, SRAM or ROM accesses. */

  uint32_t FSMC_DataLatency;            /*!< Defines the number of memory clock cycles to issue
                                             to the memory before getting the first data.
                                             The value of this parameter depends on the memory type as shown below:
                                              - It must be set to 0 in case of a CRAM
                                              - It is don't care in asynchronous NOR, SRAM or ROM accesses
                                              - It may assume a value between 0 and 0xF in NOR Flash memories
                                                with synchronous burst mode enable */

  uint32_t FSMC_AccessMode;             /*!< Specifies the asynchronous access mode. 
                                             This parameter can be a value of @ref FSMC_Access_Mode */
}FSMC_NORSRAMTimingInitTypeDef;

?????????? FSMC_AddressSetupTime:本成员设置地址建立时间,它可以被设置为0-0xF个HCLK周期数,按 STM32标准库的默认配置,HCLK的时钟频率为72MHz,即一个HCLK周期为 1/72微秒。

????????? FSMC_AddressHoldTime:本成员设置地址保持时间,它可以被设置为0-0xF个HCLK周期数。?

????????? FSMC_DataSetupTime:本成员设置数据建立时间,它可以被设置为0-0xF个HCLK周期数。?

????????? FSMC_BusTurnAroundDuration:本成员设置总线转换周期,在NOR FLASH存储器中,地址线与数据线可以分时复用,总线转换周期就是指总线在这两种状态间切换需要的延时,防止冲突。控制其它存储器时这个参数无效,配置为0即可。?

????????? FSMC_CLKDivision:本成员用于设置时钟分频,它以HCLK时钟作为输入,经过FSMC_CLKDivision 分频后输出到FSMC_CLK引脚作为通讯使用的同步时钟。控制其它异步通讯的 存储器时这个参数无效,配置为0即可。?

????????? FSMC_DataLatency:本成员设置数据保持时间,它表示在读取第一个数据之前要等待的周期数,该周期指同步时钟的周期,本参数仅用于同步NOR FLASH类型的存储器,控制其它类型的存储器时,本参数无效。?

????????? FSMC_AccessMode:本成员设置存储器访问模式,不同的模式下FSMC访问存储器地址时引脚输出的时序不一样,可选FSMC_AccessMode_A/B/C/D模式。一般来说控制SRAM时使用A模式。?

? ? ? ? 3.1.2、FSMC的SRAM初始化结构体?

????????FSMC初始化结构体,除最后两个成员是上一小节讲解的时序配置外, 其它结构体成员的配置都对应到FSMC_BCR中的寄存器位。?

typedef struct
{
  uint32_t FSMC_Bank;                /*!< Specifies the NOR/SRAM memory bank that will be used.
                                          This parameter can be a value of @ref FSMC_NORSRAM_Bank */

  uint32_t FSMC_DataAddressMux;      /*!< Specifies whether the address and data values are
                                          multiplexed on the databus or not. 
                                          This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing */

  uint32_t FSMC_MemoryType;          /*!< Specifies the type of external memory attached to
                                          the corresponding memory bank.
                                          This parameter can be a value of @ref FSMC_Memory_Type */

  uint32_t FSMC_MemoryDataWidth;     /*!< Specifies the external memory device width.
                                          This parameter can be a value of @ref FSMC_Data_Width */

  uint32_t FSMC_BurstAccessMode;     /*!< Enables or disables the burst access mode for Flash memory,
                                          valid only with synchronous burst Flash memories.
                                          This parameter can be a value of @ref FSMC_Burst_Access_Mode */
                                       
  uint32_t FSMC_AsynchronousWait;     /*!< Enables or disables wait signal during asynchronous transfers,
                                          valid only with asynchronous Flash memories.
                                          This parameter can be a value of @ref FSMC_AsynchronousWait */

  uint32_t FSMC_WaitSignalPolarity;  /*!< Specifies the wait signal polarity, valid only when accessing
                                          the Flash memory in burst mode.
                                          This parameter can be a value of @ref FSMC_Wait_Signal_Polarity */

  uint32_t FSMC_WrapMode;            /*!< Enables or disables the Wrapped burst access mode for Flash
                                          memory, valid only when accessing Flash memories in burst mode.
                                          This parameter can be a value of @ref FSMC_Wrap_Mode */

  uint32_t FSMC_WaitSignalActive;    /*!< Specifies if the wait signal is asserted by the memory one
                                          clock cycle before the wait state or during the wait state,
                                          valid only when accessing memories in burst mode. 
                                          This parameter can be a value of @ref FSMC_Wait_Timing */

  uint32_t FSMC_WriteOperation;      /*!< Enables or disables the write operation in the selected bank by the FSMC. 
                                          This parameter can be a value of @ref FSMC_Write_Operation */

  uint32_t FSMC_WaitSignal;          /*!< Enables or disables the wait-state insertion via wait
                                          signal, valid for Flash memory access in burst mode. 
                                          This parameter can be a value of @ref FSMC_Wait_Signal */

  uint32_t FSMC_ExtendedMode;        /*!< Enables or disables the extended mode.
                                          This parameter can be a value of @ref FSMC_Extended_Mode */

  uint32_t FSMC_WriteBurst;          /*!< Enables or disables the write burst operation.
                                          This parameter can be a value of @ref FSMC_Write_Burst */ 

  FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct; /*!< Timing Parameters for write and read access if the  ExtendedMode is not used*/  

  FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct;     /*!< Timing Parameters for write access if the  ExtendedMode is used*/      
}FSMC_NORSRAMInitTypeDef;
映射范围
可以输入的宏对应的地址区域
FSMC_Bank1_NORSRAM10x60000000-0x63FFFFFF
FSMC_Bank1_NORSRAM20x64000000-0x67FFFFFF
FSMC_Bank1_NORSRAM30x68000000-0x6BFFFFFF
FSMC_Bank1_NORSRAM40x6C000000-0x6FFFFFFF

?????????? FSMC_Bank:本成员用于选择FSMC映射的存储区域,它的可选参数以及相应的内核地址映射范围见上面的表格。

????????? FSMC_DataAddressMux:本成员用于设置地址总线与数据总线是否复用 (FSMC_DataAddressMux_Enable /Disable),在控制NOR FLASH时,可以地址总线与数据总线可以分时复用,以减少使用STM32信号线的数量。?

????????? FSMC_MemoryType:本成员用于设置要控制的存储器类型,它支持控制的存储器类型为 SRAM、PSRAM以及NOR FLASH(FSMC_MemoryType_SRAM/PSRAM/NOR)。?

????????? FSMC_MemoryDataWidth:本成员用于设置要控制的存储器的数据宽度,可选择设置成8或16位 (FSMC_MemoryDataWidth_8b /16b)。?

????????? FSMC_BurstAccessMode:本成员用于设置是否使用突发访问模式 (FSMC_BurstAccessMode_Enable/Disable),突发访问模式是指发送一个地址后连续访问多个数据,非突发模式下每访问一个数据都需要输入一个地址,仅在控制同步类型的存储器时才能使用突发模式。?

????????? FSMC_AsynchronousWait:本成员用于设置是否使能在同步传输时使用的等待信号 (FSMC_AsynchronousWait_Enable/Disable),在控制同步类型的NOR或PSRAM时,存储器可以使用FSMC_NWAIT引脚通知STM32需要等待。?

????????? FSMC_WaitSignalPolarity:本成员用于设置等待信号的有效极性,即要求等待时,使用高电平还是 低电平(FSMC_WaitSignalPolarity_High/Low)。

????????? FSMC_WrapMode:本成员用于设置是否支持把非对齐的AHB突发操作分割成2次线性操作 (FSMC_WrapMode_Enable/Disable),该配置仅在突发模式下有效。?

????????? FSMC_WaitSignalActive:本成员用于配置在突发传输模式时,决定存储器是在等待状态之前的一个数据周期有效还是在等待状态期间有效 (FSMC_WaitSignalActive_BeforeWaitState/DuringWaitState)。?

????????? FSMC_WriteOperation:这个成员用于设置是否写使能(FSMC_WriteOperation_ Enable /Disable),禁止写使能的话FSMC只能从存储器中读取数据,不能写入。?

????????? FSMC_WaitSignal:本成员用于设置当存储器牌突发传输模式时,是否允许通过NWAIT信 号插入等待状态(FSMC_WaitSignal_Enable/Disable)。?

????????? FSMC_ExtendedMode:本成员用于设置是否使用扩展模式 (FSMC_ExtendedMode_Enable/Disable),在非扩展模式下,对存储器读写的时序都只使用FSMC_BCR寄存器中的配置,即下面的 FSMC_ReadWriteTimingStruct结构体成员;

????????在扩展模式下,对存储器的读写时 序可以分开配置,读时序使用FSMC_BCR寄存器,写时序使用FSMC_BWTR寄存器的配置,即下面的FSMC_WriteTimingStruct结构体。?

????????? FSMC_ReadWriteTimingStruct:本成员是一个指针,赋值时使用上一小节中讲解的时序结构体 FSMC_NORSRAMInitTypeDef设置,当不使用扩展模式时,读写时序都使用本 成员的参数配置。

????????? FSMC_WriteTimingStruct:同样地,本成员也是一个时序结构体的指针,只有当使用扩展模式时, 本配置才有效,它是写操作使用的时序。?

?????

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-07-20 19:03:54  更:2022-07-20 19:06:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 14:39:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码