找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8108|回复: 10
打印 上一主题 下一主题
收起左侧

单片机+ch375读U盘 5110液晶显示

  [复制链接]
跳转到指定楼层
楼主



电路原理图


ch375与单片机接线图.jpg
  1. #include <reg52.h>
  2. #include <stdio.h>
  3. #include "CH375HF4.H"
  4. #include "5110.H"

  5. #define           CH375HF_NO_CODE                1
  6. sbit P22=P2^2;
  7. sbit P23=P2^3;
  8. //uchar num=0;
  9. /* 以下定义的详细说明请看CH375HF4.H文件 */
  10. #define LIB_CFG_DISK_IO                        1                /* 磁盘读写的数据的复制方式,1为"单DPTR复制",2为"双DPTR复制",3为"单DPTR和P2+R0复制" */
  11. #define LIB_CFG_FILE_IO                        1                /* 文件读写的数据的复制方式,0为"外部子程序",1为"单DPTR复制",2为"双DPTR复制",3为"单DPTR和P2+R0复制" */
  12. #define LIB_CFG_INT_EN                        0                /* CH375的INT#引脚连接方式,0为"查询方式",1为"中断方式" */

  13. #define CH375_CMD_PORT_ADDR                0xBeF1        /* CH375命令端口的I/O地址 */
  14. #define CH375_DAT_PORT_ADDR                0xBCF0        /* CH375数据端口的I/O地址 */
  15. /* 只使用单片机内置的1KB外部RAM: 0000H-01FFH 为磁盘读写缓冲区, 以字节为单位读写文件不需要文件数据读写缓冲区FILE_DATA_BUF */
  16. #define        DISK_BASE_BUF_ADDR                0x0000        /* 外部RAM的磁盘数据缓冲区的起始地址,从该单元开始的缓冲区长度为SECTOR_SIZE */

  17. #define CH375_INT_WIRE                        INT0        /* P3.2, INT0, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */

  18. #define NO_DEFAULT_CH375_F_ENUM                1                /* 未调用CH375FileEnumer程序故禁止以节约代码 */
  19. #define NO_DEFAULT_CH375_F_QUERY        1                /* 未调用CH375FileQuery程序故禁止以节约代码 */



  20. #ifdef        NO_DEFAULT_CH375_INT                        /* 自行编写中断处理程序,加上了超时处理,并且在等待中断的过程中可以做其它事 */
  21. void xQueryInterrupt( void )                        /* 查询CH375中断并更新中断状态,该程序基本框架可以参考CH375HF?.H文件 */
  22. {
  23.         UINT16        i;
  24.         for ( i = 65535; i != 0; i -- ) {  /* 正常情况下该过程为几毫秒到几十毫秒,偶尔也会达到几百毫秒 */
  25. //                if ( CH375_INT_WIRE == 0 ) break;  /* 如果CH375的中断引脚输出低电平则说明CH375操作完成 */
  26.                 if ( ( CH375_CMD_PORT & 0x80 ) == 0 ) break; // 对于CH375B芯片,也查询CH375B的命令端口的位7为0说明中电平
  27. //                在等待CH375中断的过程中,可以做些需要及时处理的事情
  28.         }
  29.         if ( i == 0 ) //CH375超时,通常是硬件问题;
  30.         CH375_CMD_PORT = CMD_GET_STATUS;  /* 获取当前中断状态 */
  31.         mDelay2uS( );  /* 操作无意义,用于至少延时2uS,可以用多个NOP空操作指令实现 */
  32.         CH375IntStatus = CH375_DAT_PORT;  /* 获取中断状态 */
  33.         if ( CH375IntStatus == USB_INT_DISCONNECT ) CH375DiskStatus = DISK_DISCONNECT;  /* 检测到USB设备断开事件 */
  34.         else if ( CH375IntStatus == USB_INT_CONNECT ) CH375DiskStatus = DISK_CONNECT;  /* 检测到USB设备连接事件 */
  35. }
  36. #endif

  37. /* 以毫秒为单位延时,不精确,适用于24MHz时钟 */
  38. void        mDelaymS( UINT8 delay )
  39. {
  40.         unsigned char        i, j, c;
  41.         for ( i = delay; i != 0; i -- ) {
  42.                 for ( j = 200; j != 0; j -- ) c += 3;  /* 在24MHz时钟下延时500uS */
  43.                 for ( j = 200; j != 0; j -- ) c += 3;  /* 在24MHz时钟下延时500uS */
  44.         }
  45. }

  46. /* 将程序空间的字符串复制到内部RAM中,返回字符串长度 */
  47. UINT8        mCopyCodeStringToIRAM( UINT8 idata *iDestination, UINT8 code *iSource )
  48. {
  49.         UINT8        i = 0;
  50.         while ( *iDestination = *iSource ) {
  51.                 iDestination ++;
  52.                 iSource ++;
  53.                 i ++;
  54.         }
  55.         return( i );
  56. }

  57. /* 检查操作状态,如果错误则显示错误代码并停机 */
  58. void        mStopIfError( UINT8 iError )
  59. {
  60.         if ( iError == ERR_SUCCESS ) return;  /* 操作成功 */
  61.         printf( "Error: %02X\n", (UINT16)iError );  /* 显示错误 */
  62.         while ( 1 );


  63. }

  64. void host( )
  65. {
  66.         UINT8        i, c, TotalCount;
  67.         UINT8        code *pCodeStr;
  68.         UINT16        EnumCount;

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

  72.         i = CH375LibInit( );  /* 初始化CH375程序库和CH375芯片,操作成功返回0 */
  73.        
  74.         mStopIfError( i );        /* 检查操作状态,如果错误则显示错误代码并停机 */

  75. while ( 1 )
  76.   {
  77.         //        printf( "Insert USB disk\n" );
  78.         LCD_write_hanzi(0,2,2);  //插       
  79.         LCD_write_hanzi(1,2,3);  //入
  80.         LCD_write_shu(4,2,6);  //u
  81.         LCD_write_hanzi(3,2,4);  //盘
  82.     LCD_write_shu(8,2,5);  //.
  83.         LCD_write_shu(9,2,5);  //.
  84.         LCD_write_shu(10,2,5);  //.
  85.         LCD_write_shu(11,2,5);  //.
  86.                 while ( CH375DiskStatus < DISK_CONNECT )   /* 等待U盘插入 */
  87.                 {          CH375LibInit( );
  88. /*                        if ( CH375_INT_WIRE == 0 ) xQueryInterrupt( );*/  /* 如果CH375中断,那么查询CH375中断并更新中断状态,可以改成中断方式 */
  89.                         mDelaymS( 100 );  /* 没必要频繁查询 */
  90.                         if ( CH375DiskConnect( ) == ERR_SUCCESS ) break;        /* 查询方式: 检查磁盘是否连接,返回成功说明连接 */
  91.                 }

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


  94. /* 检查U盘是否准备好,但是某些U盘必须要执行这一步才能工作 */
  95.                 for ( i = 0; i < 5; i ++ )   /* 有的U盘总是返回未准备好,不过可以被忽略 */
  96.                 {        mDelaymS( 100 );
  97.                 //        printf( "Ready ?\n" );

  98.           LCD_write_shu(0,4,7);  //r
  99.           LCD_write_shu(1,4,8);  //e
  100.           LCD_write_shu(2,4,9);  //a
  101.           LCD_write_shu(3,4,10);  //d
  102.         LCD_write_shu(4,4,11);  //y
  103.         LCD_write_shu(5,4,12);  //?
  104.         LCD_write_shu(6,4,13);  //


  105.                         if ( CH375DiskReady( ) == ERR_SUCCESS ) break;  /* 查询磁盘是否准备好,不支持CH375S,节约代码空间 */
  106. //                        if ( CH375sDiskReady( ) == ERR_SUCCESS ) break;  /* 查询磁盘是否准备好,支持CH375S和CH375A,但占用更多的代码空间 */
  107.                 }

  108. #if DISK_BASE_BUF_LEN
  109.                 if ( DISK_BASE_BUF_LEN < CH375vSectorSize )   /* 检查磁盘数据缓冲区是否足够大,CH375vSectorSize是U盘的实际扇区大小 */
  110.                 {        printf( "Too large sector size\n" );
  111.                         while ( CH375DiskConnect( ) == ERR_SUCCESS ) mDelaymS( 100 );
  112.                         continue;
  113.                 }
  114. #endif
  115.                  while(1)
  116.         {
  117.                  if(P22==0)          //判断是否按下
  118.         { mDelaymS( 5 );           //延时
  119.                if(P22==0)           //确实按下

  120.          while(!P22);        //松手检测
  121.                  mDelaymS( 5 );
  122.            while(!P22);
  123.                     break;
  124.            }
  125.                  
  126.          }
  127.         //        printf( "Open\n" );
  128.                 LCD_clear(); //清屏幕
  129.           LCD_write_shu(0,0,14);  //o
  130.           LCD_write_shu(1,0,15);  //p
  131.           LCD_write_shu(2,0,16);  //e
  132.           LCD_write_shu(3,0,17);  //n


  133.                 mCopyCodeStringToIRAM( mCmdParam.Open.mPathName, "/QQ.TXT" );  /* 文件名*/
  134.                 i = CH375FileOpen( );  /* 打开文件 */
  135.                 if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE )   /* 没有找到子目录,没有找到文件名 */
  136.        {
  137.                         if ( i == ERR_MISS_DIR ) pCodeStr = "/*";  /* 子目录不存在则列出根目录下的所有文件 */
  138.                         else pCodeStr = "/QQ*";  /* 文件不存在则列出子目录下的以文件名开头的文件 */
  139.                 //        printf( "List file %s\n", pCodeStr );


  140.                         for ( EnumCount = 0; EnumCount < 10000; EnumCount ++ )  /* 最多搜索前10000个文件,实际上没有限制 */
  141.                         {         i = mCopyCodeStringToIRAM( mCmdParam.Open.mPathName, pCodeStr );  /* 搜索文件名,*为通配符,适用于所有文件或者子目录 */
  142.                                 mCmdParam.Open.mPathName[ i ] = 0xFF;  /* 根据字符串长度将结束符替换为搜索的序号,从0到254,如果是0xFF即255则说明搜索序号在CH375vFileSize变量中 */
  143.                                 CH375vFileSize = EnumCount;  /* 指定搜索/枚举的序号 */
  144.                                 i = CH375FileOpen( );  /* 打开文件,如果文件名中含有通配符*,则为搜索文件而不打开 */
  145.                                      /* CH375FileEnum 与 CH375FileOpen 的唯一区别是当后者返回ERR_FOUND_NAME时那么对应于前者返回ERR_SUCCESS */
  146.                                 if ( i == ERR_MISS_FILE ) break;  /* 再也搜索不到匹配的文件,已经没有匹配的文件名 */
  147.                                 if ( i == ERR_FOUND_NAME )  /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */
  148.                                  {         printf( "  match file %04d#: %s\n", (unsigned int)EnumCount, mCmdParam.Open.mPathName );  /* 显示序号和搜索到的匹配文件名或者子目录名 */
  149.                                         continue;  /* 继续搜索下一个匹配的文件名,下次搜索时序号会加1 */
  150.                               }
  151.                                 else   /* 出错 */
  152.                                 {        mStopIfError( i );
  153.                                         break;
  154.                                 }
  155.                     }
  156.             }
  157.                 else   /* 找到文件或者出错 */
  158.                 {        mStopIfError( i );
  159.                         TotalCount = CH375vFileSize;  /* 准备读取总长度 */
  160.                 //        printf( "从文件中读出的前%d个字符是:\n",(UINT16)TotalCount );

  161.                     LCD_write_hanzi(0,2,5);  //文       
  162.         LCD_write_hanzi(1,2,6);  //件
  163.         LCD_write_hanzi(2,2,7);  //名
  164.         LCD_write_shu(6,2,18);  //:
  165.         LCD_write_shu(7,2,19);  //q
  166.         LCD_write_shu(8,2,19);  //q
  167.     LCD_write_shu(9,2,5);  //.
  168.         LCD_write_shu(10,2,20);  //t
  169.         LCD_write_shu(11,2,21);  //x
  170.         LCD_write_shu(12,2,20);  //t

  171.                 while(1)
  172.          {
  173.                  if(P22==0)          //判断是否按下
  174.         { mDelaymS( 5 );           //延时
  175.                if(P22==0)           //确实按下

  176.          while(!P22);        //松手检测
  177.                  mDelaymS( 5 );
  178.            while(!P22);
  179.                     break;
  180.            }
  181.      }
  182.                           LCD_clear(); //清屏幕
  183.                  LCD_write_hanzi(0,0,8);  //内
  184.         LCD_write_hanzi(1,0,9);  //容
  185.         LCD_write_shu(4,0,18);  //:
  186.        
  187.         LCD_write_hanzi(0,2,10);  //创
  188.         LCD_write_hanzi(1,2,11);  //新
  189.            LCD_write_hanzi(2,2,12);  //实
  190.         LCD_write_hanzi(3,2,13);  //验
  191.         LCD_write_hanzi(4,2,14); //室
  192.                 LCD_write_hanzi(5,2,21); //室

  193.         LCD_write_shu(0,4,22);  //v
  194.     LCD_write_shu(1,4,16);  //e
  195.         LCD_write_shu(2,4,7);  //r
  196.         LCD_write_shu(3,4,11);  //y
  197.         LCD_write_shu(4,4,13);  //
  198.     LCD_write_shu(5,4,23);  //g
  199.     LCD_write_shu(6,4,14);  //o
  200.         LCD_write_shu(7,4,14);  //o
  201.         LCD_write_shu(8,4,10);  //d
  202.         LCD_write_shu(9,4,24);  //!


  203.                         while ( TotalCount )   /* 如果文件比较大,一次读不完,可以再调用CH375ByteRead继续读取,文件指针自动向后移动 */
  204.                    {                if ( TotalCount > MAX_BYTE_IO ) c = MAX_BYTE_IO;  /* 剩余数据较多,限制单次读写的长度不能超过 sizeof( mCmdParam.ByteRead.mByteBuffer ) */
  205.                                 else c = TotalCount;  /* 最后剩余的字节数 */
  206.                                 mCmdParam.ByteRead.mByteCount = c;  /* 请求读出几十字节数据 */
  207.                                 i = CH375ByteRead( );  /* 以字节为单位读取数据块,单次读写的长度不能超过MAX_BYTE_IO,第二次调用时接着刚才的向后读 */
  208.                                 mStopIfError( i );
  209.                                 TotalCount -= mCmdParam.ByteRead.mByteCount;  /* 计数,减去当前实际已经读出的字符数 */
  210.                                 for ( i=0; i!=mCmdParam.ByteRead.mByteCount; i++ ) printf( "%C", mCmdParam.ByteRead.mByteBuffer[i] );  /* 显示读出的字符 */
  211.                                 if ( mCmdParam.ByteRead.mByteCount < c )   /* 实际读出的字符数少于要求读出的字符数,说明已经到文件的结尾 */
  212.                                 {        printf( "\n" );
  213.                                         printf( "文件已经结束\n" );
  214.                                         break;
  215.                                 }
  216.                 }

  217.                         printf( "Close\n" );
  218.                         i = CH375FileClose( );  /* 关闭文件 */
  219.                         mStopIfError( i );
  220.                  }

  221. #ifdef EN_DISK_WRITE  /* 子程序库支持写操作 */
  222. /* 产生新文件(覆盖原文件数据),关于向原有文件中添加数据的例子请参考EXAM7和EXAM8 */

  223.                 //printf( "Create\n" );
  224.                 mCopyCodeStringToIRAM( mCmdParam.Create.mPathName, "/QQ.TXT" );  /* 新文件名,在根目录下,中文文件名 */
  225.                 i = CH375FileCreate( );  /* 新建文件并打开,如果文件已经存在则先删除后再新建 */
  226.                 mStopIfError( i );
  227.                 //printf( "Write\n" );
  228.                                 while(1)
  229.          {
  230.                  if(P22==0)          //判断是否按下
  231.         { mDelaymS( 5 );           //延时
  232.                if(P22==0)           //确实按下

  233.          while(!P22);        //松手检测
  234.                  mDelaymS( 5 );
  235.            while(!P22);
  236.                     break;
  237.            }
  238.      }
  239.                         LCD_clear(); //清屏幕
  240.                  LCD_write_hanzi(0,0,15);  //写
  241.         LCD_write_hanzi(1,0,5);  //文       
  242.         LCD_write_hanzi(2,0,6);  //件

  243.        
  244.         LCD_write_hanzi(0,2,16);  //覆
  245.         LCD_write_hanzi(1,2,17);  //盖
  246.            LCD_write_hanzi(2,2,18);  //原
  247.         LCD_write_hanzi(3,2,5);  //文
  248.         LCD_write_hanzi(4,2,6); //件



  249.                 pCodeStr = "wangmaoquan163\xd\xavery good!\xd\xa";
  250.                 while( 1 )   /* 分多次写入文件数据 */
  251.            {   for ( i=0; i<MAX_BYTE_IO; i++ )
  252.                         {        c = *pCodeStr;
  253.                                 mCmdParam.ByteWrite.mByteBuffer[i] = c;
  254.                                 if ( c == 0 ) break;  /* 源字符串结束 */
  255.                                 pCodeStr++;
  256.                     }
  257.                         if ( i == 0 ) break;  /* 源字符串结束,完成写文件 */
  258.                         mCmdParam.ByteWrite.mByteCount = i;  /* 写入数据的字符数,单次读写的长度不能超过MAX_BYTE_IO,第二次调用时接着刚才的向后写 */
  259.                         i = CH375ByteWrite( );  /* 向文件写入数据 */
  260.                         mStopIfError( i );
  261.                 }
  262.         //        printf( "Close\n" );

  263.                 LCD_write_shu(0,4,14);  //o
  264.                 LCD_write_shu(1,4,25);  //k
  265.                  LCD_write_shu(2,4,24);  //!

  266.                 mCmdParam.Close.mUpdateLen = 1;  /* 自动计算文件长度,以字节为单位写文件,建议让程序库关闭文件以便自动更新文件长度 */
  267.                 i = CH375FileClose( );
  268.                 mStopIfError( i );
  269. #endif






  270.         //        printf( "Take out USB disk\n" );
  271. //                while ( CH375DiskStatus != DISK_DISCONNECT ) xQueryInterrupt( );  /* 查询CH375中断并更新中断状态,等待U盘拔出 */
  272.                 while ( CH375DiskStatus >= DISK_CONNECT )   /* 等待U盘拔出 */
  273.                 {        if ( CH375DiskConnect( ) != ERR_SUCCESS ) break;
  274.                        /* 删除某文件 */

  275.                     if(P23==0)          //判断是否按下
  276.       { mDelaymS( 5 );           //延时
  277.                if(P23==0)           //确实按下

  278.          while(!P22);        //松手检测
  279.                  mDelaymS( 5 );
  280.            while(!P22);
  281.                     
  282.                            //        printf( "Erase\n" );
  283.                 mCopyCodeStringToIRAM( mCmdParam.Create.mPathName, "/QQ.TXT" );//  将被删除的文件名,在根目录下
  284.                 i = CH375FileErase( );//  删除文件并关闭
  285.                 if ( i != ERR_SUCCESS ) printf( "Error: %02X\n", (UINT16)i );//  显示错误
  286.                                               LCD_clear(); //清屏幕
  287.                  LCD_write_hanzi(0,0,19);  //删
  288.         LCD_write_hanzi(1,0,20);  //除       
  289.      LCD_write_hanzi(2,0,5);  //文
  290.         LCD_write_hanzi(3,0,6); //件

  291.                         LCD_write_shu(0,2,14);  //o
  292.                 LCD_write_shu(1,2,25);  //k
  293.                  LCD_write_shu(2,2,24);  //!
  294.           
  295.            }
  296.                         mDelaymS( 100 );
  297.                 }
  298.            mDelaymS( 100 );
  299.    }
  300. }
复制代码

ch375读写u盘,配合按键操作,在5110液晶上显示,也可串口发送显示(去掉屏蔽即可)。本人亲测。压缩包包涵有源程序、99se原理图、接线图等




所有资料下载:
ch375_5110.rar (224.04 KB, 下载次数: 125)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏7 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:108931 发表于 2016-7-20 22:21 | 只看该作者
看看吧能不能用上。
回复

使用道具 举报

板凳
ID:64089 发表于 2016-7-21 12:54 | 只看该作者
Good i like it,thanks!
回复

使用道具 举报

地板
ID:134954 发表于 2016-7-25 15:59 | 只看该作者
在么
楼主  为什么我OPEN以后出现错误:1F
回复

使用道具 举报

5#
ID:111632 发表于 2016-11-23 15:55 | 只看该作者
串口发送接收指的是单片机上的串口还是CH375上的?
回复

使用道具 举报

6#
ID:189880 发表于 2017-4-15 16:42 | 只看该作者
下来看看能否可以
回复

使用道具 举报

7#
ID:16695 发表于 2017-4-22 08:38 | 只看该作者
资料不错,在找
回复

使用道具 举报

8#
ID:236933 发表于 2017-10-1 22:25 | 只看该作者
下载试试看!!!
回复

使用道具 举报

9#
ID:146874 发表于 2017-10-9 19:08 | 只看该作者
下载试试看
回复

使用道具 举报

10#
ID:858595 发表于 2020-12-12 16:17 来自手机 | 只看该作者
可以发一下电路原件吗?
回复

使用道具 举报

11#
ID:858595 发表于 2020-12-12 16:24 来自手机 | 只看该作者
就是prroteus原理图
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表