内含51读写操作ch372/ch373的例程及库文件,有需要的小伙伴可以下载哦。
CH372+MCU的U盘方案:C语言源程序 V1.1
1、硬件需求:普通的MCS51单片机,CH372(或者CH375),存储器(SRAM或者闪存等)
2、用途:了解U盘的程序原理,设计自己的U盘/闪存盘/SRAM盘等,
可以直接将仪器的数据以U盘形式交给计算机,计算机端无需驱动程序
3、这是一个基于CH375/CH372通用接口芯片用62256作存储的U盘方案。
其中CH375/CH372使用外置固件的设备模式,存储器用62256只是用于演示用。
实际应用应根据存储器的种类和容量做相应修改。
本方案只是一个例程所以在一些问题上没有细化,实际应用中要注意。
4、使用前,需要加上头文件 CH375INC.H 才能编译通过,该文件在网上评估板资料中有。
5、方案中有一个文件系统,是我们调试时用的,这个文件系统适应于存储器比较小的系统。
当然你可以不用,让WINDOWS来格式化就可以了。只是在容量小于20K时WINDOWS就格不了。
6、DOCUMENT目录下是相关英文技术规范文档。
单片机源程序如下:
- /* 可引导U盘方案 CH372/CH375 + MCS51 + EEPROM24CXX
- ;
- ;****************************************************************************
- UDISK程序
- 用32K的SRAM62256做小容量的U盘,可以替换为闪存做成真正的U盘
- */
- /* MCS-51单片机C语言的示例程序 */
- #define MY_DISK_SIZE 0x00000040 /* U盘容量 */
- #pragma NOAREGS
- #include <reg52.h>
- #include "CH375INC.H"
- #include "USBDISK.H"
- unsigned char mVarSetupRequest; //USB请求码
- unsigned char mVarSetupLength; // 控制传输后续数据长度
- unsigned char code * VarSetupDescr; //描述符偏移地址
- unsigned char idata VarUsbAddress; //USB分配地址
- union {
- unsigned int mDataLength; //数据长度
- unsigned char mdataLen[2]; //
- } LEN;
- unsigned int XDataAdd; //数据地址
- //因为在此用的是256作存储,所以用的是整型
- unsigned char BcswStatus; //CSW状态
- bit CH375FLAGERR; //错误清0
- bit CH375CONFLAG; //配置标志
- bit CH375BULKUP; //数据上传
- bit CH375BULKDOWN; //数据下传
- bit CH375CSW; //CSW上传标志
- bit FSTALL; //数据错误标志
- bit lastFSTALL;
- unsigned char *pBuf; //端点2上传下传全局数据指针
- unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */
- unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375数据端口的I/O地址 */
- unsigned char xdata *pXDatbuf; //存储器地址指针
- mREQUEST_PACKET request;
- MASS_PARA MassPara;
- sbit CH375ACT = P1^4;
- unsigned char mSenseKey;
- unsigned char mASC;
- unsigned char mdCBWTag[4]; //dCBWTag
- void DiskInit(){ //本子程序用于对SRAM进行初始化,默认格式化
- unsigned char xdata *IntData;
- unsigned int i;
- IntData=0;
- if(*IntData==0xEB){
- IntData++;
- if(*IntData==0x3E){
- IntData++;
- if(*IntData==0x90)return;
- }
- } // 如果有文件信息则不格式化
- IntData=0; //自己写入FAT文件系统
- for (i=0;i!=0X200;i++){
- *IntData=DBR[i];
- IntData++;
- }
- //自己写入FAT文件系统
- for (i=0;i!=0X200;i++){
- *IntData=FAT[i];
- IntData++;
- }
- if ( DBR[0x11] == 2 ) { // 两个FAT表
- for (i=0;i!=0X200;i++){
- *IntData=FAT[i];
- IntData++;
- }
- } //自己写入DIR文件系统
- for (i=0;i!=0X200;i++){
- *IntData=ROOT[i];
- IntData++;
- }
- }
- #define Delay1us() /* 对于MCS51,因其速度较慢,完全不需要该子程序 */
- //void Delay1us(){ /* 对于MCS51,因其速度较慢,完全不需要该子程序 */
- // for ( i=DELAY_START_VALUE; i!=0; i-- );
- //}
- void Delay2us( )
- {
- unsigned char i;
- #define DELAY_START_VALUE 1 /* 根据单片机的时钟选择初值,20MHz以下为0,30MHz以上为2 */
- for ( i=DELAY_START_VALUE; i!=0; i-- );
- }
- /* 延时50毫秒,不精确 */
- void Delay50ms( )
- {
- unsigned char i, j;
- for ( i=200; i!=0; i-- ) for ( j=250; j!=0; j-- );
- }
- void CH375_WR_CMD_PORT( unsigned char cmd ) { /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */
- Delay2us( );
- CH375_CMD_PORT=cmd;
- Delay2us( );
- }
- void CH375_WR_DAT_PORT( unsigned char dat ) { /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */
- CH375_DAT_PORT=dat;
- Delay1us( ); /* 因为MCS51单片机较慢所以实际上无需延时 */
- }
- unsigned char CH375_RD_DAT_PORT() { /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */
- Delay1us( ); /* 因为MCS51单片机较慢所以实际上无需延时 */
- return( CH375_DAT_PORT );
- }
- /* CH375初始化子程序 */
- void CH375_Init( )
- {
- unsigned char i;
- /* 设置USB工作模式, 必要操作 */
- CH375_WR_CMD_PORT( CMD_SET_USB_MODE );
- CH375_WR_DAT_PORT( 1 ); /* 设置为使用内置固件的USB设备方式 */
- Delay2us( );
- for ( i=0xff; i!=0; i-- ) { /* 等待操作成功,通常需要等待10uS-20uS */
- if ( CH375_RD_DAT_PORT()==CMD_RET_SUCCESS ) break;
- }
- /* 下述启用中断,假定CH375连接在INT0 */
- IT0 = 0; /* 置外部信号为低电平触发 */
- IE0 = 0; /* 清中断标志 */
- EX0 = 1; /* 允许CH375中断 */
- }
- //*****************************************************************************
- //BLOCK ONLY The Thirteen Cases
- void BulkThirteen(unsigned char Case)
- {
- switch(Case)
- {
- case CASEOK:
- case CASE1: /* Hn=Dn*/
- case CASE6: /* Hi=Di*/
- BcswStatus = 0;
- break;
- case CASE12: /* Ho=Do*/
- BcswStatus = 0;
- break;
- case CASE2: /* Hn<Di*/
- case CASE3: /* Hn<Do*/
- CH375_WR_CMD_PORT(CMD_SET_ENDP7); //清除端点2上传
- CH375_WR_DAT_PORT(0x0f);
- FSTALL=1;
- //这里上传端点设置一个STALL,待主机清掉 // may or may-not
- BcswStatus =2;
- break;
- case CASE4: /* Hi>Dn*/
- case CASE5: /* Hi>Di*/
- CH375_WR_CMD_PORT(CMD_SET_ENDP7); //清除端点2上传
- CH375_WR_DAT_PORT(0x0f);
- FSTALL=1;
- //这里上传端点设置一个STALL,待主机清掉
- BcswStatus= 1; //CSW_GOOD or CSW_FAIL
- break;
- case CASE7: /* Hi<Di*/
- case CASE8: /* Hi<>Do */
- CH375_WR_CMD_PORT(CMD_SET_ENDP7); //清除端点2上传
- CH375_WR_DAT_PORT(0x0f);
- FSTALL=1;
- //这里上传端点设置一个STALL,待主机清掉
- BcswStatus = 2;
- break;
- case CASE9: /* Ho>Dn*/
- case CASE11: /* Ho>Do*/
- CH375_WR_CMD_PORT(CMD_SET_ENDP6); //清除端点2上传
- CH375_WR_DAT_PORT(0x0f);
- FSTALL=1;
- //这里上传端点设置一个STALL,待主机清掉
- BcswStatus =1; //CSW_GOOD or CSW_FAIL
- break;
- case CASE10: /* Ho<>Di */
- case CASE13: /* Ho<Do*/
- CH375_WR_CMD_PORT(CMD_SET_ENDP7); //清除端点2上传
- CH375_WR_DAT_PORT(0x0f);
- FSTALL=1;
- //这里上传端点设置一个STALL,待主机清掉
- CH375_WR_CMD_PORT(CMD_SET_ENDP6); //清除端点2上传
- CH375_WR_DAT_PORT(0x0f);
- //这里上传端点设置一个STALL,待主机清掉
- BcswStatus = 2;
- break;
- case CASECBW: /* invalid CBW */
- CH375_WR_CMD_PORT(CMD_SET_ENDP7);
- CH375_WR_DAT_PORT(0x0f);
- FSTALL=1;
- //这里上传端点设置一个STALL,待主机清掉
- CH375_WR_CMD_PORT(CMD_SET_ENDP6);
- CH375_WR_DAT_PORT(0x0f);
- //这里上传端点设置一个STALL,待主机清掉
- BcswStatus = 2;
- break;
- case CASECMDFAIL:
- CH375_WR_CMD_PORT(CMD_SET_ENDP7);
- CH375_WR_DAT_PORT(0x0f);
- FSTALL=1;
- //这里上传端点设置一个STALL,待主机清掉
- BcswStatus= 1;
- break;
- default:
- break;
- }
- }
- //*********************************************************
- //UFI CMD
- void UFI_Hunding(void ){
- switch(MassPara.cbw.cbwcb.buf1[0]){
- case INQUIRY:
- UFI_inquiry();
- break;
- case WRITE:
- UFI_write();
- break;
- case TES_UNIT:
- UFI_testUnit();
- break;
- case READ:
- UFI_read10();
- break;
- case REQUEST_SENSE:
- UFI_requestSense();
- break;
- case READ_CAPACITY:
- UFI_readCapacity();
- break;
- case VERIFY:
- UFI_verify();
- break;
- // case 0x23:
- // break;
- // case MODE_SELECT:
- // UFI_modeSlect();
- // break;
- case MODE_SENSE:
- UFI_modeSense();
- break;
- case MODE_SENSE5:
- UFI_modeSense5();
- break;
- // case WRITE_BUFFER:
- // UFI_writeBuf();
- // break;
- // case PREVENT:
- // break;
- // case FORMAT_UNIT:
- // UFI_format();
- // break;
- // case RELEASE:
- // break;
- case STA_STO_UNIT:
- UFI_staStoUnit();
- break;
- case PRE_OR_MED:
- UFI_perOrMed();
- break;
- default:
- mSenseKey=5;
- mASC=0x20;
- BcswStatus=1;
- CH375BULKUP=0;
- BulkThirteen(CASECBW);
- break;
- }
- }
- /*//ufi协议处理
- void UFI_format(void ){
- //格式化命令不支持
- mSenseKey=5;
- mASCQ=0;
- mASC=0x20;
- BulkThirteen(CASECMDFAIL);
- }*/
- void UFI_inquiry(void ){
- pBuf=DBINQUITY; ////查询U盘信息
- if(LEN.mDataLength>36)LEN.mDataLength=36;
- BcswStatus=0;
- mSenseKey=0;
- mASC=0;
- }
- /*void UFI_modeSlect(void ){
- BcswStatus=1; //模式选择不支持
- mSenseKey=5;
- mASCQ=0;
- mASC=0x20;
- } //*/
- void UFI_modeSense(void ){
- //模式认识
- if(MassPara.cbw.cbwcb.buf1[2]==0x3F){
- if ( LEN.mDataLength > sizeof(modesense3F) ) LEN.mDataLength = sizeof(modesense3F);
- pBuf=modesense3F;
- BcswStatus=0;
- mSenseKey=0;
- mASC=0;
- }
- else {
- CH375BULKUP=0;
- mSenseKey=5;
- mASC=0x20;
- BcswStatus=1;
- BulkThirteen(CASECMDFAIL);
- }
- }
- void UFI_modeSense5(void ){
- if(MassPara.cbw.cbwcb.buf1[2]==0x3F){
- if ( LEN.mDataLength > sizeof(mode5sense3F) ) LEN.mDataLength = sizeof(mode5sense3F);
- pBuf=mode5sense3F;
- BcswStatus=0;
- mSenseKey=0;
- mASC=0;
- }
- else {
- CH375BULKUP=0;
- mSenseKey=5;
- mASC=0x20;
- BcswStatus=1;
- BulkThirteen(CASECMDFAIL);
- }
- }
- void UFI_perOrMed(void ){ //允许移出磁盘
- BcswStatus=0;
- mSenseKey=0;
- mASC=0;
- }
- //这里因为是用62256做优盘所以地址不超过32K,高地址先不关心
- void UFI_read10(void){
- //读取数据
- LEN.mDataLength=MassPara.cbw.cbwcb.buf1[8]*512;
- pXDatbuf=MassPara.cbw.cbwcb.buf1[5]*512;
- pBuf=pXDatbuf;
- BcswStatus=0;
- mSenseKey=0;
- mASC=0;
- }
- void UFI_readCapacity(void ){
- if ( LEN.mDataLength > sizeof(DBCAPACITY) ) LEN.mDataLength = sizeof(DBCAPACITY);
- pBuf=(unsigned char*)DBCAPACITY; //读取容量
- BcswStatus=0;
- mSenseKey=0;
- mASC=0;
- }
- void UFI_verify(void ){
- BcswStatus=0; //校验存储器空间
- mSenseKey=0;
- mASC=0;
- //这里这里只是作为演示所以没有真正检测物理存储器
- //但实际上这一步一定要处理
- }
- void UFI_requestSense(void ){
- //请求认识
- if ( FSTALL | lastFSTALL ) {
- lastFSTALL=FSTALL;
- FSTALL=0;
- MassPara.Sense.ErrorCode=0x70;
- MassPara.Sense.Reserved1=0;
- MassPara.Sense.SenseKey=mSenseKey;
- MassPara.Sense.Information[0]=0;
- MassPara.Sense.Information[1]=0;
- MassPara.Sense.Information[2]=0;
- MassPara.Sense.Information[3]=0;
- MassPara.Sense.AddSenseLength=0x0a;
- MassPara.Sense.Reserved2[0]=0;
- MassPara.Sense.Reserved2[1]=0;
- MassPara.Sense.Reserved2[2]=0;
- MassPara.Sense.Reserved2[3]=0;
- MassPara.Sense.AddSenseCode=mASC;
- MassPara.Sense.AddSenseCodeQua=00;
- MassPara.Sense.Reserved3[0]=0;
- MassPara.Sense.Reserved3[1]=0;
- MassPara.Sense.Reserved3[2]=0;
- MassPara.Sense.Reserved3[3]=0;
- pBuf=MassPara.buf;
- BcswStatus=0;
- }
- else {
- lastFSTALL=FSTALL;
- FSTALL=0;
- MassPara.Sense.ErrorCode=0x70;
- MassPara.Sense.Reserved1=0;
- MassPara.Sense.SenseKey=0x00;
- MassPara.Sense.Information[0]=0;
- MassPara.Sense.Information[1]=0;
- MassPara.Sense.Information[2]=0;
- MassPara.Sense.Information[3]=0;
- MassPara.Sense.AddSenseLength=0x0a;
- MassPara.Sense.Reserved2[0]=0;
- MassPara.Sense.Reserved2[1]=0;
- MassPara.Sense.Reserved2[2]=0;
- MassPara.Sense.Reserved2[3]=0;
- MassPara.Sense.AddSenseCode=0x00;
- MassPara.Sense.AddSenseCodeQua=00;
- MassPara.Sense.Reserved3[0]=0;
- MassPara.Sense.Reserved3[1]=0;
- MassPara.Sense.Reserved3[2]=0;
- MassPara.Sense.Reserved3[3]=0;
- pBuf=MassPara.buf;
- BcswStatus=0;
- }
- }
- void UFI_staStoUnit(void ){
- CH375BULKDOWN=0;
- CH375BULKUP=0;
- BcswStatus=0;
- mSenseKey=0;
- mASC=0;
- }
- void UFI_testUnit(void ){
- CH375BULKDOWN=0;
- CH375BULKUP=0;
- BcswStatus=0; //测试U盘是否准备好
- mSenseKey=0;
- mASC=0;
- }
- void UFI_write(void ){
- LEN.mDataLength=MassPara.cbw.cbwcb.buf1[8]*512; //写数据
- pXDatbuf=MassPara.cbw.cbwcb.buf1[5]*512; //取外部RAM的首地址
- pBuf=pXDatbuf;
- BcswStatus=0;
- mSenseKey=0;
- mASC=0;
- }
- //UFI END
- //**********************************************************************************
- void CH375bulkUpData(){ //调用端点2上传数据
- unsigned char len;
- if(LEN.mDataLength>0x40){
- len=0x40;
- LEN.mDataLength-=0x40;
- }
- else {
- len= (unsigned char) LEN.mDataLength;
- LEN.mDataLength=0;
- CH375BULKUP=0;
- }
- CH375_WR_CMD_PORT(CMD_WR_USB_DATA7); //发出写端点0的命令
- CH375_WR_DAT_PORT(len);
- do{
- CH375_WR_DAT_PORT( *pBuf );
- pBuf++;
- }while(--len);
- }
- void mCH375UpCsw()
- {
- unsigned char i; //如果数据为0
- pBuf=&MassPara.buf[0];
- CH375CSW=0; //上传CSW
- CH375BULKUP=0; //取消数据上传
- MassPara.buf[0]=0x55; //dCSWSignature
- MassPara.buf[1]=0x53;
- MassPara.buf[2]=0x42;
- MassPara.buf[3]=0x53;
- MassPara.buf[4]=mdCBWTag[0];
- MassPara.buf[5]=mdCBWTag[1];
- MassPara.buf[6]=mdCBWTag[2];
- MassPara.buf[7]=mdCBWTag[3];
- MassPara.buf[8]=0;
- MassPara.buf[9]=0;
- MassPara.buf[10]=LEN.mdataLen[1];
- MassPara.buf[11]=LEN.mdataLen[0];
- MassPara.buf[12]=BcswStatus;
- CH375_WR_CMD_PORT(CMD_WR_USB_DATA7); //发出写端点0的命令
- CH375_WR_DAT_PORT(13);
- for(i=0;i!=13;i++){
- CH375_WR_DAT_PORT(MassPara.buf[i]);
- }
- }
- void mCH375BulkOnly(){
- if(MassPara.buf[0]==0x55){
- if(MassPara.buf[1]==0x53){
- if(MassPara.buf[2]==0x42){
- if(MassPara.buf[3]==0x43){
- // LEN.mDataLength=BIG_ENDIAN(MassPara.cbw.dCBWDatL); //做BO协议处理
- LEN.mdataLen[1]=*(unsigned char *)(&MassPara.cbw.dCBWDatL); /* 将PC机的低字节在前的16位字数据转换为C51的高字节在前的数据 */
- LEN.mdataLen[0]=*( (unsigned char *)(&MassPara.cbw.dCBWDatL) + 1 );
- mdCBWTag[0]=MassPara.buf[4];
- mdCBWTag[1]=MassPara.buf[5];
- mdCBWTag[2]=MassPara.buf[6];
- mdCBWTag[3]=MassPara.buf[7]; //取出数据长度
- if(LEN.mDataLength){
- CH375BULKDOWN=(MassPara.cbw.bmCBWFlags&0X80)?0:1; //判断是上传还是下传数据
- CH375BULKUP=(MassPara.cbw.bmCBWFlags&0X80)?1:0;
- }
- // if(!CBWLUN){ //只支持一个物理盘
- CH375CSW=1;
- UFI_Hunding();
- //调用UFI协议处理
- // }
- // else ;//此处应做错误处理
- }
- else{ CH375_WR_CMD_PORT(CMD_SET_ENDP7); //清除端点2上传
- CH375_WR_DAT_PORT(0x0f);
- }
- }
- else{ CH375_WR_CMD_PORT(CMD_SET_ENDP7); //清除端点2上传
- CH375_WR_DAT_PORT(0x0f);
- }
- }
- else{ CH375_WR_CMD_PORT(CMD_SET_ENDP7); //清除端点2上传
- CH375_WR_DAT_PORT(0x0f);
- }
- }
- else { CH375_WR_CMD_PORT(CMD_SET_ENDP7); //清除端点2上传
- CH375_WR_DAT_PORT(0x0f);
- }
- }
- void mCH375BulkDownData(){
- unsigned char len;
- CH375_WR_CMD_PORT(CMD_RD_USB_DATA); //发出读数据命令
- len=CH375_RD_DAT_PORT(); //读出长度
- //判?
- LEN.mDataLength-=len; //全局数据长度减掉当前获得的长度
- do{
- *pBuf=CH375_RD_DAT_PORT(); //复制数据进入存储区
- pBuf++;
- }while(--len);
- if(LEN.mDataLength==0){ //如果数据为0,则传送CSW
- CH375BULKDOWN=0;
- mCH375UpCsw(); //上传CSW
- }
- }
- //*********************************************************
- //端点0数据上传
- void mCh375Ep0Up(){
- unsigned char i,len;
- if(mVarSetupLength){ //长度不为0传输具体长度的数据
- if(mVarSetupLength<=8){
- len=mVarSetupLength;
- mVarSetupLength=0;
- } //长度小于8则长输要求的长度
- else{
- len=8;
- mVarSetupLength-=8;
- } //长度大于8则传输8个,切总长度减8
- CH375_WR_CMD_PORT(CMD_WR_USB_DATA3); //发出写端点0的命令
- CH375_WR_DAT_PORT(len); //写入长度
- for(i=0;i!=len;i++)
- CH375_WR_DAT_PORT(request.buffer[i]); //循环写入数据
- }
- else{
- CH375_WR_CMD_PORT(CMD_WR_USB_DATA3); //发出写端点0的命令
- CH375_WR_DAT_PORT(0); //上传0长度数据,这是一个状态阶段
- }
- }
- //复制描述符以便上传
- void mCh375DesUp(){
- unsigned char k;
- for (k=0; k!=8; k++ ) {
- request.buffer[k]=*VarSetupDescr; //依次复制8个描述符,
- VarSetupDescr++;
- }
- }
- /* CH375中断服务程序INT0,使用寄存器组1 */
- void mCH375Interrupt( ) interrupt 0 using 1
- {
- unsigned char InterruptStatus;
- unsigned char length, len;
- CH375_WR_CMD_PORT(CMD_GET_STATUS); /* 获取中断状态并取消中断请求 */
- InterruptStatus =CH375_RD_DAT_PORT(); /* 获取中断状态 */
- /* 清中断标志,对应于INT0中断 */
- switch(InterruptStatus){ // 分析中断状态
- case USB_INT_EP2_OUT: // 批量端点下传成功
- if(CH375BULKDOWN)mCH375BulkDownData(); //如果上传数据阶段则调用数据上传
- else{ //不是数据下传则判断是否
- CH375_WR_CMD_PORT(CMD_RD_USB_DATA); //发出读数据命令
- length=CH375_RD_DAT_PORT();
- if(!length)break; //数据包长度为零则跳出
- //首先读出的是长度
- for(len=0;len!=length;len++) MassPara.buf[len]=CH375_RD_DAT_PORT(); //将数据读入到缓冲区
- mCH375BulkOnly();
- if(!CH375BULKDOWN){
- if(CH375BULKUP)CH375bulkUpData(); //调用批量数据上传
- else if(!FSTALL)mCH375UpCsw(); //没有数据上传调用CSW上传
- //在这里做上传数据调用
- }
- }
- break;
- case USB_INT_EP2_IN:
- if(CH375BULKUP)CH375bulkUpData(); //调用数据上传
- else if(CH375CSW)mCH375UpCsw(); //上传CSW
- CH375_WR_CMD_PORT (CMD_UNLOCK_USB); //批量端点上传成功,未处理
- break;
- case USB_INT_EP1_IN: //中断端点上传成功,未处理
- CH375_WR_CMD_PORT (CMD_UNLOCK_USB); //释放缓冲区
- break;
- case USB_INT_EP1_OUT: //中断端点下传成功,未处理
- CH375_WR_CMD_PORT (CMD_UNLOCK_USB); //释放缓冲区
- break;
- case USB_INT_EP0_SETUP: //控制端点建立成功
- CH375FLAGERR=0;
- CH375_WR_CMD_PORT(CMD_RD_USB_DATA);
- length=CH375_RD_DAT_PORT();
- for(len=0;len!=length;len++)request.buffer[len]=CH375_RD_DAT_PORT(); // 取出数据
- if(length==0x08){
- mVarSetupLength=request.buffer[6]&0x7f; //控制传输数据长度最大设置为128
- if((request.r.bmReuestType)&0x40){ //厂商请求,未处理
- }
- if((request.r.bmReuestType)&0x20){ //类请求,未处理
- if(request.buffer[1]==0xfe)request.buffer[0]=0; //类请求得到逻辑盘数目,这里只有一个盘所以
- // else if(request.buffer[1]==0x00); //复位逻辑单元,这里未处理
- }
- if(!((request.r.bmReuestType)&0x60)){ //标准请求
- mVarSetupRequest=request.r.bRequest; //暂存标准请求码
- switch(request.r.bRequest){ // 分析标准请求
- case DEF_USB_CLR_FEATURE: //清除特性
- if((request.r.bmReuestType&0x1F)==0X02){ //不是端点不支持
- switch(request.buffer[4]){
- case 0x82:
- CH375_WR_CMD_PORT(CMD_SET_ENDP7); //清除端点2上传
- CH375_WR_DAT_PORT(0x8E); //发命令清除端点
- if(CH375CSW)mCH375UpCsw();
- lastFSTALL=FSTALL;
- FSTALL=0;
- break;
- case 0x02:
- CH375_WR_CMD_PORT(CMD_SET_ENDP6);
- CH375_WR_DAT_PORT(0x80); //清除端点2下传
- if(CH375CSW)mCH375UpCsw();
- lastFSTALL=FSTALL;
- FSTALL=0;
- break;
- case 0x81:
- CH375_WR_CMD_PORT(CMD_SET_ENDP5); //清除端点1上传
- CH375_WR_DAT_PORT(0x8E);
- break;
- case 0x01:
- CH375_WR_CMD_PORT(CMD_SET_ENDP4); //清除端点1下传
- CH375_WR_DAT_PORT(0x80);
- break;
- default:
- break;
- }
- }
- else{
- CH375FLAGERR=1; //不支持的清除特性,置错误标志
- }
- break;
- case DEF_USB_GET_STATUS: //获得状态
- request.buffer[0]=0;
- request.buffer[1]=0; //上传状态
- break;
- case DEF_USB_SET_ADDRESS: //设置地址
- VarUsbAddress=request.buffer[2]; //暂存USB主机发来的地址
- break;
- case DEF_USB_GET_DESCR: //获得描述符
- if(request.buffer[3]==1) //设备描述符上传
- VarSetupDescr=DevDes;
- else if(request.buffer[3]==2) //配置描述符上传
- VarSetupDescr=ConDes;
- else if(request.buffer[3]==3) {
- if ( request.buffer[2]== 0 ) VarSetupDescr=LangDes;
- else VarSetupDescr=SerDes; //做字符串处理
- }
- mCh375DesUp(); //其余描述符不支持
- break;
- case DEF_USB_GET_CONFIG: //获得配置
- request.buffer[0]=0; //没有配置则传0
- if(CH375CONFLAG) request.buffer[0]=1; //已经配置则传1;这是在描述符里规定的
- break;
- case DEF_USB_SET_CONFIG: //设置配置
- CH375CONFLAG=0;
- CH375ACT=1;
- if ( request.buffer[2] != 0 ) {
- CH375CONFLAG=1; //设置配置标志
- CH375ACT=0; //输出配置完成信号
- }
- break;
- case DEF_USB_GET_INTERF: //得到接口
- request.buffer[0]=1; //上传接口数,本事例只支持一个接口
- break;
- case DEF_USB_SET_INTERF: //设置接口
- break;
- default :
- break; //不支持的标准请求
- }
- }
- }
- else { //不支持的控制传输,不是8字节的控制传输
- CH375FLAGERR=1;
- }
- if(!CH375FLAGERR) mCh375Ep0Up(); //没有错误/调用数据上传,,长度为0上传为状态
- else {
- CH375_WR_CMD_PORT(CMD_SET_ENDP3); //设置端点1为STALL,指示一个错误
- CH375_WR_DAT_PORT(0x0F);
- }
- CH375_WR_CMD_PORT (CMD_UNLOCK_USB);
- break;
- case USB_INT_EP0_IN:
- CH375_WR_CMD_PORT (CMD_UNLOCK_USB); //控制端点上串成功
- if(mVarSetupRequest==DEF_USB_GET_DESCR){ //描述符上传
- mCh375DesUp();
- mCh375Ep0Up();
- }
- else if(mVarSetupRequest==DEF_USB_SET_ADDRESS){ //设置地址
- CH375_WR_CMD_PORT(CMD_SET_USB_ADDR);
- CH375_WR_DAT_PORT(VarUsbAddress); //设置USB地址,设置下次事务的USB地址
- }
- break;
- case USB_INT_EP0_OUT: //控制端点下传成功
- CH375_WR_CMD_PORT (CMD_UNLOCK_USB); //释放缓冲区
- break;
- default:
- if((InterruptStatus&0x03)==0x03){ //总线复位
- FSTALL=0;
- CH375FLAGERR=0; //错误清0
- CH375CONFLAG=0; //配置清0
- mVarSetupLength=0;
- CH375FLAGERR=0; //错误清0
- CH375BULKUP=0; //
- CH375BULKDOWN=0;
- CH375CSW=0;
- FSTALL=0;
- CH375ACT=1; //清配置完成输出
- }
- else{ //命令不支持
- ;
- }
- CH375_WR_CMD_PORT (CMD_UNLOCK_USB); //释放缓冲区
- CH375_RD_DAT_PORT( );
- break;
- }
- }
- main( ) {
- Delay50ms( ); /* 延时等待CH375初始化完成,如果单片机由CH375提供复位信号则不必延时 */
- Delay50ms( ); /* 延时等待CH375初始化完成,如果单片机由CH375提供复位信号则不必延时 */
- DiskInit(); //对SRAM进行初始化,默认格式化,如果是闪存那么应该跳过此步
- CH375_Init( ); /* 初始化CH375 */
- EA=1;
- while(1);
- }
复制代码
所有资料51hei提供下载:
CH372DSK.ZIP
(332.77 KB, 下载次数: 14)
|