⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sd_card.c

📁 avr+TFT+SD卡实现数码相框功能
💻 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 + -