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

📄 udisk.c

📁 周立功LPC23XX系列U盘源码。UDiskDrvDemo
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzou ZLG-MCU Development Co., LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:			udisk.c
** Descriptions:		LPC2300系列ARM控制U盘伴侣的串口驱动程序
**
**------------------------------------------------------------------------------------------------------
** Created by:			Zhoulishan
** Created date:		2007-04-16
** Version:				1.0
** Descriptions:		The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:			Litiantian
** Modified date:	
** Version:
** Descriptions:	    大大改善代码可读性,并修正若干BUG。	
********************************************************************************************************/
#include 	"config.h"

FileCB		CurFileCB = {0xff, 0};		// 当前文件控制块初始化为:当前文件句柄空闲、当前文件大小为0	
CONTR_DISK	rwdisk;						// 声明了一个文件操作的数据结构实体,通过该变量来完成文件的读写、删除操作

/********************************************************************************************************
** 函数名称:SendRequest
** 功能描述:请求帧发送函数
** 输入参数:buff:	待发送字符串的缓存区指针
**           len:	待发送字符的长度
** 输出参数:无
**********************************************************************************************************/
void SendRequest(uint8 *buff, uint16 len)
{
	uint16	i;
	for (i = 0;i < len;i++)
	{
		while ((U0LSR & 0x20) == 0x00);	// 等待字符发送完毕
		U0THR = *(buff + i);			// 发送一个字符
	}
	while ((U0LSR & 0x20) == 0x00);
}

/********************************************************************************************************
** 函数名称:ReceOneChar
** 功能描述:处理应答帧
** 输入参数:ReceCharacter:	 接收的字符
** 输出参数:无
********************************************************************************************************/
void ReceOneChar(uint8 ReceChar)
{
	static uint8	HFBuffer[6]; 		// 帧控制信息接收缓存,用于存储接收的帧的前6个字节,即帧的控制信息
	static uint8 	HFNumber = 0;		// 帧控制信息接收缓存的位置“指针”

	static uint16	DataLen;  			// 应答帧数据域长度
	static uint8	state 	 = 0;		// 应答帧处理阶段标志,为0时指示正在处理应答帧的控制信息,为1时指示正在处理应答帧的数据域

	/* 判断是否允许通讯,否则直接返回 */
	if (rwdisk.state != 0)		
	{
		return;							// 不允许通讯,返回
	}
	
	/* 根据处理标志,对应答帧进行不同处理 */
	switch (state)
	{
		/* 								帧处理阶段1 										*/
		case 0:
			/* 将接收的帧控制信息存储到帧控制信息接收缓存 */
			HFBuffer[HFNumber] = ReceChar;
			HFNumber++;

			/* 若接收的是无效帧,则复位HFNumber */
			if (HFBuffer[0] != 'S')
			{				
				if ( HFNumber == 2 )
				{	
					if (HFBuffer[1] != ':')
					{	
						HFNumber = 0;
					}
				}
			}
			/* 将接收帧的控制信息记录入rwdisk变量 */
			if (HFNumber == 6)
			{	
				HFNumber 	= 0;
				/* 记录功能代码和功能代码执行状态信息 */
				rwdisk.cmd 	= HFBuffer[2];
				rwdisk.cmds	= HFBuffer[3];

				/* 记录需读出数据的长度 */
				DataLen 	= HFBuffer[4] + HFBuffer[5]*0x100;
				rwdisk.rlen = DataLen;
				rwdisk.wlen = 0;

				/* 若还要接收应答帧的数据域,进入帧处理阶段2,否则停止通讯,结束帧处理 */
				if (DataLen != 0)
				{
					state 	= 1;
				}
				else
				{
					rwdisk.state = COMMNUNICATION_OFF;	
				}
			}
			break;

		/* 								帧处理阶段2, 接收应答帧数据域 						*/
		case 1:
			rwdisk.write_ptr[rwdisk.wlen] = ReceChar;
			rwdisk.wlen++;
			if (DataLen == rwdisk.wlen)
			{
				/* 接收数据域完毕,停止通讯,应答帧处理阶段标志复位 */
				rwdisk.state = COMMNUNICATION_OFF;				
				state 		 = 0;
			}
			break;

		default:
            break;
	}
}
/*********************************************************************************************************
** 函数名称: UART0_Exception
** 功能描述: UART0中断服务程序,在中断里完成应答帧处理
** 输入参数: 无
** 输出参数: 无
********************************************************************************************************/
void __irq UART0_Exception(void)
{
    uint8 IIR,  temp;
    
    VICIntEnClr |= 1 << UART0_INT;					

    while (((IIR = U0IIR) & 0x01) == 0)	// 有中断发生
    {                                               
        switch (IIR & 0x0e)
        {
            case 0x02:                  // THRE中断
                break;
            case 0x0c:
            case 0x04:                  // 接收数据可用
				ReceOneChar(U0RBR);		// 应答帧处理
               	break;					// 处理接收到的数据
            case 0x06:                  // 线状态中断
                temp = U0LSR;
                break;
            default :
                break;
        }
    } 

	VICIntEnable |= 1 << UART0_INT;		// 使能本中断
  
    VICVectAddr = 0;            					
}

/*********************************************************************************************************
** 函数名称: UART0Init
** 功能描述: 初始化UART0 
** 输入参数: bps:	波特率
** 输出参数: 无
********************************************************************************************************/
void UART0Init(uint32 bps)
{
    uint16 Fdiv = 0;
    
	PCONP |= 1 << 3;					// 使能UART0
	PINSEL0 = (0x01 << 4) | (0x01 << 6);// 设置P0.2和P0.3连接到UART0

    U0LCR = 0x80;                       // 允许访问分频因子寄存器
    Fdiv = (Fpclk / 16) / bps;          // 设置波特率
    U0DLM = Fdiv / 256;							
	U0DLL = Fdiv % 256;						
    U0LCR = 0x03;                      	// 禁止访问分频因子寄存器, 且设置通讯帧格式为8个数据位, 1个停止位, 无奇偶校验
	U0IER = 0x05;                      	// 允许接收中断和线状态中断
    U0FCR = 0x07;                       // 使能接收FIFO长度为1个字节

    VICIntEnClr  |= 1 << UART0_INT;				
	VICVectPri6   = 0x05;				// 设置串口中断优先级为5
	VICVectAddr6  = (uint32)UART0_Exception;		
	VICIntEnable |= 1 << UART0_INT;					
	IRQEnable();
} 	

void FreeFCB(void);
/********************************************************************************************************
** 函数名称:UDiskIni
** 功能描述:操作EasyUDisk功能模块之前需调用的初始化函数
** 输入参数:Baud  初始化使用的波特率
** 输出参数:无
********************************************************************************************************/
void UDiskIni(uint32 baud)
{
   FreeFCB();							// 释放文件控制块
   rwdisk.state = COMMNUNICATION_OFF;	// 禁止主从机通讯
   UART0Init(baud);						// 串口0初始化
}			

/*********************************************************************************************************
** 函数名称: Wait_Ack
** 功能描述: 等待从机处理完毕
** 输入参数: 无
** 输出参数: TRUE:	从机处理完毕
**			 FALSE:	超时
********************************************************************************************************/
uint8 Wait_Ack(void)
{
	uint32 i = 0;
	rwdisk.state = COMMNUNICATION_ON;

	for (i = 0;i < WAIT_TIME_OUT;i++)	// 软件延时等待
	{
		if (COMMNUNICATION_OFF == rwdisk.state)
		{
			return (TRUE);
		}
	}
	
	return (FALSE);
}

/*********************************************************************************************************
** 函数名称: GetSysInfo
** 功能描述: 获取系统信息
** 输入参数: sysinfptr:	系统信息数据块变量的指针
** 输出参数: TRUE:		正常应答返回
**			 FALSE:		超时出错返回
********************************************************************************************************/
uint8 GetSysInfo(SYSINF *sysinfptr)
{
	uint8	reqbuff[6];						// 请求帧缓存,未包括请求帧的数据域
	uint8   framedat_rcvbuf[14];			// 应答帧数据域的接收缓存

	reqbuff[0] 	= 'U';	
	reqbuff[1]	= ':';	
	reqbuff[2] 	= 0x00;
	reqbuff[3] 	= 0;		
	reqbuff[4] 	= 0;	
	reqbuff[5] 	= 0;

	rwdisk.write_ptr 	= framedat_rcvbuf;	// 设定接收应答帧数据域中数据的接收缓存	
	
	/* 发送系统信息查询请求帧 */
	SendRequest(reqbuff, 6);		
	
	/* 接收返回的系统信息到系统信息接收块 */
	if (TRUE == Wait_Ack())			
	{
		if (rwdisk.cmds == 0)
		{	
			sysinfptr->Baud  	= framedat_rcvbuf[0];
			sysinfptr->Year  	= framedat_rcvbuf[1];
			sysinfptr->Month 	= framedat_rcvbuf[2];
			sysinfptr->Dom   	= framedat_rcvbuf[3];
			sysinfptr->Hour  	= framedat_rcvbuf[4];
			sysinfptr->Min   	= framedat_rcvbuf[5];
			sysinfptr->Sec     	= framedat_rcvbuf[6];
				
			sysinfptr->DiskIn   = framedat_rcvbuf[7];
			sysinfptr->FH.fh    = framedat_rcvbuf[8];
			sysinfptr->FH.fsize = framedat_rcvbuf[9]+framedat_rcvbuf[10]*0x100+framedat_rcvbuf[11]*0x10000+framedat_rcvbuf[12]*0x1000000;
			sysinfptr->version  = framedat_rcvbuf[13];
			return (TRUE);
		}
	}
	return (FALSE);
}

/*********************************************************************************************************
** 函数名称: SetUDiskSysInfo
** 功能描述: 设置EasyUDisk的系统信息
** 输入参数: sysinfptr:		系统信息数据块指针
** 输出参数: TRUE:			正常应答返回
**			 FALSE:			超时出错返回
********************************************************************************************************/
uint8  SetUDiskSysInfo(SYSINF *sysinfptr)
{
	uint8	reqbuff[13];   					// 请求帧缓存,存储系统信息设置请求帧的全部信息
	uint8	framedat_rcvbuf[13];			// 应答帧数据域接收缓存

	rwdisk.write_ptr = framedat_rcvbuf;		// 设置用于接收应答帧数据域数据的接收缓存
	
	/* 初始化请求帧 */
	reqbuff[0]  = 'U';	
	reqbuff[1]  = ':';	
	reqbuff[2]  = 0x01;
	reqbuff[3]  = 0;		
	reqbuff[4]  = 7;	
	reqbuff[5]  = 0;
	reqbuff[6]  = sysinfptr->Baud ;
	reqbuff[7]  = sysinfptr->Year ;
	reqbuff[8]  = sysinfptr->Month;
	reqbuff[9]  = sysinfptr->Dom;
	reqbuff[10] = sysinfptr->Hour;
	reqbuff[11] = sysinfptr->Min;
	reqbuff[12] = sysinfptr->Sec;
				
	SendRequest(reqbuff, 13);		
	
	/* 接收应答帧,若指令执行成功则返回TRUE */
	if (Wait_Ack() == TRUE)					
	{
		if (rwdisk.cmds == CMD_SUCCESS)
		{	
			return (TRUE);
		}
	}
	return (FALSE);
}

/*********************************************************************************************************
** 函数名称: MakeDir
** 功能描述: 建立目录
** 输入参数: Path: 绝对路径或相对路径或目录名
** 输出参数: 若接收到应答则返回指令的执行状态;若没有接收到回应, 则返回0xff
********************************************************************************************************/
uint8 MakeDir(char *Path)
{
	uint8	reqbuff[6];
	uint8	framedat_rcvbuf[6];		 	// 应答帧数据域接收缓存
	uint8	ret;

	reqbuff[0] 	= 'U';
	reqbuff[1]	= ':';
	reqbuff[2] 	= 0x50;
	reqbuff[3] 	= 0xff;
	reqbuff[4] 	= strlen(Path);			// 目录名长度 
	reqbuff[5] 	= 0;
	
	/* 发送命令请求帧 */
	SendRequest(reqbuff, 6);			
	SendRequest((uint8*)Path, strlen(Path));	
	
	rwdisk.write_ptr = framedat_rcvbuf;
	
	/* 等待应答	*/
	if (Wait_Ack() == TRUE)					
	{
		ret = rwdisk.cmds;
	}
	else	
	{
		ret = 0xff;
	}	
	return (ret);
}

/*********************************************************************************************************
** 函数名称: ChangeDirDir
** 功能描述: 设置当前目录
** 输入参数: DirName:  设置目录的路径
** 输出参数: 为0表示正常,
**			 非零值为失败
********************************************************************************************************/
uint8 ChangeDir(char *DirName)
{
	uint8	reqbuff[6];
	uint8	framedat_rcvbuf[6];		 	// 应答帧数据域接收缓存
	uint8	namelen;
	uint8	ret;

	rwdisk.write_ptr = framedat_rcvbuf;
	
	reqbuff[0] = 'U';
	reqbuff[1] = ':';
	reqbuff[2] = 0x52;
	reqbuff[3] = 0x00;
	namelen    = strlen(DirName);			
	reqbuff[4] = namelen; 
	reqbuff[5] = 0;
	
	SendRequest(reqbuff, 6);					
	SendRequest((uint8*)DirName, namelen);	
	
	
	if (Wait_Ack()  == TRUE)					
	{
		if (rwdisk.cmds == CMD_SUCCESS)
		{	
			ret = 0;
		}
		else
		{
			ret = rwdisk.cmds;
		}
	}
	else	
	{
		ret = 0xff;						// 设备没响应
	}	
	return (ret);
}

/*********************************************************************************************************
** 函数名称: RemoveDir
** 功能描述: 删除指定的目录
** 输入参数: DirName:  被删除目录的名字或路径
** 输出参数: 为0表示正常删除目录,
**			 非零值为删除目录失败
********************************************************************************************************/
uint8 RemoveDir(char *DirName)
{
	uint8	reqbuff[6];
	uint8	framedat_rcvbuf[6];		 	// 应答帧数据域接收缓存
	uint8	namelen;
	uint8	ret;
	
	reqbuff[0] = 'U';
	reqbuff[1] = ':';
	reqbuff[2] = 0x53;
	reqbuff[3] = 0x00;
	namelen    = strlen(DirName);		// 获取文件名字符串长度
	reqbuff[4] = namelen; 
	reqbuff[5] = 0;
	
	SendRequest(reqbuff, 6);					
	SendRequest((uint8*)DirName, namelen);		
	
	rwdisk.write_ptr = framedat_rcvbuf;
	
	if (Wait_Ack() == TRUE)				// 等待应答

⌨️ 快捷键说明

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