📄 sd_card.c
字号:
/******************************************************************
*Project :ATmega128 + tft320x240 + SD card + USART
*Author :Andy Zhu ---Digital Photo Frame(数码相框)
*Date :10.1-2008
*Other : None
******************************************************************/
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdint.h>
//#include<stdio.h>
#include "sd.h"
#include "spi.h"
#include "tft.h"
#include "touch.h"
#include "usart.h"
#include "fat.h"
//#include "cortex.h"
//#include "me.h"
//#include "battery.h"
//#include "signal.h"
//#include "sd_ico.h"
//#include "stm32_cover.h"
//#include "picture2.h"
//#include "pic_temp.h"
//#include<AsciiLib.h>
//#include<Chinese.h>
//#include "girl.h"
//extern CID_Reg SD_CID_infor;
#define TRUE 1
#define FALSE 0
//void GetFileInfor(unsigned char *DIR_BUF);
uint8_t Reg_Buf[512];
uint8_t FAT_Buf[512];
extern CID_Reg SD_CID_infor;
extern CSD_Reg SD_CSD_infor;
extern OCR_Reg SD_OCR_infor;
extern SCR_Reg SD_SCR_infor;
extern BPB_STR FAT32_BPB_infor;
extern DIR_SHORT_STR FAT32_DIR_infor;
extern VOLUME_INFO_TYPE SD_CAPACITY_infor;
int8_t VolumeName[9];
uint8_t File_read_complete; //文件读完标志
unsigned char DIR_Buffer[32];
extern uint32_t FirstSecNum; //逻辑扇区0
extern uint32_t FirstRootDirSecNum; //根目录决定扇区数
uint32_t FileSec; //文件所在决定物理扇区号
uint32_t FAT_offset_sec; //相当于FAT1的偏移扇区数
uint32_t FAT_infor; //FAT簇链的内容
uint32_t FAT_infor_next; //下一个FAT项的内容
uint16_t FAT_offset_bytes; //FAT项在一个扇区中的偏移量
uint16_t File_Spare_bytes; //最后一个簇里剩余的字节数
uint32_t TFT_count; //液晶整幅图片占用字节数153600
uint16_t Color_data; //液晶16bit的数据
//=================================
int main(void)
{
unsigned char STATE = 0;
uint16_t i;
uint8_t j;
//uint32_t temp;
DDRB |= (1<<RS)|(1<<CS)|(1<<MOSI)|(1<<SCK)|(1<<RES); //OUTPUT MODE
SPI_init();
Clr_RES();
DelayNS(200);
Set_RES();
lcd_init();
USART_init();
DispOneColor(BLUE);
//------------------------------------------
DelayNS(300);
send_command(0x22);
DrawString(70,0, "ATMEL AVR", RED, BLUE, NORMAL);
DrawString(0,16, "Mega128<==>TFT320x240 Demo", RED, BLUE, NORMAL);
while(1)
{
asm("nop");
send_command(0x22);
DrawString(0,48, "SD card testing!", YELLOW, BLUE, NORMAL);
DrawString(0,64, "Initialize SD card...", YELLOW, BLUE, NORMAL);
SD_Init();
STATE = SD_Reset();
if (STATE == 0)
{
DrawString(0,80, "SD card Init succeed!", GREEN, BLUE, NORMAL);
}
else
{
DrawString(0,80, "SD card is ERROR!", GREEN, BLUE, NORMAL);
}
STATE = Read_SD_Reg(Reg_Buf,SD_SEND_CID,16);
if (STATE == 0)
{
DrawString(0,96, "CID Register read succeed!", GREEN, BLUE, NORMAL);
Get_SD_card_CID_Infor(Reg_Buf);
}
else
{
DrawString(0,96, "CID Register read ERROR!", GREEN, BLUE, NORMAL);
}
asm("nop");
STATE = Read_SD_Reg(Reg_Buf,SD_SEND_CSD,16);
if (STATE == 0)
{
DrawString(0,112, "CSD Register read succeed!", GREEN, BLUE, NORMAL);
Get_SD_card_CSD_Infor(Reg_Buf);
}
else
{
DrawString(0,112, "CSD Register read ERROR!", GREEN, BLUE, NORMAL);
}
asm("nop");
STATE = Read_SD_Reg(Reg_Buf,SD_READ_OCR,4);
if (STATE == 0)
{
DrawString(0,128, "OCR Register read succeed!", GREEN, BLUE, NORMAL);
Get_SD_card_OCR_Infor(Reg_Buf);
}
else
{
DrawString(0,128, "OCR Register read ERROR!", GREEN, BLUE, NORMAL);
}
asm("nop");
asm("nop");
STATE = Read_SD_Reg(Reg_Buf,SD_APP_CMD,0);
STATE = Read_SD_Reg(Reg_Buf,SD_SEND_SCR_APP,8);
if (STATE == 0)
{
DrawString(0,144, "SCR Register read succeed!", GREEN, BLUE, NORMAL);
Get_SD_card_SCR_Infor(Reg_Buf);
}
else
{
DrawString(0,144, "SCR Register read ERROR!", GREEN, BLUE, NORMAL);
}
asm("nop");
Get_SD_card_Volume_Infor();
DrawString(0,160, "SD Capacity is: MB", GREEN, BLUE, NORMAL);
DispNum(120,160, SD_CAPACITY_infor.size_MB);
//--------------------------------------------------
Get_FAT_BPB_Infor();//---读取启动扇区(DBR)中BPB的相关信息
//====================计算根目录的绝对扇区号======================================
FirstRootDirSecNum = Calculate_FirstRootDirSecNum();
/*
USART_Send_string("\n<====读取根目录的首个扇区!=====>\n");
SD_ReadSingleBlock(FirstRootDirSecNum,Reg_Buf); //读取根目录的首个扇区
for(i=0; i<512; i++)
{
USART_Putchar(Reg_Buf[i]);
}
_delay_ms(100);
USART_Send_string("\n<====根目录的首个扇区发送完毕!//=====>\n");
//---读取一个文件的相关信息------
for (j=0; j<32; j++)
{
DIR_Buffer[j] = Reg_Buf[32*14+j]; //读取指定文件的文件信息
}
GetFileInfor(DIR_Buffer,&FAT32_DIR_infor); //得到指定文件的相关信息
_delay_ms(100);
*/
/*
//------------串口输出短文件名-----------------
for (j=0; j<8; j++)//输出短文件名+'.'
{
if (FAT32_DIR_infor.DIR_Name[j] != 0x20)
USART_Putchar(FAT32_DIR_infor.DIR_Name[j]);
else
{
USART_Putchar('.');
break;
}
}
for (j=0; j<3; j++)//输出扩展名
{
if (FAT32_DIR_infor.DIR_ExtName[j] != 0x20)
USART_Putchar(FAT32_DIR_infor.DIR_ExtName[j]);
else
break;
}
USART_Putchar('\n');
USART_Putchar('\n');
*/
/*
//----------通过串口发送整个的指定文件到PC-------
FAT_infor = FAT32_DIR_infor.DIR_FstClus; //文件所在首簇号
File_read_complete = FALSE;
do
{
//查找FAT1项中的相关簇链数据
//FAT_offset_sec = (FAT32_DIR_infor.DIR_FstClus << 2) / 512;
//FAT_offset_sec = FAT32_DIR_infor.DIR_FstClus >> 7;
FAT_offset_sec = FAT_infor >> 7;
FAT_offset_bytes = (uint16_t)(FAT_infor << 2) % 512;
SD_ReadSingleBlock((FirstSecNum + FAT_offset_sec + FAT32_BPB_infor.BPB_ResSec),FAT_Buf); //读FAT文件
FAT_infor_next = FAT_Buf[FAT_offset_bytes + 3];
FAT_infor_next <<= 8;
FAT_infor_next |= FAT_Buf[FAT_offset_bytes + 2];
FAT_infor_next <<= 8;
FAT_infor_next |= FAT_Buf[FAT_offset_bytes + 1];
FAT_infor_next <<= 8;
FAT_infor_next |= FAT_Buf[FAT_offset_bytes]; //已经读到文件所在的下一个簇的簇号或其他信息
if (FAT_infor_next == 0x0fffffFf) //是文件的最后一簇
{
FileSec = (FAT_infor - 2)*FAT32_BPB_infor.BPB_SecPerClus + FirstRootDirSecNum;
//计算最后一簇中剩余的字节数
File_Spare_bytes = FAT32_DIR_infor.DIR_FileSize % (FAT32_BPB_infor.BPB_BytesPerSec*FAT32_BPB_infor.BPB_SecPerClus);
for (j=0; j<FAT32_BPB_infor.BPB_SecPerClus; j++)
{
SD_ReadSingleBlock(FileSec + j,Reg_Buf); //读文件
if (j < File_Spare_bytes/512) //剩余的的字节数超过一个扇区
{
for(i=0; i<512; i++) //串口输出读到的一个扇区数据
{
USART_Putchar(Reg_Buf[i]);
}
}
if (j == File_Spare_bytes/512) //剩余的字节数不足一个扇区
{
for(i=0; i<File_Spare_bytes%512; i++) //串口输出读到的不足一个扇区数据
{
USART_Putchar(Reg_Buf[i]);
}
break;
}
}
USART_Putchar('\n');
File_read_complete = TRUE;
}
else
{
FileSec = (FAT_infor - 2)*FAT32_BPB_infor.BPB_SecPerClus + FirstRootDirSecNum;
for (j=0; j<FAT32_BPB_infor.BPB_SecPerClus; j++)
{
SD_ReadSingleBlock(FileSec + j,Reg_Buf); //读文件
for(i=0; i<512; i++) //串口输出读到的第一个扇区数据
{
USART_Putchar(Reg_Buf[i]);
}
}
FAT_infor = FAT_infor_next;
}
}while(File_read_complete == FALSE);
*/
//FAT_infor = FAT_Get_File_FirCluNum("\\PIC1.HA");
//-----------读取SD卡中的字模,并用液晶显示--------
//FAT_infor = FAT32_DIR_infor.DIR_FstClus; //文件所在首簇号
//FAT_infor = 0x000000C2; //---pic2
//FAT_infor = 0x00000003; //---pic1
//FAT_infor = FAT_Get_File_FirCluNum("\\PIC1.BIN");
//FAT_infor = FAT_Get_File_FirCluNum("\\PIC2.BIN");
FAT_infor = FAT_Get_File_FirCluNum("\\CORTEX.BIN");
//FAT_infor = FAT_Get_File_FirCluNum("\\GIRL_1.BIN");
//FAT_infor = FAT_Get_File_FirCluNum("\\ME_1.BIN");
//FAT_infor = FAT_Get_File_FirCluNum("\\IMAGES\\PIC2.BIN");
File_read_complete = FALSE;
TFT_count = 0;
write_com(0x0021,0); //行首址0
write_com(0x0020,0); //列首址0
send_command(0x22);
do
{
//查找FAT1项中的相关簇链数据
FAT_offset_sec = FAT_infor >> 7;
FAT_offset_bytes = (uint16_t)(FAT_infor << 2) % 512;
SD_ReadSingleBlock((FirstSecNum + FAT_offset_sec + FAT32_BPB_infor.BPB_ResSec),FAT_Buf); //读FAT文件
FAT_infor_next = FAT_Buf[FAT_offset_bytes + 3];
FAT_infor_next <<= 8;
FAT_infor_next |= FAT_Buf[FAT_offset_bytes + 2];
FAT_infor_next <<= 8;
FAT_infor_next |= FAT_Buf[FAT_offset_bytes + 1];
FAT_infor_next <<= 8;
FAT_infor_next |= FAT_Buf[FAT_offset_bytes]; //已经读到文件所在的下一个簇的簇号或其他信息
if (FAT_infor_next == 0x0fffffFf) //是文件的最后一簇
{
FileSec = (FAT_infor - 2)*FAT32_BPB_infor.BPB_SecPerClus + FirstRootDirSecNum;
//计算最后一簇中剩余的字节数
File_Spare_bytes = FAT32_DIR_infor.DIR_FileSize % (FAT32_BPB_infor.BPB_BytesPerSec*FAT32_BPB_infor.BPB_SecPerClus);
for (j=0; j<FAT32_BPB_infor.BPB_SecPerClus; j++)
{
SD_ReadSingleBlock(FileSec + j,Reg_Buf); //读文件
if (File_Spare_bytes == 0)
{
for(i=0; i<512; i+=2,TFT_count+=2) //
{
Color_data = Reg_Buf[i+1];
Color_data <<= 8;
Color_data |= Reg_Buf[i];
send_data(Color_data);
}
}
}
USART_Putchar('\n');
File_read_complete = TRUE;
}
else
{
FileSec = (FAT_infor - 2)*FAT32_BPB_infor.BPB_SecPerClus + FirstRootDirSecNum;
for (j=0; j<FAT32_BPB_infor.BPB_SecPerClus; j++)
{
SD_ReadSingleBlock(FileSec + j,Reg_Buf); //读文件
for(i=0; i<512; i+=2,TFT_count+=2) //
{
Color_data = Reg_Buf[i+1];
Color_data <<= 8;
Color_data |= Reg_Buf[i];
send_data(Color_data);
}
}
FAT_infor = FAT_infor_next;
}
}while(File_read_complete == FALSE);
//-------------------------------------------------
while (1)
{
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
}
}
//-----------------------------------------------------------
//-----------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -