访问电脑版页面

导航:老古开发网手机版STM32单片机STM32单片机的中断系统

STM32_USB之完全双缓存(包括发送和接收) -- 更新中断处理

导读:STM32的USB双缓存接收代码其实已经可以在ST提供的USB示例代码中找到,只要稍加修改,就可以得到将近1MB的数据接收性能。虽然Datasheet中说明USB发送也同样可以使用双缓存,但并没有示例代码,由于为了测试性能,自己
关键字:
STM32,USB,中断处理,双缓存,

STM32的USB双缓存接收代码其实已经可以在ST提供的USB示例代码中找到,只要稍加修改,就可以得到将近1MB的数据接收性能。虽然Datasheet中说明USB发送也同样可以使用双缓存,但并没有示例代码,由于为了测试性能,自己做了一个,测试中没有发现问题,虽然对性能的提升不如在USB接收上实现双缓存那么多。

注意:
FreeUserBuffer的作用是切换当前的USB缓存。

1.接收双缓冲:

EPX_OUT_Callback中,此代码只是在ST的示例程序的基础上稍加修改,并且不是偶写的,而是一个网友测试的:

if(GetENDPOINT(ENDP3) & EP_DTOG_TX)

{
FreeUserBuffer(ENDP3, EP_DBUF_OUT);
pkg_len = GetEPDblBuf0Count(ENDP3);
PMAToUserBufferCopy(buffer_out + count_out, ENDP3_RXADDR0, pkg_len);
}
else
{
FreeUserBuffer(ENDP3, EP_DBUF_OUT);
pkg_len = GetEPDblBuf1Count(ENDP3);
PMAToUserBufferCopy(buffer_out + count_out, ENDP3_RXADDR1, pkg_len);
}


2.发送双缓冲:
发送双缓冲也可以类似的实现,不过代码要比接收双缓冲复杂得多。不过了解原理的话,应该也差不多。
ST的STM32论坛里,也有人提出这个问题:http://www.st.com/mcu/forums-cat-7768-23.html,不过一直都没有人回答。
不过他的代码还有一些问题,或者可以说,他对原理还不够了解。实际代码还要比他的这个复杂。
中断处理代码:

// 有发送程序计算总共的数据表数量(包括ZLP)
// 每次IN中断,则把总共要发送的数据包数量-1

usb_in_numofpackage--;
if(GetENDPOINT(ENDP2) & EP_DTOG_RX)
{
if(usb_in_numofpackage > 0)
{
// enable next package
// FreeUserBuffer的作用是切换当前的缓存
// 如果还有数据包要发送,则切换缓存(数据已经准备好了)
FreeUserBuffer(ENDP2, EP_DBUF_IN);
}
// usb_in_data_remain是需要放入缓存的数据长度
//在USB发送函数中,首先会填充2个缓冲,usb_in_data_remain为总长度-2个缓冲的长度
if(usb_in_data_remain > 0)
{
// 还有数据要发送
if(usb_in_data_remain > VIRTUAL_COM_PORT_DATA_SIZE)
{
len = VIRTUAL_COM_PORT_DATA_SIZE;
}
else
{
len = usb_in_data_remain;
}

//把数据拷贝到空闲的缓冲区中,并且设置长度
UserToPMABufferCopy(buffer_in, ENDP2_TXADDR0, len);
SetEPDblBuf0Count(ENDP2, EP_DBUF_IN, len);
// usb_in_data_remain减去已经放入缓冲区的长度
usb_in_data_remain -= len;
//更新数据指针
buffer_in += len;
}
else
{
// 数据都已放入缓冲,设置空闲缓冲区长度为0
SetEPDblBuf0Count(ENDP2, EP_DBUF_IN, 0);
}
}
else
{
if(usb_in_numofpackage > 0)
{
// enable next package
FreeUserBuffer(ENDP2, EP_DBUF_IN);
}
if(usb_in_data_remain > 0)
{
if(usb_in_data_remain > VIRTUAL_COM_PORT_DATA_SIZE)
{
len = VIRTUAL_COM_PORT_DATA_SIZE;
}
else
{
len = usb_in_data_remain;
}
UserToPMABufferCopy(buffer_in, ENDP2_TXADDR1, len);
SetEPDblBuf1Count(ENDP2, EP_DBUF_IN, len);
usb_in_data_remain -= len;
buffer_in += len;
}
else
{
SetEPDblBuf1Count(ENDP2, EP_DBUF_IN, 0);
}
}


来源:互联网   作者:karen  2018/10/23 18:00:02
栏目: [ STM32单片机的中断系统]

相关阅读

关于STM32中断向量表的位置 、重定向问题

STM32F0(3)EXTI 外部中断配置

STM32单片机外部中断的设置方法

STM32单片机中抢占优先级和响应优先级的表达方式解析

STM32单片机是怎样执行中断函数中的应用的

STM32单片机的EXIT中断解析

如何配置stm32中断的优先级

STM32的基本概念及中断应用

STM32中断过程详解

如何采用STM32单片机中断向量控制器NVIC来分配优先级的数量

STM32的Cortex-M3中断异常处理

STM32单片机实现外部中断的步骤及方法

STM32单片机为什么要中断

STM32中断与嵌套NVIC快速入门

关于STM32配置中断和GPIO针脚问题

基于STM32单片机秒中断源和闹钟中断源的解决方案

STM32学习笔记——外部中断的初步了解

STM32单片机优先级的定义

STM32 GPIO外部中断总结

STM32单片机的外部中断和中断控制器的特点解析