标题:
ch372 51单片机例程及库文件
[打印本页]
作者:
moyst
时间:
2019-11-6 20:41
标题:
ch372 51单片机例程及库文件
内含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
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1