內含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目錄下是相關英文技術規范文檔。
51hei.png (5.29 KB, 下載次數: 31)
下載附件
2019-11-10 02:34 上傳
單片機源程序如下:
- /* 可引導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)
2019-11-6 20:39 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|