当前位置:首页 > 单片机 > 单片机
[导读][cpp] view plaincopyprint?#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" #includ

[cpp] view plaincopyprint?

#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<

//如果配置标识不为0,或配置标识为0,但是是端点0时,才算正常

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

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

在STM32嵌入式开发的日常调试中,HardFault硬件错误、程序随机跑飞是几乎所有开发者都遇到过的棘手问题。传统调试方式下,开发者只能对着故障后残存的几个寄存器值反复推演,或是反复连接仿真器单步复现,不仅定位效率极低...

关键字: STM32 STM32嵌入式

在STM32上跑Java,听起来像是天方夜谭——毕竟入门级STM32F0只有4KB RAM和16KB Flash,连轻量JVM都无法适配。但自从STM32F4/F7/H7系列把片上RAM推到192KB乃至1MB以上,在C...

关键字: STM32 轻量JVM 动态类加载

RT-Thread的设备驱动框架将硬件抽象为统一的设备对象,应用程序通过标准接口(open/read/write/control)操作外设,无需关心底层寄存器。本文以STM32上的一个虚拟GPIO输出设备为例,演示从零编...

关键字: RT-Thread 设备驱动 STM32

USB TypeC接口已成为现代电子设备的通用接口。从笔记本电脑和智能手机到USB TypeC(AI)计算平台和工业边缘设备,USB TypeC仅通过一根线缆,即可同时实现高速数据传输与大功率供电。随着USB供电协议(U...

关键字: USB TypeC USB TypeC

本次使用的线缆基于Prolific公司于2012年发布的USB转UART(TTL)芯片。由于该芯片已较旧,Windows 11系统上的驱动程序已不再支持它。因此,我们需要下载一个更早版本的驱动程序,并将其安装以替代当前更...

关键字: Windows 11 USB 树莓派

当STM32的供应波动和成本压力持续发酵,GD32作为国产替代方案正被越来越多的团队提上日程。硬件层面的Pin-to-Pin兼容性让板级替换变得简单——GD32F103与STM32F103在引脚上完全兼容。但“焊上去能跑...

关键字: GD32 STM32

我们最近完成了一个项目,解决了中型仓库客户的一个实际痛点:在众多货箱中查找物品耗时过长。他们的拣选人员每天工作时间的30%到40%都花在走动和扫描上。为此,我们开发了一套智能库存系统,利用LED灯带精准照亮每个物品所在的...

关键字: LED 树莓派 USB

传统的USB测试仪和直连式电压/电流表通常属于“哑巴”设备。它们仅在基础屏幕上显示数字,却缺乏智能性、连接性和上下文理解能力。作为硬件开发者,我们经常需要测试电池续航能力、评估充电效率、运行自动化生命周期测试,并监控远程...

关键字: 传感器 USB ESP32

Tab5-ADB 是一款固件,可将 M5Stack Tab5 转换为独立的 ADB 主机和安卓远程控制台。它通过 USB 或 TCP/IP 与安卓设备连接,让您无需电脑即可实现屏幕镜像、触控操作、查看设备信息、运行 sh...

关键字: USB Wi-Fi M5Stack Tab5
关闭