📄 ch374 key v1.0.c
字号:
#include "HAL.H"
#include "HAL_BASE.C"
#include "PARA_HW.C"
#define HID_A 4
#define NO_KEY 0
#define K1 0x08
#define LED1 0x70
#define LED2 0x30
#define LED3 0x10
#define SetConfigurationFlag 0
#define GetInterfaceFLag 0x81
#define DEF_HID_GET_REPORT 0x01
#define DEF_HID_GET_IDLE 0x02
const UINT8C MyDevDescr[ ] = { /*设备描述符 device descriptor*/
0x12, //bLength
0x01, //常数DEVIDE(01H) bDescriptorType
0x01,0x01, //bcdUSB
0x00, //bDeviceClass
0x00, //bDeviceSubclass
0x00, //bDeviceProtocol
0x08, //bMaxPacketSize 端点0的最大信息包大小
0xFF,0xFF, //idVendor
0x01,0x00, //idProduct
0x00,0x01, //bcdDevice 设备版本信息
0x04, //iManufacturer 索引值 制造者的字符串描述符的索引值
0x0E, //iProduct 索引值 产品的字符串描述符的索引值
0x30, //iSerialNumber 索引值 序号的字符串描述符的索引值
0x01 //bNumConfigurations 可能配置的数目
};
const UINT8C HIDClassDescr[ ] = { //*HID描述符 hid descriptor
0x09, //bLength
0x21, //bDescriptorType
0x10,0x01, //bcdHID
0x00, //bCountryCode
0x01, //bNumDescriptors
0x22, //bDescriptorType
0x3F,0x00 //wDescriptorLength
};
const UINT8C MyCfgDescr[ ] = { /*配置描述符 configuration descriptor*/
0x09, //bLength
0x02, //常数CONFIGURATION(02H) bDesciptorType
0x22,0x00, //wTotalLength 此配置传回的所有数据大小(字节)
0x01, //bNumInterfacr
0x01, //bConfiguration Value Set_Configuration与Get_Configuration请求的标识符
0x00, //iConfiguration 索引值 此配置的字符串描述符的索引值
0x80, //bmAttributes 自身电源/总线电源以及远程唤醒设置
0x32, //MaxPower
/*接口描述符 interface descriptor*/
0x09, //bLength
0x04, //常数INTERFACE(04H) bDesciptorType
0x00, //bInterfaceNumber 识别此接口的数字
0x00, //bAlternateSetting 用来选择一个替代设置的树枝
0x01, //bNumEndpoints
0x03, //bInterfaceClass
0x01, //bInterfaceSubclass
0x01, //bInterfaceProtocol
0x00, //iInterface 索引值 此接口的字符串描述符的索引值
//*HID描述符 hid descriptor
0x09, //bLength
0x21, //bDescriptorType
0x01,0x01, //bcdHID ???????????????????????????????????????????????????????
0x00, //bCountryCode
0x01, //bNumDescriptors
0x22, //bDescriptorType
0x3F,0x00, //wDescriptorLength
/*端点描述符 endpoint descriptor*/
0x07, //bLength
0x05, //常数ENDPOINT(05H) bDesciptorType
0x81, //bEndpointAddress 端点数目与方向
0x03, //bmAttributes 支持的传输类型:中断端点
0x08,0x00, //wMaxPackerSize 支持的最大信息包大小
0x0A //bInterval 最大延迟/轮询时距/NAK速率
};
const UINT8C HIDReportDescr[ ] = {
0x05,0x01, //Usage Page( Generic Desktop )
0x09,0x06, //Usage( Keyboard ) 表示报表用于HID键盘数据定义
0xA1,0x01, //Collection( Application )
0x05,0x07, //Usage Page( Key Codes ) 该段定义标准键盘的修饰键,其中修饰键个数为8个
0x19,0xE0, //Usage Minimum( 224 )
0x29,0xE7, //Usage Maximum( 231 )
0x15,0x00, //Logical Minimum( 0 )
0x25,0x01, //Logical Maximum( 1 )
0x75,0x01, //Report Size( 1 )
0x95,0x08, //Report Count( 8 )
0x81,0x02, //Input( Data, Variable, Absolute )
0x95,0x01, //Report Count( 1 ) //保留字节
0x75,0x08, //Report Size( 8 )
0x81,0x01, //Input( Constant )
0x95,0x05, //Report Count( 5 ) 该段定义一个输出报表,该报表包含主机控制LED亮和灭的指令
0x75,0x01, //Report Size( 1 )
0x05,0x08, //Usage Page( Page# for LEDS )
0x19,0x01, //Usage Minimum( 1 )
0x29,0x05, //Usage Maximum( 5 )
0x91,0x02, //Output( Data, Variable, Absolute )
0x95,0x01, //Report Count( 1 ) 保留字节
0x75,0x03, //Report Size( 3 )
0x91,0x01, //Output( Constant )
0x95,0x06, //Report Count( 6 ) 该段定义输入键盘报表的键值报表区,该区由6个字节大小,从0到101的键码组成
0x75,0x08, //Report Size( 8 )
0x15,0x00, //Logical Minimum( 0 )
0x25,0x65, //Logical Maximum( 101 )
0x05,0x07, //Usage Page( Key Code )
0x19,0x00, //Usage Minimum( 0 )
0x29,0x65, //Usage Maximum( 101 )
0x81,0x00, //Input( Data, Array )
0xC0 //End Collection
};
void KeyBoardInit( void ); //MCU内部相关资源初始化
void Init374Device( void ); //初始化USB设备
void USB_DeviceInterrupt( void ); //USB设备中断服务程序
void Usb_Get_Descriptor( void ); //Get_Descriptor 读取描述符请求
void Usb_Set_Address( void ); //Set_Address 设置地址
void Usb_Set_Configuration( void ); //Set_Configuration 设置设备配置值
void Usb_Get_Interface( void ); //Get_Interface 查询接口替代值
void Usb_Get_Configuration( void ); //Get_Configuration 查询设备配置值
void Usb_Get_Status( void ); //Get_Status 查询设备、接口或端点的特性状态
void Usb_HID_Set_Report( void ); //Set_Report 主机发送报表给设备
void Usb_HID_Get_Report( void ); //Get_Report 主机向设备请求报表
void Usb_HID_Set_Idle( void ); //Set_Idle 设置HID设备报表的中断输入间隔
void Usb_HID_Get_Idle( void ); //Get_Idle 查询HID设备报表的中断输入间隔
void Led_Task( void ); //键盘指示灯事务处理
void Key_Task( void ); //键盘任务处理
void KeyScan( void ); //键盘扫描
void TimeCounter( void ); //定时器/计数器0计数事务
USB_SETUP_REQ SetupReqBuf;
UINT8 KeyHit;
UINT8 KeyChang;
UINT8 UsbConfig = 0; //USB配置标志
UINT8 LedStatus;
UINT8 MainKeyStatus[ 8 ];
UINT8 NumKeyStatus;
UINT8 data_to_transfer;
UINT8 SetupLen;
PUINT8 pDescr;
UINT8 time_period;
UINT8 TimeCount = 0;
UINT8 DataChang;
void main( void )
{
mDelaymS( 50 ); //等待CH374复位完成
CH374_PORT_INIT( ); //CH374接口初始化
Init374Device( ); //初始化USB设备
KeyBoardInit( );
while( 1 )
{
Key_Task( );
if( Query374Interrupt( ) ) //等待USB设备中断,然后处理USB设备中断
USB_DeviceInterrupt( );
}
}
void KeyBoardInit( void ) //MCU内部相关资源初始化
{
KeyHit = 0;
KeyChang = 0;
DataChang = 0;
LedStatus = 0;
NumKeyStatus = 0;
time_period = 0;
TMOD = 0x01;
TH0 = 0xE0;
TL0 = 0xC0;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void Init374Device( void ) //初始化USB设备
{
Write374Byte( REG_USB_ADDR, 0x00 ); //清USB设备地址
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); //清端点0控制寄存器
Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( 0 ) );
Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( 0 ) );
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); // 清所有中断标志
Write374Byte( REG_INTER_EN, BIT_IE_TRANSFER | BIT_IE_BUS_RESET | BIT_IE_USB_SUSPEND ); // 允许使能传输完成中断和USB总线复位中断以及USB总线挂起中断,芯片唤醒完成中断
Write374Byte( REG_SYS_CTRL, BIT_CTRL_OE_POLAR ); // 对于CH374T或者UEN引脚悬空的CH374S必须置BIT_CTRL_OE_POLAR为1
Write374Byte( REG_USB_SETUP, BIT_SETP_TRANS_EN | BIT_SETP_PULLUP_EN ); // 启动USB设备
}
void USB_DeviceInterrupt( void ) //USB设备中断服务程序
{
UINT8 s;
static UINT8 SetupReq;
s = Read374Byte( REG_INTER_FLAG ); //获取中断状态
if( s & BIT_IF_BUS_RESET ) //USB总线复位
{
Write374Byte( REG_USB_ADDR, 0x00 ); //清USB设备地址
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); //清端点0控制寄存器
Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( 0 ) );
Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( 0 ) );
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_BUS_RESET ); // 清中断标志
}
else if( s & BIT_IF_TRANSFER ) //USB传输完成
{
s = Read374Byte( REG_USB_STATUS ); //查询USB状态寄存器
switch( s & BIT_STAT_PID_ENDP ) //USB设备中断状态
{
case USB_INT_EP1_IN:
{
Usb_HID_Get_Report( );
break;
}
case USB_INT_EP0_SETUP:
{
data_to_transfer = Read374Byte( REG_USB_LENGTH );
if ( data_to_transfer == sizeof( USB_SETUP_REQ ) )
{
Read374Block( RAM_ENDP0_RECV, data_to_transfer, (PUINT8)&SetupReqBuf );
SetupLen = SetupReqBuf.wLengthL;
if( SetupReqBuf.wLengthH || SetupLen > 0x7F )//限制总长度
SetupLen = 0x7F;
data_to_transfer = 0; //默认为成功并且上传0长度数据
SetupReq = SetupReqBuf.bReq; //请求码
switch( SetupReq )
{
case DEF_USB_GET_DESCR:
{
Usb_Get_Descriptor( );
break;
}
case DEF_USB_SET_ADDRESS:
{
Usb_Set_Address( );
break;
}
case DEF_USB_SET_CONFIG:
{
if ( SetupReqBuf.bType == SetConfigurationFlag )
Usb_Set_Configuration( );
else if ( SetupReqBuf.bType == USB_HID_DESCR_TYPE )
Usb_HID_Set_Report( );
break;
}
case DEF_USB_GET_CONFIG:
{
Usb_Get_Configuration ( );
break;
}
case DEF_USB_GET_INTERF:
{
if ( SetupReqBuf.bType == GetInterfaceFLag )
Usb_Get_Interface( );
else if ( SetupReqBuf.bType == USB_HID_DESCR_TYPE )
Usb_HID_Set_Idle( );
break;
}
case DEF_HID_GET_IDLE:
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -