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

📄 u_func_a.c

📁 c8051f020+CH375读写U盘文件的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include<c8051f020.h>
#include<intrins.h>
#include"lcd.h"
#include"read_U.h"
#include"read_U_a.h"
#include"read_U_b.h"
//#include"infrared_receive.h"



/*******************************************************************************
------读键值程序---------------------------------------------------
********************************************************************************
说明:入口参数:无
	  出口参数:键值
*******************************************************************************/
unsigned char Wait_Infrared()
{
 unsigned char KeyValue;
 unsigned int i;
 while(1)
	{
	 P4=0xff;
	 while(P4<=0x0f);
	   
     for(i=0;i<30000;i++) _nop_;
	 if(P4>0x0f)
		  {
		   KeyValue=P4;
		   for(i=0;i<9000;i++) Delay();
		   return KeyValue;
		  }
    }
}

/*******************************************************************************
------延时程序---------------------------------------------------
********************************************************************************
说明:入口参数:无
	  出口参数:无
*******************************************************************************/  
void Delay()
{
 unsigned char i;
 for(i=0;i<60;i++)
 _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}

/*******************************************************************************
------设置单片机晶振为外部晶振--------------------------------------------------
********************************************************************************
说明:入口参数:无
	  出口参数:无
*******************************************************************************/
void Oscillator_Init()
{
    int i = 0;
   /* OSCXCN    = 0x77;
    for (i = 0; i < 3000; i++);  // Wait 1ms for initialization
    while ((OSCXCN & 0x80) == 0);
    OSCICN    = 0x08;
	*/
	    OSCXCN    = 0x67;
    for (i = 0; i < 3000; i++);  // Wait 1ms for initialization
    while ((OSCXCN & 0x80) == 0);
    OSCICN    = 0x08;
}

/*******************************************************************************
------单片机系统初始化---------------------------------------------------
********************************************************************************
说明:入口参数:无
	  出口参数:无
*******************************************************************************/
void Mcu_Init()
{
 WDTCN     = 0xDE;
 WDTCN     = 0xAD;
 XBR2      = 0x40;
 Oscillator_Init();
 LCD_Init();
// Infrared_Init();
 Currt_File=0;
// IE=0x80;  //开总中断
// EIE2|=0x20;//开中断7
}

/*******************************************************************************
------文件显示程序---------------------------------------------------
********************************************************************************
说明:入口参数:x坐标,y坐标,文件号
	  出口参数:无
*******************************************************************************/
void PrintfFat(unsigned char x,unsigned char y,char file_num)	 //用于显示文件名和扩展名
	{unsigned char i,*pt;
	pt=Fat[file_num].name;
	LCD_Goto(x,y);
	_nop_();
	for(i=0;*(pt+i)!=0;i++)
		LCD_WriteData(*(pt+i));
	pt=Fat[file_num].ext;
	if(*(pt)!=0x20)
	   {
	    LCD_WriteData(0x2e);
		for(i=0;i<3;i++)
		   LCD_WriteData(*(pt+i));
	   }
	else 
	   {
	     for(i=0;i<3;i++)
		   LCD_WriteData(*(pt+i));
		 LCD_WriteData(*(pt));
	   }
	}

/*******************************************************************************
------选择要读出数据的u盘---------------------------------------------------
********************************************************************************
说明:入口参数:无
	  出口参数:0:所显示的第一个U盘(U盘A),0xFF:所显示的第二个U盘(U盘B)
*******************************************************************************/
unsigned char SelectDisk()
{
 unsigned char Key,WhchDisk=0;
 LCD_Printf(1,1,">>");
 while(1)
 {
  Key=Wait_Infrared();
  if(Key==DOWN||Key==UP)
     {
	  WhchDisk=~WhchDisk; 
	  LCD_Printf((WhchDisk/0xff)+1,1,">>");
	  LCD_Printf((~WhchDisk/0xff)+1,1,"  ");
	 }
  else return WhchDisk;
 }
}






/*******************************************************************************
------CH375写命令---------------------------------------------------
********************************************************************************
说明:入口参数:命令字
	  出口参数:无
*******************************************************************************/
void CH375HM_INDEX_WR_a(index)
{

P2=index;
USB_A0a=1;
//P2MDOUT=0xff;
USB_RDa=1;

USB_CSa=0;
USB_WRa=0;
Delay();
USB_WRa=1;
USB_CSa=1;
USB_A0a=1;
P2=0xff;
}

/*******************************************************************************
------CH375写数据---------------------------------------------------
********************************************************************************
说明:入口参数:数据
	  出口参数:无
*******************************************************************************/
void CH375HM_DATA_WR_a(Data)
{ 
P2=Data;
//P2MDOUT=0xff;
USB_A0a=0;
USB_CSa=0;
USB_WRa=0;
Delay();
USB_WRa=1;
USB_CSa=1;
USB_A0a=1;
P2=0xff;
}

/*******************************************************************************
------CH375读数据---------------------------------------------------
********************************************************************************
说明:入口参数:无
	  出口参数:数据
*******************************************************************************/
unsigned char CH375HM_DATA_RD_a(void)
{
 unsigned char m; 
 P2MDOUT=0x00;
 USB_A0a=0;
 USB_CSa=0;
 USB_RDa=0;
 Delay();
 m=P2;
 USB_RDa=1;
 USB_CSa=1;
 USB_A0a=1;
 return (m);
}

/*******************************************************************************
------初始化U盘A---------------------------------------------------
********************************************************************************
说明:入口参数:无
	  出口参数:0x14:初始化成功,0x1f:初始化失败
*******************************************************************************/
unsigned char Init_Disk_a()
{
    unsigned char sta;
	CH375HM_INDEX_WR_a(DISK_INIT);
    Delay();
	sta=Wait_Int_a();
    while(sta!=0x14);
	sta=USB_INT_DISK_ERR;
	CH375HM_INDEX_WR_a(DISK_READY);
	Delay();
    sta=Wait_Int_a();
	CH375HM_INDEX_WR_a(  DISK_R_SENSE );  /* 检查USB 存储设备的错误 */
    sta = Wait_Int_a( );  /* 等待中断并获取状态 */
	CH375HM_INDEX_WR_a(DISK_READY);
    sta=Wait_Int_a();
	return sta;	   
}

/*******************************************************************************
------CH375设置A盘工作模式---------------------------------------------------
********************************************************************************
说明:入口参数:数据
	  出口参数:0x51:操作成功,0x5f:操作失败
*******************************************************************************/
unsigned char Set_Mode_a(unsigned char mode)
{
    unsigned char temp;
 	CH375HM_INDEX_WR_a(SET_USB_MODE);
	CH375HM_DATA_WR_a(mode);
	temp=CH375HM_DATA_RD_a();
	return (temp);
}

	

/*******************************************************************************
------读A盘扇区程序---------------------------------------------------
********************************************************************************
说明: 写入单片机中数据缓冲区
      入口参数:扇区号LBA
	  出口参数:0x14:操作成功,0x1f:操作失败
*******************************************************************************/
unsigned char Rd_Sector_a(unsigned long LBA)
{
  unsigned char sta,i,j,Next_Num=0;
  unsigned char xdata *pt;
  sta=0x1f;
  pt=Data_Buf;
  CH375HM_INDEX_WR_a( DISK_READ );                        /* 从USB存储器读数据块 */
  CH375HM_DATA_WR_a( (unsigned char)LBA );                /* LBA的最低8位 */
  CH375HM_DATA_WR_a( (unsigned char)( LBA >> 8 ) );
  CH375HM_DATA_WR_a( (unsigned char)( LBA >> 16 ) );
  CH375HM_DATA_WR_a( (unsigned char)( LBA >> 24 ) );      /* LBA的最高8位 */
  CH375HM_DATA_WR_a( 1 );                           /* 扇区数 */ 
  Delay();
  for(i=0;i<9;i++)
    {
	sta=Wait_Int_a();
     if(sta==0x1f||sta==0x14) return sta;
	 CH375HM_INDEX_WR_a(RD_USB_DATA);
	 Next_Num=CH375HM_DATA_RD_a();
     for(j=0;j<Next_Num;j++)
	    {
		 *pt=CH375HM_DATA_RD_a();
		 pt++;
		}
	  CH375HM_INDEX_WR_a(DISK_RD_GO);
	 }
return 0xff;
}

/*******************************************************************************
------写A盘扇区程序---------------------------------------------------
********************************************************************************
说明: 入口参数:扇区号LBA
	  出口参数:无
*******************************************************************************/
void Wr_Sector_a(unsigned long LBA)
{
 unsigned char sta,i,j;
  unsigned char xdata *pt;
  sta=0x1f;
  pt=Data_Buf;
  CH375HM_INDEX_WR_a( DISK_WRITE );                        /* 写数据块到USB存储器 */
  CH375HM_DATA_WR_a( (unsigned char)LBA );                /* LBA的最低8位 */
  CH375HM_DATA_WR_a( (unsigned char)( LBA >> 8 ) );
  CH375HM_DATA_WR_a( (unsigned char)( LBA >> 16 ) );
  CH375HM_DATA_WR_a( (unsigned char)( LBA >> 24 ) );      /* LBA的最高8位 */
  CH375HM_DATA_WR_a( 1 );                           /* 扇区数 */ 
  Delay();
  for(i=0;i<9;i++)
    {
     sta=sta=Wait_Int_a();
     if(sta==0x1f||sta==0x14) return;
	 CH375HM_INDEX_WR_a(WR_USB_DATA7);
	 CH375HM_DATA_WR_a(64);
	 for(j=0;j<64;j++)
	   {
	    CH375HM_DATA_WR_a(*pt);
		pt++;
	   }
	 CH375HM_INDEX_WR_a(DISK_WR_GO);
	}
}

/*******************************************************************************
------读CH375的中断状态---------------------------------------------------
********************************************************************************
说明: 入口参数:无
	  出口参数:中断状态
*******************************************************************************/
unsigned char Wait_Int_a()
{
 unsigned sta=0,temp=0;
 while(temp!=0x40) 
   temp=P3IF&0x40;
 P3IF&=0xbf;//清中断6的中断标志
 CH375HM_INDEX_WR_a(GET_STATUS);
 Delay();
 sta=CH375HM_DATA_RD_a();
 return sta;
}


/*******************************************************************************
------读A盘的基本数据---------------------------------------------------
********************************************************************************
说明: 入口参数:无
	  出口参数:0x14:操作成功,0x1f:操作失败
*******************************************************************************/
unsigned char Get_Base_a()
{
 unsigned char a,b;
 unsigned char xdata *pt;
 Rd_Sector_a(0x00000000);
 pt=Data_Buf;
 a=*pt;b=*(pt+1);	  
 if(a!=0xeb&&b!=0x58)
    {
	 hidd_sect_a=*(pt+0x1c6);
	 Rd_Sector_a( (unsigned long)hidd_sect_a );
	}
 a=*pt;b=*(pt+1);
 if(a==0xeb&&b==0x58)
   {
    hidd_sect_a=*(pt+0x1c);
 	byte_sect_a=*(pt+0x0b)+(*(pt+0x0c)<<8);
	sect_clust_a=*(pt+0x0d);
	resv_sect_a=*(pt+0x0e)+(*(pt+0x0f)<<8);
    sect_fat_a=*(pt+0x24)+(*(pt+0x25)<<8);
	root_a=hidd_sect_a+resv_sect_a+2*sect_fat_a;
	return 0x14;
   }
 else return 0x1f; 
}

/*******************************************************************************
------显示A盘盘名---------------------------------------------------
********************************************************************************
说明: 入口参数:无
	  出口参数:无
*******************************************************************************/
void Show_Disk_a()
{
 unsigned char i;
 unsigned char  *disk_name_a;		 
 unsigned char xdata *pt;
 unsigned int data charact;			 
 Rd_Sector_a(root_a);
 pt=Data_Buf;
 for(i=0;i<16;i++)
   {
//   charact=Data_Buf[0x0b+i*32];	//这种也赋不了
	charact=*(pt+0x0b+i*32);	  //charact不定义为data就赋不了值。???
    if(charact==0x08) 
       {
        disk_name_a=pt+i*32;		  //disk_name定义成指向xdata也赋不了值。???
        *(disk_name_a+11)=0;
        LCD_Printf(1,2,disk_name_a);
        return;
       }
   }

}  

/*******************************************************************************
------读长文件项---------------------------------------------------
********************************************************************************
说明: 入口参数:无
	  出口参数:无
*******************************************************************************/
void Get_Lfat_a()
{
 unsigned char xdata *pt;
 unsigned char temp1,temp2,i=0,*na,nai=0;
 unsigned int Temp_Ofst;
 unsigned char which[26]={1,3,5,7,9,14,16,18,20,22,24,28,30};  //确定长文件名储存的地方
 pt=Data_Buf;
 na=Fat[Currt_File].name;
 if(St_Ofst_a==0)		 //若短文件名在扇区的第一个32字节,则指向上一个扇区的最后32字节
    {
	 Rd_Sector_a(Rd_Rec.Last_Sect);
	 Temp_Ofst=480;		  
	}
 else Temp_Ofst=St_Ofst_a-32;//若短文件名不在本扇区的第一个32字节,则指向上一个32字节
 do{  //读长文件名  
    while(i<13)
	{
    temp1=*(pt+Temp_Ofst+which[i]);
	if(temp1==0x2e) 
	  {
	   *(na+nai)=0;
	   break;
	  }
	temp2=*(pt+Temp_Ofst+which[i]+1);
	if(temp2!=0)
	  {  
	   *(na+nai)=0x7e;
	   *(na+nai+1)=0x31;
	   *(na+nai+2)=0;
	   break;
	  }					 
	*(na+nai)=temp1;
	nai++;
	i++;
	}
	if(Temp_Ofst==0)  //若已在本扇区最开始
    {
	 if(*(pt+Temp_Ofst)<0x3f) break; //若是长文件名的最后一段
	 else
	   {
	    Rd_Sector_a(Rd_Rec.Last_Sect);
	    Temp_Ofst=512;
	   }
	}
	Temp_Ofst-=32;
   }while(*(pt+Temp_Ofst+32)<0x3f);
   Rd_Sector_a(Rd_Rec.Currt_Sect);
}


/*******************************************************************************
------读A盘文件名---------------------------------------------------
********************************************************************************
说明: 目前只读一个扇区中的文件名
      入口参数:文件夹首簇号
	  出口参数:0xff:文件名已读完,其他:已读文件数
*******************************************************************************/
unsigned char Dis_Fat_In_Clust_a(unsigned long Menu_Clust)
{
 unsigned long Menu_LBA;
 unsigned char *na,i,j,rd_short=0;
 unsigned char xdata *pt;
 St_Ofst_a=0;
 Currt_File=0;
 File_Over=0;
 Menu_LBA=(Menu_Clust-2)*sect_clust_a+root_a;
 Rd_Rec.Currt_Sect=Rd_Rec.Last_Sect=Menu_LBA;
 Rd_Rec.Next_Sect=Rd_Rec.Currt_Sect+1;


 while(Rd_Rec.Currt_Sect-Menu_LBA<sect_clust_a)  //读完整个簇
   {
    Rd_Sector_a(Rd_Rec.Currt_Sect);
   pt=Data_Buf;
    if(*(pt+St_Ofst_a)!=0xe5&&*(pt+St_Ofst_a+11)!=0x0f&&*(pt+St_Ofst_a+11)!=0x08&&*(pt+St_Ofst_a)!=0x2e)	 //判断是否为有效文件
	  {
	  na=Fat[Currt_File].ext;		  //读扩展名
	  for(i=0;i<3;i++)
	     {
		   *(na+i)=*(pt+St_Ofst_a+8+i);
		 }
	  
//	  Fat[Currt_File].St_Clust=*(pt+St_Ofst+0x1a)+*(pt+St_Ofst+0x1b)<<8+*(pt+St_Ofst+0x14)<<16;	  //定义Fat[Currt_File].St_Clust为一个长整型这样赋不了值?
      
	  Fat[Currt_File].St_Clust.num[3]=*(pt+St_Ofst_a+0x1a);	   //起始簇
	  Fat[Currt_File].St_Clust.num[2]=*(pt+St_Ofst_a+0x1b);
	  Fat[Currt_File].St_Clust.num[1]=*(pt+St_Ofst_a+0x14);
	  Fat[Currt_File].St_Clust.num[0]=*(pt+St_Ofst_a+0x15);
//	  Fat[Currt_File].Big=*(pt+St_Ofst+0x1c)+*(pt+St_Ofst+0x1d)<<8+*(pt+St_Ofst+0x1e)<<16+*(pt+St_Ofst+0x1f)<<24;	//这个跟Fat[Currt_File].St_Clust一样赋不了??
	  Fat[Currt_File].Big.num[0]=*(pt+St_Ofst_a+0x1f);  //文件大小
	  Fat[Currt_File].Big.num[1]=*(pt+St_Ofst_a+0x1e);
	  Fat[Currt_File].Big.num[2]=*(pt+St_Ofst_a+0x1d);
	  Fat[Currt_File].Big.num[3]=*(pt+St_Ofst_a+0x1c);

	  Fat[Currt_File].Sector=Rd_Rec.Currt_Sect;   //文件目录项所在的扇区

⌨️ 快捷键说明

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