STM32 usb_endp.c和usb_istr.c文件分析

发布者:lqs1975最新更新时间:2016-12-20 来源: eefocus关键字:STM32  usb_endp.c  usb_istr.c 手机看文章 扫描二维码
随时随地手机看文章

有时候总在想,怎么样的学习才是最好的?就像学习USB,到底只要学到会应用就可以了,还是要深入到协议内容和驱动底层呢?经常对别人说自己会某某东西,其实自己也只是一知半解的,只会些应用去糊弄别人。于是总在安慰自己:我只要会做些应用就可以了!!!

下面介绍STM32 USB工程的usb_endp.c文件和usb_istr.c两个文件。

首先是usb_endp.c,这个文件很简单,就是定义了结果几个端点输入输出函数,我的工程只有。

uint8_t USB_Receive_Buffer[REPORT_COUNT];  //端点接收数据的缓存 REPORT_COUNT=64

uint8_t USB_Send_Buffer[REPORT_COUNT];   //端点发送数据的缓存

volatile uint8_t USB_Received_Flag=0;   //USB接收到数据的标志




/*******************************************************************************

* Function Name  : EP1_IN_Callback.

* Description    : 端点1输入的回调函数

* Input          : None.

* Output         : None.

* Return         : None.

*******************************************************************************/

void EP1_IN_Callback(void)

{


}

/*******************************************************************************

* Function Name  : EP1_OUT_Callback.

* Description    : 端点1输出回调函数

* Input          : None.

* Output         : None.

* Return         : None.

*******************************************************************************/

void EP1_OUT_Callback(void)

{

USB_SIL_Read(EP1_OUT,USB_Receive_Buffer);//读取输出端点的数据

USB_Received_Flag=1; //收到数据的标志

}

/*******************************************************************************

* Function Name  : EP2_IN_Callback.

* Description    : 端点输入的回调函数.

* Input          : None.

* Output         : None.

* Return         : None.

*******************************************************************************/

void EP2_IN_Callback(void)

{


}


接下去分下usb_istr.c,这个c文件,主要是注册一些端点响应函数,如上面的端点输入输出回电函数,还有就是ISTR中断状态状态寄存器的中断处理,如下:

__IO uint16_t wIstr;   /* 用来保存ISRT寄存器读出的数值 */

__IO uint8_t bIntPackSOF = 0;   /* 连续两个数据包之间收到的帧起始包数量(SOFs) */



/*定义指向指针的函数指针数组,函数指针分别指向7个端点输入服务程序*/

void (*pEpInt_IN[7])(void) =

  {

    EP1_IN_Callback,

    EP2_IN_Callback,

    EP3_IN_Callback,

    EP4_IN_Callback,

    EP5_IN_Callback,

    EP6_IN_Callback,

    EP7_IN_Callback,

  };


/*定义指向指针的函数指针数组,函数指针分别指向7个端点输出服务程序*/

void (*pEpInt_OUT[7])(void) =

  {

    EP1_OUT_Callback,

    EP2_OUT_Callback,

    EP3_OUT_Callback,

    EP4_OUT_Callback,

    EP5_OUT_Callback,

    EP6_OUT_Callback,

    EP7_OUT_Callback,

  };


#ifndef STM32F10X_CL


/*******************************************************************************

* Function Name  : USB_Istr

* Description    : ISTR中断事件的中断服务程序

* Input          : None.

* Output         : None.

* Return         : None.

*******************************************************************************/

void USB_Istr(void)

