打印
[应用相关]

STM32-custom usb

[复制链接]
楼主: 欢乐家园
手机看帖
扫描二维码
随时随地手机跟帖
21
欢乐家园|  楼主 | 2021-2-22 22:20 | 只看该作者 回帖奖励 |倒序浏览
在两根”/*——*/“中间的代码是最重要的,我们根据配置描述可知,端点1作为输出端点,端点2作为输入端点,所以在Reset函数中需要对端点进行初始化:端点0在USB枚举阶段作为通讯的端点,要配置成控制端点,收发有效;端点1配置成中断传输端点,端点接收有效,发送无效;端点2配置成中断传输端点,端点发送有效。

使用特权

评论回复
22
欢乐家园|  楼主 | 2021-2-22 22:21 | 只看该作者
我们在之前关于数据收发流程中说到,数据接收的流程: USB_LP_CAN1_RX0_IRQHandler—>USB_Istr—->CTR_LP—>EPx_OUT_Callback。所以我们这里首先需要定义USB中断服务程序 USB_LP_CAN1_RX0_IRQHandler,再还要编写端点接收回调函数: EPx_OUT_Callback函数。

使用特权

评论回复
23
欢乐家园|  楼主 | 2021-2-22 22:21 | 只看该作者
在hw_config.c中编写USB中断配置函数:

使用特权

评论回复
24
欢乐家园|  楼主 | 2021-2-22 22:22 | 只看该作者
C_InitStructure.NVIC_IRQChannel = OTG_FS_WKUP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_Init(&NVIC_InitStructure);  
#else
/* Enable the USB interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;  //设置USB中断服务程序
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

#endif /* STM32F10X_CL */

}


  

使用特权

评论回复
25
欢乐家园|  楼主 | 2021-2-22 22:23 | 只看该作者
我们这里只配置 USB_LP_CAN1_RX0_IRQn这个中断,接着在stm32f10x_it.c中编写 USB_LP_CAN1_RX0_IRQHandler()函数:

使用特权

评论回复
26
欢乐家园|  楼主 | 2021-2-22 22:24 | 只看该作者
void USB_LP_CAN1_RX0_IRQHandler(void)
{
  USB_Istr();
}


   

使用特权

评论回复
27
欢乐家园|  楼主 | 2021-2-22 22:24 | 只看该作者
这个中断服务程序只调用USB_Istr()函数。经过这个函数的处理,最终程序会执行到 EPx_OUT_Callback函数,由于我们使用端点1作为接受数据的端点,所以我在usb_endp.c中编写 EP1_OUT_Callback()函数:

使用特权

评论回复
28
欢乐家园|  楼主 | 2021-2-22 22:25 | 只看该作者
/*******************************************************************************
* Function Name  : EP1_OUT_Callback.
* Description    : 端点1输出回调函数
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void EP1_OUT_Callback(void)
{
#ifndef STM32F10X_CL
PMAToUserBufferCopy(USB_Receive_Buffer, ENDP1_RXADDR, REPORT_COUNT); //PMA缓冲区接收到的数据拷贝到用户自定义缓冲区USB_Receive_Buffer中
     SetEPRxStatus(ENDP1, EP_RX_VALID);                                     //设置端点的接收状态为有效,因为端点接收到数据后会端点状态自动设置成停止状态
     USB_Received_Flag=1;                                                 //设置接收到数据标志位
#else
USB_SIL_Read(EP1_OUT,USB_Receive_Buffer);                            //读取输出端点的数据到USB_Receive_Buffer中
USB_Received_Flag=1;                                                 //收到数据的标志
#endif
}


   

使用特权

评论回复
29
欢乐家园|  楼主 | 2021-2-22 22:25 | 只看该作者
这个函数起始很简单,从端点缓冲区中读取数据,保存在 USB_Receive_Buffer[]数组中,到时候,可以直接拿这个数组进行数据操作了。

使用特权

评论回复
30
欢乐家园|  楼主 | 2021-2-22 22:26 | 只看该作者
我们还有编写一个端点发送函数:USB_SendData()。我在自己建的usb_io.c文件中,编写该函数:

使用特权

评论回复
31
欢乐家园|  楼主 | 2021-2-22 22:27 | 只看该作者
/*******************************************************************************
* Function Name  : EP1_IN_Callback.
* Description    : USB向主机发送数据
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
uint32_t USB_SendData(uint8_t *data,uint32_t dataNum)
{
#ifndef STM32F10X_CL
//将数据通过USB发送出去
UserToPMABufferCopy(data, ENDP2_TXADDR, dataNum); //拷贝dataNum个数据到PMA中
SetEPTxCount(ENDP2, REPORT_COUNT);                    //从端点2发送64字节数据
SetEPTxValid(ENDP2);                              //使能端点2的发送状态
#else
USB_SIL_Write(EP2_IN, data, dataNum);
#endif
return dataNum;  
}

使用特权

评论回复
32
欢乐家园|  楼主 | 2021-2-22 22:28 | 只看该作者
依旧很简单,只要来那个要发送的数据包写入端点的缓冲区中,再使能下短短,数据就看可以发送出去了、

使用特权

评论回复
33
欢乐家园|  楼主 | 2021-2-22 22:29 | 只看该作者
最后,我们来编写我们的main函数:

使用特权

评论回复
34
欢乐家园|  楼主 | 2021-2-22 22:30 | 只看该作者
/********************************************************
函数:main()
描述:程序入口地址
参数:无
返回:无
********************************************************/
int main(void)
{  
uint8_t data[64];
uint32_t i=0,ret=0;
BSP_Init();
printf(” |===============================================|\r\n”);
printf(”                USB CustomHID 程序开始           \r\n”);
printf(“|===============================================|\r\n”);
while(1)
{
     if(USB_Received_Flag)
     {
         USB_Received_Flag=0;
         ret = USB_GetData(data,sizeof(data));         //读取数据
         printf(“usb get data %d byte data\r\n”,ret);    //答应接收到的字节数
         for(i=0;i<ret;i++){
             printf(“0x%02X “,data[i]);        //答应接收到的数据
         }
         printf(“\n\r”);
         USB_SendData(data,sizeof(data));      //发送接收到的数据
     }   
}
}

使用特权

评论回复
35
欢乐家园|  楼主 | 2021-2-22 22:32 | 只看该作者
主函数的意思是,USB设备接收到什么数据,就向USB主机发送什么数据,并且在串口打印出收到的数据。

使用特权

评论回复
36
drer| | 2021-3-4 07:32 | 只看该作者
主要的难题是调试

使用特权

评论回复
37
gwsan| | 2021-3-4 07:33 | 只看该作者
许多需要注意的点都提出来了

使用特权

评论回复
38
kxsi| | 2021-3-4 07:34 | 只看该作者
如果不识别 怎么处理呢

使用特权

评论回复
39
nawu| | 2021-3-4 07:36 | 只看该作者
出问题的时候 如何判定是硬件还是软件引起的问题呢

使用特权

评论回复
40
qcliu| | 2021-3-4 07:37 | 只看该作者
以前不知道还有这么多需要配置的地方

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则