基于STM32的USB程序开发笔记(二)
时间:10-02
整理:3721RD
点击:
第2篇:STM32 USB固件函数的驱动原理
首先需要了解一个概念:
USB 设备(DEVICE)从来只是被动触发,USB主机(HOST)掌握主动权,发送什么数据,什么时候发送,是给设备数据还是从设备请求数据,都是由USB 主机完成的,USB设备只是配合主机完成设备的枚举、数据方向和大小。根据数据特性再决定该不该回复该如何回复、该不该接收该如何接收这些动作。
了解这些,再仔细查看STM32的参考手册USB部分以及STM32的中断向量表,从中可以找到两个中断:
/*******************************************************************************
* Function Name : USB_HP_CAN_TX_IRQHandler
* Description : This function handles USB High Priority or CAN TX interrupts
* requests.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void USB_HP_CAN_TX_IRQHandler(void)
{
USB_HPI();
}
/*******************************************************************************
* Function Name : USB_LP_CAN_RX0_IRQHandler
* Description : This function handles USB Low Priority or CAN RX0 interrupts
* requests.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void USB_LP_CAN_RX0_IRQHandler(void)
{
USB_LPI();
}
即 USB的高、低优先权中断处理函数,这也是整个STM32 USB的事件驱动源,USB_HPI()与USB_LPI()既而转向usb_core(.c,.h)进行相关处理。中断传输(interrupt)、控制传输(control)、大流量传输(bulk)由USB_LPI()响应,大流量传输(bulk)同样可能响应USB_HPI(),同步传输 (isochronous)只响应USB_HPI()。
这样响应USB的所有请求只需要关注usb_core.c文件中的 USB_LPI()与USB_HPI()函数。由于本人也是对USB刚刚有所了解,因而在本例笔记中USB_HPI()函数未做任何处理,在此开源希望大家能完善与纠正错误并能共享喜悦。以下是USB_LPI()函数:
// *****************************************************************************
// Function Name : USB_LPI.
// Description : Low Priority Interrupt's service routine.
// Input :
// Output :
// Return :
// *****************************************************************************
void USB_LPI(void)
{
unsigned short wValISTR = GetISTR();
#if(CNTR_MASK & ISTR_RESET) // Reset
if(wValISTR & ISTR_RESET & vwInterruptMask)
{
SetISTR(CLR_RESET);
INT_ISTR_RESET();
}
#endif
#if(CNTR_MASK & ISTR_DOVR) // DMA Over/Underrun
if(wValISTR & ISTR_DOVR & vwInterruptMask)
{
SetISTR(CLR_DOVR);
INT_ISTR_DOVR();
}
#endif
#if(CNTR_MASK & ISTR_ERR) // Error
if(wValISTR & ISTR_ERR & vwInterruptMask)
{
SetISTR(CLR_ERR);
INT_ISTR_ERROR();
}
#endif
#if(CNTR_MASK & ISTR_WKUP) // Wakeup
if(wValISTR & ISTR_WKUP & vwInterruptMask)
{
SetISTR(CLR_WKUP);
INT_ISTR_WAKEUP();
}
#endif
#if(CNTR_MASK & ISTR_SUSP) // Suspend
if(wValISTR & ISTR_SUSP & vwInterruptMask)
{
INT_ISTR_SUSPEND();
SetISTR(CLR_SUSP); // must be done after setting of CNTR_FSUSP
}
#endif
#if(CNTR_MASK & ISTR_SOF) // Start Of Frame
if(wValISTR & ISTR_SOF & vwInterruptMask)
{
SetISTR(CLR_SOF);
INT_ISTR_SOF();
}
#endif
#if(CNTR_MASK & ISTR_ESOF) // Expected Start Of Frame
if(wValISTR & ISTR_ESOF & vwInterruptMask)
{
SetISTR(CLR_ESOF);
INT_ISTR_ESOF();
}
#endif
#if(CNTR_MASK & ISTR_CTR) // Correct Transfer
if(wValISTR & ISTR_CTR & vwInterruptMask)
{
INT_ISTR_CTR();
}
#endif
}
// *****************************************************************************
// Function Name : USB_HPI.
// Description : High Priority Interrupt's service routine.
// Input :
// Output :
// Return :
// *****************************************************************************
void USB_HPI(void)
{
}
可以看出,在USB_LPI()函数中,根据STM32 USB的中断状态寄存器(ISTR)的标志位的状态以及定义的USB控制寄存器中断事件屏蔽码,响应各自的中断事件,比如 INT_ISTR_RESET()响应USB的复位中断,一般可在此函数内进行USB的寄存器的初始化;INT_ISTR_CTR()响应一次正确的数据传输中断,顾名思义,在完成一次正确的数据传输操作后,就会响应此函数。
具体含义请仔细查阅STM32参考手册,下篇将针对这些响应函数进行逐一的详细介绍。
首先需要了解一个概念:
USB 设备(DEVICE)从来只是被动触发,USB主机(HOST)掌握主动权,发送什么数据,什么时候发送,是给设备数据还是从设备请求数据,都是由USB 主机完成的,USB设备只是配合主机完成设备的枚举、数据方向和大小。根据数据特性再决定该不该回复该如何回复、该不该接收该如何接收这些动作。
了解这些,再仔细查看STM32的参考手册USB部分以及STM32的中断向量表,从中可以找到两个中断:
/*******************************************************************************
* Function Name : USB_HP_CAN_TX_IRQHandler
* Description : This function handles USB High Priority or CAN TX interrupts
* requests.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void USB_HP_CAN_TX_IRQHandler(void)
{
USB_HPI();
}
/*******************************************************************************
* Function Name : USB_LP_CAN_RX0_IRQHandler
* Description : This function handles USB Low Priority or CAN RX0 interrupts
* requests.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void USB_LP_CAN_RX0_IRQHandler(void)
{
USB_LPI();
}
即 USB的高、低优先权中断处理函数,这也是整个STM32 USB的事件驱动源,USB_HPI()与USB_LPI()既而转向usb_core(.c,.h)进行相关处理。中断传输(interrupt)、控制传输(control)、大流量传输(bulk)由USB_LPI()响应,大流量传输(bulk)同样可能响应USB_HPI(),同步传输 (isochronous)只响应USB_HPI()。
这样响应USB的所有请求只需要关注usb_core.c文件中的 USB_LPI()与USB_HPI()函数。由于本人也是对USB刚刚有所了解,因而在本例笔记中USB_HPI()函数未做任何处理,在此开源希望大家能完善与纠正错误并能共享喜悦。以下是USB_LPI()函数:
// *****************************************************************************
// Function Name : USB_LPI.
// Description : Low Priority Interrupt's service routine.
// Input :
// Output :
// Return :
// *****************************************************************************
void USB_LPI(void)
{
unsigned short wValISTR = GetISTR();
#if(CNTR_MASK & ISTR_RESET) // Reset
if(wValISTR & ISTR_RESET & vwInterruptMask)
{
SetISTR(CLR_RESET);
INT_ISTR_RESET();
}
#endif
#if(CNTR_MASK & ISTR_DOVR) // DMA Over/Underrun
if(wValISTR & ISTR_DOVR & vwInterruptMask)
{
SetISTR(CLR_DOVR);
INT_ISTR_DOVR();
}
#endif
#if(CNTR_MASK & ISTR_ERR) // Error
if(wValISTR & ISTR_ERR & vwInterruptMask)
{
SetISTR(CLR_ERR);
INT_ISTR_ERROR();
}
#endif
#if(CNTR_MASK & ISTR_WKUP) // Wakeup
if(wValISTR & ISTR_WKUP & vwInterruptMask)
{
SetISTR(CLR_WKUP);
INT_ISTR_WAKEUP();
}
#endif
#if(CNTR_MASK & ISTR_SUSP) // Suspend
if(wValISTR & ISTR_SUSP & vwInterruptMask)
{
INT_ISTR_SUSPEND();
SetISTR(CLR_SUSP); // must be done after setting of CNTR_FSUSP
}
#endif
#if(CNTR_MASK & ISTR_SOF) // Start Of Frame
if(wValISTR & ISTR_SOF & vwInterruptMask)
{
SetISTR(CLR_SOF);
INT_ISTR_SOF();
}
#endif
#if(CNTR_MASK & ISTR_ESOF) // Expected Start Of Frame
if(wValISTR & ISTR_ESOF & vwInterruptMask)
{
SetISTR(CLR_ESOF);
INT_ISTR_ESOF();
}
#endif
#if(CNTR_MASK & ISTR_CTR) // Correct Transfer
if(wValISTR & ISTR_CTR & vwInterruptMask)
{
INT_ISTR_CTR();
}
#endif
}
// *****************************************************************************
// Function Name : USB_HPI.
// Description : High Priority Interrupt's service routine.
// Input :
// Output :
// Return :
// *****************************************************************************
void USB_HPI(void)
{
}
可以看出,在USB_LPI()函数中,根据STM32 USB的中断状态寄存器(ISTR)的标志位的状态以及定义的USB控制寄存器中断事件屏蔽码,响应各自的中断事件,比如 INT_ISTR_RESET()响应USB的复位中断,一般可在此函数内进行USB的寄存器的初始化;INT_ISTR_CTR()响应一次正确的数据传输中断,顾名思义,在完成一次正确的数据传输操作后,就会响应此函数。
具体含义请仔细查阅STM32参考手册,下篇将针对这些响应函数进行逐一的详细介绍。
学习学习