{


  wIstr = _GetISTR(); //读取中断状态寄存器(ISTR)的值


#if (IMR_MSK & ISTR_CTR) //正确传输中断CTR标志

  if (wIstr & ISTR_CTR & wInterrupt_Mask)

  {

    /* servicing of the endpoint correct transfer interrupt */

    /* clear of the CTR flag into the sub */

    CTR_LP(); //调用正确传输中断服务程序

#ifdef CTR_CALLBACK

    CTR_Callback(); //当定义了CTR_CALLBACK,则调用CTR_Callback,像钩子函数一样,在发生CRT中断时做点什么

#endif

  }

#endif  

  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

#if (IMR_MSK & ISTR_RESET) //复位(RESET)中断标志

  if (wIstr & ISTR_RESET & wInterrupt_Mask) //读出的中断标志是RESET中断标志,且RESET中断使能了

  {

    _SetISTR((uint16_t)CLR_RESET);//清除RESET中断标志

    Device_Property.Reset();//调用复位函数

#ifdef RESET_CALLBACK

    RESET_CALLBACK(); //当定义了RESET_CALLBACK,则调用RESET_CALLBACK,像钩子函数一样,在发生RESET中断时做点什么

#endif

  }

#endif

  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

#if (IMR_MSK & ISTR_DOVR) //分组缓冲区溢出(DOVR)中断标志

  if (wIstr & ISTR_DOVR & wInterrupt_Mask)//读出的中断标志是DOVR中断标志,且DOVR中断使能了

  {

    _SetISTR((uint16_t)CLR_DOVR);//清除DOVR中断标志

#ifdef DOVR_CALLBACK

    DOVR_Callback(); //当定义了DOVR_CALLBACK,则调用DOVR_Callback,像钩子函数一样,在发生DOVR中断时做点什么

#endif

  }

#endif

  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

#if (IMR_MSK & ISTR_ERR) //错误(ERR)中断标志

  if (wIstr & ISTR_ERR & wInterrupt_Mask)//读出的中断标志是ERR中断标志,且ERR中断使能了

  {

    _SetISTR((uint16_t)CLR_ERR);//清除ERR中断标志

#ifdef ERR_CALLBACK

    ERR_Callback(); //当定义了ERR_CALLBACK,则调用ERR_Callback,像钩子函数一样,在发生ERR中断时做点什么

#endif

  }

#endif

  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

#if (IMR_MSK & ISTR_WKUP) //唤醒(WKUP)中断标志

  if (wIstr & ISTR_WKUP & wInterrupt_Mask)//读出的中断标志是WKUP中断标志,且WKUP中断使能了

  {

    _SetISTR((uint16_t)CLR_WKUP);//清除ERR中断标志

    Resume(RESUME_EXTERNAL);//调用唤醒函数

#ifdef WKUP_CALLBACK

    WKUP_Callback(); //当定义了WKUP_CALLBACK,则调用WKUP_Callback,像钩子函数一样,在发生WKUP中断时做点什么

#endif

  }

#endif

  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

#if (IMR_MSK & ISTR_SUSP) //挂起(SUSP)中断标志

  if (wIstr & ISTR_SUSP & wInterrupt_Mask)//读出的中断标志是SUSP中断标志,且SUSP中断使能了

  {


    /* check if SUSPEND is possible */

    if (fSuspendEnabled) //检查是否可以可以挂起

    {

      Suspend(); //如果可以挂起,则调用挂起函数

    }

    else

    {

      /* if not possible then resume after xx ms */

      Resume(RESUME_LATER); //如果不可以挂起,则在xx ms后恢复

    }

    /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */

    _SetISTR((uint16_t)CLR_SUSP);//清除SUSP中断标志

#ifdef SUSP_CALLBACK

    SUSP_Callback(); //当定义了SUSP_CALLBACK,则调用SUSP_Callback,像钩子函数一样,在发生SUSP中断时做点什么

#endif

  }

#endif

  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

#if (IMR_MSK & ISTR_SOF) //帧首(SOF)中断标志

  if (wIstr & ISTR_SOF & wInterrupt_Mask)//读出的中断标志是SOF中断标志,且SOF中断使能了

  {

    _SetISTR((uint16_t)CLR_SOF);//清除SOF中断标志

    bIntPackSOF++; //统计共接收到多少SOF


#ifdef SOF_CALLBACK

    SOF_Callback(); //当定义了SOF_CALLBACK,则调用SOF_Callback,像钩子函数一样,在发生SOF中断时做点什么

#endif

  }

#endif

  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

#if (IMR_MSK & ISTR_ESOF)   //期望帧首(ESOF)中断标志,当没有收到期望的SOF帧首是触发中断

  if (wIstr & ISTR_ESOF & wInterrupt_Mask)//读出的中断标志是SOF中断标志,且ESOF中断使能了

  {

    _SetISTR((uint16_t)CLR_ESOF);//清除ESOF中断标志

    /* resume handling timing is made with ESOFs */  

/* request without change of the machine state */

    Resume(RESUME_ESOF); //恢复ESOF的处理时间


#ifdef ESOF_CALLBACK

    ESOF_Callback(); //当定义了ESOF_CALLBACK,则调用ESOF_Callback像钩子函数一样,在发生ESOF中断时做点什么

#endif

  }

#endif

} /* USB_Istr */



void USB_Istr(void)这个函数很重要,要注意的是每次读取响应的中断标志后要清除该中断标志!!!


关键字:STM32  usb_endp.c  usb_istr.c 引用地址:STM32 usb_endp.c和usb_istr.c文件分析

上一篇:STM32 USB工程的文件分析
下一篇:STM32关于USB的相关寄存器

推荐阅读最新更新时间:2024-03-16 15:26

STM32编译环境、建立工程模板以及程序下载
1、之前写51的程序我们一般都是用的keil5软件,现在写32程序,要用到keil MDK软件,但是keil5和keil MDK不兼容,也就是说在keil5里面我们没办法写STM32F1之类的程序,而在keil MDK里面也没办法写51的程序,所以说为了让他们俩相互兼容,即我们要实现在keilMDK里面要既能够写51的程序,也能够写32的程序,我当初在网上找了好多方法都不行,最后发现一种特别简单好用的方法,就是在把keil5和keil MDK两个软件安装在同一个文件夹下面。具体步骤就是 (1)安装keil5软件(尽量不要安装在C盘),然后激活它。这里激活的时候要在注册机里选择C51。 (2)安装keil MDK软件,在安装
[单片机]
<font color='red'>STM32</font>编译环境、建立工程模板以及程序下载
STM32外部中断易出错总结
前言:这些问题都是我之前在工作中遇到的,后来觉得需要总结,自己记忆不好,所以在这个给自己打个mark。 一:触发方式 STM32 的外部中断是通过边沿来触发的,不支持电平触发; 二:外部中断分组 STM32 的每一个GPIO都能配置成一个外部中断触发源,STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB0,PC0,PD0,PE0,PF0,PG0为第一组,那么依此类推,我们能得出一共有16 组,STM32 规定,每一组中同时只能有一个中断触发源工作,那么,最多工作的也就是16个外部中断。 STM32 分组和对应中断处理函数分配: 管脚 中断标志 中断处理函
[单片机]
STM32内存地址说明
STM32内存分配 在MDK编译过程中,内存的划分如下: Code是存储程序代码的。 RO-data是存储const常量和指令。 RW-data是存储初始化值不为0的全局变量。 ZI-data是存储未初始化的全局变量或初始化值为0的全局变量。 Flash=Code + RO Data + RW Data; RAM=RW-data+ZI-data; 此内存划分暂未包括堆栈,堆栈会在程序运行时,占用RAM。 堆栈的内存占用就是MDK里,RAM分配给RW-data+ZI-data之后的地址开始分配的。
[单片机]
<font color='red'>STM32</font>内存地址说明
stm32基础实验2(按键输入—查询模式)
一、实验原理 1、实现步骤 (1)使能按键对应IO口时钟。调用函数:RCC_APB2PeriphClockCmd(); (2) 初始化IO模式:上拉/下拉输入。调用函数:GPIO_Init(); (3)扫描IO口电平(库函数/寄存器/位操作)。 读取IO口输入电平三种方式 uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);(库函数) GPIOx_IDR:端口输入寄存器(寄存器) PEin(4)-读取GPIOE.4口电平(位操作) Static申明的局部变量,存储在静态存储区。它在函数调用结束之后,不会被释放。它的
[单片机]
<font color='red'>stm32</font>基础实验2(按键输入—查询模式)
关于STM32数据手册中的定时器信号
打开STM32数据手册中的总体框图。娘的,又TMD一阵眼花缭乱。 首先,我们可以看到这个图大概有两个不分,一个部分是时钟源,另一个部分则是输入输出时钟源计数,到CNT计数器,然后根据捕获比较寄存器进行记录或比较。记录或比较有不同的配置。 首先是TI信号 TI1 TI2 TI3 TI4:这个信号就是外部信号,是直接与管脚相连的信号,图中还有一个问题就是TI1是可以是第一通道的外部信号进行触发,也可以设置为,第一通道,第二通道,第三通道异或进行触发。外部信号送往滤波器和边沿检测器。 TIxFP触发有效信号。 TI1FP1 TI1FP2TI2FP1 TI2FP2 TI3FP3 TI3FP4TI4FP3 TI4FP4:这个就是一个触发
[单片机]
STM32芯片系统结构
STM32芯片架构 STM32F103系列芯片的系统架构如下: STM32芯片基于ARM公司的Cortex-M3内核,由ST公司设计生产,内核与总线矩阵之间有I(指令)、S(系统)、D(数据)三条信号线。内核通过总线矩阵与FLASH、SRAM、外设连接。而外设包括GPIO、USART、I2C、SPI等。 STM32芯片系统结构 STM32F103 系列芯片(不包含互联网型)的系统结构如下: 从上图可以看出,在小容量、中容量和大容量产品中,主系统由以下部分构 成: 四个驱动单元: Cortex-M3 内核 DCode 总线(D-bus) Cortex-M3 内核系统总线(S-bus) 通用 DMA1 通用 DMA2 四个被动
[单片机]
<font color='red'>STM32</font>芯片系统结构
STM32之独立看门狗的那些事
为什么MCU会具有看门狗呢?带着这个疑问,来了解看门狗的那些事。就连51单片机都带有看门狗,说明这条狗对我们来说有着 不一般的意义。看门狗的目的一句话说:防止程序乱跑。MCU在不同的环境下程序的运行会受到干扰,比如陷入死循环怎么办? 这就是养狗的好处呀,就算你没养过狗,你也看过猪跑吧。 先看固件库的几个函数 void IWDG_WriteAccessCmd(uint16_t IWDG_WriteAccess); void IWDG_SetPrescaler(uint8_t IWDG_Prescaler); void IWDG_SetReload(uint16_t Reload); void IWDG_ReloadCounter(
[单片机]
基于STM32单片机的电子称设计
摘要 电子秤是将检测与转换技术、计算机技术、信息处理、数字技术等技术综合一体的现代新型称重仪器。它与我们日常生活紧密结合息息相关。 电子称主要以单片机作为中心控制单元,通过称重传感器进行模数转换单元,在配以键盘、显示电路及强大软件来组成。电子称不但计量准确、快速方便,更重要的自动称重、数字显示,对人们生活的影响越来越大,广受欢迎。 本系统的设计主要从硬件电路设计,软件编程调试,实物焊接调试三部分进行详细阐述。硬件电路主要是基于单片机为核心的控制单元实现数据的处理,采用压力传感器对数据进行采集,电子秤专用24位AD转换芯片HX711对传感器采集到的模拟量进行AD转换,转换后的数据送到单片机进行处理显示,数据显示由LCD160
[单片机]
基于<font color='red'>STM32</font>单片机的电子称设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多每日新闻
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved