📄 usbp.c
字号:
//*************************************************************************************************
// Module Name : USBP.C
// CreateDate : 2005-05-02
// ModifData : 2005-05-03
// Description :
// Author : 李远正
// Version : V1.0
//*************************************************************************************************
//
// U盘文件读写模块, 连接方式: 并口+( 中断 或 查询 )
// MCS-51单片机C语言示例程序, 仅适用于V2.5及以上版本的模块
// 因为使用U盘文件读写模块而不是使用U盘文件级子程序库,所以占用较少的单片机资源
#include <C8051F020.H>
#include <absacc.h>
#include "USBP.H"
/*
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//
CMD_PARAM mCmdParam; // 默认情况下该结构将占用64字节的RAM,可以修改MAX_PATH_LEN常量,当修改为32时,只占用32字节的RAM
unsigned char mIntStatus; // CH375模块的中断状态或者操作完成状态
*/
//*************************************************************************************************
// 对于模拟的并口读写时序或者其它并口读写方式,请修改以下3个子程序 mDelayuS( 1 );
#define CH375HM_INDEX_WR( Index ) { CH375HM_INDEX = ( Index ); } // 写索引地址
#define CH375HM_DATA_WR( Data ) { CH375HM_DATA = ( Data ); } // 写数据
#define CH375HM_DATA_RD( ) ( CH375HM_DATA ) // 读数据
//=================================================================================================
//=================================================================================================
// 并口连接方式
#if CH375HM_CONNECT == 1
//---------------------------------------------
// 中断方式
#if CH375HM_INT == 1
//-------------------------------------------------------------------------------------------------
// 1 uS Delay
void mDelayuS( unsigned char usecond )
{
unsigned char i;
while( usecond-- ) for( i=0; i<1; i++ );
}
//=================================================================================================
// 中断方式 : ExecCommand( );
//=================================================================================================
// 中断方式有两个子程序如下 :
//-------------------------------------------------------------------------------------------------
// CH375模块的中断服务程序
void CH375HMInterrupt( ) interrupt CH375HM_INT_NO
{
unsigned char status, i;
#define DataCount status // 节约一个变量单元
CH375HM_INT_N( ); // 关闭中断
CH375HM_INDEX_WR( 63 ); // 写入索引地址63
status = CH375HM_DATA_RD( ); // 从索引地址63读取中断状态
CH375HM_STA = 1; // 中断应答,取消来自模块的中断请求
mDelayuS( 3 ); // 3 uS
// 正在从U盘读数据块,请求数据读出.( 每次传输过程必须在2mS 时间之内完成,否则有些U 盘可能会工作不正常。)
if ( status == USB_INT_DISK_READ )
{
DataCount = 64; // 计数,从CH421的索引地址00H开始,连续取走64 字节的数据块
i = 0;
do // 要提高文件数据读写速度,这段程序用汇编程序效率更高,在C51中,do+while比for或者while结构效率高
{
CH375HM_INDEX_WR( i++ );
*buffer++ = CH375HM_DATA_RD( ); // 从索引地址0到63依次读出64字节的数据,保存到外部缓冲区
} while ( -- DataCount ); // 上面这一小段C程序用汇编程序效率要高近一倍
CH375HM_STA = 0; // 产生下降沿通知模块继续,说明64字节数据已经读取完成
}
// 正在向U盘写数据块,请求数据写入.( 每次传输过程必须在2mS 时间之内完成,否则有些U 盘可能会工作不正常。)
else if ( status == USB_INT_DISK_WRITE )
{
CH375HM_INDEX_WR( 0 );
i = 64;
do // 要提高文件数据读写速度,这段程序用汇编程序写效率更高,在C51中,do+while比for或者while结构效率高
{
CH375HM_DATA_WR( *buffer++ ); // 向索引地址0到63依次写入64字节的数据,写入的数据来自外部缓冲区
} while ( -- i );
CH375HM_STA = 0; // 产生下降沿通知模块继续,说明64字节数据已经写入完成
}
// 读写数据块失败重试,应该向回修改缓冲区指针
else if ( status == USB_INT_DISK_RETRY )
{
CH375HM_INDEX_WR( 0 );
i = CH375HM_DATA_RD( ); // 大端模式下为回改指针字节数的高8位,如果是小端模式那么接收到的是回改指针字节数的低8位
CH375HM_INDEX_WR( 1 );
DataCount = CH375HM_DATA_RD( ); // 大端模式下为回改指针字节数的低8位,如果是小端模式那么接收到的是回改指针字节数的高8位
buffer -= ( (unsigned short)i << 8 ) + DataCount; // 这是大端模式下的回改指针,对于小端模式,应该是( (unsigned short)status << 8 ) + i
CH375HM_STA = 0; // 产生下降沿通知模块继续,说明重试状态码已经处理完成
}
// 是事件通知状态或者操作完成状态,保存中断状态
else
{
mIntStatus = status;
// while( CH375HM_INT_WIRE == 0 ); 如果是电平方式的中断,那么应该等待中断请求引脚无效,模块应该在收到中断应答后的3uS撤消中断
}
CH375HM_INT_FLAGN( ); // 清中断标志
CH375HM_INT_EN( ); // 允许中断
}
//-------------------------------------------------------------------------------------------------
// 执行命令
// 输入命令码和输入参数长度,返回操作状态码,输入参数和返回参数都在CMD_PARAM结构中
unsigned char ExecCommand( unsigned char cmd, unsigned char len )
{
unsigned char i, j, status;
unsigned char data *buf;
CH375HM_INT_N( ); // 关闭中断,防止中断应答修改模块的索引地址,如果是查询中断则不必关闭中断
CH375HM_INDEX_WR( 0 ); // 索引地址置0
CH375HM_DATA_WR( cmd ); // 向索引地址00H写入命令码
CH375HM_DATA_WR( len ); // 向索引地址01H写入后续参数的长度
if ( len ) // 有参数
{
i = len;
buf = (unsigned char *)&mCmdParam; // 指向输入参数的起始地址
do // 使用do+while结构是因为其效率高于for
{
CH375HM_DATA_WR( *buf++ ); // 从索引地址02H开始,写入参数
} while ( -- i );
}
mIntStatus = 0xFF; // 清中断状态
CH375HM_INT_EN( ); // 允许中断
CH375HM_STA = 0; // 产生下降沿通知模块,说明命令包已经写入,请求开始执行命令
while ( mIntStatus == 0xFF ); // 等待模块完成操作并返回操作状态 ( Waiting for interrupt )
status = mIntStatus;
if ( status == ERR_SUCCESS ) // 操作成功
{
CH375HM_INT_N( ); // 关闭中断,防止中断应答修改模块的索引地址,如果是查询中断则不必关闭中断
CH375HM_INDEX_WR( 1 );
i = CH375HM_DATA_RD( ); // 从索引地址01H读取返回结果数据的长度
if ( i ) // 有结果数据
{
buf = (unsigned char *)&mCmdParam; // 指向输出参数的起始地址
j = 2;
do // 使用do+while结构是因为其效率高于for
{
CH375HM_INDEX_WR( j++ );
*buf++ = CH375HM_DATA_RD( ); // 从索引地址02H开始,读取结果
} while ( -- i );
}
CH375HM_INT_EN( ); // 允许中断
}
else // 操作失败
{
if ( status == ERR_DISK_DISCON || status == ERR_USB_CONNECT ) mDelaymS( 100 ); // U盘刚刚连接或者断开,应该延时几十毫秒再操作
}
return( status );
}
//---------------------------------------------
// 查询方式
#else
//=================================================================================================
// 查询方式 : ExecCommand( );
//=================================================================================================
//
//-------------------------------------------------------------------------------------------------
// 执行命令
// 输入命令码和输入参数长度,返回操作状态码,输入参数和返回参数都在CMD_PARAM结构中
unsigned char ExecCommand( unsigned char cmd, unsigned char len )
{
unsigned char i, status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -