网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> 技术文库 >> 嵌入式 >> 文章正文
  Mega8 SPI读写DataFlash的代码           ★★★ 【字体:
Mega8 SPI读写DataFlash的代码
作者:61IC录入    文章来源:本站原创    点击数:    更新时间:2006-4-7    
;***************************************************************************
;
; File Name        :'DFlash.asm"
; Title            :SPI interface to Serial DataFlash
; Date            :2003.06.01.
; Version        :1.0.0
; Support telephone    :+36-70-333-4034,  old: +36-30-9541-658 VFX
; Support fax        :
; Support Email        :info@vfx.hu
; Target MCU        :ATmega8
;
;***************************************************************************
;    D E S C R I P T I O N
;
; SPI interface to AT45DBxxx Serial DataFlash
;
; Functions to access the Atmel AT45Dxxx dataflash series
;  Supports 1Mbit - 128Mbit
;
;***************************************************************************
;    M O D I F I C A T I O N   H I S T O R Y
;
;
;       rev.      date      who      why
;    ----    ----------  ---        ------------------------------------
;    0.01    2003.06.01  VFX        Creation
;
;***************************************************************************
;Hardware
;***************************************************************************
;*
;*    SYSCLK: f=16.000 MHz (T= 62.5 ns)
;*
;***************************************************************************
;
; CS    - Chip Select
; SCK   - Serial Clock
; SI    - Serial Input
; SO    - Serial Output
; WP    - Hardware Page Write Protect Pin
; RESET - Chip Reset
; RDY/BUSY - Ready/Busy
;
; To provide optimal flexibility, the memory array of the AT45DB081B is
;divided into three levels of granularity comprising of sectors, blocks,
;and pages. All program operations to the DataFlash occur on a page-by-page
;basis; however, the optional erase operations can be performed at the block
;or page level.
;
;
;The device operation is controlled by instructions from the host processor.
;The list of instructions and their associated opcodes are contained in
;Tables 1 through 4. A valid instruction starts with the falling edge of CS
;followed by the appropriate 8-bit opcode and the desired buffer or main memory
;address location. While the CS pin is low, tog-gling the SCK pin controls the
;loading of the opcode and the desired buffer or main memory address location
;through the SI (serial input) pin. All instructions, addresses and data are
;transferred with the most significant bit (MSB) first.
;Buffer addressing is referenced in the datasheet using the terminology
;BFA8 - BFA0 to denote the nine address bits required to designate a byte address
;within a buffer. Main memory addressing is referenced using the terminology
;PA11 - PA0 and BA8 - BA0 where PA11 - PA0 denotes the 12 address bits required
;to designate a page address and BA8 - BA0 denotes the nine address bits
;required to designate a byte address within the page.
;
;
;Status Register Format
;Bit   7      6    5   4  3  2  1  0
;  RDY/BUSY COMP   1   0  0  1  X  X    45DB161
;***************************************************************************
;* Const Def
;

;Look-up table for these sizes ->  512k, 1M, 2M, 4M, 8M, 16M, 32M, 64M
;flash unsigned char DF_pagebits[]  ={  9,  9,  9,  9,  9,  10,  10,  11};    //index of internal page address bits



;Dataflash opcodes
.equ MainMemPageRead    =     0x52    ;Main Memory Page Read Inactive Clk Pol Low or High
.equ FlashPageRead    =    0x52    ;Main memory page read
.equ FlashToBuf1Transfer=    0x53    ;Main memory page to buffer 1 transfer
.equ Buf1Read        =    0x54    ;Buffer 1 read
.equ FlashToBuf2Transfer=    0x55    ;Main memory page to buffer 2 transfer
.equ Buf2Read        =    0x56    ;Buffer 2 read
.equ StatusReg        =    0x57    ;Status register
.equ StatusRegMode3    =    0xD7    ;Status register read SPI Mode 0 or 3
.equ AutoPageReWrBuf1    =    0x58    ;Auto page rewrite through buffer 1
.equ AutoPageReWrBuf2    =    0x59    ;Auto page rewrite through buffer 2
.equ FlashToBuf1Compare    =    0x60    ;Main memory page to buffer 1 compare
.equ FlashToBuf2Compare    =    0x61    ;Main memory page to buffer 2 compare
.equ ContArrayRead    =    0x68    ;Continuous Array Read (Note : Only A/B-parts supported)
.equ FlashProgBuf1    =    0x82    ;Main memory page program through buffer 1
.equ Buf1ToFlashWE    =    0x83    ;Buffer 1 to main memory page program with built-in erase
.equ Buf1Write        =    0x84    ;Buffer 1 write
.equ FlashProgBuf2    =    0x85    ;Main memory page program through buffer 2
.equ Buf2ToFlashWE    =    0x86    ;Buffer 2 to main memory page program with built-in erase
.equ Buf2Write        =    0x87    ;Buffer 2 write
.equ Buf1ToFlash    =    0x88    ;Buffer 1 to main memory page program without built-in erase
.equ Buf2ToFlash    =    0x89    ;Buffer 2 to main memory page program without built-in erase
.equ MainMemPageReadSPI =    0xD2    ;Main Memory Page Read SPI Mode 0 or 3
.equ ContArrayReadSPI   =    0xE8    ;Continuous Array Read SPI Mode 0 or 3


;Table 2. Program and Erase Commands
.equ Buffer1Write       = 0x84 ;Buffer 1 Write
.equ Buffer2Write       = 0x87 ;Buffer 2 Write
.equ Buffer1toMem       = 0x88 ;Buffer 1 to Main Memory Page Program without Built-in Erase
.equ Buffer2toMem       = 0x89 ;Buffer 2 to Main Memory Page Program without Built-in Erase
.equ DFPageErase        = 0x81 ;Page Erase
.equ DFBlockErase       = 0x50 ;Block Erase
.equ MemPageProgBuff1   = 0x82 ;Main Memory Page Program through Buffer 1
.equ MemPageProgBuff2   = 0x85 ;Main Memory Page Program through Buffer 2


;Table 3. Additional Commands
.equ MemPagetoBuff1     = 0x53 ;Main Memory Page to Buffer 1 Transfer
.equ MemPagetoBuff2     = 0x55 ;Main Memory Page to Buffer 2 Transfer
.equ MemPagetoBuff1Cmp  = 0x60 ;Main Memory Page to Buffer 1 Compare
.equ MemPagetoBuff2Cmp  = 0x61 ;Main Memory Page to Buffer 2 Compare
.equ PageRewriteBuff1   = 0x58 ;Auto Page Rewrite through Buffer 1
.equ PageRewriteBuff2   = 0x59 ;Auto Page Rewrite through Buffer 2



;**************************************************************************
;* Hardware Def.
;

; RDY/BUSY - Ready/Busy
.equ    DFRDY_PORT = PORTD
.equ    DFRDY_DIR = DDRD
.equ    DFRDY_PIN = PIND
.equ    DFRDY = 7

.equ    DFRES_PORT = PORTD
.equ    DFRES_DIR = DDRD
.equ    DFRES = 5

.equ    DFCS_PORT = PORTC
.equ    DFCS_DIR = DDRC
.equ    DFCs = 2



.equ    MOSI_DIR = DDRB
.equ    MOSI_PORT = PORTB
.equ    MOSI = 3

.equ    MISO_DIR = DDRB
.equ    MISO_PORT = PORTB
.equ    MISO_PIN = PINB
.equ    MISO = 4

.equ    SCLK_DIR = DDRB
.equ    SCLK_PORT = PORTB
.equ    SCLK = 5

.equ    DFSS_DIR = DDRB
.equ    DFSS_PORT = PORTB
.equ    DFSS = 2



;***************************************************************************
;**** VARIABLES
.DSEG

DFSize:        .byte 1
DFPageSize:    .byte 1
DFPageBits:    .byte 1

.equ    DFBuffer = AppData

;DFBuffer:    .byte 128    ;Data buffer
; !!! use AppData buffer from user.asm --> save RAM Space !!!
; !!! Self update not supported in application !!!

;***************************************************************************
.ESEG


;***************************************************************************
;**** CODE SEG
;***************************************************************************
.CSEG

;p,x,y,z,0
;page bits = p
;page number = x * 256
;page size = y * 256 (264)
;type = z
;
AT45DBxxx:    .db  9, 2,1,0b00001100    ;AT45DB011 1Mbit
        .db  9, 4,1,0b00010100    ;AT45DB021 2Mbit
        .db  9, 8,1,0b00011100    ;AT45DB041 4Mbit
        .db  9,16,1,0b00100100    ;AT45DB081 8Mbit
        .db 10,16,2,0b00101100    ;AT45DB161 16Mbit
        .db 10,32,2,0b00110100    ;AT45DB321 32Mbit
        .db 11,32,4,0b00111000    ;AT45DB642 64Mbit
                .db 11,64,4,0b00010000  ;AT45DB1282 128Mbit
        .dw 0,0


;****************************************************************************
;***           S P I    R U T I N S
;***
;****************************************************************************
;* SPI_init
;*
;* Initialize our port pins for use as SPI master.
;*
;***************************************************************************
;
SPI_init:
        sbi    DFCS_PORT,DFCS        ;DFlash CE pin is output for ATmega
        sbi    DFCS_DIR,DFCS        ;CS=1

        sbi    DFRES_PORT,DFRES
        sbi    DFRES_DIR,DFRES        ;DFlash Reset = H


        cbi    DFRDY_DIR,DFRDY
        sbi    DFRDY_PORT,DFRDY    ;DFlash R/B pullup input

        in    R16,PORTB
        andi    R16,0b11000011
        ori    R16,0b00101100
        out    PORTB,R16        ;SS, MOSI, SCK output; MISO input

        in    R16,DDRB
        andi    R16,0b11000011
        ori    R16,0b00101100
        out    DDRB,R16


        ldi    R16,0b01011100
        out    SPCR,R16    ;[7] - SPIE: SPI Interrupt Enable
                    ;[6] - SPE: SPI Enable
                    ;[5] - DORD: Data Order
                    ;[4] - MSTR: Master/Slave Select
                    ;[3] - CPOL: Clock Polarity
                    ;[2] - CPHA: Clock Phase
                    ;[1:0] - SPR1,SPR0: SPI Clock Rate Select
                    ; SPI2X SPR1 SPR0 SCK Frequency
                    ;   0    0    0      fosc/4
                    ;   0    0    1      fosc/16
                    ;   0    1    0      fosc/64
                    ;   0    1    1      fosc/128
                    ;   1    0    0      fosc/2
                    ;   1    0    1      fosc/8
                    ;   1    1    0      fosc/32
                    ;   1    1    1      fosc/64

        ldi    R16,0b00000001
        out    SPSR,R16    ;[7] - SPIF: SPI Interrupt Flag
                    ;[6] - WCOL: Write COLlision flag
                    ;[5:1] - Res: Reserved Bits
                    ;[0] - SPI2X: Double SPI Speed Bit
        in    R16,SPSR
        in    R16,SPDR    ;Clear SPIF & WCOL bits


        cbi    DFRES_PORT,DFRES    ;DFlash Reset
                        ;DFlash Reset>10us
        ldi    ZL,low(SYSCLK/100000)
        ldi    ZH,High(SYSCLK/100000)
W10us1:        sbiw    ZL,1
        brne    W10us1

        sbi    DFRES_PORT,DFRES    ;DFlash Reset = 1

        ldi    R16,50            ;Reset Recoveri time = 1 us
W10us2:        dec    R16
        brne    W10us2

        rcall    DF_ReadStatus
        cbr    R16,0b11000011
        ldi    ZL,low(AT45DBxxx*2)    ;ATmega128 -> set PAMPZ!!
        ldi    ZH,high(AT45DBxxx*2)
SearchDF:    lpm    R17,Z+
        sts    DFPageBits,R17
        lpm    R18,Z+
        sts    DFSize,R18
        lpm    R18,Z+
        sts    DFPageSize,R18
        lpm    R2,Z+
        cp    R16,R2
        breq    DFHit
        tst    R17
        brne    SearchDF
DFHit:
        ret

;*****************************************************************************
;*DF_SPI_RW
;*
;* Read and writes one byte from/to SPI master
;*
;* In: R16 - Byte to be written to SPI data register
;*
;* Out: R16 - Byte read from SPI data register
;*
;******************************************************************************
;
DF_SPI_RW:
        out    SPDR,R16
DF_SPI_RW0:
        sbis    SPSR,spif
         rjmp    DF_SPI_RW0    ;wait for transfer complete, poll SPIF-flag
        in    R16,SPDR
        ret

;*****************************************************************************
;*Read_DF_status
;*
;* Status info concerning the Dataflash is busy or not.
;* Status info concerning compare between buffer and flash page
;* Status info concerning size of actual device
;*
;* In: -
;*
;* Out: R16 - status byte. Consult Dataflash datasheet for further decoding info
;*
;******************************************************************************
;
DF_ReadStatus:
        sbi    DFCS_PORT,DFCS        ;DF CS inactive
        nop
        nop
        cbi    DFCS_PORT,DFCS        ;DF CS Active!
                        ;to reset dataflash command decoder
        ldi    R16,StatusRegMode3
        rcall    DF_SPI_RW        ;send status register read op-code
        clr    R16
        rcall    DF_SPI_RW        ;dummy write to get result
        ret


;*****************************************************************************
;* WaitToDF
;*
;* Wait for DataFlash to Ready
;*
;* In: -
;*
;* Out: -
;*
;******************************************************************************
;
WaitToDF:
              rcall    DF_ReadStatus
               cbr    R16,0x7F        ;Csak a Busy Flag marad meg
               breq    WaitToDF        ;monitor the status register, wait until busy-flag is high
        sbi    DFCS_PORT,DFCS         ;DF CS inactive
        nop
        cbi    DFCS_PORT,DFCS        ;DF CS Active! , reset dataflash command decoder
        ret

;*****************************************************************************
;Page_To_Buffer
;
; Transfers a page from flash to dataflash SRAM buffer
;
; In:    R0    = BufferNo -> R0 = 0 usage Buffer 1
;                     = non zero usage Buffer 2
;     R19:R18 = PageAdr  -> Address of page to be transferred to buffer
;
; Out: -
;*****************************************************************************
;
DF_PageToBuffer:
        rcall    WaitToDF
        ldi    R16,FlashToBuf1Transfer    ;transfer to buffer 1 op-code
        tst    R0
        breq    DF_PageToBuff01
        ldi    R16,FlashToBuf2Transfer    ;transfer to buffer 2 op-code
DF_PageToBuff01:
        rcall    DF_SPI_RW        ;send op-code
        lds    R16,DFPageBits
        subi    R16,8
DF_PageToBuff02:
        lsl    R18
        rol    R19
        dec    R16
        brne    DF_PageToBuff02

        mov    R16,R19
        rcall    DF_SPI_RW    ;upper part of page address
        mov    R16,R18
        rcall    DF_SPI_RW    ;lower part of page address
        clr    R16
        rcall    DF_SPI_RW

        sbi    DFCS_PORT,DFCS        ;DF CS inactive
        ret


;*****************************************************************************
;DF_BufferReadByte
;
; Reads one byte from one of the dataflash internal SRAM buffers
;
; In:    R0    = BufferNo -> R0 = 0 usage Buffer 1
;                     = non zero usage Buffer 2
;     R19:R18 = IntPageAdr  -> Internal page address
;
; Out:    R16 - One read byte (any value)
;
;*****************************************************************************
;
DF_BufferReadByte:
        rcall    WaitToDF
        ldi    R16,Buf1Read        ;read byte from buffer 1
        tst    R0
        breq    BufferReadByte01
        ldi    R16,Buf2Read        ;read byte from buffer 2
BufferReadByte01:
        rcall    DF_SPI_RW        ;send op-code
        clr    R16
        rcall    DF_SPI_RW        ;don't cares
        mov    R16,R19
        rcall    DF_SPI_RW           ;upper part of page address
        mov    R16,R18
        rcall    DF_SPI_RW              ;lower part of page address
        clr    R16
        rcall    DF_SPI_RW        ;additional don't cares
        clr    R16
        rcall    DF_SPI_RW        ;read byte
        sbi    DFCS_PORT,DFCS        ;DF CS inactive
        ret


;*****************************************************************************
;DF_BufferReadStr
;
; Reads one or more bytes from one of the dataflash internal SRAM buffers,
; and puts read bytes into buffer pointed to by X
; In:    R0:     BufferNo -> R0 = 0 usage Buffer 1
;                   = non zero usage Buffer 2
;         R19:R18  ->    Internal page address
;         R21:R20     ->    Number of bytes to be read
;         X       ->    address of buffer to be used for read bytes
;
; Out: -
;
;*****************************************************************************
;
DF_BufferReadStr:
        rcall    WaitToDF
        ldi    R16,Buf1Read        ;read byte from buffer 1
        tst    R0
        breq    DF_BufferReadStr01
        ldi    R16,Buf2Read        ;read byte from buffer 2
DF_BufferReadStr01:
        rcall    DF_SPI_RW        ;send op-code
        clr    R16
        rcall    DF_SPI_RW        ;don't cares
        mov    R16,R19
        rcall    DF_SPI_RW           ;upper part of page address
        mov    R16,R18
        rcall    DF_SPI_RW              ;lower part of page address
        clr    R16
        rcall    DF_SPI_RW        ;additional don't cares
        push    YL
        push    YH
        movw    YL,R20            ;Internal page address + Number of bytes to be read <= Page Size!!!
DF_BufferReadStr02:
        clr    R16
        rcall    DF_SPI_RW
        st    X+,R16            ;Store DF data byte
        sbiw    YL,1
        brne    DF_BufferReadStr02
        pop    YH
        pop    YL
        sbi    DFCS_PORT,DFCS        ;DF CS inactive
        ret

;*****************************************************************************
; DF_BufferWriteEnable
;
; Enables continous write functionality to one of the dataflash buffers
; NOTE : User must ensure that CS goes high to terminate this mode
; before accessing other dataflash functionalities
;
; In:    R0:     BufferNo -> R0 = 0 usage Buffer 1
;                   = non zero usage Buffer 2
;         R19:R18  ->    Internal page address to start writing from
;
; Out: None
;
;*****************************************************************************
;
DF_BufferWriteEnable:
        rcall    WaitToDF
        ldi    R16,Buf1Write        ;buffer 1 write op-code
        tst    R0
        breq    DF_BufferWriteEnable01
        ldi    R16,Buf2Write        ;buffer 2 write op-code
DF_BufferWriteEnable01:
        rcall    DF_SPI_RW        ;send op-code
        clr    R16
        rcall    DF_SPI_RW        ;don't cares
        mov    R16,R19
        rcall    DF_SPI_RW           ;upper part of page address
        mov    R16,R18
        rcall    DF_SPI_RW              ;lower part of page address
        ret

;*****************************************************************************
; DF_BufferWriteByte:
;
; Writes one byte to one of the dataflash internal SRAM buffers
;
; In:    R0:     BufferNo -> R0 = 0 usage Buffer 1
;                   = non zero usage Buffer 2
;         R19:R18  ->    Internal page address to write byte to
;    R16     -> Data byte to be written
;
; Out: None
;
;*****************************************************************************
;
DF_BufferWriteByte:
        push    R16
        rcall    WaitToDF
        ldi    R16,Buf1Write        ;buffer 1 write op-code
        tst    R0
        breq    DF_BufferWriteByte01
        ldi    R16,Buf2Write        ;buffer 2 write op-code
DF_BufferWriteByte01:
        rcall    DF_SPI_RW        ;send op-code
        clr    R16
        rcall    DF_SPI_RW        ;don't cares
        mov    R16,R19
        rcall    DF_SPI_RW           ;upper part of page address
        mov    R16,R18
        rcall    DF_SPI_RW              ;lower part of page address
        pop    R16
        rcall    DF_SPI_RW        ;write data byte
DF_EndWrite:
        sbi    DFCS_PORT,DFCS        ;DF CS inactive
        ret

;*****************************************************************************
; DF_BufferWriteStr
;
; Copies one or more bytes to one of the dataflash internal SRAM buffers
; from AVR SRAM buffer pointed to by X
;
; In:    R0:     BufferNo -> R0 = 0 usage Buffer 1
;                   = non zero usage Buffer 2
;         R19:R18  ->    Internal page address
;         R21:R20     ->    Number of bytes to be read
;         X       ->    address of buffer to be used for write bytes
;
; Out: None
;
;*****************************************************************************
;
DF_BufferWriteStr:
        rcall    WaitToDF
        ldi    R16,Buf1Write        ;write byte to buffer 1
        tst    R0
        breq    DF_BufferWriteStr01
        ldi    R16,Buf2Write        ;write byte to buffer 2
DF_BufferWriteStr01:
        rcall    DF_SPI_RW        ;send op-code
        clr    R16
        rcall    DF_SPI_RW        ;don't cares
        mov    R16,R19
        rcall    DF_SPI_RW           ;upper part of page address
        mov    R16,R18
        rcall    DF_SPI_RW              ;lower part of page address
        push    YL
        push    YH
        movw    YL,R20            ;Internal page address + Number of bytes to be read <= Page Size!!!
DF_BufferWriteStr02:
        ld    R16,X+            ;Store DF data byte
        rcall    DF_SPI_RW
        sbiw    YL,1
        brne    DF_BufferWriteStr02
        pop    YH
        pop    YL
        ret

;*****************************************************************************
; DF_BufferToPage
; DF_BufferToPageWErase
;
; Transfers a page from dataflash SRAM buffer to flash
;
; In:    R0    = BufferNo -> R0 = 0 usage Buffer 1
;                     = non zero usage Buffer 2
;     R19:R18 = PageAdr  ->  Address of flash page to be programmed
;
; Out: None
;
;*****************************************************************************
;
DF_BufferToPage:
        rcall    WaitToDF
        ldi    R16,Buffer1toMem    ;buffer 1 to flash without erase
        tst    R0
        breq    DF_BufferToPage01
        ldi    R16,Buffer1toMem
        rjmp    DF_BufferToPage01

DF_BufferToPageWErase:
        rcall    WaitToDF
        ldi    R16,Buf1ToFlashWE    ;buffer 1 to flash with erase op-code
        tst    R0
        breq    DF_BufferToPage01
        ldi    R16,Buf2ToFlashWE      ;buffer 2 to flash with erase op-code
DF_BufferToPage01:
        rcall    DF_SPI_RW        ;send op-code
        lds    R16,DFPageBits
        subi    R16,8
DF_BufferToPage02:
        lsl    R18
        rol    R19
        dec    R16
        brne    DF_BufferToPage02

        mov    R16,R19
        rcall    DF_SPI_RW    ;upper part of page address
        mov    R16,R18
        rcall    DF_SPI_RW    ;lower part of page address
        clr    R16
        rcall    DF_SPI_RW
        nop
        sbi    DFCS_PORT,DFCS        ;DF CS inactive
        ret

;*****************************************************************************
; DF_PageErase
;
; Erase Flash Page
;
; In:    R19:R18 = PageAdr  ->  Address of flash page to be erased
;
; Out: None
;
;*****************************************************************************
;
DF_PageErase:
        rcall    WaitToDF
        ldi    R16,DFPageErase
        rcall    DF_SPI_RW        ;send op-code

        lds    R16,DFPageBits
        subi    R16,8
DF_PageErase01:
        lsl    R18
        rol    R19
        dec    R16
        brne    DF_PageErase01

        mov    R16,R19
        rcall    DF_SPI_RW        ;upper part of page address
        mov    R16,R18
        rcall    DF_SPI_RW        ;lower part of page address
        clr    R16
        rcall    DF_SPI_RW        ;dumpy part of address!!!
        nop
        sbi    DFCS_PORT,DFCS        ;DF CS inactive
        ret



;*****************************************************************************
; DF_CheckErasedPage
;
; Test Erased Flash Page
;
; In:    R19:R18 = PageAdr  ->  Address of flash page to be tested
;    R0 = used buffer 0 = buffer0 other = buffer1
;
; Out:    c=0 no error
;    c=1 Bad Page! Dont use!!
;
;*****************************************************************************
;
DF_CheckErasedPage:
        rcall    WaitToDF
        push    R0
        rcall    DF_PageToBuffer

                clr    XL
        ldi    R16,8
        lds    XH,DFPageSize
        mul    R16,XH
        add    XL,R0
        adc    XH,R1            ;X full lenght of page in byte
        pop    R0
                  
DF_Check00:    
        push    R0
        push    XL
        push    XH
        sbiw    XL,1
        movw    R18,XL
        rcall    DF_BufferReadByte
        pop    XH
        pop    XL
        pop    R0
        cpi    R16,0xFF
        brne    DF_BadPage
        sbiw    XL,1
        brne    DF_Check00
        clc
        ret                ;ok page cleared well
DF_BadPage:    
        sec
        ret                ;Bad Page!
               欢迎点击进入:TI德州中文网   (国内唯一针对TI应用的中文技术网站)    文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    没有相关文章
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号