当前位置:首页 > 单片机 > 单片机
[导读][cpp] view plaincopyprint?#include #include #include "usbreg.h" #include "usbuser.h" #include "usbcore.h" #include "usb_hw.h" #define _DEBUG_ #include "debug.h" #define USB_EP_NUM 4 /*端点缓冲区的开

[cpp] view plaincopyprint?

#include

#include

#include "usbreg.h"

#include "usbuser.h"

#include "usbcore.h"

#include "usb_hw.h"

#define _DEBUG_

#include "debug.h"

#define USB_EP_NUM 4

/*端点缓冲区的开始地址

*因为每个缓冲块都需要一个端点描术表

*而所有的端点描述表放在,USB缓冲区的首部

*此地址是相对于USB缓冲区的地址,我认为加上Offset更好些

*这里使用2个端点

*端点0与端点1

*此时EP_BUF_ADDR指向缓冲区的内容

*/

#define EP_BUF_ADDR (sizeof(EP_BUF_DSCR)*USB_EP_NUM)

/*USB缓冲区首地址包括缓冲区描述表,绝对地址*/

EP_BUF_DSCR * pBUF_DSCR = (EP_BUF_DSCR *) USB_PMA_ADDR;

/*端点空闲缓冲区地址

*用于指示目前为止USB缓冲区中还没有分配的空闲地址的首地址*/

WORD FreeBufAddr;

/*功能:用于初始化USB的时钟等部分

*参数:无

*返回值:无

*/

void USB_Init(void)

{

printf("进入USB_Init,进行初始化rn");

//使能USB时钟

RCC->APB1ENR |= (1<<23);

//使能USB中断

/*因为USB低优先级中断的中断号为20,而NVIC——IPRX

*寄存器用四位来存储中断优先级,所以20/4=5 ,

*然后使能第20位中断*/

NVIC->IPR[5] |=0x10;

NVIC->ISER[0]|=(1<<20);

}

/*功能:用于复位USB模块

*参数:无

*返回值:无

*/

/*现在以我的水平还搞不懂双缓冲为何物,所以先不搞^-^*/

/*一些资料:

*USB低优先级中断(通道20):可由所有USB事件触发(正确传输,USB复位等).

*USB高优先级中断(通道19):仅能由同步和双缓冲批量传输事件触发,目的是保证最大的传输速率.

*USB唤醒中断(通道42):由USB挂起模式的唤醒事件触发. OTG_FS_WKUP唤醒

*

*复位要执行的内容可以参见rm0008 21.4.2节

*/

void USB_Reset(void)

{

PrintS("USB_Resetrn");

/*复位了嘛,那所有以前产生的中断都没有用了,清了完事!*/

ISTR=0;

/*通过设置CNTR来控制stm32的USB模块的工作方式

*所有的USB事件中断都是在低优先级中断(通道20)上处理的

*好吧就先使能这么多吧,先跑起来再说!

*/

CNTR= CNTR_CTRM | // 使能正确传输中断

CNTR_RESETM | //使能复位中断

CNTR_SUSPM | //使能挂起中断

CNTR_WKUPM ; //使能唤醒中断

FreeBufAddr = EP_BUF_ADDR; //此时FreeBuff指向第一个缓冲区首地址(不包括描述符表),相对地址

BTABLE = 0x00; //设置缓冲区描述表的位置仍是相对地址

/*为端点0设置缓冲区及各种控制位*/

pBUF_DSCR->ADDR_TX = FreeBufAddr;

FreeBufAddr+=8; //端点0设置为8个字节,一般控制数据为8个字节

pBUF_DSCR->ADDR_RX = FreeBufAddr;

FreeBufAddr+=8;

/*在count_Rx字段中10~14bit用来表示缓冲区字节的快数

*而15bit用来表示块的大小

*0---2byte

*1---1byte

*我们这里使用了8个字节,bit15为0,所以应该((8<<10)>>1)即8<<9;

*至于count_Rx我们在发送时再来赋值

*/

pBUF_DSCR->COUNT_RX= 8 << 9;

/*设置端点0为控制端点,接收缓冲区有效

*低四位代表端点地址

*/

EPxREG(0) = EP_CONTROL | EP_RX_VALID;

/*使能USB模块,并设置USB地址为0,以响应枚举*/

DADDR = DADDR_EF | 0;

}

/*功能:复位一个端点

*参数: 端点号

* EPNum:bit3~bit0 ----> 端点号

* EPNum:bit7 ----> 端点方向

*

*返回值:无

*/

/*其实就是将下一个要发送的数据包变成DATA0*/

void EP_Reset(DWORD EPNum)

{

DWORD num,var;

PrintS("EP_Resetrn");

/*获得端点号,低四位为端点号*/

num = EPNum & 0x0F;

var = EPxREG(num);

/*如果bit7为1则将此端点的发送toggle置为0,

*否则将此端点的接收toggle置为0

*因为数据总是从data0数据包开始发送的

*/

if(EPNum & 0x80)

EPxREG(num) = var & (EP_MASK | EP_DTOG_TX);/*输入端点*/

else

EPxREG(num) = var & (EP_MASK | EP_DTOG_RX);/*输出端点*/

}

/*功能:连接或断开USB功能

*参数:true -->连接USB

* false-->关闭USB

*返回值:无

*/

void USB_Connect(BOOL turnon)

{

/*需要注意一点的事,所有的USB寄存器尽量用=而不要用与或非

*在编程手册上有明确表明,这样可能会导至出一些问题*/

printf("进入连接USB程序rn");

/*将USB强制复位*/

CNTR = CNTR_FRES;

// printf("test1rn");

/*因为刚连接所以应该跟才启动一样,将所有没有处理的中断给清理掉*/

ISTR=0;

// printf("test2rn");

if(turnon)

{

// printf("test3rn");

/*使能GPIOA,然后将PA.8置低,使USB

*的D+加1.5K上接电阻,使USB集线器识别了高速设备

*这样才能让USB识别

*/

RCC->APB2ENR |= (1 << 2); /* enable clock for GPIOA */

GPIOA->CRH &= ~(0x0f << 0 * 4); /* clear port PA8 */

GPIOA->CRH |= (0x03 << 0 * 4); /* PA6 General purpose output open-drain, max speed 50 MHz */

GPIOA->BRR = ( 1 << 8 ); /* reset PA8 (set to low) */

/*经过调试发现,这个语句的本意是:复位USB模块

*然后在此使能CNTR_RESETM即复位中断标志

*至于端点0的初始化留在USB低优先级中进行处理

*当然,我们也只开了低优先级中断^_^!*/

CNTR = CNTR_RESETM; /*此处只使能了复位中断,*/

}

else

CNTR = CNTR_FRES | CNTR_PDWN ;/*复位并关闭*/

}

/*功能:设置端点状态

*参数:EPnum --->端点号

* stat --->要设置的状态值

*返回值:无

*/

void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR * pEPD)

{

DWORD num,val;

//取得端点号

num = pEPD->bEndpointAddress & 0xf;

val = pEPD->wMaxPacketSize;

//如果是IN端点

if(pEPD->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK)

{

//此处我只想说pBUF_DSCR是指针,剩下的就是语法问题了

(pBUF_DSCR + num)->ADDR_TX = FreeBufAddr;

/*取2的倍数,因为缓冲区都是字对齐的,注意此处如果大于1023会出现浪费现象

*因为USB_COUNTn

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱: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
关闭