免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2100 | 回复: 0
打印 上一主题 下一主题

SD卡文件系统+彩屏显示图片 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-21 08:41 |只看该作者 |倒序浏览
tff.c文件,这是一个外国人所写。
可以到其官网参考。
先将该文件上传如下:
文件: tff.rar
大小: 12KB
下载: 下载
sd.c文件如下:
/*-----------------------------------------------------------------------*/
/* MMC/SDSC/SDHC (in SPI mode) control module  (C)                       */
/*-----------------------------------------------------------------------*/
/* filename: sdc_diskio.c                                                */
// FFT文件系统的移植部分,需要设置好SD卡的几个函数
//
//
//
//
//
//硬件环境: MINI STM32
//软甲环境: MDK
//SD卡管脚: SCLK   A5
//           MOSI   A7
//    MISO   A6
//    SD_CS   B6
//按键管脚: MINI STM32 S1按键 A3
//串口管脚: MINI STM32 A9(TX)   A10(RX)
/*-----------------------------------------------------------------------*/
#include "STM32Lib\\stm32f10x.h"
#include "diskio.h"
#include "tff.h"
#include "hal.h"
#include "ili9320.h"
#include "delay.h"
#define heng 240
#define shu  320
//#include "usart.h"
/* Definitions for MMC/SDC command */
#define CMD0 (0x40+0) /* GO_IDLE_STATE */
#define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */
#define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */
#define CMD8 (0x40+8) /* SEND_IF_COND */
#define CMD9 (0x40+9) /* SEND_CSD */
#define CMD10 (0x40+10) /* SEND_CID */
#define CMD12 (0x40+12) /* STOP_TRANSMISSION */
#define ACMD13 (0xC0+13) /* SD_STATUS (SDC) */
#define CMD16 (0x40+16) /* SET_BLOCKLEN */
#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
#define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
#define CMD23 (0x40+23) /* SET_BLOCK_COUNT (MMC) */
#define ACMD23 (0xC0+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
#define CMD24 (0x40+24) /* WRITE_BLOCK */
#define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
#define CMD55 (0x40+55) /* APP_CMD */
#define CMD58 (0x40+58) /* READ_OCR */
#define MMC_SELECT()     GPIO_ResetBits(GPIOB, GPIO_Pin_6)       /* MMC CS = L */
#define MMC_DESELECT()   GPIO_SetBits(GPIOB, GPIO_Pin_6)         /* MMC CS = H */

/*--------------------------------------------------------------------------
  Module Private Functions
  ---------------------------------------------------------------------------*/
static volatile
DSTATUS Stat = STA_NOINIT; /* Disk status */
static
BYTE CardType;       /* b0:MMC(1), b1:SDv1(2), b2:SDv2(4), b3:Block addressing(8) */
extern volatile u16 Timer1,Timer2; 
/***************************************
**函数名:MMC_SPI_Config
**功能:初始化SPI的接口IO,使其支持SPI接口
**注意事项:这个实际是在disk_initialize上调用所以可以考虑更改在MAIN调用
***************************************/
void SPI_Release(void);
void MMC_SPI_Config(void)
{
}
//每次要用SD的时候都调用此函数。
void TurnToSD(void)
{
    SPI_InitTypeDef  SPI_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_GPIOB |
            RCC_APB2Periph_GPIOC |
            RCC_APB2Periph_AFIO |
            RCC_APB2Periph_SPI1,
            ENABLE);
    /*A5=CLK,A6=MISO,A7=MOSI*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /*A5=CLK,A6=MISO,A7=MOSI*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
  
    /* Configure PB.6 as CS*/
 //置高
 GPIO_SetBits(GPIOB, GPIO_Pin_6);//置为高
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    /* SPI1 configuration */
 SPI_Cmd(SPI1, DISABLE); //必须要有才能改变MODE
    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_High;        //CPOL=1 时钟悬空高
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;       //CPHA=1 数据捕获第二个
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;        //软件NSS
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; //256分频
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;      //高位在前
    SPI_InitStructure.SPI_CRCPolynomial = 7;        //CRC7
   
 SPI_Init(SPI1, &SPI_InitStructure);
 //SPI_SSOutputCmd(SPI1, ENABLE); //使能NSS脚可用 
    /* Enable SPI1  */
    SPI_Cmd(SPI1, ENABLE);
 SPI_Release();  //复位一下总线,这个比较重要
}
#define NULL 0
void TestSD(void)
{
 FATFS fs;
    FIL fil;
 FRESULT res;  //文件系统返回信息
 char byte[65];
    u32 len;
 f_mount(0,&fs);//注册一个文件系统
 res=f_open(&fil,"/text/test.txt",FA_OPEN_EXISTING|FA_READ);
    if(res!=FR_OK)
    {
        USART1_Puts("SD  card open file error!\r\n");
        return;
    }
    //读取文件并打印到串口上
    for(;;)
 {
        res = f_read(&fil, byte, sizeof(byte)-1, &len);
     if (res || len == 0)
            break;   // error or eof
     byte[len]='\0';
        USART1_Puts(byte);
 }
    f_close(&fil);
 f_mount(0, NULL);
}
 
const char Txt_Name[5][11]={"1.txt","2.txt","3.txt","4.txt","5.txt"};
const char filename[21][11]={"1.bmp","2.bmp","3.bmp","4.bmp","5.bmp","6.bmp","7.bmp","8.bmp","9.bmp","10.bmp","11.bmp","12.bmp","13.bmp","14.bmp","15.bmp","16.bmp","17.bmp","18.bmp","19.bmp","20.bmp","21.bmp"};
//FIL file;
unsigned char data[2048]; 
FATFS fs;
FRESULT res;
UINT br;
void Draw_Picture(u16 x,u16 y,char filename[])
{
    FIL file;
u16 i;
u16 m,n;
    unsigned int file_cnt,cnt,temp1,temp2;
    u16 temp;   
//TFT_clear(White);  //清屏为黄色背景
res = f_mount(0, &fs);
res = f_open(&file,filename , FA_OPEN_EXISTING | FA_READ);   //打开图片  
 if(res!=FR_OK)
 {
 GUI_Text(0,line2,"BMP PLAY FAILD...",sizeof("BMP PLAY FAILD..."),Red,0x1234);
 }
res = f_read(&file, data, 0x36, &br);     //读取文件头信息
if(data[0]==0x42 && data[1]==0x4D)        //文件格式标记为BM
{
temp2 = data[18]+(data[19]<<8)+(data[20]<<16)+(data[21]<<24);
temp1 = data[22]+(data[23]<<8)+(data[24]<<16)+(data[25]<<24);
temp = data[28]+(data[29]<<8);
if(temp==16)                     //16位真彩色
{
 file_cnt = data[2]+(data[3]<<8)+(data[4]<<16)+(data[5]<<24);  //读取文件长度
 cnt=0;
 m=0,n=0;
 ili9320_SetCursor(0,0);
 while(1)
 {
 res = f_read(&file, data,1024, &br);                     //读取1536个数据
 cnt += 1024;
 if(cnt >= file_cnt)                                       //长度超过文件长度,退出
 break;
 for(i=0;i<512;i++)
 {
  //if((temp2==480)&&(temp1==272))
  if((temp2==heng)&&(temp1==shu)) 
  {
   ili9320_WriteData(((data[i*2+1])<<9|(data[i*2])));
  Set_Rs;
  Set_nWr;
  Clr_nWr;
  }
  else
  {
   ili9320_SetPoint(x+n,y+m,((data[i*2+1])<<9|(data[i*2])));
   if(n+1==temp2)
   {
   m++;
   //ili9320_SetCursor(n,m);
   n=0;
   }
   else n++;
     }//end if 480 272
   }//end for
   }//end while                 
}//end ese if
else if(temp==24)                     //24位真彩色
{
file_cnt = data[2]+(data[3]<<8)+(data[4]<<16)+(data[5]<<24);  //读取文件长度
cnt=0;
m=0,n=0;
ili9320_SetCursor(0,0);
    while(1)
    {
    res = f_read(&file, data, 1536, &br);                     //读取1536个数据
    cnt += 1536;
    if(cnt >= file_cnt)                                       //长度超过文件长度,退出
    break;
    for(i=0;i<512;i++)
    {
  //if((temp2==480)&&(temp1==272))
  if((temp2==heng)&&(temp1==shu)) 
  {
   ili9320_WriteData((data[i*3+2]*32/256)<<11 |
           (data[i*3+1]*64/256)<<5 |(data[i*3]*32/256));
  Set_Rs;
  Set_nWr;
  Clr_nWr;
  }
  else
  {
   ili9320_SetPoint(x+n,y+m,(data[i*3+2]*32/256)<<11 |
        (data[i*3+1]*64/256)<<5 |(data[i*3]*32/256));
   if(n+1==temp2)
   {
   m++;
   //ili9320_SetCursor(n,m);
   n=0;
   }
   else n++;
  }//end if 480 272
    }//end for
    } //end while                 
}//end ese if 24
else if(temp==32)                          //32位增强型真彩色
{
file_cnt = data[2]+(data[3]<<8)+(data[4]<<16)+(data[5]<<24);//读取文件长度
cnt=0;
m=0,n=0;
ili9320_SetCursor(0,0);
while(1)

res = f_read(&file, data, 2048, &br);   //读取2048个数据
cnt += sizeof(data);
    if(cnt >= file_cnt)                             //长度超过文件长度,退出
 break;
 for(i=0;i<512;i++)                              //显示数据
 { 
  //if((temp2==480)&&(temp1==272))
  if((temp2==heng)&&(temp1==shu))
  {
   ili9320_WriteData((data[i*4+2]>>3)<<11 |
        (data[i*4+1]>>2)<<5 |(data[i*4]>>3));
  Set_Rs;
  Set_nWr;
  Clr_nWr;
  }
  else
  {
   ili9320_SetPoint(x+n,y+m,(data[i*4+2]>>3)<<11 |
        (data[i*4+1]>>2)<<5 |(data[i*4]>>3));
  if(n+1==temp2)
  {
  m++;
  //ili9320_SetCursor(n,m);
  n=0;
  }
  else n++;
  }//end if 480 272
   }//end for
}//end while   
}//end ese if
}
// Close open files 
f_close(&file); 
//Delay_nms(3000);     //延时3秒
}
 
 
 
 
//*_*这个函数有待优化
static
u8 SPI_ReadWrite_Byte(unsigned char byte)
{
    /* Loop while DR register in not emplty */
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
    /* Send byte through the SPI1 peripheral */
    SPI_I2S_SendData(SPI1, byte);
    /* Wait to receive a byte */
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
    /* Return the byte read from the SPI bus */
    return SPI_I2S_ReceiveData(SPI1); 
}
static
void SPI_LowSpeed(void)
{
    SPI_InitTypeDef  SPI_InitStructure;
    /* SPI1 configuration */
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI1, &SPI_InitStructure);
    /* SPI1 enable */
    SPI_Cmd(SPI1, ENABLE);
}
static
void SPI_HighSpeed(void)
{
    SPI_InitTypeDef  SPI_InitStructure;
    /* SPI1 configuration */
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI1, &SPI_InitStructure);
    /* SPI1 enable */
    SPI_Cmd(SPI1, ENABLE);
}
/*-----------------------------------------------------------------------*/
/* Wait for card ready                                                   */
/*-----------------------------------------------------------------------*/
static
BYTE Wait_Ready (void)
{
    BYTE res;
    Timer2 = 50; /* Wait for ready in timeout of 500ms */
    SPI_ReadWrite_Byte(0xff);;
    do{
        res = SPI_ReadWrite_Byte(0xff);
    }while ((res != 0xFF) && Timer2);
    return res;
}
/*-----------------------------------------------------------------------*/
/* Deselect the card and release SPI bus                                 */
/*-----------------------------------------------------------------------*/
static
void SPI_Release(void)
{
    MMC_DESELECT();
    SPI_ReadWrite_Byte(0xff);;
}
 
