南京沁恒CH552单片机系列使用教程
第一章 CH552介绍及开发环境搭建
第二章 CH552示例程序编写及下载
第三章 CH552使用代码分析
第四章 基于CH552的USB-HID开发
前言
记录一下USB-HID开发过程。只是对例程进行了简单的调用,并没有进行深度开发。
一、添加示例代码
删除原工程中的main.c文件,添加USB\Device\CompositeKM.c文件,该文件是关于USB键盘鼠标的定义。
USBDeviceInit();//USB设备模式初始化
//EA = 1; //允许单片机中断
UEP1_T_LEN = 0;//预使用发送长度一定要清空
UEP2_T_LEN = 0;//预使用发送长度一定要清空
mDelaymS(2000);
EA = 1;//整合程序后,单片机中断延时开放,否则可能会影响USB初始化
while(1)//将串口接收到的数据发送到USB
{
if(Timer_Usart0_Flag == 1)
{
Timer_Usart0_Flag = 0;
USART0_SAT = USART0_NUM;//接收长度
USART0_NUM = 0;//指针清零
flag_usb_send=1 ;
for( i = 0;i<USART0_SAT;i++)//自身数据发送
{
CH554UART1SendByte(USART0_RecBuff[i]);
}
}
if(Ready & (flag_usb_send==1))//自身数据发送到USB
{
if(USART0_SAT)
{
USBSendstr(USART0_RecBuff,USART0_SAT);
USART0_SAT = 0;
}
mDelaymS(10);//删除可能会导致USB发送的字符一直发送
CH554WDTFeed(0);
}
自制的USBHID,插入到设备,设备如果重启,会不识别,原因是USB主机启动时间比USBHID启动的慢,USBHID初始化失败,解决办法可以增发初始化失败重新初始化的逻辑,或者增加看门狗超时复位也可解决。
二、键盘键值
USB 规范规定了键盘的键值:
字符串转键值代码实现,篇幅原因,只实现了常用的按键。所有键值要遍历一遍,效率较低,各位有更好的实现方法,欢迎交流。
void USBSendstr(char* s,UINT8 len)
{
UINT8 i = 0;
memset(HIDKey,0,8);
for(i=0;i<len;i++)
{
if(s[i]==48)//0
{
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[2] = (s[i]-9);
Enp1IntIn();
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[2] = 0; //按键结束
Enp1IntIn();
}
else if(s[i]>=49 && s[i]<=57)//1-9
{
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[2] = (s[i]-19);
Enp1IntIn();
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[2] = 0; //按键结束
Enp1IntIn();
}
else if(s[i]>='A' && s[i]<='Z')//A-Z 65-90
{
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[0] = 2;
HIDKey[2] = (s[i]-61);
Enp1IntIn();
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[0] = 0;
HIDKey[2] = 0; //按键结束
Enp1IntIn();
}
else if(s[i]>='a' && s[i]<='z')//a-z 97-122
{
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[2] = (s[i]-93);
Enp1IntIn();
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[2] = 0; //按键结束
Enp1IntIn();
}
else if(s[i]==13)//enter
{
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[0] = 2;
HIDKey[2] = 40;
Enp1IntIn();
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[0] = 0;
HIDKey[2] = 0; //按键结束
Enp1IntIn();
}
else if(s[i]==' ')//
{
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[0] = 0;
HIDKey[2] = 44;
Enp1IntIn();
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[0] = 0;
HIDKey[2] = 0; //按键结束
Enp1IntIn();
}
else//?
{
// UEP1_CTRL = UEP1_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; //默认应答NAK
// UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK; //默认应答NAK
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[0] = 2;
HIDKey[2] = 56;
Enp1IntIn();
while( Endp1Busy )
{
; //如果忙(上一包数据没有传上去),则等待。
}
HIDKey[0] = 0;
HIDKey[2] = 0; //按键结束
Enp1IntIn();
}
}
HIDKey[0] = 0;
HIDKey[2] = 0; //按键结束
Enp1IntIn();
flag_usb_send = 0;
}
总结
文章中提到的相关资料,可从第一章的资料包里提取。
如有表述错误,介绍模糊的地方,欢迎交流指正。