历史上的今天
今天是:2024年11月07日(星期四)
2020年11月07日 | 关于stm32的USB学习笔记之usbcore.c
2020-11-07 来源:eefocus
#include #include "usbreg.h" #include "usbcore.h" #include "usbuser.h" #include "usbcfg.h" #include "usb.h" #include "usb_hw.h" #include "usbdesc.h" #include "hid.h" #include "hiduser.h" #define _DEBUG_ #include "debug.h" #pragma diag_suppress 111,1441 //用来指示USB设备的状态 WORD USB_DeviceStatus; //用来存储设备的地址 BYTE USB_DeviceAddress; //用来存储USB当前使用的设备的配置 BYTE USB_Configuration; //此配置使用端点 DWORD USB_EndPointMask; //用于标志此端点是否已经被停止0~15依次代表15个端点 DWORD USB_EndPointHalt; //此配置使用的接口数 BYTE USB_NumInterfaces; //每个接口可用的当前接口可替换值 BYTE USB_AltSetting[USB_IF_NUM]; /*用于临时存储控制传输时的数据包*/ USB_SETUP_PACKET SetupPacket; /*用于向主机发送数据的EP0的数据结构*/ USB_EP_DATA EP0Data; /*EP0Buf用于向USB发送数据时用的缓冲区*/ BYTE EP0Buf[USB_MAX_PACKET0]; /*功能:复位USB的一些数据标志 *参数:无 *返回值:无 */ void USB_ResetCore(void) { //默认为总线供电,因为我们的USB现在不都是插在电脑上才能工作的么&^_^ USB_DeviceStatus = USB_POWER; //在枚举之初地址当然是0 USB_DeviceAddress = 0; //配置描述符的标识从1开始,这里也先置为0 USB_Configuration = 0; //目前使用的是端点0 USB_EndPointMask = 0x00010001; //没有停止的端点 USB_EndPointHalt = 0x00000000; } /*功能:建立阶段,读取建立数据包 *参数:无 *返回值:无 */ void USB_SetupStage(void) { USB_ReadEP(0x00,(BYTE*)&SetupPacket); } /*功能:建立阶段,In握手包 *参数:无 *返回值:无 */ void USB_StatusInStage(void) { USB_WriteEP(0x80,NULL,0); } /*功能:建立阶段,Out握手包 *参数:无 *返回值:无 */ void USB_StatusOutStage(void) { USB_ReadEP(0x00,EP0Buf); } /*功能:数据In阶段 *参数:无 *返回值:无 */ void USB_DataInStage(void) { DWORD cnt; //先计算引次要发送多少数据 if(EP0Data.Count > USB_MAX_PACKET0) cnt = USB_MAX_PACKET0; else cnt = EP0Data.Count; //这里写端点却主机读,则将Dir位置1 cnt = USB_WriteEP(0x80,EP0Data.pData,cnt); EP0Data.pData += cnt; EP0Data.Count -= cnt; } /*功能:数据Out阶段 *参数:无 *返回值:无 */ void USB_DataOutStage(void) { DWORD cnt; cnt = USB_ReadEP(0x00,EP0Data.pData); EP0Data.pData+=cnt; EP0Data.Count-=cnt; } /*功能:获取USB设备的状态 *参数:无 *返回值:TRUE --->成功 * FALSE --->错误 */ __inline BOOL USB_GetStatus(void) { DWORD n,m; switch(SetupPacket.bmRequestType.BM.Recipient) { //接收端是设备 case REQUEST_TO_DEVICE: //返回设备状态给他 EP0Data.pData = (BYTE *)&USB_DeviceStatus; //将状态信息发送给主机 USB_DataInStage(); break; //接收端是接口 case REQUEST_TO_INTERFACE: /*配置描述符的标识从1开始,并且请求的接口号不能大于接口的数目,因为接口数目从0开始 *因为我们接口描述符中的接口号是一个字节所以这里wIndex中的数据中人低字节有效 */ if((USB_Configuration !=0)&&(SetupPacket.wIndex.WB.L < USB_NumInterfaces)) { //清0两个字节,因为根据USB协议此处必须返回0 *((__packed WORD *)EP0Buf) = 0; EP0Data.pData = EP0Buf; //发送给主机 USB_DataInStage(); } //此接口出现了错误 else return FALSE; break; case REQUEST_TO_ENDPOINT: //端点号高1位0方向,低4位为端点号 n = SetupPacket.wIndex.WB.L & 0x8f; //m的高16位代表in端点的标志,低16位代表out端点的标志 m = (n&0x80)?(1<<16 )<< (n&0x0f) :(1< if((USB_Configuration !=0)||((n&0x0f)==0)&&(USB_EndPointMask & m)) { //查看此端点是否已经停用 *((__packed WORD *)EP0Buf) = (USB_EndPointHalt &m )?1:0; EP0Data.pData = EP0Buf; //将数据发送给主机 USB_DataInStage(); } //说明配置描述符出了问题 else return FALSE; break; default: return FALSE; } return TRUE; } /*功能:设置/清除USB设备的特征 *参数:sc 0----->清除 1----->设置 *返回值:TRUE --->成功 * FALSE --->错误 */ __inline BOOL USB_SetClrFeature(DWORD sc) { DWORD n,m; switch(SetupPacket.bmRequestType.BM.Recipient) { //接收端是设备,则清除或设置设备的特性 case REQUEST_TO_DEVICE: if(SetupPacket.wValue.W == USB_FEATURE_REMOTE_WAKEUP) { if(sc) { printf("设置设备远程唤醒特性rn"); //设置USB状态为使能远程唤醒 USB_DeviceStatus |= USB_GETSTATUS_REMOTE_WAKEUP; /*stm32硬件本身就支持远程唤醒,这里就不用设置了 *当然,软件支不支持在于对中断屏蔽位的设置 */ } else { printf("清除设备远程唤醒特性rn"); USB_DeviceStatus &= ~USB_GETSTATUS_REMOTE_WAKEUP; /*stm32硬件本身就支持远程唤醒,这里就不用设置了 *当然,软件支不支持在于对中断屏蔽位的设置
史海拾趣
|
本公司提供良好发展机会和平台 我公司是一家主营一卡通智能管理系统、智能卡机具、热工仪表三大类产品,集研发、生产、销售、工程安装维护等全套工程实施,具有雄厚技术、销售实力的民营企业。 公司于2003年11月取得ISO9001认证;2005年8月,被杭 ...… 查看全部问答> |
|
详细信息: 书籍作者:天津市半导体器件厂 图书出版社:内发 图书类别:理科、工程技术 出版时间:1970-10 印刷时间:1970-10-01 开本:大16开 页数:135 页 装订:平装 & ...… 查看全部问答> |
|
急求助:有没有TTL电平直接转232和485两种电平的器件?有成品最好. 有没有TTL电平直接转232和485两种电平的器件?有成品最好. 也就是说用这个产品有三个接口.可以直接把TTL电平转成232和485信号输出.… 查看全部问答> |




