历史上的今天
返回首页

历史上的今天

今天是:2025年02月18日(星期二)

正在发生

2020年02月18日 | CH375_CH376 U盘读写模块在51单片机上的应用

2020-02-18 来源:51hei

电路原理图如下:
 

ch375资料手册:
 


本程序的接线图:

单片机源程序如下(host.c文件):

/* 

****************************************

**  Copyright  (C)  W.ch  1999-2004   **

****************************************

**  USB Host File Interface for CH375 **

**  TC2.0@PC, KC7.0@MCS51             **

****************************************

*/

/* CH375 主机文件系统接口 */

/* 支持: FAT12/FAT16/FAT32 */


/* MCS-51单片机C语言的U盘文件读写示例程序, 适用于89C52或者更大程序空间的单片机,也适用于ATMEL/PHILIPS/SST等具有1KB内部RAM的单片机 */

/* 该程序将U盘中的/C51/CH375HFT.C文件中的前200个字符显示出来,

   如果找不到原文件CH375HFT.C, 那么该程序将显示C51子目录下所有以CH375开头的文件名,

   如果找不到C51子目录, 那么该程序将显示根目录下的所有文件名,

   最后将程序ROM中的一个字符串写入写入新建的文件"NEWFILE.TXT"中

*/

/* CH375的INT#引脚采用查询方式处理, 数据复制方式为"单DPTR复制",兼容性最好但是速度最慢,

   本例只使用512字节的外部RAM, 同时作为磁盘数据缓冲区和文件数据缓冲区, 演示没有外部RAM但是单片机的内置RAM大于768字节的应用 */


/* 本例以字节为单位读写U盘文件,读写速度较扇区模式慢,但是由于字节模式读写文件不需要文件数据缓冲区FILE_DATA_BUF,

   所以总共只需要600字节的RAM,适用于单片机硬件资源有限、数据量小并且读写速度要求不高的系统 */


/*#define         NO_DEFAULT_CH375_INT                1*/        /* 在应用程序中定义NO_DEFAULT_CH375_INT可以禁止默认的中断处理程序,然后用自行编写的程序代替它 */

/*#define                CH375HF_NO_CODE                1*/

#include "CH375.H"


#ifdef        NO_DEFAULT_CH375_INT                        /* 自行编写中断处理程序,加上了超时处理,并且在等待中断的过程中可以做其它事 */

void xQueryInterrupt( void )                        /* 查询CH375中断并更新中断状态,该程序基本框架可以参考CH375HF?.H文件 */

{

        UINT16        i;

        for ( i = 65535; i != 0; i -- ) {  /* 正常情况下该过程为几毫秒到几十毫秒,偶尔也会达到几百毫秒 */

                if ( CH375_INT_WIRE == 0 ) break;  /* 如果CH375的中断引脚输出低电平则说明CH375操作完成 */

/*                if ( ( CH375_CMD_PORT & 0x80 ) == 0 ) break;  对于CH375B芯片,也查询CH375B的命令端口的位7为0说明中断引脚输出低电平 */

        }

        if ( i == 0 )

        CH375_CMD_PORT = CMD_GET_STATUS;  /* 获取当前中断状态 */

        mDelay2uS( );  /* 操作无意义,用于至少延时2uS,可以用多个NOP空操作指令实现 */

        CH375IntStatus = CH375_DAT_PORT;  /* 获取中断状态 */

        if ( CH375IntStatus == USB_INT_DISCONNECT ) CH375DiskStatus = DISK_DISCONNECT;  /* 检测到USB设备断开事件 */

        else if ( CH375IntStatus == USB_INT_CONNECT ) CH375DiskStatus = DISK_CONNECT;  /* 检测到USB设备连接事件 */

}

#endif


/* 以毫秒为单位延时,不精确,适用于24MHz时钟 */

void        mDelaymS( UINT8 delay )

{

        unsigned char        i, j, c;

        for ( i = delay; i != 0; i -- ) {

                for ( j = 200; j != 0; j -- ) c += 3;  /* 在24MHz时钟下延时500uS */

                for ( j = 200; j != 0; j -- ) c += 3;  /* 在24MHz时钟下延时500uS */

        }

}


/* 将程序空间的字符串复制到内部RAM中,返回字符串长度 */

UINT8        mCopyCodeStringToIRAM( UINT8 idata *iDestination, UINT8 code *iSource )

{

        UINT8        i = 0;

        while ( *iDestination = *iSource ) {

                iDestination ++;

                iSource ++;

                i ++;

        }

        return( i );

}


/* 检查操作状态,如果错误则显示错误代码并停机 */

void        mStopIfError( UINT8 iError )

{

        if ( iError == ERR_SUCCESS ) return;  /* 操作成功 */

        printf( "Error: %02Xn", (UINT16)iError );  /* 显示错误 */

        while ( 1 ) {

                LED_UDISK_IN( );  /* LED闪烁 */

                mDelaymS( 100 );

                LED_UDISK_OUT( );

                mDelaymS( 100 );

        }

}


void host( ) {

        UINT8        i, c, TotalCount;

        UINT8        code *pCodeStr;

        UINT16        EnumCount;


#if DISK_BASE_BUF_LEN == 0

        pDISK_BASE_BUF = &my_buffer[0];  /* 不在.H文件中定义CH375的专用缓冲区,而是用缓冲区指针指向其它应用程序的缓冲区便于合用以节约RAM */

#endif


        i = CH375LibInit( );  /* 初始化CH375程序库和CH375芯片,操作成功返回0 */

        mStopIfError( i );

        while ( 1 ) {

                printf( "Insert USB diskn" );

                while ( CH375DiskStatus < DISK_CONNECT ) {  /* 等待U盘插入 */

                

/*                        if ( CH375_INT_WIRE == 0 ) xQueryInterrupt( );*/  /* 如果CH375中断,那么查询CH375中断并更新中断状态,可以改成中断方式 */

                        mDelaymS( 100 );  /* 没必要频繁查询 */

                        if ( CH375DiskConnect( ) == ERR_SUCCESS ) break;        /* 查询方式: 检查磁盘是否连接,返回成功说明连接 */

                }

                LED_UDISK_IN( );  /* LED亮 */

                mDelaymS( 250 );  /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */


/* 检查U盘是否准备好,但是某些U盘必须要执行这一步才能工作 */

                for ( i = 0; i < 5; i ++ ) {  /* 有的U盘总是返回未准备好,不过可以被忽略 */

                        mDelaymS( 100 );

                        printf( "Ready ?n" );

//                        if ( CH375DiskReady( ) == ERR_SUCCESS ) break;  /* 查询磁盘是否准备好,不支持CH375S,节约代码空间 */

                        if ( CH375sDiskReady( ) == ERR_SUCCESS ) break;  /* 查询磁盘是否准备好,支持CH375S和CH375A,但占用更多的代码空间 */

                }


#if DISK_BASE_BUF_LEN

                if ( DISK_BASE_BUF_LEN < CH375vSectorSize ) {  /* 检查磁盘数据缓冲区是否足够大,CH375vSectorSize是U盘的实际扇区大小 */

                        printf( "Too large sector sizen" );

                        while ( CH375DiskConnect( ) == ERR_SUCCESS ) mDelaymS( 100 );

                        continue;

                }

#endif

/* 读取原文件 */

                printf( "Openn" );

                mCopyCodeStringToIRAM( mCmdParam.Open.mPathName, "/LCSOFT.TXT" );  /* 文件名,该文件在C51子目录下 */

                i = CH375FileOpen( );  /* 打开文件 */

                if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) {  /* 没有找到C51子目录,没有找到CH375HFT.C文件 */

/* 列出文件 */

                        if ( i == ERR_MISS_DIR ) pCodeStr = "/*";  /* C51子目录不存在则列出根目录下的所有文件 */

                        else pCodeStr = "/LC*";  /* CH375HFT.C文件不存在则列出C51子目录下的以CH375开头的文件 */

                        printf( "List file %sn", pCodeStr );

                        for ( EnumCount = 0; EnumCount < 10000; EnumCount ++ ) {  /* 最多搜索前10000个文件,实际上没有限制 */

                                i = mCopyCodeStringToIRAM( mCmdParam.Open.mPathName, pCodeStr );  /* 搜索文件名,*为通配符,适用于所有文件或者子目录 */

                                mCmdParam.Open.mPathName[ i ] = 0xFF;  /* 根据字符串长度将结束符替换为搜索的序号,从0到254,如果是0xFF即255则说明搜索序号在CH375vFileSize变量中 */

                                CH375vFileSize = EnumCount;  /* 指定搜索/枚举的序号 */

                                i = CH375FileOpen( );  /* 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 */

/* CH375FileEnum 与 CH375FileOpen 的唯一区别是当后者返回ERR_FOUND_NAME时那么对应于前者返回ERR_SUCCESS */

                                if ( i == ERR_MISS_FILE ) break;  /* 再也搜索不到匹配的文件,已经没有匹配的文件名 */

                                if ( i == ERR_FOUND_NAME ) {  /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */

                                        printf( "  match file %04d#: %sn", (unsigned int)EnumCount, mCmdParam.Open.mPathName );  /* 显示序号和搜索到的匹配文件名或者子目录名 */

推荐阅读

史海拾趣

Alcatel-Lucent公司的发展小趣事
  1. Alcatel-Lucent 的起源可以追溯到 19 世纪末的法国。1880 年,一家名为 Compagnie Générale d'Électricité (CGE) 的公司在法国成立,主要从事电信和电气设备的制造和销售。这家公司后来成为了 Alcatel-Lucent 的前身之一。

  2. 20 世纪初,CGE 开始涉足电信领域,并开始在法国和国际市场上发展。该公司逐渐成为了一家领先的电信设备制造商,并参与了许多重要的电信基础设施项目。

  3. 2006 年,法国的 Alcatel 和美国的 Lucent Technologies 公司宣布合并,成立了 Alcatel-Lucent 公司。这次合并创造了一个综合性的电信设备制造商,覆盖了通信网络、软件和服务等多个领域。

  4. 合并后,Alcatel-Lucent 成为了全球领先的电信设备供应商之一,为全球各地的电信运营商提供了广泛的产品和解决方案,包括固定和移动网络、光纤通信、宽带接入和数据中心等领域。

  5. 在成立后的几年里,Alcatel-Lucent 继续推出创新的产品和技术,包括下一代移动通信技术 LTE、IP/MPLS 网络和云计算解决方案等,为数字化时代的通信基础设施发展做出了重要贡献。

台湾富致(FUZETEC)公司的发展小趣事

Futaba Electric最初起源于收音机收讯真空管的制造,但在1970年,公司做出了重大的战略调整,决定结束真空管业务,专注于萤光表示管(VFD)的生产。这一决策标志着公司从传统电子元件向高级显示技术的转型。随着VFD技术的不断发展,Futaba凭借其在清晰度、视角和亮度方面的卓越表现,逐渐在全球VFD市场中占据领先地位,目前市场份额超过60%。这一转型不仅使Futaba成为VFD技术的领导者,还为其在汽车仪表盘和抬头显示器等领域的广泛应用奠定了基础。

兆易创新(GigaDevice)公司的发展小趣事

为了更好地服务于中国市场,Futaba在2002年成立了双叶电子科技开发(北京)有限公司。该公司专营Futaba的全线产品,包括VFD真空荧光显示管和RC无线遥控设备等。这一举措标志着Futaba在全球化布局上迈出了重要一步,也为公司在中国市场的快速发展奠定了基础。北京分公司的成立不仅加强了Futaba与中国客户的联系,还促进了公司在技术、产品和市场等方面的全方位合作。

Blaze Display Technology Co Ltd公司的发展小趣事

随着技术的不断进步,Blaze公司意识到要想在激烈的市场竞争中立于不败之地,必须不断进行技术创新和品质升级。因此,公司加大了研发投入,引进了一批高端技术人才和先进设备,成功研发出了多项具有自主知识产权的核心技术。同时,公司还严格把控产品质量,确保每一块显示屏都达到行业领先水平。

General Magnetics Inc公司的发展小趣事
用于电力传输和分配过程中的电压变换。
品赞(G-Switch)公司的发展小趣事
检查控制回路中的接线是否正确,各元件是否损坏。

问答坊 | AI 解惑

igbt问题

请问高手:IGBT驱动波形,什么样算正常。我的电路中给IGBT全桥加上直流电压后,栅极驱动波形上就会有高次谐波(在上升和下降沿附近) 如何解决。谢谢…

查看全部问答>

中国IC设计企业的艰难与勇气

下午有幸见到芯慧同用的董事长罗晋,不知不觉聊了近3个小时。比起人人都知道的中星微、展讯,芯慧同用只是一家还默默无闻的小公司。说实话,我真不知道该怎么样介绍罗晋,因为他同时还是另一家公司华视奇的高管。而在北京海淀知春路量子银座的501室 ...…

查看全部问答>

程控音频功率放大器

本帖最后由 paulhyde 于 2014-9-15 09:27 编辑 程控音频功率放大器怎么做啊!有知道的没?  …

查看全部问答>

一款30MHz频段无线收发电路

30MHzp频段无线收发简单电路的资料比较少,是因为这个频段传输速率受到很大的限制.。这个收发电路使用3V供电,使用直径34MM的电感线圈作为收发的共用天线,使用半双工收发,距离可以到数十米远,现把电路传上,仅共参考。 发现问题及时交流。…

查看全部问答>

别人整理的电源设计谜团

别人整理的电源设计谜团…

查看全部问答>

pxa270wince下大页面nandflash驱动的问题?

我最近在做pxa270wince下大页面nandflash的驱动,更改了read,write函数后,在控制面板里可以看到这个设备,容量显示也是正确的,可是一格式化,就在FMD_SetBlockStatus中把每一个block立刻mark成bad,不知道该如何解决,有做过这个的大大给我讲一下 ...…

查看全部问答>

内存映射文件创建失败

想在wince下用内存映射文件的方式读文件,这样会快些,在VC上试过了,可行.所以想移动wince下,但现在有个问题就是在CreateFileMapping就过不去了,返回为空.有人做过的指点下吧..多谢                  & ...…

查看全部问答>

几周来学习STM32的小实验:用STM32内置的高速ADC实现简易示波

    这几周一直在埋头学习STM32,在论坛上学到了不少知识,得到了大家的帮助,这里衷心的向大家表示感谢,尤其是特别要感谢论坛上GRANT_JX大大:)正是有幸得到了他热心相赠的STM32F103VB芯片以及评估版的PCB,我才能够顺 ...…

查看全部问答>

有源滤波器求助

本帖最后由 paulhyde 于 2014-9-15 09:47 编辑 有源滤波器求助,为什么我制作的SK有源滤波器总会自激振荡啊?设计上感觉没有任何问题,有谁遇到过类似的问题吗?  …

查看全部问答>