/*-----------------------------------------------------------------------*/
/* Power Control  (Platform dependent)                                   */
/*-----------------------------------------------------------------------*/
/* When the target system does not support socket power control, there   */
/* is nothing to do in these functions and chk_power always returns 1.   */
/*-----------------------------------------------------------------------*/
//暂时取消电源管理
#define MMC_POWERON()    /*GPIO_ResetBits(GPIOD, GPIO_Pin_10)      */
#define MMC_POWEROFF()   /*GPIO_SetBits(GPIOD, GPIO_Pin_10)   */
int chk_power(void)  /* Socket power state: 0=off, 1=on */
{
    return 1;
}
/*-----------------------------------------------------------------------*/
/* Receive a data packet from MMC                                        */
/*-----------------------------------------------------------------------*/
static
bool Receive_DataBlock(
        BYTE *buff,   /* Data buffer to store received data */
        UINT btr   /* Byte count (must be multiple of 4) */
        )
{
    BYTE token;
   
    Timer1 = 10;
    do {       /* Wait for data packet in timeout of 100ms */
        token = SPI_ReadWrite_Byte(0xff);
    } while ((token == 0xFF) && Timer1);
    if(token != 0xFE) return FALSE; /* If not valid data token, retutn with error */
    do {       /* Receive the data block into buffer */
        *buff++ = SPI_ReadWrite_Byte(0xff);
    } while (btr--);
    SPI_ReadWrite_Byte(0xff);  /* Discard CRC */
    SPI_ReadWrite_Byte(0xff);
    return TRUE;     /* Return with success */
}
 
/*-----------------------------------------------------------------------*/
/* Send a data packet to MMC                                             */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
static
bool Transmit_DataBlock (
        const BYTE *buff, /* 512 byte data block to be transmitted */
        BYTE token   /* Data/Stop token */
        )
{
    BYTE resp;
    UINT wc;

    if (Wait_Ready() != 0xFF) return FALSE;
    SPI_ReadWrite_Byte(token);   /* Transmit data token */
    if (token != 0xFD) {             /* Is data token, 0xFD for stop token */
        wc = 512;
        do {       /* Transmit the 512 byte data block to MMC */
            SPI_ReadWrite_Byte(*buff++);
        } while (--wc);
        SPI_ReadWrite_Byte(0xFF);  /* CRC (Dummy) */
        SPI_ReadWrite_Byte(0xFF);
        resp = SPI_ReadWrite_Byte(0xff);/* Reveive data response */
        if ((resp & 0x1F) != 0x05)  /* If not accepted, return with error */
            return FALSE;
    }
    return TRUE;
}
#endif /* _READONLY */
/*-----------------------------------------------------------------------*/
/* Send a command packet to MMC                                          */
/* Output: R1, R2, R3 response                                           */
/*         In idle mode R1 Response is 0x01                              */
/*         When the card is initialized successfuly, R1 response is 0x00 */
/*-----------------------------------------------------------------------*/
static
BYTE Send_Command(
        BYTE cmd,  /* Command byte */
        DWORD arg  /* Argument */
        )
{
    BYTE n, res;
    /* Is a ACMD<n>? */
    if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */
        cmd &= 0x7F;
        res = Send_Command(CMD55, 0);
        if (res > 1) return res;
    }
    /* Select the card and wait for ready */
    MMC_DESELECT();
    MMC_SELECT();
    if (Wait_Ready() != 0xFF) return 0xFF;
    /* Send command packet */
    SPI_ReadWrite_Byte(cmd);
    SPI_ReadWrite_Byte((BYTE)(arg >> 24));  /* Argument[31..24] */
    SPI_ReadWrite_Byte((BYTE)(arg >> 16));  /* Argument[23..16] */
    SPI_ReadWrite_Byte((BYTE)(arg >> 8));  /* Argument[15..8] */
    SPI_ReadWrite_Byte((BYTE)arg);    /* Argument[7..0] */
    n = 0x01;               /* Dummy CRC + Stop */
    if (cmd == CMD0) n = 0x95;           /* Valid CRC for CMD0(0) */
    if (cmd == CMD8) n = 0x87;           /* Valid CRC for CMD8(0x1AA) */
    SPI_ReadWrite_Byte(n);
    /* Receive command response */
    if (cmd == CMD12) {
        /* The received byte immediataly following
         * CMD12 is a stuff byte, it should be discarded
         * before receive the response of the CMD12. */
        SPI_ReadWrite_Byte(0xff);     
    }
    /* Wait for a valid response in timeout of 10 attempts */
    n = 10;        
    do{
        res = SPI_ReadWrite_Byte(0xff);
    }while ((res & 0x80) && --n);
    return res;   /* Return with the response value */
}
/*--------------------------------------------------------------------------
  Public Functions
  ---------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive                                                 */
/*-----------------------------------------------------------------------*/
//在auto_mount()内调用
DSTATUS disk_initialize (
        BYTE drv  /* Physical drive nmuber (0) */
        )
{
    BYTE n, cmd, ty, ocr[4];

    if (drv) return STA_NOINIT;       /* Supports only single drive */
    if (Stat & STA_NODISK) return Stat;             /* No card in the socket */
    MMC_SPI_Config(); //初始化IO
  
    MMC_POWERON();                /* 开电 */
    for(Timer1=50; Timer1; );             
    SPI_LowSpeed();   
    MMC_DESELECT();       //不选SD
 /* Wait for enter Idle state in timeout of 5000 msec */
    Timer1 = 500;
    do{
        for (n = 10; n; n--) SPI_ReadWrite_Byte(0xff);     /* 80 dummy clocks */
    }
    while((Send_Command(CMD0,0) != 1) && Timer1);
    ty = 0;
    Timer1 = 200;           /* Initialization timeout of 2000 msec */
    if (Send_Command(CMD8, 0x1AA) == 1) {     /* 检查是否支持SDC Ver2 */
        for (n = 0; n < 4; n++)
            ocr[n] = SPI_ReadWrite_Byte(0xff); /* Get trailing return value of R7 resp */
        if (ocr[2] == 0x01 && ocr[3] == 0xAA) {   
            /* The card can work at vdd range of 2.7-3.6V */
            /* Wait for leaving idle state (ACMD41 with HCS bit) */
            while (Timer1 && Send_Command(ACMD41, 1UL << 30));      
            if (Timer1 && Send_Command(CMD58, 0) == 0) {  
                /* Check CCS bit in the OCR */
                for (n = 0; n < 4; n++)
                    ocr[n] = SPI_ReadWrite_Byte(0xff);
                /* When CCS bit is set  R/W in block address insted of byte address */
                ty = (ocr[0] & 0x40) ? 12 : 4;
            }
        }
    } else {       
        /* SDSC or MMC */
        if (Send_Command(ACMD41, 0) <= 1)  {           /* initialize successful will response 0x00 */
            ty = 2; cmd = ACMD41; /* SDv1 */
        } else {
            ty = 1; cmd = CMD1;  /* MMC */
        }
        while (Timer1 && Send_Command(cmd, 0));   /* Wait for leaving idle state */
        if (!Timer1 || Send_Command(CMD16, 512) != 0) /* Set R/W block length to 512 */
            ty = 0;
    }
    CardType = ty; 
    SPI_HighSpeed();
    SPI_Release();
    if (ty) {
        /* Initialization succeded */
        Stat &= ~STA_NOINIT; 
    //    USART1_Puts("Initialization succeded.\n");
    } else {              
        /* Initialization failed */
        MMC_POWEROFF();
    //    USART1_Puts("Initialization failed.\n");
    }
    return Stat;
}
 
/*-----------------------------------------------------------------------*/
/* Get Disk Status                                                       */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
        BYTE drv  /* Physical drive nmuber (0) */
        )
{
    if (drv) return STA_NOINIT;  /* Supports only single drive */
    return Stat;
}
 
/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
        BYTE drv,   /* Physical drive nmuber (0) */
        BYTE *buff,   /* Pointer to the data buffer to store read data */
        DWORD sector,          /* Start sector number (LBA) */
        BYTE count   /* Sector count (1..255) */
        )
{
    if (drv || !count) return RES_PARERR;
    if (Stat & STA_NOINIT) return RES_NOTRDY;
    if (!(CardType & 8)) sector *= 512; /* Convert to byte address if needed */
    if (count == 1) { /* Single block read */
        if ((Send_Command(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
                && Receive_DataBlock(buff, 512))
            count = 0;
    }
    else {    /* Multiple block read */
        if (Send_Command(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
            do {
                if (!Receive_DataBlock(buff, 512)) break;
                buff += 512;
            } while (--count);
            Send_Command(CMD12, 0);    /* STOP_TRANSMISSION */
        }
    }
    SPI_Release();
    return count ? RES_ERROR : RES_OK;
}
 
/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
DRESULT disk_write (
        BYTE drv,   /* Physical drive nmuber (0) */
        const BYTE *buff, /* Pointer to the data to be written */
        DWORD sector,  /* Start sector number (LBA) */
        BYTE count   /* Sector count (1..255) */
        )
{
    if (drv || !count) return RES_PARERR;
    if (Stat & STA_NOINIT) return RES_NOTRDY;
    if (Stat & STA_PROTECT) return RES_WRPRT;
    if (!(CardType & 8)) sector *= 512; /* Convert to byte address if needed */
    if (count == 1) { /* Single block write */
        if ((Send_Command(CMD24, sector) == 0) /* WRITE_BLOCK */
                && Transmit_DataBlock(buff, 0xFE))
            count = 0;
    }
    else {    /* Multiple block write */
        if (CardType & 6) Send_Command(ACMD23, count);
        if (Send_Command(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
            do {
                if (!Transmit_DataBlock(buff, 0xFC)) break;
                buff += 512;
            } while (--count);
            if (!Transmit_DataBlock(0, 0xFD)) /* STOP_TRAN token */
                count = 1;                      /* faild */
        }
    }
    SPI_Release();
    return count ? RES_ERROR : RES_OK;
}
#endif /* _READONLY == 0 */
 
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */
/*-----------------------------------------------------------------------*/
#if _USE_IOCTL != 0
DRESULT disk_ioctl (
        BYTE drv,  /* Physical drive nmuber (0) */
        BYTE ctrl,  /* Control code */
        void *buff  /* Buffer to send/receive control data */
        )
{
    DRESULT res;
    BYTE n, csd[16], *ptr = buff;
    WORD csize;

    if (drv) return RES_PARERR;
    res = RES_ERROR;
    if (ctrl == CTRL_POWER) {
        switch (*ptr) {
            case 0:  /* Sub control code == 0 (POWER_OFF) */
                if (chk_power())
                    MMC_POWEROFF();   /* Power off */
                res = RES_OK;
                break;
            case 1:  /* Sub control code == 1 (POWER_ON) */
                MMC_POWERON();    /* Power on */
                res = RES_OK;
                break;
            case 2:  /* Sub control code == 2 (POWER_GET) */
                *(ptr+1) = (BYTE)chk_power();
                res = RES_OK;
                break;
            default :
                res = RES_PARERR;
        }
    }
    else {
        if (Stat & STA_NOINIT) return RES_NOTRDY;
        switch (ctrl) {
            case CTRL_SYNC :  /* Make sure that no pending write process */
                MMC_SELECT();
                if (Wait_Ready() == 0xFF)
                    res = RES_OK;
                break;
            case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
                if ((Send_Command(CMD9, 0) == 0) && Receive_DataBlock(csd, 16)) {
                    if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
                        csize = csd[9] + ((WORD)csd[8] << 8) + 1;
                        *(DWORD*)buff = (DWORD)csize << 10;
                    } else {     /* SDC ver 1.XX or MMC*/
                        n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
                        csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1;
                        *(DWORD*)buff = (DWORD)csize << (n - 9);
                    }
                    res = RES_OK;
                }
                break;
            case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */
                *(WORD*)buff = 512;
                res = RES_OK;
                break;
            case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
                if (CardType & 4) {   /* SDC ver 2.00 */
                    if (Send_Command(ACMD13, 0) == 0) {  /* Read SD status */
                        SPI_ReadWrite_Byte(0xff);
                        if (Receive_DataBlock(csd, 16)) {    /* Read partial block */
                            for (n = 64 - 16; n; n--) SPI_ReadWrite_Byte(0xff); /* Purge trailing data */
                            *(DWORD*)buff = 16UL << (csd[10] >> 4);
                            res = RES_OK;
                        }
                    }
                } else {     /* SDC ver 1.XX or MMC */
                    if ((Send_Command(CMD9, 0) == 0) && Receive_DataBlock(csd, 16)) { /* Read CSD */
                        if (CardType & 2) {   /* SDC ver 1.XX */
                            *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
                        } else {     /* MMC */
                            *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1);
                        }
                        res = RES_OK;
                    }
                }
                break;
            case MMC_GET_TYPE :  /* Get card type flags (1 byte) */
                *ptr = CardType;
                res = RES_OK;
                break;
            case MMC_GET_CSD :  /* Receive CSD as a data block (16 bytes) */
                if (Send_Command(CMD9, 0) == 0  /* READ_CSD */
                        && Receive_DataBlock(ptr, 16))
                    res = RES_OK;
                break;
            case MMC_GET_CID :  /* Receive CID as a data block (16 bytes) */
                if (Send_Command(CMD10, 0) == 0  /* READ_CID */
                        && Receive_DataBlock(ptr, 16))
                    res = RES_OK;
                break;
            case MMC_GET_OCR :  /* Receive OCR as an R3 resp (4 bytes) */
                if (Send_Command(CMD58, 0) == 0) { /* READ_OCR */
                    for (n = 4; n; n--) *ptr++ = SPI_ReadWrite_Byte(0xff);
                    res = RES_OK;
                }
                break;
            case MMC_GET_SDSTAT : /* Receive SD statsu as a data block (64 bytes) */
                if (Send_Command(ACMD13, 0) == 0) { /* SD_STATUS */
                    SPI_ReadWrite_Byte(0xff);
                    if (Receive_DataBlock(ptr, 64))
                        res = RES_OK;
                }
                break;
            default:
                res = RES_PARERR;
        }
    }
   
    SPI_Release();
    return res;
}
#endif /* _USE_IOCTL != 0 */
DWORD get_fattime (void)
{
    return 0; 
}
/*-----------------------------------------------------------------------*/
/* Device Timer Interrupt Procedure  (Platform dependent)                */
/*-----------------------------------------------------------------------*/
/* This function must be called in period of 10ms                        */
/*
   void disk_timerproc (void)
   {
   static BYTE pv;
   BYTE n, s;

   n = Timer1;          // 100Hz decrement timer
   if (n) Timer1 = --n;
   n = Timer2;
   if (n) Timer2 = --n;
   n = pv;
   pv = SOCKPORT & (SOCKWP | SOCKINS); // Sample socket switch
   if (n == pv) {         // Have contacts stabled?
   s = Stat;
   if (pv & SOCKWP)   // WP is H (write protected)
   s |= STA_PROTECT;
   else      // WP is L (write enabled)
   s &= ~STA_PROTECT;
   if (pv & SOCKINS)   // INS = H (Socket empty)
   s |= (STA_NODISK | STA_NOINIT);
   else      // INS = L (Card inserted)
   s &= ~STA_NODISK;
   Stat = s;
   }
   }
   */
void Pic_Viewer(void)
{
    FIL file;
   // u16 k;
    u16 i,j=0;
    unsigned int cnt,file_cnt,temp1;
    u16 temp;
   GUI_Text(0,line9,"START",sizeof("START"),Red,0x1234);
  while(1)
  {      
   
          if(j>21)
          {
            //GUI_Text(line9, 30, "BMP PLAY ...");
   GUI_Text(0,line9,"BMP PLAY ...",sizeof("BMP PLAY ..."),Red,0x1234);
            delay_ms(300);     //延时5秒
            break;
            j=0;
          }
      
    for(j=1;j<=21;j++)
      {   
               //ili9320_Clear(Yellow);  //清屏为黄色背景
            res = f_mount(0, &fs); 
            res = f_open(&file, filename[j], FA_OPEN_EXISTING | FA_READ);   //打开图片 
                   if(j>21)
                   {
                     break;
                   }
      if(res!=FR_OK)
      {
          //while(1);
    GUI_Text(0,line5,"BMP PLAY FAILD...",sizeof("BMP PLAY FAILD..."),Red,0x1234);
      }
   else
   {
      GUI_Text(0,line5,"FR_OK...",sizeof("BMP PLAY FAILD..."),Red,0x1234);
   }
   delay_ms(500);
             res = f_read(&file, data, 0x36, &br);     //读取文件头信息
             ili9320_SetCursor(0,0);
      if(data[0]==0x42 && data[1]==0x4D)        //文件格式标记为BM
   {
             //printp("\r\n 测试点3---通过~!\r\n");
            
             temp = data[18]+(data[19]<<8)+(data[20]<<16)+(data[21]<<24);
             temp1 = data[22]+(data[23]<<8)+(data[24]<<16)+(data[25]<<24);
          //if(temp==240 && temp1==320)             //文件像素为:Width320*Height240
       if(temp==shu && temp1==heng) 
                   // if(temp==320 && temp1==480)             //文件像素为:Width320*Height240
             {
                                      temp = data[28]+(data[29]<<8);
                                        if(temp==32)                          //32位增强型真彩色
                                        {
                                          file_cnt = data[2]+(data[3]<<8)+(data[4]<<16)+(data[5]<<24);//读取文件长度
                                          cnt=36;
                                              while(1)
                                              {
                                                res = f_read(&file, data, 2048, &br);   //读取2048个数据
                                                cnt += sizeof(data);
                                                if(cnt >= file_cnt)                             //长度超过文件长度,退出
                                                  break;
                                                        for(i=0;i<512;i++)                              //显示数据
                                                        {  
                                                          ili9320_WriteData((data[i*4+2]>>3)<<11 |
                                                                       (data[i*4+1]>>2)<<5 |(data[i*4]>>3));
                                                        
                                                        }   
                                                
                                           
                                                    }  
                                                                     
                                               }
                                        else if(temp==24)                     //24位真彩色
                                        {
                                            file_cnt = data[2]+(data[3]<<8)+(data[4]<<16)+(data[5]<<24);  //读取文件长度
                                            cnt=36;
                                            while(1)
                                            {
                                              res = f_read(&file, data, 1536, &br);                     //读取1536个数据
                                              cnt += 1536;
                                              if(cnt >= file_cnt)                                       //长度超过文件长度,退出
                                                break;
                                              for(i=0;i<512;i++)
                                              {
                                                ili9320_WriteData((data[i*3+2]*32/256)<<11 |
                                                              (data[i*3+1]*64/256)<<5 |(data[i*3]*32/256));
                                               
                                              }
                                            }                 
                                        }//end ese if
                                       
                                         else if(temp==16)                     //24位真彩色
                                        {
                                            file_cnt = data[2]+(data[3]<<8)+(data[4]<<16)+(data[5]<<24);  //读取文件长度
                                            cnt=36;
                                            while(1)
                                            {
                                              res = f_read(&file, data,1024, &br);                     //读取1536个数据
                                              cnt += 1024;
                                              if(cnt >= file_cnt)                                       //长度超过文件长度,退出
                                                break;
                                              for(i=0;i<512;i++)
                                              {
 
                                               ili9320_WriteData(((data[i*2+1])<<9|(data[i*2])));
                                              }
                                            }                 
                                        }//end ese if
               
             }
                                  else
                                  {
                                      ili9320_Clear(White);  //清屏为白色背景
                                      //delay_ms(500);     //延时3秒
                                      //d_WriteString(50,140," Image is too big... ",RED,YELLOW);
                                      //Lcd_WriteString(50,160,"  Play  Images~!   ",RED,YELLOW);
                                     
           GUI_Text(0,line5,"BMP ERROR...",sizeof("BMP ERROR..."),Red,0x1234);
                                      delay_ms(500);     //延时3秒
                                      ili9320_Clear(White);  //清屏为白色背景
                                      ili9320_SetCursor(0,0);
                                      file_cnt = data[2]+(data[3]<<8)+(data[4]<<16)+(data[5]<<24);//读取文件长度
                                          cnt=36;
                                              while(1)
                                              {
                                                res = f_read(&file, data, 2048, &br);   //读取2048个数据
                                                cnt += sizeof(data);
                                                if(cnt >= file_cnt)                             //长度超过文件长度,退出
                                                  break;
                                                    for(i=0;i<512;i++)                              //显示数据
                                                    {  
                                                      ili9320_WriteData((data[i*4+2]>>3)<<11 |
                                                                   (data[i*4+1]>>2)<<5 |(data[i*4]>>3));
                                                    
                                                    }   
                                                                                                                        
                                               }
                                   }//end else
          }//end if   
     // Close open files
       f_close(&file);
       // Unregister work area prior to discard it
       f_mount(0, NULL);  
       delay_ms(2000);     //延时3秒
       }//end for(;;)
   
       }//end while(1)
}

还有一个文件就是ili9320.c
#include "ili9320.h"
#include "ili9320_font.h"
#include <stdlib.h> //abs函数
u16 DeviceCode;
//画笔颜色
INT16U  POINT_COLOR;
INT16U  BACK_COLOR;
void Lcd_Configuration(void)
{
 RCC->APB2ENR|=0X0000001C;//先使能外设IO PORTA,B,C时钟
 
 GPIOB->CRH=0x33333333;
 GPIOB->ODR|=0xFF00;
 
 GPIOC->CRL=0x33333333;
 GPIOC->CRH&=0xFF000000;
 GPIOC->CRH|=0x00333333;
 GPIOC->ODR|=0x3FFF;
 Lcd_Light_ON;
}
/****************************************************************************
* 名    称:void ili9320_Initializtion()
* 功    能:初始化 ILI9320 控制器
* 入口参数:无
* 出口参数:无
* 说    明:
* 调用方法:ili9320_Initializtion();
****************************************************************************/
void ili9320_Initializtion(void)
{
  /*****************************
  **    硬件连接说明          **
  ** STM32         ili9320    **
  ** PE0~15 <----> DB0~15     **
  ** PD15   <----> nRD        **
  ** PD14   <----> RS         **
  ** PD13   <----> nWR        **
  ** PD12   <----> nCS        **
  ** PD11   <----> nReset     **
  ** PC0    <----> BK_LED     **
  ******************************/
  u16 i;
    Lcd_Configuration();
 
   ili9320_WriteData(0xffff);
   Set_Rst;
 Set_nWr;
 Set_Cs;
 Set_Rs;
 Set_nRd;
 Set_Rst;
    ili9320_Reset();                                         // 复位 ili9320_Reset
    for(i=50000;i>0;i--);
    for(i=50000;i>0;i--);
    for(i=50000;i>0;i--);
    ili9320_WriteRegister(0x0000,0x0001);ili9320_Delay(10000);
    for(i=50000;i>0;i--);
    for(i=50000;i>0;i--);
    DeviceCode = ili9320_ReadRegister(0x0000);
 if(DeviceCode==0x9325||DeviceCode==0x9328)
 {
    ili9320_WriteRegister(0x00e7,0x0010);     
        ili9320_WriteRegister(0x0000,0x0001);       //start internal osc
        ili9320_WriteRegister(0x0001,0x0100);    
        ili9320_WriteRegister(0x0002,0x0700);      //power on sequence                    
        ili9320_WriteRegister(0x0003,(1<<12)|(1<<5)|(1<<4) );  //65K
        ili9320_WriteRegister(0x0004,0x0000);                                  
        ili9320_WriteRegister(0x0008,0x0207);           
        ili9320_WriteRegister(0x0009,0x0000);        
        ili9320_WriteRegister(0x000a,0x0000);      //display setting        
        ili9320_WriteRegister(0x000c,0x0001);     //display setting         
        ili9320_WriteRegister(0x000d,0x0000);      //0f3c         
        ili9320_WriteRegister(0x000f,0x0000);
  //Power On sequence //
        ili9320_WriteRegister(0x0010,0x0000);  
        ili9320_WriteRegister(0x0011,0x0007);
        ili9320_WriteRegister(0x0012,0x0000);                                                                
        ili9320_WriteRegister(0x0013,0x0000);                
        for(i=50000;i>0;i--);
  for(i=50000;i>0;i--);
        ili9320_WriteRegister(0x0010,0x1590);  
        ili9320_WriteRegister(0x0011,0x0227);
        for(i=50000;i>0;i--);
  for(i=50000;i>0;i--);
        ili9320_WriteRegister(0x0012,0x009c);                 
        for(i=50000;i>0;i--);
  for(i=50000;i>0;i--);
        ili9320_WriteRegister(0x0013,0x1900);  
        ili9320_WriteRegister(0x0029,0x0023);
        ili9320_WriteRegister(0x002b,0x000e);
        for(i=50000;i>0;i--);
  for(i=50000;i>0;i--);
        ili9320_WriteRegister(0x0020,0x0000);                                                           
        ili9320_WriteRegister(0x0021,0x0000);          
///////////////////////////////////////////////////////     
        for(i=50000;i>0;i--);
  for(i=50000;i>0;i--);
        ili9320_WriteRegister(0x0030,0x0007);
        ili9320_WriteRegister(0x0031,0x0707);  
        ili9320_WriteRegister(0x0032,0x0006);
        ili9320_WriteRegister(0x0035,0x0704);
        ili9320_WriteRegister(0x0036,0x1f04);
        ili9320_WriteRegister(0x0037,0x0004);
        ili9320_WriteRegister(0x0038,0x0000);       
        ili9320_WriteRegister(0x0039,0x0706);    
        ili9320_WriteRegister(0x003c,0x0701);
        ili9320_WriteRegister(0x003d,0x000f);
        for(i=50000;i>0;i--);
  for(i=50000;i>0;i--);
        ili9320_WriteRegister(0x0050,0x0000);       
        ili9320_WriteRegister(0x0051,0x00ef);  
        ili9320_WriteRegister(0x0052,0x0000);    
        ili9320_WriteRegister(0x0053,0x013f);
        ili9320_WriteRegister(0x0060,0xa700);       
        ili9320_WriteRegister(0x0061,0x0001);
        ili9320_WriteRegister(0x006a,0x0000);
        ili9320_WriteRegister(0x0080,0x0000);
        ili9320_WriteRegister(0x0081,0x0000);
        ili9320_WriteRegister(0x0082,0x0000);
        ili9320_WriteRegister(0x0083,0x0000);
        ili9320_WriteRegister(0x0084,0x0000);
        ili9320_WriteRegister(0x0085,0x0000);
     
        ili9320_WriteRegister(0x0090,0x0010);    
        ili9320_WriteRegister(0x0092,0x0000); 
        ili9320_WriteRegister(0x0093,0x0003);
        ili9320_WriteRegister(0x0095,0x0110);
        ili9320_WriteRegister(0x0097,0x0000);       
        ili9320_WriteRegister(0x0098,0x0000); 
        //display on sequence    
        ili9320_WriteRegister(0x0007,0x0133);
   
        ili9320_WriteRegister(0x0020,0x0000);                                                           
        ili9320_WriteRegister(0x0021,0x0000);
 }
 else if(DeviceCode==0x9320)
 {
  ili9320_WriteRegister(0x00,0x0000);
  ili9320_WriteRegister(0x01,0x0100); //Driver Output Contral.
  ili9320_WriteRegister(0x02,0x0700); //LCD Driver Waveform Contral.
  ili9320_WriteRegister(0x03,0x1018); //Entry Mode Set.
 
  ili9320_WriteRegister(0x04,0x0000); //Scalling Contral.
  ili9320_WriteRegister(0x08,0x0202); //Display Contral 2.(0x0207)
  ili9320_WriteRegister(0x09,0x0000); //Display Contral 3.(0x0000)
  ili9320_WriteRegister(0x0a,0x0000); //Frame Cycle Contal.(0x0000)
  ili9320_WriteRegister(0x0c,(1<<0)); //Extern Display Interface Contral 1.(0x0000)
  ili9320_WriteRegister(0x0d,0x0000); //Frame Maker Position.
  ili9320_WriteRegister(0x0f,0x0000); //Extern Display Interface Contral 2.
 
  for(i=50000;i>0;i--);
  for(i=50000;i>0;i--);
  ili9320_WriteRegister(0x07,0x0101); //Display Contral.
  for(i=50000;i>0;i--);
  for(i=50000;i>0;i--);
 
  ili9320_WriteRegister(0x10,(1<<12)|(0<<8)|(1<<7)|(1<<6)|(0<<4)); //Power Control 1.(0x16b0)
  ili9320_WriteRegister(0x11,0x0007);         //Power Control 2.(0x0001)
  ili9320_WriteRegister(0x12,(1<<8)|(1<<4)|(0<<0));     //Power Control 3.(0x0138)
  ili9320_WriteRegister(0x13,0x0b00);         //Power Control 4.
  ili9320_WriteRegister(0x29,0x0000);         //Power Control 7.
 
  ili9320_WriteRegister(0x2b,(1<<14)|(1<<4));
  
  ili9320_WriteRegister(0x50,0);  //Set X Start.
  ili9320_WriteRegister(0x51,239); //Set X End.
  ili9320_WriteRegister(0x52,0);  //Set Y Start.
  ili9320_WriteRegister(0x53,319); //Set Y End.
 
  ili9320_WriteRegister(0x60,0x2700); //Driver Output Control.
  ili9320_WriteRegister(0x61,0x0001); //Driver Output Control.
  ili9320_WriteRegister(0x6a,0x0000); //Vertical Srcoll Control.
 
  ili9320_WriteRegister(0x80,0x0000); //Display Position? Partial Display 1.
  ili9320_WriteRegister(0x81,0x0000); //RAM Address Start? Partial Display 1.
  ili9320_WriteRegister(0x82,0x0000); //RAM Address End-Partial Display 1.
  ili9320_WriteRegister(0x83,0x0000); //Displsy Position? Partial Display 2.
  ili9320_WriteRegister(0x84,0x0000); //RAM Address Start? Partial Display 2.
  ili9320_WriteRegister(0x85,0x0000); //RAM Address End? Partial Display 2.
 
  ili9320_WriteRegister(0x90,(0<<7)|(16<<0)); //Frame Cycle Contral.(0x0013)
  ili9320_WriteRegister(0x92,0x0000); //Panel Interface Contral 2.(0x0000)
  ili9320_WriteRegister(0x93,0x0001); //Panel Interface Contral 3.
  ili9320_WriteRegister(0x95,0x0110); //Frame Cycle Contral.(0x0110)
  ili9320_WriteRegister(0x97,(0<<8)); //
  ili9320_WriteRegister(0x98,0x0000); //Frame Cycle Contral.

  ili9320_WriteRegister(0x07,0x0173); //(0x0173)
 }
 else if(DeviceCode==0x9919)
 {
   //------POWER ON &RESET DISPLAY OFF
   ili9320_WriteRegister(0x28,0x0006);
  
   ili9320_WriteRegister(0x00,0x0001);
  
   ili9320_WriteRegister(0x10,0x0000);
  
   ili9320_WriteRegister(0x01,0x72ef);
   ili9320_WriteRegister(0x02,0x0600);
   ili9320_WriteRegister(0x03,0x6a38);
  
   ili9320_WriteRegister(0x11,0x6874);  //70
  
  
   //RAM WRITE DATA MASK
   ili9320_WriteRegister(0x0f,0x0000);
   //RAM WRITE DATA MASK
   ili9320_WriteRegister(0x0b,0x5308);
  
   ili9320_WriteRegister(0x0c,0x0003);
  
   ili9320_WriteRegister(0x0d,0x000a);
  
   ili9320_WriteRegister(0x0e,0x2e00);  //0030
  
   ili9320_WriteRegister(0x1e,0x00be);
  
   ili9320_WriteRegister(0x25,0x8000);
  
   ili9320_WriteRegister(0x26,0x7800);
  
   ili9320_WriteRegister(0x27,0x0078);
  
   ili9320_WriteRegister(0x4e,0x0000);
  
   ili9320_WriteRegister(0x4f,0x0000);
  
   ili9320_WriteRegister(0x12,0x08d9);
  
   //-----------------Adjust the Gamma Curve----//
   ili9320_WriteRegister(0x30,0x0000);  //0007
  
   ili9320_WriteRegister(0x31,0x0104);  //0203
  
   ili9320_WriteRegister(0x32,0x0100);  //0001
   ili9320_WriteRegister(0x33,0x0305);  //0007
   ili9320_WriteRegister(0x34,0x0505);  //0007
  
   ili9320_WriteRegister(0x35,0x0305);  //0407
  
   ili9320_WriteRegister(0x36,0x0707);  //0407
  
   ili9320_WriteRegister(0x37,0x0300);  //0607
  
   ili9320_WriteRegister(0x3a,0x1200);  //0106
  
   ili9320_WriteRegister(0x3b,0x0800);  
   ili9320_WriteRegister(0x07,0x0033);
 }
 else if(DeviceCode==0x9331)
 {
   /*********POWER ON &RESET DISPLAY OFF*/
  /************* Start Initial Sequence **********/
  ili9320_WriteRegister(0x00E7, 0x1014);
  ili9320_WriteRegister(0x0001, 0x0100); // set SS and SM bit   0x0100
  ili9320_WriteRegister(0x0002, 0x0200); // set 1 line inversion
  ili9320_WriteRegister(0x0003, 0x1030); // set GRAM write direction and BGR=1.     0x1030
  ili9320_WriteRegister(0x0008, 0x0202); // set the back porch and front porch
  ili9320_WriteRegister(0x0009, 0x0000); // set non-display area refresh cycle ISC[3:0]
  ili9320_WriteRegister(0x000A, 0x0000); // FMARK function
  ili9320_WriteRegister(0x000C, 0x0000); // RGB interface setting
  ili9320_WriteRegister(0x000D, 0x0000); // Frame marker Position
  ili9320_WriteRegister(0x000F, 0x0000); // RGB interface polarity
  //*************Power On sequence ****************//
  ili9320_WriteRegister(0x0010, 0x0000); // SAP, BT[3:0], AP, DSTB, SLP, STB
  ili9320_WriteRegister(0x0011, 0x0007); // DC1[2:0], DC0[2:0], VC[2:0]
  ili9320_WriteRegister(0x0012, 0x0000); // VREG1OUT voltage
  ili9320_WriteRegister(0x0013, 0x0000); // VDV[4:0] for VCOM amplitude
  ili9320_Delay(200); // Dis-charge capacitor power voltage
  ili9320_WriteRegister(0x0010, 0x1690); // SAP, BT[3:0], AP, DSTB, SLP, STB
  ili9320_WriteRegister(0x0011, 0x0227); // DC1[2:0], DC0[2:0], VC[2:0]
  ili9320_Delay(50); // Delay 50ms
  ili9320_WriteRegister(0x0012, 0x000C); // Internal reference voltage= Vci;
  ili9320_Delay(50); // Delay 50ms
  ili9320_WriteRegister(0x0013, 0x0800); // Set VDV[4:0] for VCOM amplitude
  ili9320_WriteRegister(0x0029, 0x0011); // Set VCM[5:0] for VCOMH
  ili9320_WriteRegister(0x002B, 0x000B); // Set Frame Rate
  ili9320_Delay(50); // Delay 50ms
  ili9320_WriteRegister(0x0020, 0x0000); // GRAM horizontal Address
  ili9320_WriteRegister(0x0021, 0x0000); // GRAM Vertical Address
  // ----------- Adjust the Gamma Curve ----------//
  ili9320_WriteRegister(0x0030, 0x0000);
  ili9320_WriteRegister(0x0031, 0x0106);
  ili9320_WriteRegister(0x0032, 0x0000);
  ili9320_WriteRegister(0x0035, 0x0204);
  ili9320_WriteRegister(0x0036, 0x160A);
  ili9320_WriteRegister(0x0037, 0x0707);
  ili9320_WriteRegister(0x0038, 0x0106);
  ili9320_WriteRegister(0x0039, 0x0707);
  ili9320_WriteRegister(0x003C, 0x0402);
  ili9320_WriteRegister(0x003D, 0x0C0F);
  //------------------ Set GRAM area ---------------//
  ili9320_WriteRegister(0x0050, 0x0000); // Horizontal GRAM Start Address
  ili9320_WriteRegister(0x0051, 0x00EF); // Horizontal GRAM End Address
  ili9320_WriteRegister(0x0052, 0x0000); // Vertical GRAM Start Address
  ili9320_WriteRegister(0x0053, 0x013F); // Vertical GRAM Start Address
  ili9320_WriteRegister(0x0060, 0x2700); // Gate Scan Line
  ili9320_WriteRegister(0x0061, 0x0001); // NDL,VLE, REV
  ili9320_WriteRegister(0x006A, 0x0000); // set scrolling line
  //-------------- Partial Display Control ---------//
  ili9320_WriteRegister(0x0080, 0x0000);
  ili9320_WriteRegister(0x0081, 0x0000);
  ili9320_WriteRegister(0x0082, 0x0000);
  ili9320_WriteRegister(0x0083, 0x0000);
  ili9320_WriteRegister(0x0084, 0x0000);
  ili9320_WriteRegister(0x0085, 0x0000);
  //-------------- Panel Control -------------------//
  ili9320_WriteRegister(0x0090, 0x0010);
  ili9320_WriteRegister(0x0092, 0x0600);
  ili9320_WriteRegister(0x0007,0x0021);  
  ili9320_Delay(50);
  ili9320_WriteRegister(0x0007,0x0061);
  ili9320_Delay(50);
  ili9320_WriteRegister(0x0007,0x0133);  // 262K color and display ON
  ili9320_Delay(50);
 } 
 else if(DeviceCode==0x7783)
 {
  // Start Initial Sequence
  ili9320_WriteRegister(0x00FF,0x0001);
  ili9320_WriteRegister(0x00F3,0x0008);
  ili9320_WriteRegister(0x0001,0x0100);
  ili9320_WriteRegister(0x0002,0x0700);
  ili9320_WriteRegister(0x0003,0x1030);  //0x1030
  ili9320_WriteRegister(0x0008,0x0302);
  ili9320_WriteRegister(0x0008,0x0207);
  ili9320_WriteRegister(0x0009,0x0000);
  ili9320_WriteRegister(0x000A,0x0000);
  ili9320_WriteRegister(0x0010,0x0000);  //0x0790
  ili9320_WriteRegister(0x0011,0x0005);
  ili9320_WriteRegister(0x0012,0x0000);
  ili9320_WriteRegister(0x0013,0x0000);
  ili9320_Delay(50);
  ili9320_WriteRegister(0x0010,0x12B0);
  ili9320_Delay(50);
  ili9320_WriteRegister(0x0011,0x0007);
  ili9320_Delay(50);
  ili9320_WriteRegister(0x0012,0x008B);
  ili9320_Delay(50);
  ili9320_WriteRegister(0x0013,0x1700);
  ili9320_Delay(50);
  ili9320_WriteRegister(0x0029,0x0022);
  
  //################# void Gamma_Set(void) ####################//
  ili9320_WriteRegister(0x0030,0x0000);
  ili9320_WriteRegister(0x0031,0x0707);
  ili9320_WriteRegister(0x0032,0x0505);
  ili9320_WriteRegister(0x0035,0x0107);
  ili9320_WriteRegister(0x0036,0x0008);
  ili9320_WriteRegister(0x0037,0x0000);
  ili9320_WriteRegister(0x0038,0x0202);
  ili9320_WriteRegister(0x0039,0x0106);
  ili9320_WriteRegister(0x003C,0x0202);
  ili9320_WriteRegister(0x003D,0x0408);
  ili9320_Delay(50);
  
  ili9320_WriteRegister(0x0050,0x0000);  
  ili9320_WriteRegister(0x0051,0x00EF);  
  ili9320_WriteRegister(0x0052,0x0000);  
  ili9320_WriteRegister(0x0053,0x013F);  
  ili9320_WriteRegister(0x0060,0xA700);  
  ili9320_WriteRegister(0x0061,0x0001);
  ili9320_WriteRegister(0x0090,0x0033);    
  ili9320_WriteRegister(0x002B,0x000B);  
  ili9320_WriteRegister(0x0007,0x0133);
  ili9320_Delay(50);
 } 
 else if(DeviceCode==0x4531)
 {  
  // Setup display
  ili9320_WriteRegister(0x00,0x0001);
     ili9320_WriteRegister(0x10,0x0628);
     ili9320_WriteRegister(0x12,0x0006);
     ili9320_WriteRegister(0x13,0x0A32);
     ili9320_WriteRegister(0x11,0x0040);
     ili9320_WriteRegister(0x15,0x0050);
     ili9320_WriteRegister(0x12,0x0016);
     ili9320_Delay(15);
     ili9320_WriteRegister(0x10,0x5660);
     ili9320_Delay(15);
     ili9320_WriteRegister(0x13,0x2A4E);
     ili9320_WriteRegister(0x01,0x0100);
     ili9320_WriteRegister(0x02,0x0300);
 
     ili9320_WriteRegister(0x03,0x1030);
//     ili9320_WriteRegister(0x03,0x1038);
 
     ili9320_WriteRegister(0x08,0x0202);
     ili9320_WriteRegister(0x0A,0x0000);
     ili9320_WriteRegister(0x30,0x0000);
     ili9320_WriteRegister(0x31,0x0402);
     ili9320_WriteRegister(0x32,0x0106);
     ili9320_WriteRegister(0x33,0x0700);
     ili9320_WriteRegister(0x34,0x0104);
     ili9320_WriteRegister(0x35,0x0301);
     ili9320_WriteRegister(0x36,0x0707);
     ili9320_WriteRegister(0x37,0x0305);
     ili9320_WriteRegister(0x38,0x0208);
     ili9320_WriteRegister(0x39,0x0F0B);
     ili9320_Delay(15);
     ili9320_WriteRegister(0x41,0x0002);
     ili9320_WriteRegister(0x60,0x2700);
     ili9320_WriteRegister(0x61,0x0001);
     ili9320_WriteRegister(0x90,0x0119);
     ili9320_WriteRegister(0x92,0x010A);
     ili9320_WriteRegister(0x93,0x0004);
     ili9320_WriteRegister(0xA0,0x0100);
//     ili9320_WriteRegister(0x07,0x0001);
     ili9320_Delay(15);
//     ili9320_WriteRegister(0x07,0x0021);
     ili9320_Delay(15);
//     ili9320_WriteRegister(0x07,0x0023);
     ili9320_Delay(15);
//     ili9320_WriteRegister(0x07,0x0033);
     ili9320_Delay(15);
     ili9320_WriteRegister(0x07,0x0133);
     ili9320_Delay(15);
     ili9320_WriteRegister(0xA0,0x0000);
     ili9320_Delay(20);
 }      
  for(i=50000;i>0;i--);
  ili9320_Clear(0x00f8);
  ili9320_Clear(0xf800);
}
/****************************************************************************
* 名    称:void ili9320_SetCursor(u16 x,u16 y)
* 功    能:设置屏幕座标
* 入口参数:x      行座标
*           y      列座标
* 出口参数:无
* 说    明:
* 调用方法:ili9320_SetCursor(10,10);
****************************************************************************/
__inline void ili9320_SetCursor(u16 x,u16 y)
{
 if(DeviceCode==0x8989)
 {
   ili9320_WriteRegister(0x004e,y);        //行
     ili9320_WriteRegister(0x004f,319-x);  //列
 }
 else if(DeviceCode==0x9919)
 {
  ili9320_WriteRegister(0x004e,x); // 行
    ili9320_WriteRegister(0x004f,y); // 列 
 }
 else
 {
    ili9320_WriteRegister(0x0020,y); // 行
    ili9320_WriteRegister(0x0021,319-x); // 列
 }
}
/****************************************************************************
* 名    称:void ili9320_SetWindows(u16 StartX,u16 StartY,u16 EndX,u16 EndY)
* 功    能:设置窗口区域
* 入口参数:StartX     行起始座标
*           StartY     列起始座标
*           EndX       行结束座标
*           EndY       列结束座标
* 出口参数:无
* 说    明:
* 调用方法:ili9320_SetWindows(0,0,100,100);
****************************************************************************/
__inline void ili9320_SetWindows(u16 StartX,u16 StartY,u16 EndX,u16 EndY)
{
  ili9320_SetCursor(StartX,StartY);
  ili9320_WriteRegister(0x0050, StartX);
  ili9320_WriteRegister(0x0052, StartY);
  ili9320_WriteRegister(0x0051, EndX);
  ili9320_WriteRegister(0x0053, EndY);
 
}
/****************************************************************************
* 名    称:void ili9320_Clear(u16 dat)
* 功    能:将屏幕填充成指定的颜色,如清屏,则填充 0xffff
* 入口参数:dat      填充值
* 出口参数:无
* 说    明:
* 调用方法:ili9320_Clear(0xffff);
****************************************************************************/
void ili9320_Clear(u16 dat)
{
  u32  i;
  ili9320_SetCursor(0x0000, 0x0000); 
  Clr_Cs;
  ili9320_WriteIndex(0x0022);
  Set_Rs;  
  ili9320_WriteData(dat);
  for(i=0;i<76800;i++)
  {
 Clr_nWr;
 Set_nWr;
  }
  Set_Cs;
}
/****************************************************************************
* 名    称:u16 ili9320_GetPoint(u16 x,u16 y)
* 功    能:获取指定座标的颜色值
* 入口参数:x      行座标
*           y      列座标
* 出口参数:当前座标颜色值
* 说    明:
* 调用方法:i=ili9320_GetPoint(10,10);
****************************************************************************/
u16 ili9320_GetPoint(u16 x,u16 y)
{
  u16 temp;
  ili9320_SetCursor(x,y);
  Clr_Cs;
  ili9320_WriteIndex(0x0022);
   Clr_nRd; 
 temp = ili9320_ReadData(); //dummy
   Set_nRd;  
   Clr_nRd; 
 temp = ili9320_ReadData();
   Set_nRd; 
   Set_Cs;
   if(DeviceCode!=0x7783)
      temp=ili9320_BGR2RGB(temp);
   return (temp);
}
/****************************************************************************
* 名    称:void ili9320_SetPoint(u16 x,u16 y,u16 point)
* 功    能:在指定座标画点
* 入口参数:x      行座标
*           y      列座标
*           point  点的颜色
* 出口参数:无
* 说    明:
* 调用方法:ili9320_SetPoint(10,10,0x0fe0);
****************************************************************************/
void ili9320_SetPoint(u16 x,u16 y,u16 point)
{
  if ( (x>320)||(y>240) ) return;
  ili9320_SetCursor(x,y);
  Clr_Cs;
  ili9320_WriteIndex(0x0022);
  Set_Rs;
  ili9320_WriteData(point);
  Clr_nWr;Set_nWr;
  Set_Cs;
}

/****************************************************************************
* 名    称:u16 ili9320_BGR2RGB(u16 c)
* 功    能:RRRRRGGGGGGBBBBB 改为 BBBBBGGGGGGRRRRR 格式
* 入口参数:c      BRG 颜色值
* 出口参数:RGB 颜色值
* 说    明:内部函数调用
* 调用方法:
****************************************************************************/
u16 ili9320_BGR2RGB(u16 c)
{
  u16  r, g, b, rgb;
  b = (c>>0)  & 0x1f;
  g = (c>>5)  & 0x3f;
  r = (c>>11) & 0x1f;
 
  rgb =  (b<<11) + (g<<5) + (r<<0);
  return( rgb );
}
/****************************************************************************
* 名    称:void ili9320_WriteIndex(u16 idx)
* 功    能:写 ili9320 控制器寄存器地址
* 入口参数:idx   寄存器地址
* 出口参数:无
* 说    明:调用前需先选中控制器,内部函数
* 调用方法:ili9320_WriteIndex(0x0000);
****************************************************************************/
__inline void ili9320_WriteIndex(u16 idx)
{
    Clr_Rs;
 Set_nRd;
 ili9320_WriteData(idx);
 Clr_nWr;
 Set_nWr;
 Set_Rs;
}
/****************************************************************************
* 名    称:void ili9320_WriteData(u16 dat)
* 功    能:写 ili9320 寄存器数据
* 入口参数:dat     寄存器数据
* 出口参数:无
* 说    明:向控制器指定地址写入数据,调用前需先写寄存器地址,内部函数
* 调用方法:ili9320_WriteData(0x1030)
****************************************************************************/
void ili9320_WriteData(u16 data)
{
 GPIOB->ODR=((GPIOB->ODR&0x00ff)|(data<<8));
 GPIOC->ODR=((GPIOC->ODR&0xff00)|(data>>8));
}
/****************************************************************************
* 名    称:u16 ili9320_ReadData(void)
* 功    能:读取控制器数据
* 入口参数:无
* 出口参数:返回读取到的数据
* 说    明:内部函数
* 调用方法:i=ili9320_ReadData();
****************************************************************************/
__inline u16 ili9320_ReadData(void)
{
//========================================================================
// **                                                                    **
// ** nCS       ----\__________________________________________/-------  **
// ** RS        ------\____________/-----------------------------------  **
// ** nRD       -------------------------\_____/---------------------  **
// ** nWR       --------\_______/--------------------------------------  **
// ** DB[0:15]  ---------[index]----------[data]-----------------------  **
// **                                                                    **
//========================================================================
 u16 tmp;
 GPIOB->CRH = (GPIOB->CRH & 0x00000000) | 0x44444444;
 GPIOC->CRL = (GPIOC->CRL & 0x00000000) | 0x44444444;
 tmp = (((GPIOB->IDR)>>8)|((GPIOC->IDR)<<8));
 GPIOB->CRH = (GPIOB->CRH & 0x00000000) | 0x33333333;
 GPIOC->CRL = (GPIOC->CRL & 0x00000000) | 0x33333333;
 return tmp;
}
/****************************************************************************
* 名    称:u16 ili9320_ReadRegister(u16 index)
* 功    能:读取指定地址寄存器的值
* 入口参数:index    寄存器地址
* 出口参数:寄存器值
* 说    明:内部函数
* 调用方法:i=ili9320_ReadRegister(0x0022);
****************************************************************************/
__inline u16 ili9320_ReadRegister(u16 index)
{
   Clr_Cs;
 ili9320_WriteIndex(index);
 Clr_nRd;    
 index = ili9320_ReadData();
 Set_nRd;       
 Set_Cs;
 return index;
}
/****************************************************************************
* 名    称:void ili9320_WriteRegister(u16 index,u16 dat)
* 功    能:写指定地址寄存器的值
* 入口参数:index    寄存器地址
*         :dat      寄存器值
* 出口参数:无
* 说    明:内部函数
* 调用方法:ili9320_WriteRegister(0x0000,0x0001);
****************************************************************************/
__inline void ili9320_WriteRegister(u16 index,u16 dat)
{
 /************************************************************************
  **                                                                    **
  ** nCS       ----\__________________________________________/-------  **
  ** RS        ------\____________/-----------------------------------  **
  ** nRD       -------------------------------------------------------  **
  ** nWR       --------\_______/--------\_____/-----------------------  **
  ** DB[0:15]  ---------[index]----------[data]-----------------------  **
  **                                                                    **
  ************************************************************************/
    Clr_Cs;
 Clr_Rs;
 Set_nRd;
 ili9320_WriteData(index);
   Clr_nWr;
 Set_nWr;
 Set_Rs;      
 ili9320_WriteData(dat); 
 Clr_nWr;
 Set_nWr;
 Set_Cs;
}
/****************************************************************************
* 名    称:void ili9320_Reset()
* 功    能:复位 ili9320 控制器
* 入口参数:无
* 出口参数:无
* 说    明:复位控制器,内部函数
* 调用方法:ili9320_Reset()
****************************************************************************/
void ili9320_Reset()
{
  /***************************************
   **                                   **
   **  -------\______________/-------   **
   **         | <---Tres---> |          **
   **                                   **
   **  Tres: Min.1ms                    **
   ***************************************/
   
   Set_Rst;;
    ili9320_Delay(50000);
   Clr_Rst;
    ili9320_Delay(50000);
   Set_Rst;
    ili9320_Delay(50000);
}
/****************************************************************************
* 名    称:void ili9320_BackLight(u8 status)
* 功    能:开、关液晶背光
* 入口参数:status     1:背光开  0:背光关
* 出口参数:无
* 说    明:
* 调用方法:ili9320_BackLight(1);
****************************************************************************/
void ili9320_BackLight(u8 status)
{
  if ( status >= 1 )
  {
    Lcd_Light_ON;
  }
  else
  {
    Lcd_Light_OFF;
  }
}
/****************************************************************************
* 名    称:void ili9320_Delay(vu32 nCount)
* 功    能:延时
* 入口参数:nCount   延时值
* 出口参数:无
* 说    明:
* 调用方法:ili9320_Delay(10000);
****************************************************************************/
void ili9320_Delay(vu32 nCount)
{
  for(; nCount != 0; nCount--);
}

void GUI_Point(INT16U x,INT16U y)
{
  if ( (x>320)||(y>240) ) return;
  ili9320_SetCursor(x,y);
  Clr_Cs;
  ili9320_WriteIndex(0x0022);
  Set_Rs;
  ili9320_WriteData(POINT_COLOR);
  Clr_nWr;Set_nWr;
  Set_Cs;
}
 //画线
//x1,y1:起点坐标
//x2,y2:终点坐标 
void GUI_Line(INT16U x0, INT16U y0,INT16U x1,INT16U y1)
{
    u16 x,y;
  u16 dx;// = abs(x1 - x0);
  u16 dy;// = abs(y1 - y0);
 if(y0==y1)
 {
  if(x0<=x1)
  {
   x=x0;
  }
  else
  {
   x=x1;
   x1=x0;
  }
    while(x <= x1)
    {
      ili9320_SetPoint(x,y0,POINT_COLOR);
      x++;
    }
    return;
 }
 else if(y0>y1)
 {
  dy=y0-y1;
 }
 else
 {
  dy=y1-y0;
 }
 
  if(x0==x1)
 {
  if(y0<=y1)
  {
   y=y0;
  }
  else
  {
   y=y1;
   y1=y0;
  }
    while(y <= y1)
    {
      ili9320_SetPoint(x0,y,POINT_COLOR);
      y++;
    }
    return;
 }
 else if(x0 > x1)
  {
  dx=x0-x1;
    x = x1;
    x1 = x0;
    y = y1;
    y1 = y0;
  }
  else
  {
  dx=x1-x0;
    x = x0;
    y = y0;
  }
  if(dx == dy)
  {
    while(x <= x1)
    {
      x++;
   if(y>y1)
   {
    y--;
   }
   else
   {
       y++;
   }
      ili9320_SetPoint(x,y,POINT_COLOR);
    }
  }
  else
  {
   ili9320_SetPoint(x, y, POINT_COLOR);
    if(y < y1)
    {
      if(dx > dy)
      {
       s16 p = dy * 2 - dx;
       s16 twoDy = 2 * dy;
       s16 twoDyMinusDx = 2 * (dy - dx);
       while(x < x1)
       {
         x++;
         if(p < 0)
         {
           p += twoDy;
         }
         else
         {
           y++;
           p += twoDyMinusDx;
         }
         ili9320_SetPoint(x, y,POINT_COLOR);
       }
      }
      else
      {
       s16 p = dx * 2 - dy;
       s16 twoDx = 2 * dx;
       s16 twoDxMinusDy = 2 * (dx - dy);
       while(y < y1)
       {
         y++;
         if(p < 0)
         {
           p += twoDx;
         }
         else
         {
           x++;
           p+= twoDxMinusDy;
         }
         ili9320_SetPoint(x, y, POINT_COLOR);
       }
      }
    }
    else
    {
      if(dx > dy)
      {
       s16 p = dy * 2 - dx;
       s16 twoDy = 2 * dy;
       s16 twoDyMinusDx = 2 * (dy - dx);
       while(x < x1)
       {
         x++;
         if(p < 0)
         {
           p += twoDy;
         }
         else
         {
           y--;
           p += twoDyMinusDx;
         }
         ili9320_SetPoint(x, y,POINT_COLOR);
       }
      }
      else
      {
       s16 p = dx * 2 - dy;
       s16 twoDx = 2 * dx;
       s16 twoDxMinusDy = 2 * (dx - dy);
       while(y1 < y)
       {
         y--;
         if(p < 0)
         {
           p += twoDx;
         }
         else
         {
           x++;
           p+= twoDxMinusDy;
         }
         ili9320_SetPoint(x, y,POINT_COLOR);
       }
      }
    }
  }
}
//画矩形
void GUI_Rectangle(INT16U x1, INT16U y1, INT16U x2, INT16U y2)
{
 GUI_Line(x1,y1,x2,y1);
 GUI_Line(x1,y1,x1,y2);
 GUI_Line(x1,y2,x2,y2);
 GUI_Line(x2,y1,x2,y2);
}
//在指定位置画一个指定大小的圆
//(x,y):中心点
//r    :半径
void GUI_Circle(INT16U x0,INT16U y0,INT16U r)
{
 int a,b;
 int di;
 a=0;
 b=r;
 di=3-2*r;             //判断下个点位置的标志
 while(a<=b)
 {
  GUI_Point(x0-b,y0-a);             //3          
  GUI_Point(x0+b,y0-a);             //0          
  GUI_Point(x0-a,y0+b);             //1      
  GUI_Point(x0-b,y0-a);             //7          
  GUI_Point(x0-a,y0-b);             //2            
  GUI_Point(x0+b,y0+a);             //4              
  GUI_Point(x0+a,y0-b);             //5
  GUI_Point(x0+a,y0+b);             //6
  GUI_Point(x0-b,y0+a);            
  a++;
  /***使用Bresenham算法画圆**/    
  if(di<0)di +=4*a+6;  
  else
  {
   di+=10+4*(a-b);  
   b--;
  }
  GUI_Point(x0+a,y0+b);
 }
}
/****************************************************************************
* 名    称:void ili9320_DrawPicture(u16 StartX,u16 StartY,u16 EndX,u16 EndY,u16 *pic)
* 功    能:在指定座标范围显示一副图片
* 入口参数:StartX     行起始座标
*           StartY     列起始座标
*           EndX       行结束座标
*           EndY       列结束座标
            pic        图片头指针
* 出口参数:无
* 说    明:图片取模格式为水平扫描,16位颜色模式
* 调用方法:ili9320_DrawPicture(0,0,100,100,(u16*)demo);
****************************************************************************/
void ili9320_DrawPicture(u16 StartX,u16 StartY,u16 EndX,u16 EndY,u16 *pic)
{
  u16  i;
  ili9320_SetWindows(StartX,StartY,EndX,EndY);
  ili9320_SetCursor(StartX,StartY);
 
  Clr_Cs;
  ili9320_WriteIndex(0x0022);
  Set_Rs;
  for (i=0;i<(EndX*EndY);i++)
  {
      ili9320_WriteData(*pic++);
   Clr_nWr;Set_nWr;
  }
     
  Set_Cs;
}
/****************************************************************************
* 名    称:void ili9320_PutChar(u16 x,u16 y,u8 c,u16 charColor,u16 bkColor)
* 功    能:在指定座标显示一个8x16点阵的ascii字符
* 入口参数:x          行座标
*           y          列座标
*           charColor  字符的颜色
*           bkColor    字符背景颜色
* 出口参数:无
* 说    明:显示范围限定为可显示的ascii码
* 调用方法:ili9320_PutChar(10,10,'a',0x0000,0xffff);
****************************************************************************/
void ili9320_PutChar(u16 x,u16 y,u8 c,u16 charColor,u16 bkColor)
{
  u16 i=0;
  u16 j=0;
 
  u8 tmp_char=0;
  for (i=0;i<16;i++)
  {
    tmp_char=ascii_8x16[((c-0x20)*16)+i];
    for (j=0;j<8;j++)
    {
      if ( (tmp_char >> 7-j) & 0x01 == 0x01)
        {
          ili9320_SetPoint(x+j,y+i,charColor); // 字符颜色
        }
        else
        {
          ili9320_SetPoint(x+j,y+i,bkColor); // 背景颜色
        }
    }
  }
}
/****************************************************************************
* 名    称:void GUI_Text(u16 x, u16 y, u8 *str, u16 len,u16 Color, u16 bkColor)
* 功    能:在指定座标显示字符串
* 入口参数:x      行座标
*           y      列座标
*           *str   字符串
*           len    字符串长度
*           Color  字符颜色
*           bkColor字符背景颜色
* 出口参数:无
* 说    明:
* 调用方法:GUI_Text(0,0,"0123456789",10,0x0000,0xffff);
****************************************************************************/
void GUI_Text(u16 x, u16 y, u8 *str, u16 len,u16 Color, u16 bkColor)
{
  u8 i;
 
  for (i=0;i<len;i++)
  {
    ili9320_PutChar((x+8*i),y,*str++,Color,bkColor);
  }
}

FATFS文件系统的官网为:
主要是熟悉下面函数的用法:

FatFs module provides following functions to the applications. In other words, this list describes what FatFs can do to access the FAT volumes.

文件系统移植好后,只要会用上面的函数就可以实现相应的功能了。

主程序文件:


/************************************************************
**实验名称:SD
**功能:测试SD卡,
**注意事项:系统直接集成TFF文件系统,把SD卡上/BWSTDO/test.txt文件的字符通过串口打印出来,做此实验前请先
   确保SD卡上有BWSTDO目录并且目录中有test.txt文件,TXT文件内可以随意写上你要写的字符串.
**版本:V1.0
**日期:2010.9.20
*************************************************************/
//硬件环境: MINI STM32
//软甲环境: MDK
//SD卡管脚: SCLK   A5
//           MOSI   A7
//    MISO   A6
//    SD_CS   B6
//按键管脚: MINI STM32 S1按键 A3
//串口管脚: MINI STM32 A9(TX)   A10(RX)
//邮箱:number007cool@163.com
#include "STM32Lib\\stm32f10x.h"
#include "hal.h"
#include "sys.h"
#include "ili9320.h"
#include "integer.h"
#include "gps.h"
#include "delay.h"
extern void Draw_Picture(u16 x,u16 y,char filename[]);
void TestBoard(void);
//char filename[26][11]={"1.bmp","2.bmp","3.bmp","4.bmp","5.bmp","6.bmp","7.bmp","8.bmp","9.bmp","10.bmp","11.bmp","12.bmp","13.bmp","14.bmp","15.bmp","16.bmp","17.bmp","18.bmp","19.bmp","20.bmp","21.bmp","22.bmp","23.bmp","24.bmp","25.bmp"};
char name[7];
int main(void)
{
    alt_u8 dis_buff1[16];
 alt_u8 dis_buff2[16];
 alt_u8 dis_buff3[16];
  gps_save_info GPS_info;

 ChipHalInit();   //片内硬件初始化
 ChipOutHalInit();  //片外硬件初始化
 ili9320_Initializtion();
 ili9320_Clear(0);
    POINT_COLOR=0x0000;
 BACK_COLOR = 0;


  //LED1_OFF;
  //LED2_OFF;
  
 USART1_Puts("\r\n Please input the card and confirm file put in /text/test.txt \r\n");
 TurnToSD();
 USART1_Puts("\r\n push the left key to test!\r\n");
  Draw_Picture(0,0,"11.bmp");
  delay_ms(1000);
  Draw_Picture(0,0,"28.bmp");
  delay_ms(1000);
  Draw_Picture(0,0,"49.bmp");
  delay_ms(1000);
 for(;;)
 {
 //if(GET_LEFT()==0)//按MINI STM32上面s1键  就读取根目录BWSTDO 文件夹下面的test.txt文件
  { u8 x;
     //TestSD();
  //USART1_Puts("\r\n");
  //Draw_Picture(0,0,"19.bmp");
  //Pic_Viewer();
  for(x=1;x<100;x++)
  {
   ili9320_Clear(Black);
   if(x<10)
   {
   name[0]=x%10+'0';
   name[1]='.';
   name[2]='b';
   name[3]='m';
   name[4]='p';
   name[5]='\0';
  
   }
   else if(x<100)
   {
   name[0]=x/10+'0';
   name[1]=x%10+'0';
   name[2]='.';
   name[3]='b';
   name[4]='m';
   name[5]='p';
   name[6]='\0';
   }
   Draw_Picture(0,0,name); 
   /*
   if(x<10)
    GUI_Text(0,line14,name,sizeof(name)-2,Red,0x1234);
   else if(x<100)
    GUI_Text(0,line14,name,sizeof(name)-1,Red,0x1234);
   gps_get_gps_save_info(&GPS_info);
   //itoa(GPS_info.weidu,str_w,10);
         lcd_get_data_from_gps_save_info(dis_buff1,dis_buff2,dis_buff3,GPS_info);
   GUI_Text(0,0,dis_buff1,sizeof(dis_buff1),Red,0x1234);
   GUI_Text(0,16,dis_buff2,sizeof(dis_buff2),Red,0x1234);
   GUI_Text(0,32,dis_buff3,sizeof(dis_buff3),Red,0x1234);
   GUI_Text(0,64,high,sizeof(high),Red,0x1234);
   GUI_Text(0,80,speed,sizeof(speed),Red,0x1234);
   GUI_Text(0,96,angle,sizeof(angle),Red,0x1234);
   */
   delay_ms(1000);
  }
  
  }
 }

}

整个工程如下:

文件: SD卡文件系统.rar
大小: 330KB
下载: 下载

上面的程序稍作修改就可分别实现下面两项功能:

1、gps解码并在彩屏上显示。

2、把sd卡中的txt文件读出,通过串口发送给上位机。(可以发送中文,不过要采用sscom软件或者自己编写的基于mscomm控件的串口上位机程序)


 

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP