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

📄 blinky1.c

📁 mp3量不要让站长把时间都花费在为您修正说明上。压缩包解压时不能有密码。系统会自动删除debug和release目录
💻 C
📖 第 1 页 / 共 5 页
字号:
#define CMD33_R 1

/* 擦除所选择的块 Erase the selected write blocks */
#define CMD38 38
#define CMD38_R 2

/***************************** 锁卡命令 Lock Card commands ***************************/
/* 设置/复位密码或上锁/解锁卡 Set/reset the password or lock/unlock the card */
#define CMD42 42
#define CMD42_R	2
/* Commands from 42 to 54, not defined here */

/***************************** 应用命令 Application-specific commands ****************/
/* 禁止下一个命令为应用命令  Flag that the next command is application-specific */
#define CMD55 55
#define CMD55_R 1

/* 应用命令的通用I/O  General purpose I/O for application-specific commands */
#define CMD56 56
#define CMD56_R 1

/* 读OCR寄存器  Read the OCR (SPI mode only) */
#define CMD58 58
#define CMD58_R 4

/* 使能或禁止 CRC Turn CRC on or off */
#define CMD59 59
#define CMD59_R 1

/***************************** 应用命令 Application-specific commands ***************/
/* 获取 SD Status寄存器 Get the SD card's status */
#define ACMD13 13
#define ACMD13_R 3

/* 得到已写入卡中的块的个数 Get the number of written write blocks (Minus errors ) */
#define ACMD22 22
#define ACMD22_R 1

/* 在写之前,设置预先擦除的块的个数 Set the number of write blocks to be pre-erased before writing */
#define ACMD23 23
#define ACMD23_R 1

/* 读取OCR寄存器 Get the card's OCR (SD mode) */
#define ACMD41 41
#define ACMD41_R 1

/* 连接/断开CD/DATA[3]引脚上的上拉电阻 Connect or disconnect the 50kOhm internal pull-up on CD/DAT[3] */
#define ACMD42 42
#define ACMD42_R 1

/* 读取SCR寄存器 Get the SD configuration register */
#define ACMD51 51
#define ACMD51_R 1


//簇定义
#define MSDOSFSROOT     0               
#define CLUST_FREE      0               
#define MSDOSFSFREE     CLUST_FREE
#define CLUST_RSRVD     0xfffffff6      // 系统保留簇
#define CLUST_BAD       0xfffffff7      // 坏簇
#define CLUST_EOFS      0xfffffff8      // 第一个结束簇
#define CLUST_EOFE      0xffffffff      // 最后一个结束簇

#define FAT12_MASK      0x00000fff      // FAT12掩码
#define FAT16_MASK      0x0000ffff      // FAT16掩码
#define FAT32_MASK      0x0fffffff      // FAT32掩码

// 分区类型
#define PART_TYPE_UNKNOWN		0x00
#define PART_TYPE_FAT12			0x01
#define PART_TYPE_XENIX			0x02
#define PART_TYPE_DOSFAT16	    0x04
#define PART_TYPE_EXTDOS		0x05
#define PART_TYPE_FAT16			0x06
#define PART_TYPE_NTFS			0x07
#define PART_TYPE_FAT32			0x0B
#define PART_TYPE_FAT32LBA	    0x0C
#define PART_TYPE_FAT16LBA	    0x0E
#define PART_TYPE_EXTDOSLBA	    0x0F
#define PART_TYPE_ONTRACK		0x33
#define PART_TYPE_NOVELL		0x40
#define PART_TYPE_PCIX			0x4B
#define PART_TYPE_PHOENIXSAVE	0xA0
#define PART_TYPE_CPM		    0xDB
#define PART_TYPE_DBFS			0xE0
#define PART_TYPE_BBT			0xFF


#define ATTR_NORMAL     		0x00            // 读写
#define ATTR_READONLY   		0x01            // 只读
#define ATTR_HIDDEN     		0x02            // 隐藏
#define ATTR_SYSTEM     		0x04            // 系统文件
#define ATTR_VOLUME     		0x08            // 卷标文件
#define ATTR_LONG_FILENAME		0x0f			// 长文件名文件			    
#define ATTR_DIRECTORY  		0x10            // 子目录文件
#define ATTR_ARCHIVE    		0x20            // 归档文件

#define  SPI1_INIT()			PINSEL1 &= ~((0x03 << 2) + (0x03 << 4) + (0x03 << 6)); \
								PINSEL1 |=  (0x01 << 2) + (0x01 << 4) + (0x01 << 6);
//power  p0.09
//#define  SD_POWER				0	
//#define  SD_POWER_GPIO()		0
//#define  SD_POWER_OUT()			0
//#define  SD_POWER_OFF()			0
//#define  SD_POWER_ON()			0

//cs	 p0.21
#define  SPI1_CS      			(0x01 << 21)              	 	
#define  SPI1_CS_GPIO()			PINSEL1 &= ~(0x03 << 10)	 		
#define  SPI1_CS_OUT()			IO0DIR |= SPI1_CS			 
#define	 SPI1_CS_SET()			IO0SET |= SPI1_CS			
#define	 SPI1_CS_CLR()			IO0CLR |= SPI1_CS				

//sck	 p0.17
#define  SPI1_SCK				(0x01 << 17)						
#define  SPI1_SCK_GPIO()		PINSEL1 &= ~(0x03 << 2)		
#define  SPI1_SCK_OUT()			IO0DIR |= SPI1_SCK				
#define	 SPI1_SCK_SET()			IO0SET |= SPI1_SCK
#define	 SPI1_SCK_CLR()			IO0CLR |= SPI1_SCK			

//miso	 p0.18	
#define  SPI1_MISO				(0x01 << 18)						
#define  SPI1_MISO_GPIO()		PINSEL1 &= ~(0x03 << 4)			
#define  SPI1_MISO_OUT()		IO0DIR &=~(SPI1_MISO)
#define	 SPI1_MISO_SET()		IO0SET |= SPI1_MISO	
#define	 SPI1_MISO_CLR()		IO0CLR |= SPI1_MISO			

//mosi	 p0.19
#define  SPI1_MOSI				(0x01 << 19)
#define  SPI1_MOSI_GPIO()		PINSEL1 &= ~(0x03 << 6)			
#define  SPI1_MOSI_OUT()		IO0DIR |= SPI1_MOSI
#define	 SPI1_MOSI_SET()		IO0SET |= SPI1_MOSI	
#define	 SPI1_MOSI_CLR()		IO0CLR |= SPI1_MOSI			


												
	 
//INT8U IsMusicFile();
uint32  NextCluster;   		 	//指向当前正在读取文件的簇号
uint32  SectorIndex=0;   		//正在读扇区

uint8   reading;

////////////////////////////////////////////////////////////////////////////////
//磁盘分区信息
////////////////////////////////////////////////////////////////////////////////
INT8U	Partition_Active;				// 0x80代表该分区为缺省分区
INT8U	Partition_StartHead;			// 该分区入口的磁头地址
INT16U	Partition_StartCylSect;			// 该分区入口的扇区地址和柱面地址
INT8U	Partition_PartType;				// 该分区类型
INT8U	Partition_EndHead;				// 该分区结束的扇区地址
INT16U	Partition_EndCylSect;			// 该分区结束的柱面地址
INT32U	Partition_StartLBA;				// 该分区内第一个扇区地址
INT32U	Partition_Size;					// 该分区所包含的扇区总数



////////////////////////////////////////////////////////////////////////////////
//fat32 BPB结构,包括扩展BPB
////////////////////////////////////////////////////////////////////////////////
INT8U	BS_jmpBoot[3];					//jmp code
INT8U	BS_OEMName[8];					//oem and os like dos5.0

INT16U	BPB_BytesPerSec; 				//扇区字节数
INT8U	BPB_SecPerClus;					//每簇扇区数
INT16U	BPB_RsvdSecCnt; 				//保留扇区数
INT8U	BPB_NumFATs;					//FAT数目
INT16U	BPB_RootEntCnt; 				//根目录项数 0
INT16U	BPB_TotSec16; 					//小扇区总数 0
INT8U	BPB_Media;						//媒体描述符
INT16U	BPB_FATSz16; 					//每FAT扇区数fat32不用为0
INT16U	BPB_SecPerTrk; 					//每道扇区数
INT16U	BPB_NumHeads; 					//磁头数
INT32U	BPB_HiddSec; 					//隐藏扇区数
INT32U	BPB_TotSec32; 					//总扇区数   
INT32U	BPB_FATSz32;					//每FAT扇区数fat32
INT16U	BPB_ExtFlags;					//fat32扩展标志
INT16U  BPB_FSVer;						//fat32特有,高位为fat32的主版本号,底位为次版本号
INT32U	BPB_RootClus;					//根目录簇号
INT16U	BPB_FSInfo;						//文件系统信息扇区号
INT16U	BPB_BKBootSec;					//引导扇区备份号
INT8U	BPB_Reserved[12];				//保留空间

INT8U	BS_drvNum;					    //物理驱动器号
INT8U	BS_Reservd1;					//保留
INT8U	BS_BootSig;						//扩展引导标签
INT32U	BS_VolID;						//分区序号
INT8U	BS_VolLab[11];					//卷标
INT8U	BS_FilSysType[8];				//系统ID



////////////////////////////////////////////////////////////////////////////////
//目录信息
////////////////////////////////////////////////////////////////////////////////
INT8U  	deName[8];
INT8U  	deExtension[3];
INT32U  Clust; 							//当前目录的簇号
INT16U 	Nums;   						//仅FAT12—FAT16中的根目录区有效
INT32U 	Index;  						//当前的BLOCK中目录项索引
INT32U 	FileSize; 						//文件长度


////////////////////////////////////////////////////////////////////////////////
//文件信息
////////////////////////////////////////////////////////////////////////////////
INT8U	DIR_Name[11];					//文件名,没有.
INT8U	DIR_Attr;         				//文件属性,自低至高,只读、隐藏、系统、卷标、子目录、归档
INT8U	DIR_NTRes;        				//系统保留
INT8U	DIR_CrtTimeTenth;  				//创建时间的10毫秒位
INT16U	DIR_CrtTime;      				//创建时间
INT16U	DIR_CrtDate;      				//创建日期
INT16U	DIR_LastAccDate;  				//最后访问日期
INT16U	DIR_FstClusHI;    				//文件起始簇号高16位               
INT16U	DIR_WrtTime;      				//最近修改时间
INT16U	DIR_WrtDate;      				//最近修改日期
INT16U	DIR_FstClusLO;    				//文件起始簇号的低16位               
INT32U	DIR_FileSize;     				//文件长度



////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
INT32U  FAT1Sec;						//FAT1表的位置
INT32U  FAT2Sec;
INT32U  FirstDataSector;				//第一个根目录位置,区号为2
INT32U  FirstDirSector;
////////////////////////////////////////////////////////////////////////////////

INT8U   BUFFER[512]; 

INT8U MP3_BUFFER[512];
INT8U  TEXT[512];



#define MP3_TYPE   0
#define WMA_TYPE   1
#define MID_TYPE   2
#define LRC_TYPE   3

INT8U filetype[][3] ={ {"MP3"},{"WMA"},{"MID"},{"LRC"}};



INT32U  FAT_MASK;
INT16U  RootDirEnts;         // 根目录总的项数(FAT12&FAT16)
void   UART0_SendByte(uint8 data);
void   UART0_SendStr(uint8 const *str);

/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
void SD_Power(void)
{
	SPI1_SCK_GPIO();	
	SPI1_SCK_OUT();
	SPI1_SCK_CLR();		
	
	SPI1_MOSI_GPIO();		
	SPI1_MOSI_OUT();
	SPI1_MOSI_CLR();		
	
    SPI1_CS_GPIO();	 		
	SPI1_CS_OUT();
	SPI1_CS_CLR();
}


void SPI1_Init(INT8U speed)
{  
	SPI1_CS_GPIO();		
	SPI1_CS_OUT();
					
	PINSEL1 &= ~((0x03 << 2) + (0x03 << 4) + (0x03 << 6)); 
	PINSEL1 |=  (0x02 << 2) + (0x02 << 4) + (0x02 << 6);
	
	SSPCR0 = (0x00 << 8) |              			// SCR=0  
            (0x00 << 7) |             				// CPHA =0时钟输出相位,仅SPI模式有效 
            (0x00 << 6) |              				// CPOL =0时钟输出极性,仅SPI模式有效
            (0x00 << 4) |              				// FRF =00 帧格式 00=SPI,01=SSI,10=Microwire,11=保留
            (0x07 << 0);               				// DSS  数据长度,0000-0010=保留,0011=4位,0111=8位,1111=16位

    SSPCR1 = (0x00 << 3) |              			// SOD  从机输出禁能,1=禁止,0=允许
            (0x00 << 2) |              				// MS   主从选择,0=主机,1=从机
            (0x01 << 1) |              				// SSE  SSP使能,1=允许SSP与其它设备通信
            (0x00 << 0);               				// LBM  回写模式
             
    SSPCPSR	= speed; 								//2-254 偶数	
  	SSPIMSC	= 0x00;								    // 取消所有中断使能		
    SSPICR	= 0x00;                     			// 中断清除寄存器
}								
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SPI1_SrByte(INT8U byte)
{
	//OS_ENTER_CRITICAL();
	SSPDR = byte;

	while( (SSPSR & 0x01) == 0 );	    			// 等待TFE置位,即发送FIFO空  										

//	OS_EXIT_CRITICAL();
	return(SSPDR);
}
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SD_ChkCard(void)
{
	//if (SD_INSERT_STATUS() != 0)
	//	return 0;									/* 未完全插入 not insert entirely */
	//else
		return 1;									/* 完全插入 insert entirely */
}
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SD_WriteCom(uint8 cmd,uint32 arg)
{
	uint8 tmp;
   	uint8 retry=0;
	
  	SPI1_CS_CLR();      							//SD卡使能

   	SPI1_SrByte((INT8U)(cmd|0x40));   				//送头命令
   	SPI1_SrByte((INT8U)(arg>>24));
   	SPI1_SrByte((INT8U)(arg>>16));     				//send 6 Byte Command to MMC/SD-Card
   	SPI1_SrByte((INT8U)(arg>>8));
   	SPI1_SrByte((INT8U)(arg));
	SPI1_SrByte((INT8U)(0x95));       				//仅仅对RESET有效的CRC效验码

	do
   	{ 
    	tmp = SPI1_SrByte(0XFF); 					//Only last 8 bit is used here.Read it out.
      	retry++;
   	}
   	while((tmp==0xff)&&(retry<100));    			//当没有收到有效的命令的时候

	if(retry>=100)
	{
		return 0;
	}
	
	if(reading == 0)
    {
      	SPI1_CS_SET();          	  				//MMC_CS_PIN=1;
    }
    else 
    {
    	SPI1_CS_CLR();                 		    	// MMC_CS_PIN = 0;   
    }
	return(tmp);
}
/**************************************************************************************************
**Name: 	  
**Function:   
**Input:	  
**Output:	  
**************************************************************************************************/
INT8U SD_ReadBlock(INT32U address,INT8U *SD_BUFFER)
{
	INT32U	addr;
	INT16U  i=0;
	INT8U   temp=0;
   	
	addr=address<<9;
	
	reading=1;
	
   	SPI1_CS_CLR();    			  				//MMC_CS_PIN=0;	    SD卡使能

   	
	temp=SD_WriteCom(CMD17,addr);     			//读出RESPONSE

	while( (SPI1_SrByte(0XFF)!= 0xFE)&&(i<400))
	{
		i++;
	}; 											//直到读取到了数据的开始头0XFE,才拿继续

   	for(i=0; i<512; i++)
	{
		*SD_BUFFER++=SPI1_SrByte(0XFF);
	}
	
   	SPI1_SrByte(0XFF);							//CRC - Byte
   	SPI1_SrByte(0XFF);							//CRC - Byte

	reading=0;

	SPI1_CS_SET(); 

	return(temp);
}
/*******************************************************************************************************************
** 函数名称: INT8U SD_WriteBlockData()				Name:	  INT8U SD_WriteBlockData()
** 功能描述: 向sd卡写数据块							Function: write block data to sd card
** 输   入: INT8U bmulti  : 是否为多块操作1:是0:否 Input:	  INT8U bmulti   : multi blocks operate 1:Y 0:N 
			 INT32U len    : 长度						  	  INT32U len     : length
			 INT8U *sendbuf: 发送缓冲区					 	  INT8U *sendbuf : the buffer of send
** 输   出: 0:   正确    >0:   错误码		  		Output:	  0:  right		>0:  error code
********************************************************************************************************************/
INT8U SD_WriteBlock(INT32U len, INT8U *sendbuf)
{
	INT16U i;
	INT8U tmp;

	SPI1_CS_CLR();
		
    SPI1_SrByte(0xFF);								/* 开始发送数据之前发送8个clock clock out 8 clk before start */
    
	SPI1_SrByte(SD_TOK_WRITE_STARTBLOCK);			/* 写单块开始令牌 start token of write single block */

	for (i = 0; i < len; i++)
        SPI1_SrByte(sendbuf[i]);					/* 发送数据 send data */

	SPI1_SrByte((i >> 8) & 0xFF);
	SPI1_SrByte(i & 0xFF); 							/* 发送CRC16校验码 send CRC16 check code */
			    
	tmp = SPI1_SrByte(0xff);
  	if ((tmp & SD_RESP_DATA_MSK) != SD_RESP_DATA_ACCETPTED)	
  	{		
   		SPI1_SrByte(0xFF);							/* 返回之前发送8个clock  clock out 8 clk before return */
   		//SPI_CS_Deassert();
   		//return SD_ERR_DATA_RESP;					/* 数据响应错误 data response error */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -