📄 usbex.c
字号:
/*
CH372 外部固件方式范例
这里仅处理标准请求和端点2的简单读写
*/
/* MCS-51单片机C语言的示例程序 */
//#pragma NOAREGS
#include <reg52.h>
//#include <AT89x52.H>
#include <string.h>
#include "CH375INC.H"
#include "stdio.h"
#include "main.h"
//unsigned char data BLK[10] _at_ 0x30;
unsigned char data BLK[10] _at_ 0x30;
unsigned char data RevBuffer[10];
//unsigned char bord;
unsigned char idata UPDATA_FLAG;
unsigned char idata buf[8];//unsigned char idata buf[8];
unsigned char up_time;
//unsigned char data BLK[10] _at_ 0x30; //读卡器的定义接收区
//sbit OUT = P2^0; //接收IO口定义
typedef union _REQUEST_PACK{
unsigned char buffer[8];
struct{
unsigned char bmReuestType; //标准请求字
unsigned char bRequest; //请求代码
unsigned int wValue; //特性选择高
unsigned int wIndx; //索引
unsigned int wLength; //数据长度
}r;
} mREQUEST_PACKET, *mpREQUEST_PACKET;
//设备描述符
unsigned char code DevDes[]={
0x12 //描述符大小
, 0x01 //常数DEVICE
, 0x10 //USB规范版本信息
, 0x01
, 0x00 //类别码,
, 0x00 //子类别码
, 0x00 //协议码
, 0x08 //端点0的最大信息包大小
, 0x3c //厂商ID
, 0x41
, 0x03 //产品ID
, 0x20
, 0x00 //设备版本信息
, 0x02
, 0x01 //索引值
, 0x02
, 0x00
, 0x01 //可能配置的数目
};
//配置描述符
unsigned char code ConDes[]={ //配置描述符
0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x04, 0xa0, 0x23,
0x09, 0x04, 0x00, 0x00, 0x01, 0x03, 0x01, 0x01, 0x05,
0x09, 0x21, 0x10, 0x01, 0x00, 0x01, 0x22, 0x41, 0x00,
0x07, 0x05, 0x81, 0x03, 0x08, 0x00, 0x18
}; //配置描述符
//unsigned char code LangDes[]={0x04,0x03,0x09,0x04}; //语言描述符
//unsigned char code SerDes[]={0x12,0x03,'C',0,'H',0,'3',0,'7',0,'5',0,'U',0,'S',0,'B',0}; //字符串描述符
unsigned char code Hid_des[]={0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07, 0x19, 0xe0,
0x29, 0xe7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08,
0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x03, 0x75, 0x01,
0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x91, 0x02, 0x95, 0x01, 0x75, 0x05,
0x91, 0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00, 0x26, 0xff, 0x00, 0x05,
0x07, 0x19, 0x00, 0x2a, 0xff, 0x00, 0x81, 0x00, 0xc0
};
unsigned char mVarSetupRequest; // ;USB请求码
unsigned char mVarSetupLength; // ;后续数据长度
unsigned char code * VarSetupDescr;// ;描述符偏移地址
unsigned char buf1[8];
unsigned char VarUsbAddress ; //
sbit CH375_INT_WIRE = 0xB0^2; /* P3.2, INT0, 连接CH375的INT#引脚,用于查询中断状态 */
bit CH375FLAGERR; //错误清0
bit CH375CONFLAG;
unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */
unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375数据端口的I/O地址 */
mREQUEST_PACKET request;
sbit CH375ACT = P1^4;
/*
void mInitSTDIO( )
{
SCON = 0x50;
PCON = 0x80;
TMOD = 0x20;
TH1 = 0xf3; // 24MHz晶振, 9600bps
TR1 = 1;
TI = 0;
}
*/
/* 延时2微秒,不精确 */
void Delay1us(){
;
}
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-- );
}
/* 将PC机的低字节在前的16位字数据转换为C51的高字节在前的数据 */
//unsigned int BIG_ENDIAN( unsigned int value )
//{
// unsigned int in, out;
// in = value;
// ((unsigned char *)&out)[1] = ((unsigned char *)&in)[0];
// ((unsigned char *)&out)[0] = ((unsigned char *)&in)[1];
// return( out );
//}
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( )
{
/* 设置USB工作模式, 必要操作 */
CH375_WR_CMD_PORT( CMD_SET_USB_MODE );
CH375_WR_DAT_PORT( 1 ); /* 设置为使用内置固件的USB设备方式 */
for ( ;; ) { /* 等待操作成功,通常需要等待10uS-20uS */
if ( CH375_RD_DAT_PORT( )==CMD_RET_SUCCESS ) break;
}
}
//*********************************************************
//*********************************************************
//端点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, c1, len;
unsigned char *pBuf;
unsigned char mBuf[14];//unsigned char mBuf[64];
CH375_WR_CMD_PORT(CMD_GET_STATUS); /* 获取中断状态并取消中断请求 */
InterruptStatus =CH375_RD_DAT_PORT(); /* 获取中断状态 */
////////////////////////////////////////////// IE0 = 0; /* 清中断标志,对应于INT0中断 */
switch(InterruptStatus){ // 分析中断状态
case USB_INT_EP2_OUT: // 批量端点下传成功
pBuf=mBuf; //数据未处理
CH375_WR_CMD_PORT(CMD_RD_USB_DATA); //发出读数据命令
length=CH375_RD_DAT_PORT(); //首先读出的是长度
for(len=0;len!=length;len++,pBuf++)*pBuf=CH375_RD_DAT_PORT(); //将数据读入到缓冲区
pBuf=mBuf;
// 演示回传
// CH375_WR_CMD_PORT(CMD_WR_USB_DATA7); //发出写上传端点命令
// CH375_WR_DAT_PORT(length);
// for(len=0;len!=length;len++,pBuf++)CH375_WR_DAT_PORT(*pBuf); //将数据写入上传端点
break;
case USB_INT_EP2_IN: //批量端点上传成功,未处理
CH375_WR_CMD_PORT (CMD_UNLOCK_USB); //释放缓冲区
break;
case USB_INT_EP1_IN: //中断端点上传成功,未处理
CH375_WR_CMD_PORT (CMD_UNLOCK_USB); //释放缓冲区
/*
// if(up_time==11){
for(i=0;i<8;i++) buf[i]=0; //发送八个字节0,相当于释放按键1
CH375_WR_CMD_PORT(CMD_WR_USB_DATA5);
CH375_WR_DAT_PORT(8);
for(i=0;i!=8;i++) CH375_WR_DAT_PORT(buf[i]);
// }
*/
break;
case USB_INT_EP1_OUT: //中断端点下传成功,未处理
CH375_WR_CMD_PORT(CMD_RD_USB_DATA); //发出读数据命令
if(length=CH375_RD_DAT_PORT()){ //长度为0跳出
for(len=0;len!=length;len++)c1=CH375_RD_DAT_PORT(); //取出下传数据
}
break;
case USB_INT_EP0_SETUP: //控制端点建立成功
CH375_WR_CMD_PORT(CMD_RD_USB_DATA);
length=CH375_RD_DAT_PORT();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -