<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STM32--USB詳細(xì)使用說明

          STM32--USB詳細(xì)使用說明

          作者: 時(shí)間:2016-11-27 來源:網(wǎng)絡(luò) 收藏
          說明:使用的是STM32F103ZET6

          硬件原理圖

          本文引用地址:http://www.ex-cimer.com/article/201611/322088.htm

          在開始枚舉設(shè)備的一些初始化

          void bsp_USBInit(void)
          {

          GPIO_InitTypeDef GPIO_InitStructure;


          RCC_APB2PeriphClockCmd(RCC_USB_PULL_UP, ENABLE);

          USB_CABLE_DISABLE();


          GPIO_InitStructure.GPIO_Pin = PIN_USB_PULL_UP;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
          GPIO_Init(GPIOB, &GPIO_InitStructure);

          {
          NVIC_InitTypeDef NVIC_InitStructure;

          NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
          NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);
          }

          RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);

          RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);


          USB_Init();

          }

          現(xiàn)在開始分析真正的初始化

          第一步:初始化,總線復(fù)位及向默認(rèn)地址 0發(fā)送 GET_DESCRIPTOR 指令包,請(qǐng)求設(shè)備描述

          1)Index[4 - 5]:表示 USB插入總線復(fù)位;

          2)Index[7 - 8]:表示主機(jī)向默認(rèn)地址發(fā)送GET_DESCRIPTOR指令包,詳細(xì)信
          息也抓出來了,如(圖二)所示

          3)Index[15 - 17]:表示設(shè)備向主機(jī)發(fā)送設(shè)備描述數(shù)據(jù) Index[16]
          4)Index[18 - 19]:表示主機(jī)完成 GET_DESCRIPTOR指令后,給設(shè)備發(fā)送一個(gè)
          空應(yīng)答

          現(xiàn)在具體的分析103的usb的執(zhí)行過程 按順序向下執(zhí)行

          ***************(1)**************

          DEVICE_INFO *pInformation;

          DEVICE_PROP *pProperty;

          DEVICE_PROP Device_Property =
          {
          Joystick_init,
          Joystick_Reset,
          Joystick_Status_In,
          Joystick_Status_Out,
          Joystick_Data_Setup,
          Joystick_NoData_Setup,
          Joystick_Get_Interface_Setting,
          Joystick_GetDeviceDescriptor,
          Joystick_GetConfigDescriptor,
          Joystick_GetStringDescriptor,
          0,
          0x40
          };

          USER_STANDARD_REQUESTS User_Standard_Requests =
          {
          Joystick_GetConfiguration,
          Joystick_SetConfiguration,
          Joystick_GetInterface,
          Joystick_SetInterface,
          Joystick_GetStatus,
          Joystick_ClearFeature,
          Joystick_SetEndPointFeature,
          Joystick_SetDeviceFeature,
          Joystick_SetDeviceAddress
          };

          //USB內(nèi)核將主機(jī)發(fā)送過來的用于實(shí)現(xiàn)USB設(shè)備的設(shè)置包保存在設(shè)備信息結(jié)構(gòu)表中
          typedef struct _DEVICE_INFO
          {
          uint8_t USBbmRequestType;
          uint8_t USBbRequest;
          uint16_t_uint8_t USBwValues;
          uint16_t_uint8_t USBwIndexs;
          uint16_t_uint8_t USBwLengths;

          uint8_t ControlState;
          uint8_t Current_Feature;
          uint8_t Current_Configuration;
          uint8_t Current_Interface;
          uint8_t Current_AlternateSetting;

          ENDPOINT_INFO Ctrl_Info;
          }DEVICE_INFO;

          usb_init.c文件里面的

          void USB_Init(void)
          {
          pInformation = &Device_Info;
          pInformation->ControlState = 2;
          pProperty = &Device_Property;
          pUser_Standard_Requests = &User_Standard_Requests;

          pProperty->Init();
          }

          ***************(2)**************通過函數(shù)指針指向這個(gè)初始化函數(shù)pProperty 在usb_prop.c文件里面

          void Joystick_init(void)
          {


          Get_SerialNum();//得到串行號(hào)

          pInformation->Current_Configuration = 0;//

          PowerOn();//將USB上電 連接設(shè)備


          USB_SIL_Init();//主要是CNTR寄存器的初始化
          bDeviceState = UNCONNECTED;//設(shè)備狀態(tài)標(biāo)志 當(dāng)前狀態(tài)未連接
          }

          hw_config.c文件里面 這個(gè)和標(biāo)準(zhǔn)的不一樣有改動(dòng),獲取設(shè)備版本號(hào),將其存入到版本號(hào)字符串。

          void Get_SerialNum(void) //得到串行號(hào)
          {
          uint32_t Device_Serial0, Device_Serial1, Device_Serial2;
          Device_Serial0 = *(__IO uint32_t*)(0x1FFFF7E8);
          Device_Serial1 = *(__IO uint32_t*)(0x1FFFF7EC);
          Device_Serial2 = *(__IO uint32_t*)(0x1FFFF7F0);
          Device_Serial0 += Device_Serial2;
          if (Device_Serial0 != 0)
          {
          IntToUnicode (Device_Serial0, &Joystick_StringSerial[2] , 8);
          IntToUnicode (Device_Serial1, &Joystick_StringSerial[18], 4);
          }
          }

          usb_pwr.c文件里面 在這個(gè)文件里面只是使能了復(fù)位,掛起,喚醒中斷,在PowerOn函數(shù)使能了復(fù)位中斷以后,將進(jìn)入到USB的復(fù)位中斷里面去。

          然后再執(zhí)行函數(shù)USB_SIL_Init 將所有的USB中斷都打開。在D+被接通上拉以后,設(shè)備就能被主機(jī)檢測(cè)到。

          RESULT PowerOn(void)
          {
          #ifndef STM32F10X_CL
          uint16_t wRegVal;


          USB_Cable_Config(ENABLE);//將USB上電連接


          //對(duì)USB模塊強(qiáng)制復(fù)位,類似于USB總線上的復(fù)位信號(hào)。USB模塊將一直保持在復(fù)位狀態(tài)下
          //直到軟件清除此位。如果USB復(fù)位中斷被使能,將產(chǎn)生一個(gè)復(fù)位中斷。
          wRegVal = CNTR_FRES;//強(qiáng)制復(fù)位
          _SetCNTR(wRegVal);


          wInterrupt_Mask = 0;
          _SetCNTR(wInterrupt_Mask);//清除復(fù)位信號(hào)

          _SetISTR(0);

          //復(fù)位中斷屏蔽位 掛起中斷屏蔽位 喚醒中斷屏蔽位使能
          wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;

          _SetCNTR(wInterrupt_Mask);
          #endif

          return USB_SUCCESS;
          }

          usb_istr.c文件里面,下面只寫了進(jìn)入到復(fù)位中斷函數(shù),進(jìn)入到USB連接狀態(tài)

          void USB_Istr(void)

          {

          wIstr = _GetISTR();

          #if (IMR_MSK & ISTR_RESET)//USB復(fù)位請(qǐng)求中斷
          if (wIstr & ISTR_RESET & wInterrupt_Mask)
          {
          _SetISTR((uint16_t)CLR_RESET);//清楚復(fù)位中斷標(biāo)志
          Device_Property.Reset();//進(jìn)入到復(fù)位中斷
          #ifdef RESET_CALLBACK
          RESET_Callback();
          #endif
          }
          #end

          }

          usb_prop.c文件里面,實(shí)現(xiàn)對(duì)端點(diǎn)的設(shè)置。

          void Joystick_Reset(void)
          {

          pInformation->Current_Configuration = 0;
          pInformation->Current_Interface = 0;


          pInformation->Current_Feature = Joystick_ConfigDescriptor[7];//供電模式選擇

          #ifdef STM32F10X_CL


          OTG_DEV_EP_Init(EP1_IN, OTG_DEV_EP_TYPE_INT, 4);
          #else

          SetBTABLE(BTABLE_ADDRESS);//分組緩沖區(qū)描述表地址設(shè)置


          SetEPType(ENDP0, EP_CONTROL);//初始化為控制端點(diǎn)類型
          SetEPTxStatus(ENDP0, EP_TX_STALL); //端點(diǎn)以STALL分組響應(yīng)所有的發(fā)送請(qǐng)求。

          //也就是端點(diǎn)狀態(tài)設(shè)置成發(fā)送無效,也就是主機(jī)的IN令牌包來的時(shí)候,回送一個(gè)STALL。
          SetEPRxAddr(ENDP0, ENDP0_RXADDR);//設(shè)置端點(diǎn)0描述符的接受地址,

          SetEPTxAddr(ENDP0, ENDP0_TXADDR);//設(shè)置端點(diǎn)0描述符的發(fā)送地址

          Clear_Status_Out(ENDP0);

          //僅用于控制端點(diǎn) 如果STATUS_OUT位被清除,OUT分組可以包含任意長(zhǎng)度的數(shù)據(jù)
          SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);

          //設(shè)置端點(diǎn)0的接受字節(jié)寄存器的最大值是64
          SetEPRxValid(ENDP0);//設(shè)置接受端點(diǎn)有效


          SetEPType(ENDP1, EP_INTERRUPT);//初始化為中斷端點(diǎn)類型
          SetEPTxAddr(ENDP1, ENDP1_TXADDR);//設(shè)置發(fā)送數(shù)據(jù)的地址
          SetEPTxCount(ENDP1, 4);//設(shè)置發(fā)送的長(zhǎng)度
          SetEPRxStatus(ENDP1, EP_RX_DIS);//設(shè)置接受端點(diǎn)關(guān)閉
          SetEPTxStatus(ENDP1, EP_TX_NAK);//設(shè)置發(fā)送端點(diǎn)端點(diǎn)非應(yīng)答


          SetDeviceAddress(0);//設(shè)置設(shè)備用缺省地址相應(yīng)
          #endif

          bDeviceState = ATTACHED;//當(dāng)前狀態(tài)連接
          }

          usb_sil.c的文件里面,主要是使能了如下這些中斷

          CNTR_CTRM 正確傳輸(CTR)中斷使能 CNTR_WKUPM 喚醒中斷使能
          CNTR_SUSPM 掛起(SUSP)中斷使能 CNTR_ERRM 出錯(cuò)中斷使能
          CNTR_SOFM 幀首中斷使能 CNTR_ESOFM 期望幀首中斷使能CNTR_RESETM 設(shè)置此位將向PC主機(jī)發(fā)送喚醒請(qǐng)求。根據(jù)USB協(xié)議,如果此位在1ms到15ms內(nèi)保持有效,主機(jī)將對(duì)USB模塊實(shí)行喚醒操作。

          uint32_t USB_SIL_Init(void)
          {
          #ifndef STM32F10X_CL


          _SetISTR(0);//清除中斷標(biāo)志
          wInterrupt_Mask = IMR_MSK;

          //這組寄存器用于定義USB模塊的工作模式,中斷的處理,設(shè)備的地址和讀取當(dāng)前幀的編號(hào)
          _SetCNTR(wInterrupt_Mask);//設(shè)置相應(yīng)的控制寄存器
          #else

          OTG_DEV_Init();
          #endif

          return 0;
          }


          上一頁 1 2 3 下一頁

          關(guān)鍵詞: STM32USB使用說

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();