CH572-USB HID例程

一、前言

书包里面背着CH572的板子,一直想玩玩USB,一直没时间,最近试了一下(对USB并不熟悉),这里选个简单的HID程序来测测

二、准备

  1. 硬件,CH554 EVK 我这里焊了CH552

在这里插入图片描述

  1. 软件准备 资料地址
  2. 如果要买芯片,可以到TB买 芯片购买链接

三、程序

  1. List item准备一下测试工具
    工具下载链接 ST论坛分享的工具
    在这里插入图片描述

  2. 测试程序地址 CH552\EVT\EXAM\USB\Device\CompatibilityHID.C

  3. 程序就不贴了,记录一些点(就算不太懂HID的流程,也OK)

    描述符

/*设备描述符*/
UINT8C DevDesc[18] = {0x12,0x01,0x10,0x01,0x00,0x00,0x00,THIS_ENDP0_SIZE,
                      0x31,0x51,0x07,0x20,0x02,0x01,0x00,0x00,
                      0x00,0x01
                     };
UINT8C CfgDesc[41] =
{
    0x09,0x02,0x29,0x00,0x01,0x01,0x04,0xA0,0x23,               //配置描述符
    0x09,0x04,0x00,0x00,0x02,0x03,0x00,0x00,0x05,               //接口描述符
    0x09,0x21,0x00,0x01,0x00,0x01,0x22,0x22,0x00,               //HID类描述符
#ifdef  Fullspeed	
    0x07,0x05,0x82,0x03,THIS_ENDP0_SIZE,0x00,0x01,              //端点描述符(全速间隔时间改成1ms)
    0x07,0x05,0x02,0x03,THIS_ENDP0_SIZE,0x00,0x01,              //端点描述符
#else
    0x07,0x05,0x82,0x03,THIS_ENDP0_SIZE,0x00,0x0A,              //端点描述符(低速间隔时间最小10ms)
    0x07,0x05,0x02,0x03,THIS_ENDP0_SIZE,0x00,0x0A,              //端点描述符
#endif	
};

在这里插入图片描述

对应就是VID 和 PID
在这里插入图片描述

端点描述符 ,这里用的都是端点2 BIT0代表端点号,BIT7代表IN OUT,这里INT和OUT都用的端点2
在这里插入图片描述


数据的发送,是通过DMA数据拷贝完成的
这里的 UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK; 意思就是要回复ACK的意思,先用 &~MASK 让用到的位值清0,再给对应的位域值

/*******************************************************************************
* Function Name  : Enp2BlukIn()
* Description    : USB设备模式端点2的批量上传
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Enp2BlukIn( )
{
    memcpy( Ep2Buffer+MAX_PACKET_SIZE, UserEp2Buf, sizeof(UserEp2Buf));        //加载上传数据
    UEP2_T_LEN = THIS_ENDP0_SIZE;                                              //上传最大包长度
    UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK;                  //有数据时上传数据并应答ACK
}

这里看看main,先将UserEp2Buf数据给到0-63,之后Ep2InKey按下了(P15),就上报64字节数据

main()
{
    UINT8 i;
    CfgFsys( );                                                           //CH559时钟选择配置
    mDelaymS(5);                                                          //修改主频等待内部晶振稳定,必加	
    mInitSTDIO( );                                                        //串口0初始化
#ifdef DE_PRINTF
    printf("start ...\n");
#endif	
    for(i=0; i<64; i++)                                                   //准备演示数据
    {
        UserEp2Buf[i] = i;
    }
    USBDeviceInit();                                                      //USB设备模式初始化
    EA = 1;                                                               //允许单片机中断		
    UEP1_T_LEN = 0;                                                       //预使用发送长度一定要清空
    UEP2_T_LEN = 0;                                                       //预使用发送长度一定要清空
    FLAG = 0;
    Ready = 0;
    while(1)
    {
        if(Ready && (Ep2InKey==0))
        {
			while( Endp2Busy );                                            //如果忙(上一包数据没有传上去),则等待。
			Endp2Busy = 1;                                                 //设置为忙状态
            Enp2BlukIn( );
            mDelaymS( 100 );
        }
        mDelaymS( 10 );                                                 //模拟单片机做其它事
    }
}

P1.5接地后,上位机收到的数据:
在这里插入图片描述


收数据部分,这里 UIS_TOKEN_OUT | 2 代表是收到下发的数据(对于主机 OUT是给从机),并且是端点2
这里令牌PID用于标识是 OUT 还是 IN 包,最后 0-3对应的是端点号
在这里插入图片描述
在这里插入图片描述

这里收到数据后取反,然后发回到上位机

void    DeviceInterrupt( void ) interrupt INT_NO_USB using 1                    //USB中断服务程序,使用寄存器组1
{
    UINT8 len,i;
    if(UIF_TRANSFER)                                                            //USB传输完成标志
    {
        switch (USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP))
        {
        case UIS_TOKEN_IN | 2:                                                  //endpoint 2# 端点批量上传
            UEP2_T_LEN = 0;                                                    //预使用发送长度一定要清空
//            UEP1_CTRL ^= bUEP_T_TOG;                                          //如果不设置自动翻转则需要手动翻转
            Endp2Busy = 0 ;
			UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_NAK;           //默认应答NAK
            break;
        case UIS_TOKEN_OUT | 2:                                                 //endpoint 2# 端点批量下传
            if ( U_TOG_OK )                                                     // 不同步的数据包将丢弃
            {
                len = USB_RX_LEN;                                               //接收数据长度,数据从Ep2Buffer首地址开始存放
                for ( i = 0; i < len; i ++ )
                {
                    Ep2Buffer[MAX_PACKET_SIZE+i] = Ep2Buffer[i] ^ 0xFF;         // OUT数据取反到IN由计算机验证
                }
                UEP2_T_LEN = len;
                UEP2_CTRL = UEP2_CTRL & ~ MASK_UEP_T_RES | UEP_T_RES_ACK;       // 允许上传
            }
            break;

发送数据测试,上位机收到返回的数据:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值