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控件的串口上位机程序)
|