USB不同的应用需要使用到的端点数和端点数据长度各不相同,如果为每个端点都单独规划一个存储区非常浪费。
所以STM32为USB模块提供了共512个字节的存储区,至于如何为每个端点分配使用这512B的空间,就是用户自己的事情了,这样存储区的分配就非常经济灵活。这512B空间的首地址是0x40006000。
你看到的#define
ENDP2_RXADDR
(0xD8),这个0xD8就是在这512B空间里的偏移地址,说明端点2收到的数据将放在0x40006000
+
0xD8
*
2的地址空间里。至于为什么要×2,是因为这部分存储区是按照2字节访问的,即每存放1个字节的数据要占据2个字节的空间。所以这段存储区的地址是从0x40006000到0x400063FF。
至于如何定义端点2的发送缓冲区,就看你的应用了。你把端点2的接受缓冲区定义在0xd8,如果端点2的接收数据长度是64个字节,那就要为端点2的接收保留64个字节,端点2的发送缓冲区就要定义到0xd8+64之后的空间。
即:#define
ENDP2_TXADDR
(0xD8+64),
当然也可以#define
ENDP2_TXADDR
(0xD8+100)或是其他。
总之如何分配这段存储区,完全可以按照你应用的需求来做。
最近研究了下103VBT6的USB,看了很多次都看不明白,我开始怀疑我的阅读能力了。现有以下几点疑问请教大家
1.缓冲区描述表在缓冲区内即0x4000 6000--0x400063FF。如果我只用端点0,那么端点0的缓冲区描述表为
ADDR0_TX、COUNT0_TX、ADDR0_RX、COUNT0_RX所对应的地址为0x4000 6000--0x4000 6008 (USB_BTABLE = 0)
现在有两人疑问:
A.0x4000 6008以后的地址可不可以作缓冲区?
B.如果给ADDR0_TX、COUNT0_TX赋个合适的值,会不会端点0的缓冲区在0x4000 6000--0x4000 6008内,从而覆盖了它的缓冲区描术表?
2.为什么分组缓冲区地址(按字节编址)要乘以2才是缓冲区在MCU的地址,能不能举个例子说明?
3.0x4000 6000--0x400063FF等于1024字节,为什么是512字节,是不是后一半没有使用,芯片为103VBT6?如果我有一个端
点用了512字节缓冲区,那么缓冲区就用完了,是不是表示其他端点就没有缓冲区可用了,连缓冲区描述表都没有空间可分配了
1.A) 如果只使用端点0,0x4000 6010以后的地址可以作缓冲区。注意不是0x4000 6008以后的地址,原因请看下面的2)。
1.B) 如果给ADDR0_TX、COUNT0_TX赋的值不合适,端点0的缓冲区有可能覆盖缓冲区描述表,所以请选择合适的值,以避免冲突。
2)这是因为分组缓冲区是一个双端口的RAM,CPU一端需要使用32位方式访问,但USB模块一端使用16位方式访问。
例如需要从0x4000 6010开始分配8个字节的缓冲区,则从CPU一端看,需要占用0x4000 6010、0x4000 6014、0x4000 6018和0x4000 601C开始的4个字的空间,即CPU端每4个字节的地址空间中,只有2个字节的地址空间对应实际的存储器,而另2个字节的地址空间没有对应到任何物理的存储器。
3)1024字节与512字节的问题,请看上面的说明。
如果有一个端点用了512字节缓冲区,那么缓冲区就用完了,表示其他端点就没有缓冲区可用了,连缓冲区描述表都没有空间可分配了。
关键字:stm32 usb 数据缓冲区
引用地址:
stm32 usb数据缓冲区疑问
推荐阅读最新更新时间:2024-03-16 14:28
USB协议深入分析 设置USB地址
前面已经解释主控器怎么样发送设备描述符下来,然后设备返回相应的设备描述符。下一步主控器的动作是做什么呢?由于在USB总线上的设备有很多,为了区分不同的设备通讯,就需要给每个设备分配一个地址,这跟网络中的IP地址是一样的,或者跟MAC地址也是一样的。因而,接着下来就是主控器分配地址给设备,USB的设备地址是从1开始到127。下面就是接收到主控器发下来的数据包: 00 05 01 00 00 00 00 00 由USB_SETUP_PACKET定义具体地分析这个数据,就可以知道应做什么样的响应了。下面就来解释这个操作。 先取得bmRequestType的类型,也就是第一个字节,它是00。从USB协议里查看,它的方向位是主控器发送给设
[单片机]
STM32编程之从寄存器到标准库
【1】上集说到寄存器编程之点灯仪式,寄存器编程看似简单,是因为点灯本身就很简单,大家知道寄存器编程是怎么回事就行了,下面我们改造一下前篇文章的程序,渐渐地我们就往标准库靠拢了!新世界,更精彩,打起精神! 【2】引入头文件 改动很小,就是把宏定义移到了.h文件中,再在.c文件中include头文件即可。以上便是头文件的引入。值得注意的是头文件开头两句和最后一句是格式,是为了防止重复声明,不加的话容易粗心出错! 【3】引入文件夹和混合编译 问题:两个.c问题如何同时编译 只需要一步配置即可,这里我们新建了一个文件夹,也完成了混合编程的目的,下一步就可以接触标准库编程方式了,下篇文章再见!
[单片机]
stm32快速学习6——SysTick 定时1s控制LED
设置使用外部8M晶振 设置引脚功能 设置systick为1s中断 利用systick中断就可以得到1s时间 //////////////////////////////////////////////////////////////////////////前言///////////////////////////////////////////////////////////////////////////////////////// stm32的systick通过少数的程序设置,当使用systick_config()函数之后,其载入值就是你的参数,并且自动打开中断,并将中断设为最低的优先级,将其时钟设为HCLK即系统时钟7
[单片机]
STM32关于USART的问题集锦
STM32F207的串口问题 问: 答1:RCC_APB2PeriphClockCmd(RCC_APB2Periph_USARTx, ENABLE) for USART1 and USART6 * RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE) for USART2, USART3, UART4 or UART5. * 3、stm32中的串口通信中的USART_WordLength,数据位的长度包不包括开始位哪些? 问:stm32中的串口通信中的USART_WordLength,数据位的长度包不包括开始位哪些? 答:不包括开始位,如果你有 校验(奇 偶)的
[单片机]
STM32----LTDC与DMA2D
一、硬件环境 第一代野火F29开发板,MCU为stm32f429IGT6。板载IS42S16400J SDRAM,16bit位宽 8M容量。 TFT为RG888接口,分辨率为800*480。 二、LTCD初始化 (1)初始化GPIO与SDRAM (2)初始化相关时钟 //2、LTDC相关时钟初始化 /* 配置 PLLSAI 分频器,它的输出作为像素同步时钟CLK*/ /* PLLSAI_VCO 输入时钟 = HSE_VALUE/PLL_M = 1 Mhz */ /* PLLSAI_VCO 输出时钟 = PLLSAI_VCO输入 * PLLSAI_N = 420 Mhz */ /* P
[单片机]
基于MDK编译器 STM32与12864液晶显示程序 和电路连接
里附上的是主程序部分和电路连接 这里用的12864液晶是5v的,电路链接部分 RS PE2 RW PE4 EN PE6 15口PSB串并 PE3 #include stm32f10x.h GPIO_InitTypeDef GPIO_InitStructure; #define RS_SET GPIO_SetBits(GPIOE, GPIO_Pin_2) #define RS_CLR GPIO_ResetBits(GPIOE, GPIO_Pin_2) #define RW_SET GPIO_SetBits(GPIOE, GPIO_Pin_4) #define RW_CLR GPIO_Re
[单片机]
STM32 APB1和APB2的区别
APB2负责AD,I/O,高级TIM,串口1。 APB1负责DA,USB,SPI,I2C,CAN,串口2345,普通TIM
[单片机]