📄 ch372.c
字号:
#include <reg51.h>
#include <intrins.h>
#include "ch372.h"
byte UsbReBuf[2]; //USB接收两个加数的缓冲区
byte UsbSendBuf[2]; //USB返回加法和的缓冲区
byte IsSend=0; //是否有数据需要发送 0-没有 1-有
/**************************************************************************
发送加法和
**************************************************************************/
void SendSum()
{
if(IsSend==1)
{
IsSend=0;
WrPoint2(UsbSendBuf,2);
}
}
/**************************************************************************
初始化
返回值:1:初始化成功 0:不成功
**************************************************************************/
byte Ch372Init()
{
byte q0;
// CH372_PORT |= CH372_INT;
// EIMSK |= CH372_INT;
if(Test372()==0)
return 0;
q0=SetUSB_Mod372(2);
if(q0!=100)
return 1;
else
return 0;
}
/**************************************************************************
执行硬件复位
**************************************************************************/
void Rst372()
{
SendCommand372(RST_ALL);
__delay_cycles(6250); //延时
}
/**************************************************************************
设置USB 的厂商识别码Vendor-ID 和产品识别码Product-ID。该命令必须在
SET_USB_MODE 命令之前执行。
VID:厂商识别码Vendor-ID
PID:产品识别码Product-ID
**************************************************************************/
void SetUSB_ID372(word16 VID,word16 PID)
{
byte q0[4];
q0[0]=VID>>8;
q0[1]=VID&0xFF;
q0[2]=PID>>8;
q0[3]=PID&0xFF;
SendCommand372(SET_USB_ID);
WriteData372(q0,4);
__delay_cycles(160); //延时
}
/**************************************************************************
设置USB工作模式
mod:工作模式。 0:未启用的USB 设备方式(上电或复位后的默认方式)
1:已启用外部固件模式
2:已启用内部固件模式
返回值:启用方式。 100:设置失败
**************************************************************************/
byte SetUSB_Mod372(byte mod)
{
byte q0,q1;
SendCommand372(SET_USB_MOD);
WriteData372(&mod,1);
//等待操作成功,通常需要等待10uS~20uS
for ( q0=100;q0!=0;q0--)
{
ReadData372(&q1,1);
if ( q1 == CMD_SUCCESS )
return mod;
}
return 100;
}
/**************************************************************************
对CH372的中断进行处理,本函数应当被中断函数调用。
**************************************************************************/
void DoInt372()
{
byte q0;
word16 sum; //加法和
SendCommand372(GET_STA);//写读CH372的中断状态的命令,并通知CH372取消中断请求
ReadData372(&q0,1); //读CH372的中断状态
switch(q0) //根据CH372的中断状态进行处理
{
case 0x03:
case 0x07:
case 0x0B:
case 0xFF:
//检测到USB总线复位,内部固件模式时不需要处理
break;
case 0x0C:
//端点0 的接收器接收到数据,SETUP 事务成功,内部固件模式时不需要处理
break;
case 0:
//端点0 的接收器接收到数据,OUT 事务成功,内部固件模式时不需要处理
break;
case 0x08:
//端点0 的发送器发送完数据,IN 事务成功,内部固件模式时不需要处理
break;
case 0x01:
//端点1 接收到数据,OUT 事务成功,内部固件模式时不需要处理
break;
case 0x09:
//端点1(中断端点)发送完数据,IN 事务成功
SendCommand372(ULK_USB); //释放当前USB缓冲区
break;
case 0x02:
//端点2(批量端点)接收到数据,OUT 事务成功
SendCommand372(R_USB_DATA); //写读端点2数据的命令
ReadData372(&q0,1); //读端点2收到数据的字节数
if(q0!=0)
{
ReadData372(UsbReBuf,q0); //读取数据,释放缓冲区
if(q0==2)
{
//收到字节数为2,为两个加数
sum=UsbReBuf[0]+UsbReBuf[1];
UsbSendBuf[0]=sum&0xFF;
UsbSendBuf[1]=sum>>8;
IsSend=1;
}
}
break;
case 0x0A:
//端点2(批量端点)发送完数据,IN 事务成功
SendCommand372(ULK_USB); //释放当前USB缓冲区
break;
}
}
/**************************************************************************
测试工作状态
返回值:1:正常 0:不正常
**************************************************************************/
byte Test372()
{
byte q0,q1=0;
SendCommand372(CHK_EXIST);
q0=0xF0;
WriteData372(&q0,1);
ReadData372(&q1,1);
q1=~q1;
if(q0==q1)
return 1;
else
return 0;
}
/**************************************************************************
向USB 端点1 的上传缓冲区写入数据块。数据块长度的有效值是0~8,
如果长度不为0,则单片机必须将后续数据逐个写入CH372。
psrc:要写的数据。
**************************************************************************/
void WrPoint1(byte* psrc,byte n_byte)
{
SendCommand372(W_USB_DATA5);
WriteData372(&n_byte,1);
WriteData372(psrc,n_byte);
}
/**************************************************************************
向USB 端点2 的上传缓冲区写入数据块。数据块长度的有效值是0~64,
如果长度不为0,则单片机必须将后续数据逐个写入CH372。
psrc:要写的数据。
**************************************************************************/
void WrPoint2(byte* psrc,byte n_byte)
{
SendCommand372(W_USB_DATA7);
WriteData372(&n_byte,1);
WriteData372(psrc,n_byte);
}
/**************************************************************************
底层命令
**************************************************************************/
/**************************************************************************
发送命令
command:命令
**************************************************************************/
void SendCommand372(byte command)
{
*((byte*)USB_CMD_ADR)=command;
__delay_cycles(20);
}
/**************************************************************************
发送数据
psrc:数据
n_byte:数据字节数。范围:0~64
**************************************************************************/
void WriteData372(byte* psrc,byte n_byte)
{
byte q0;
for(q0=0;q0<n_byte;q0++)
{
*((byte*)USB_DATA_ADR)=(*psrc);
__delay_cycles(15);
psrc++;
}
}
/**************************************************************************
读数据
pdest:数据
n_byte:数据字节数。范围:0~64
**************************************************************************/
void ReadData372(byte* pdest,byte n_byte)
{
byte q0;
for(q0=0;q0<n_byte;q0++)
{
*pdest=*((byte*)USB_DATA_ADR);
__delay_cycles(15);
pdest++;
}
}
/****************************************************************************
延时
n:延时循环次数
****************************************************************************/
void __delay_cycles(word16 n)
{
word16 q0;
for(q0=n;q0>0;q0--)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -