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

📄 ch375.c

📁 实现单片机上直接对U盘数据的读写
💻 C
字号:

#include <reg52.h>
#include <stdio.h>
#include 	<absacc.h>
#include 	<intrins.h>


#define CH375_CMD_PORT_ADDR		0xBDF1	/* CH375命令端口的I/O地址 */
#define CH375_DAT_PORT_ADDR		0xBCF0	/* CH375数据端口的I/O地址 */
#define CH375_INT_WIRE			INT0	/* P3.2, INT0, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */
#define DATA_BUFFER_ADDR		0xE000

//************** 中断状态输出******************

#define	USB_INT_SUCCESS		0x14
#define	USB_INT_CONNECT	 	0x15
#define	USB_INT_DISCONNECT	0x16
#define	USB_INT_BUS_OVER	0x17
#define	USB_INT_DISK_READ	0x1d
#define	USB_INT_DISK_WRITE	0x1e
#define USB_INT_DISK_ERR	0x1f
//*****************************
unsigned char data Cmd_buffer[5];
unsigned char xdata data_buffer[512]	_at_	DATA_BUFFER_ADDR;

unsigned char i;

/* 延时1毫秒,不精确 */
 void delay1ms(unsigned char k){
 	unsigned int i ;
	while(k>0){for (i=0;i<250;i++); k--;}
 }
 // delay 5us for 24Mhz
  void delay5us(){
 	_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
	_nop_();_nop_();_nop_();_nop_();_nop_();

 }

  void delay2us(){
 	_nop_(); _nop_(); _nop_(); _nop_(); 
	_nop_();_nop_();_nop_();_nop_();

 }
 //接受数据
  unsigned char  recv_data (void) 
  {
  	unsigned char dat1;
 		RI = 0;
		while (!RI);
		dat1 = SBUF;					
		RI = 0;	
		return dat1;		
}
/* 为printf和getkey输入输出初始化串口 */
void	mInitSTDIO( )
{
	SCON = 0x50;
	PCON = 0x80;
	TMOD = 0x20;
	TH1 = 0xf3;  /* 24MHz晶振, 9600bps */
	TR1 = 1;
	TI = 1;	
}

//复位CH375
 void mRestCH375( )
 {
 	XBYTE[CH375_CMD_PORT_ADDR] = 0x05;
	delay1ms(50);
 }
 
 //校验CH375 工作是否正常
 unsigned char mVarifyCH375(unsigned char temp)
 {
 	XBYTE[CH375_CMD_PORT_ADDR] = 0x06;

	XBYTE[CH375_DAT_PORT_ADDR] = temp;
	delay5us();
	temp = XBYTE[CH375_DAT_PORT_ADDR];
	return(temp);
		
 }
 //设置CH375的工作模式6
 void mSetmodeCH375( )
 {
  XBYTE[CH375_CMD_PORT_ADDR] = 0x15;
  XBYTE[CH375_DAT_PORT_ADDR] = 0x06;
  delay5us();
  delay5us();
  delay5us();
  delay5us();
  if ( XBYTE[CH375_DAT_PORT_ADDR] == 0x51 ) printf("Success Operation\n");
  	else printf("Error In Operation\n");	
 }
 //
 unsigned char mGet_Status_CH375()
 {
 	unsigned char temp;
 	XBYTE[CH375_CMD_PORT_ADDR] = 0x22;//获取中断状态,并取消中断
	delay2us();
	temp = XBYTE[CH375_DAT_PORT_ADDR]; //获取中断内容
	return(temp);	
 
 }

 //获取CH375 的版本号
 unsigned char mGET_CH375_VER()
 {
 	unsigned char temp;
   	XBYTE[CH375_CMD_PORT_ADDR] = 0x01;
	delay2us();
	temp = XBYTE[CH375_DAT_PORT_ADDR];
	return (temp);
 }

 //初始化USB 
 void mDisk_Init()
 {
	XBYTE[CH375_CMD_PORT_ADDR] = 0x51; // USB_INIT
	while(INT0);
	if(mGet_Status_CH375()!=USB_INT_SUCCESS) {printf("Error:%x\n",(unsigned int)mGet_Status_CH375()); return;}
 }
 //获取U 盘的容量
 void mGET_USB_Size()
 {
 	unsigned char temp;
 	unsigned long usbsize;
	unsigned long sectornum;//扇区总数
	XBYTE[CH375_CMD_PORT_ADDR] = 0x53;//USB_SIZE
	while(INT0); //CH375 请求中断
	if(mGet_Status_CH375()!=USB_INT_SUCCESS) {printf("Error:%x\n",(unsigned int)mGet_Status_CH375()); return;}
	XBYTE[CH375_CMD_PORT_ADDR] = 0x28;//READ_USB_DATA

	 for(i=0;i<4;i++){
	 	sectornum<<=8;
	 	sectornum = XBYTE[CH375_DAT_PORT_ADDR];
		
	 }
	 for(i=0;i<4;i++){
	 	temp = XBYTE[CH375_DAT_PORT_ADDR];
		
	 }
	 usbsize = sectornum>>1;
	 printf("Sector Number:%ld,Size: %ld K\n",sectornum,usbsize);
 }

 //**********读数据从U盘***********************
 	unsigned char	mReadSector( unsigned long iLbaStart, unsigned char iSectorCount )
/* iLbaStart 是准备读取的线性起始扇区号, iSectorCount 是准备读取的扇区数 */
{
	unsigned char *mBufferPoint;
	unsigned int  mBlockCount;
	unsigned char mLength,k;
	XBYTE[CH375_CMD_PORT_ADDR] = 0x54;//DISK_READ
	XBYTE[CH375_DAT_PORT_ADDR] = (unsigned char)iLbaStart ;  /* LBA的最低8位 */
	XBYTE[CH375_DAT_PORT_ADDR] = (unsigned char)( iLbaStart >> 8 ) ;
	XBYTE[CH375_DAT_PORT_ADDR] = (unsigned char)( iLbaStart >> 16 ) ;
	XBYTE[CH375_DAT_PORT_ADDR] = (unsigned char)( iLbaStart >> 24 );  /* LBA的最高8位 */
	XBYTE[CH375_DAT_PORT_ADDR] = iSectorCount ;  /* 扇区数 */
	mBufferPoint = data_buffer;  /* 指向缓冲区起始地址 */
	for ( mBlockCount = iSectorCount * 8; mBlockCount != 0; mBlockCount -- ) {  /* 数据块计数 */
			while(INT0); //等中断信号 
		if (mGet_Status_CH375() == USB_INT_DISK_READ) {  /* USB存储器读数据块,请求数据读出 */
			XBYTE[CH375_CMD_PORT_ADDR] = 0x28;	//READ_USB_DAT,即把CH375内缓冲的数据读进单片机
			mLength = XBYTE[CH375_DAT_PORT_ADDR];  /* 后续数据的长度 */
			k = mLength;
			while ( mLength ) {  /* 根据长度读取数据 */
				*mBufferPoint = XBYTE[CH375_DAT_PORT_ADDR];  /* 读出数据并保存 */
				mBufferPoint ++;
				mLength --;
			}
			for(i=0;i<k;i++){printf("%c",data_buffer[i]);}				
			XBYTE[CH375_CMD_PORT_ADDR] = 0x55;//DISK_READ_GO
		}
		else {printf("Error In Read Byte\n");break;}  /* 返回错误状态 */
	}
	printf("\n");
	if ( mBlockCount == 0 ) {
		while(INT0);  /* 等待中断并获取状态 */
		if (mGet_Status_CH375()== USB_INT_SUCCESS)  printf("Success In Read Sector\n");  /* 操作成功 */
		else printf("Error In Read Sector \n");

	}
	
}	
//***************************
 void 	mWriteSector( unsigned long iLbaStart, unsigned char iSectorCount )
 {
 	unsigned char *mBufferPoint;
	unsigned int  mBlockCount;
	unsigned char mLength;
	XBYTE[CH375_CMD_PORT_ADDR] = 0x56;//DISK_WRITE
	XBYTE[CH375_DAT_PORT_ADDR] = (unsigned char)iLbaStart ;  // LBA的最低8位
	XBYTE[CH375_DAT_PORT_ADDR] = (unsigned char)( iLbaStart >> 8 ) ;
	XBYTE[CH375_DAT_PORT_ADDR] = (unsigned char)( iLbaStart >> 16 ) ;
	XBYTE[CH375_DAT_PORT_ADDR] = (unsigned char)( iLbaStart >> 24 );  // LBA的最高8位 
	XBYTE[CH375_DAT_PORT_ADDR] = iSectorCount ;  // 扇区数 
	mBufferPoint = data_buffer;  // 指向缓冲区起始地址
	for ( mBlockCount = iSectorCount * 8; mBlockCount != 0; mBlockCount -- ) {  // 数据块计数
			while(INT0); //等中断信号 
		if (mGet_Status_CH375() == USB_INT_DISK_WRITE) {  //USB存储器读数据块,请求写数据 
			XBYTE[CH375_CMD_PORT_ADDR] = 0x2b;	//WRITE_USB_DAT
			mLength = 64;  // 后续数据的长度
			XBYTE[CH375_DAT_PORT_ADDR] = 64; //每次写入数据块64个字节 
			while ( mLength ) {  // 根据长度读取数据 
				XBYTE[CH375_DAT_PORT_ADDR] = *mBufferPoint;  // 写入数据 
				mBufferPoint ++;
				mLength --;
			}
			XBYTE[CH375_CMD_PORT_ADDR] = 0x57;//DISK_READ_GO
		}
		else {printf("Error In Write Byte\n");break;}  // 返回错误状态 
	}
	if ( mBlockCount == 0 ) {
		while(INT0);  // 等待中断并获取状态
		if (mGet_Status_CH375()== USB_INT_SUCCESS)  printf("Success In Write Sector\n");  // 操作成功 
		else printf("Error In Write Sector \n");

	}
 }
 
  void main( ){
  	unsigned int j;
	unsigned char sectorcount;
	unsigned long sectoraddr;
  	mInitSTDIO( ); //初始化
   	getchar();	  //
 	printf("Rest CH375, About 40ms\n");//
	mRestCH375( );
	j =  mGET_CH375_VER(); //CH375的版本号
	printf("CH375 Version:%#x\n",i);
	printf("Varify CH375,Please input data:");
	i = recv_data();
	printf("%#x\n",(unsigned int)i);
	j = mVarifyCH375(i);
 	printf("Invert Date  %#x\n",j);
	if((i^j)==0xff) printf("Success to Varify CH375\n");
		else printf("Error to Varify CH375\n");
	printf("Set CH375 Mode for 06\n");
	mSetmodeCH375( );
	 printf("Input Hightest Byte:");
	sectoraddr= recv_data();
	printf("%ld\n",sectoraddr);
	sectoraddr<<=8;

	printf("Input Hight Byte:");
	sectoraddr|= recv_data();
	printf("%ld\n",sectoraddr);
	sectoraddr<<=8;

	printf("Input Low Byte:");
	sectoraddr|= recv_data();
	printf("%ld\n",sectoraddr);
	sectoraddr<<=8;

	printf("Input Lowest Byte:");
	sectoraddr|= recv_data();
	printf("%ld\n",sectoraddr);

	printf("Input Sector Number:");
	sectorcount= recv_data();
	printf("%d\n",(unsigned int)sectorcount);
	
	 
	printf("Wait for USB\n");
	while(1){
		while(INT0);
		i = mGet_Status_CH375();
		switch(i){
			case 0x14: 	printf("USB_INT_SUCCESS\n");break;
			case 0x15: printf("USB_INT_CONNECT\n");
						delay1ms(100);
						mDisk_Init();	
						printf( "Read %d Sector, %ld# to buffer\n",(unsigned int)sectorcount,sectoraddr );	
						mReadSector(sectoraddr,sectorcount);
						delay1ms(100);
						printf( "Write 2 Sector 12# from buffer\n" );
						mWriteSector(12,2);
						break;

			case 0x16: printf("USB_INT_DISCONNECT\n");	break;
			case 0x17: printf("USB_INT_BUS_OVER\n");	break;
			case 0x1D: printf("USB_INT_DISK_READ\n");	break;
			case 0x1E: printf("USB_INT_DISK_WRITE\n");	break;
			case 0x1F: printf("USB_INT_DISK_ERR\n");	break;
			default:	printf("OTHER INFORMASSAGE\n");	break;
		}
		

	}
 }
 
 
 
 
 
 					  

⌨️ 快捷键说明

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