当前位置:首页 > 单片机 > 单片机
[导读][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

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

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