|
內(nèi)含51讀寫操作ch372/ch373的例程及庫文件,有需要的小伙伴可以下載哦。
CH372+MCU的U盤方案:C語言源程序 V1.1
1、硬件需求:普通的MCS51單片機(jī),CH372(或者CH375),存儲器(SRAM或者閃存等)
2、用途:了解U盤的程序原理,設(shè)計自己的U盤/閃存盤/SRAM盤等,
可以直接將儀器的數(shù)據(jù)以U盤形式交給計算機(jī),計算機(jī)端無需驅(qū)動程序
3、這是一個基于CH375/CH372通用接口芯片用62256作存儲的U盤方案。
其中CH375/CH372使用外置固件的設(shè)備模式,存儲器用62256只是用于演示用。
實際應(yīng)用應(yīng)根據(jù)存儲器的種類和容量做相應(yīng)修改。
本方案只是一個例程所以在一些問題上沒有細(xì)化,實際應(yīng)用中要注意。
4、使用前,需要加上頭文件 CH375INC.H 才能編譯通過,該文件在網(wǎng)上評估板資料中有。
5、方案中有一個文件系統(tǒng),是我們調(diào)試時用的,這個文件系統(tǒng)適應(yīng)于存儲器比較小的系統(tǒng)。
當(dāng)然你可以不用,讓W(xué)INDOWS來格式化就可以了。只是在容量小于20K時WINDOWS就格不了。
6、DOCUMENT目錄下是相關(guān)英文技術(shù)規(guī)范文檔。
單片機(jī)源程序如下:
- /* 可引導(dǎo)U盤方案 CH372/CH375 + MCS51 + EEPROM24CXX
- ;
- ;****************************************************************************
- UDISK程序
- 用32K的SRAM62256做小容量的U盤,可以替換為閃存做成真正的U盤
- */
- /* MCS-51單片機(jī)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; // 控制傳輸后續(xù)數(shù)據(jù)長度
- unsigned char code * VarSetupDescr; //描述符偏移地址
- unsigned char idata VarUsbAddress; //USB分配地址
- union {
- unsigned int mDataLength; //數(shù)據(jù)長度
- unsigned char mdataLen[2]; //
- } LEN;
- unsigned int XDataAdd; //數(shù)據(jù)地址
- //因為在此用的是256作存儲,所以用的是整型
- unsigned char BcswStatus; //CSW狀態(tài)
- bit CH375FLAGERR; //錯誤清0
- bit CH375CONFLAG; //配置標(biāo)志
- bit CH375BULKUP; //數(shù)據(jù)上傳
- bit CH375BULKDOWN; //數(shù)據(jù)下傳
- bit CH375CSW; //CSW上傳標(biāo)志
- bit FSTALL; //數(shù)據(jù)錯誤標(biāo)志
- bit lastFSTALL;
- unsigned char *pBuf; //端點2上傳下傳全局?jǐn)?shù)據(jù)指針
- unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */
- unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375數(shù)據(jù)端口的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進(jìn)行初始化,默認(rèn)格式化
- unsigned char xdata *IntData;
- unsigned int i;
- IntData=0;
- if(*IntData==0xEB){
- IntData++;
- if(*IntData==0x3E){
- IntData++;
- if(*IntData==0x90)return;
- }
- } // 如果有文件信息則不格式化
- IntData=0; //自己寫入FAT文件系統(tǒng)
- for (i=0;i!=0X200;i++){
- *IntData=DBR[i];
- IntData++;
- }
- //自己寫入FAT文件系統(tǒng)
- 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文件系統(tǒng)
- 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 /* 根據(jù)單片機(jī)的時鐘選擇初值,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,如果單片機(jī)較快則延時 */
- Delay2us( );
- CH375_CMD_PORT=cmd;
- Delay2us( );
- }
- void CH375_WR_DAT_PORT( unsigned char dat ) { /* 向CH375的數(shù)據(jù)端口寫入數(shù)據(jù),周期不小于1.5uS,如果單片機(jī)較快則延時 */
- CH375_DAT_PORT=dat;
- Delay1us( ); /* 因為MCS51單片機(jī)較慢所以實際上無需延時 */
- }
- unsigned char CH375_RD_DAT_PORT() { /* 從CH375的數(shù)據(jù)端口讀出數(shù)據(jù),周期不小于1.5uS,如果單片機(jī)較快則延時 */
- Delay1us( ); /* 因為MCS51單片機(jī)較慢所以實際上無需延時 */
- return( CH375_DAT_PORT );
- }
- /* CH375初始化子程序 */
- void CH375_Init( )
- {
- unsigned char i;
- /* 設(shè)置USB工作模式, 必要操作 */
- CH375_WR_CMD_PORT( CMD_SET_USB_MODE );
- CH375_WR_DAT_PORT( 1 ); /* 設(shè)置為使用內(nèi)置固件的USB設(shè)備方式 */
- Delay2us( );
- for ( i=0xff; i!=0; i-- ) { /* 等待操作成功,通常需要等待10uS-20uS */
- if ( CH375_RD_DAT_PORT()==CMD_RET_SUCCESS ) break;
- }
- /* 下述啟用中斷,假定CH375連接在INT0 */
- IT0 = 0; /* 置外部信號為低電平觸發(fā) */
- IE0 = 0; /* 清中斷標(biāo)志 */
- 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;
- //這里上傳端點設(shè)置一個STALL,待主機(jī)清掉 // 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;
- //這里上傳端點設(shè)置一個STALL,待主機(jī)清掉
- 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;
- //這里上傳端點設(shè)置一個STALL,待主機(jī)清掉
- 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;
- //這里上傳端點設(shè)置一個STALL,待主機(jī)清掉
- 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;
- //這里上傳端點設(shè)置一個STALL,待主機(jī)清掉
- CH375_WR_CMD_PORT(CMD_SET_ENDP6); //清除端點2上傳
- CH375_WR_DAT_PORT(0x0f);
- //這里上傳端點設(shè)置一個STALL,待主機(jī)清掉
- BcswStatus = 2;
- break;
- case CASECBW: /* invalid CBW */
- CH375_WR_CMD_PORT(CMD_SET_ENDP7);
- CH375_WR_DAT_PORT(0x0f);
- FSTALL=1;
- //這里上傳端點設(shè)置一個STALL,待主機(jī)清掉
- CH375_WR_CMD_PORT(CMD_SET_ENDP6);
- CH375_WR_DAT_PORT(0x0f);
- //這里上傳端點設(shè)置一個STALL,待主機(jī)清掉
- BcswStatus = 2;
- break;
- case CASECMDFAIL:
- CH375_WR_CMD_PORT(CMD_SET_ENDP7);
- CH375_WR_DAT_PORT(0x0f);
- FSTALL=1;
- //這里上傳端點設(shè)置一個STALL,待主機(jī)清掉
- 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協(xié)議處理
- 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 ){
- //模式認(rèn)識
- 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做優(yōu)盤所以地址不超過32K,高地址先不關(guān)心
- void UFI_read10(void){
- //讀取數(shù)據(jù)
- 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 ){
- //請求認(rèn)識
- 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盤是否準(zhǔn)備好
- mSenseKey=0;
- mASC=0;
- }
- void UFI_write(void ){
- LEN.mDataLength=MassPara.cbw.cbwcb.buf1[8]*512; //寫數(shù)據(jù)
- pXDatbuf=MassPara.cbw.cbwcb.buf1[5]*512; //取外部RAM的首地址
- pBuf=pXDatbuf;
- BcswStatus=0;
- mSenseKey=0;
- mASC=0;
- }
- //UFI END
- //**********************************************************************************
- void CH375bulkUpData(){ //調(diào)用端點2上傳數(shù)據(jù)
- 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); //發(fā)出寫端點0的命令
- CH375_WR_DAT_PORT(len);
- do{
- CH375_WR_DAT_PORT( *pBuf );
- pBuf++;
- }while(--len);
- }
- void mCH375UpCsw()
- {
- unsigned char i; //如果數(shù)據(jù)為0
- pBuf=&MassPara.buf[0];
- CH375CSW=0; //上傳CSW
- CH375BULKUP=0; //取消數(shù)據(jù)上傳
- 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); //發(fā)出寫端點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協(xié)議處理
- LEN.mdataLen[1]=*(unsigned char *)(&MassPara.cbw.dCBWDatL); /* 將PC機(jī)的低字節(jié)在前的16位字?jǐn)?shù)據(jù)轉(zhuǎn)換為C51的高字節(jié)在前的數(shù)據(jù) */
- 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]; //取出數(shù)據(jù)長度
- if(LEN.mDataLength){
- CH375BULKDOWN=(MassPara.cbw.bmCBWFlags&0X80)?0:1; //判斷是上傳還是下傳數(shù)據(jù)
- CH375BULKUP=(MassPara.cbw.bmCBWFlags&0X80)?1:0;
- }
- // if(!CBWLUN){ //只支持一個物理盤
- CH375CSW=1;
- UFI_Hunding();
- //調(diào)用UFI協(xié)議處理
- // }
- // else ;//此處應(yīng)做錯誤處理
- }
- 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); //發(fā)出讀數(shù)據(jù)命令
- len=CH375_RD_DAT_PORT(); //讀出長度
- //判?
- LEN.mDataLength-=len; //全局?jǐn)?shù)據(jù)長度減掉當(dāng)前獲得的長度
- do{
- *pBuf=CH375_RD_DAT_PORT(); //復(fù)制數(shù)據(jù)進(jìn)入存儲區(qū)
- pBuf++;
- }while(--len);
- if(LEN.mDataLength==0){ //如果數(shù)據(jù)為0,則傳送CSW
- CH375BULKDOWN=0;
- mCH375UpCsw(); //上傳CSW
- }
- }
- //*********************************************************
- //端點0數(shù)據(jù)上傳
- void mCh375Ep0Up(){
- unsigned char i,len;
- if(mVarSetupLength){ //長度不為0傳輸具體長度的數(shù)據(jù)
- if(mVarSetupLength<=8){
- len=mVarSetupLength;
- mVarSetupLength=0;
- } //長度小于8則長輸要求的長度
- else{
- len=8;
- mVarSetupLength-=8;
- } //長度大于8則傳輸8個,切總長度減8
- CH375_WR_CMD_PORT(CMD_WR_USB_DATA3); //發(fā)出寫端點0的命令
- CH375_WR_DAT_PORT(len); //寫入長度
- for(i=0;i!=len;i++)
- CH375_WR_DAT_PORT(request.buffer[i]); //循環(huán)寫入數(shù)據(jù)
- }
- else{
- CH375_WR_CMD_PORT(CMD_WR_USB_DATA3); //發(fā)出寫端點0的命令
- CH375_WR_DAT_PORT(0); //上傳0長度數(shù)據(jù),這是一個狀態(tài)階段
- }
- }
- //復(fù)制描述符以便上傳
- void mCh375DesUp(){
- unsigned char k;
- for (k=0; k!=8; k++ ) {
- request.buffer[k]=*VarSetupDescr; //依次復(fù)制8個描述符,
- VarSetupDescr++;
- }
- }
- /* CH375中斷服務(wù)程序INT0,使用寄存器組1 */
- void mCH375Interrupt( ) interrupt 0 using 1
- {
- unsigned char InterruptStatus;
- unsigned char length, len;
- CH375_WR_CMD_PORT(CMD_GET_STATUS); /* 獲取中斷狀態(tài)并取消中斷請求 */
- InterruptStatus =CH375_RD_DAT_PORT(); /* 獲取中斷狀態(tài) */
- /* 清中斷標(biāo)志,對應(yīng)于INT0中斷 */
- switch(InterruptStatus){ // 分析中斷狀態(tài)
- case USB_INT_EP2_OUT: // 批量端點下傳成功
- if(CH375BULKDOWN)mCH375BulkDownData(); //如果上傳數(shù)據(jù)階段則調(diào)用數(shù)據(jù)上傳
- else{ //不是數(shù)據(jù)下傳則判斷是否
- CH375_WR_CMD_PORT(CMD_RD_USB_DATA); //發(fā)出讀數(shù)據(jù)命令
- length=CH375_RD_DAT_PORT();
- if(!length)break; //數(shù)據(jù)包長度為零則跳出
- //首先讀出的是長度
- for(len=0;len!=length;len++) MassPara.buf[len]=CH375_RD_DAT_PORT(); //將數(shù)據(jù)讀入到緩沖區(qū)
- mCH375BulkOnly();
- if(!CH375BULKDOWN){
- if(CH375BULKUP)CH375bulkUpData(); //調(diào)用批量數(shù)據(jù)上傳
- else if(!FSTALL)mCH375UpCsw(); //沒有數(shù)據(jù)上傳調(diào)用CSW上傳
- //在這里做上傳數(shù)據(jù)調(diào)用
- }
- }
- break;
- case USB_INT_EP2_IN:
- if(CH375BULKUP)CH375bulkUpData(); //調(diào)用數(shù)據(jù)上傳
- 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); //釋放緩沖區(qū)
- break;
- case USB_INT_EP1_OUT: //中斷端點下傳成功,未處理
- CH375_WR_CMD_PORT (CMD_UNLOCK_USB); //釋放緩沖區(qū)
- 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(); // 取出數(shù)據(jù)
- if(length==0x08){
- mVarSetupLength=request.buffer[6]&0x7f; //控制傳輸數(shù)據(jù)長度最大設(shè)置為128
- if((request.r.bmReuestType)&0x40){ //廠商請求,未處理
- }
- if((request.r.bmReuestType)&0x20){ //類請求,未處理
- if(request.buffer[1]==0xfe)request.buffer[0]=0; //類請求得到邏輯盤數(shù)目,這里只有一個盤所以
- // else if(request.buffer[1]==0x00); //復(fù)位邏輯單元,這里未處理
- }
- if(!((request.r.bmReuestType)&0x60)){ //標(biāo)準(zhǔn)請求
- mVarSetupRequest=request.r.bRequest; //暫存標(biāo)準(zhǔn)請求碼
- switch(request.r.bRequest){ // 分析標(biāo)準(zhǔn)請求
- 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); //發(fā)命令清除端點
- 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; //不支持的清除特性,置錯誤標(biāo)志
- }
- break;
- case DEF_USB_GET_STATUS: //獲得狀態(tài)
- request.buffer[0]=0;
- request.buffer[1]=0; //上傳狀態(tài)
- break;
- case DEF_USB_SET_ADDRESS: //設(shè)置地址
- VarUsbAddress=request.buffer[2]; //暫存USB主機(jī)發(fā)來的地址
- break;
- case DEF_USB_GET_DESCR: //獲得描述符
- if(request.buffer[3]==1) //設(shè)備描述符上傳
- 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; //已經(jīng)配置則傳1;這是在描述符里規(guī)定的
- break;
- case DEF_USB_SET_CONFIG: //設(shè)置配置
- CH375CONFLAG=0;
- CH375ACT=1;
- if ( request.buffer[2] != 0 ) {
- CH375CONFLAG=1; //設(shè)置配置標(biāo)志
- CH375ACT=0; //輸出配置完成信號
- }
- break;
- case DEF_USB_GET_INTERF: //得到接口
- request.buffer[0]=1; //上傳接口數(shù),本事例只支持一個接口
- break;
- case DEF_USB_SET_INTERF: //設(shè)置接口
- break;
- default :
- break; //不支持的標(biāo)準(zhǔn)請求
- }
- }
- }
- else { //不支持的控制傳輸,不是8字節(jié)的控制傳輸
- CH375FLAGERR=1;
- }
- if(!CH375FLAGERR) mCh375Ep0Up(); //沒有錯誤/調(diào)用數(shù)據(jù)上傳,,長度為0上傳為狀態(tài)
- else {
- CH375_WR_CMD_PORT(CMD_SET_ENDP3); //設(shè)置端點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){ //設(shè)置地址
- CH375_WR_CMD_PORT(CMD_SET_USB_ADDR);
- CH375_WR_DAT_PORT(VarUsbAddress); //設(shè)置USB地址,設(shè)置下次事務(wù)的USB地址
- }
- break;
- case USB_INT_EP0_OUT: //控制端點下傳成功
- CH375_WR_CMD_PORT (CMD_UNLOCK_USB); //釋放緩沖區(qū)
- break;
- default:
- if((InterruptStatus&0x03)==0x03){ //總線復(fù)位
- 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); //釋放緩沖區(qū)
- CH375_RD_DAT_PORT( );
- break;
- }
- }
- main( ) {
- Delay50ms( ); /* 延時等待CH375初始化完成,如果單片機(jī)由CH375提供復(fù)位信號則不必延時 */
- Delay50ms( ); /* 延時等待CH375初始化完成,如果單片機(jī)由CH375提供復(fù)位信號則不必延時 */
- DiskInit(); //對SRAM進(jìn)行初始化,默認(rèn)格式化,如果是閃存那么應(yīng)該跳過此步
- CH375_Init( ); /* 初始化CH375 */
- EA=1;
- while(1);
- }
復(fù)制代碼
所有資料51hei提供下載:
CH372DSK.ZIP
(332.77 KB, 下載次數(shù): 14)
2019-11-6 20:39 上傳
點擊文件名下載附件
|
評分
-
查看全部評分
|