0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

USB讀卡器實(shí)驗(yàn)

汽車電子技術(shù) ? 來源:滑小稽筆記 ? 作者:電子技術(shù)園地 ? 2023-03-01 14:34 ? 次閱讀

22.1 USB概述

USB是英文Universal Serial BUS(通用串行總線)的縮寫,是一個外部總線標(biāo)準(zhǔn),用于規(guī)范電腦與外部設(shè)備的連接和通訊。是應(yīng)用在PC領(lǐng)域的接口技術(shù)。USB接口支持設(shè)備的即插即用和熱插拔功能。是在1994年底由英特爾、康柏、IBM、Microsoft等多家公司聯(lián)合提出的。發(fā)展到現(xiàn)在已經(jīng)有USB1.0/1.1/2.0/3.0/3.1等多個版本。目前用的最多的就是USB2.0和USB3.0,USB3.1目前已經(jīng)開始普及。STM32F103自帶的USB符合USB2.0規(guī)范。標(biāo)準(zhǔn)USB共四根線組成,除VCC和GND外,另外為D+,D-,這兩根數(shù)據(jù)線采用的是差分電壓的方式進(jìn)行數(shù)據(jù)傳輸?shù)摹T赨SB主機(jī)上,D-和D+都是接了15K的電阻到低的,所以在沒有設(shè)備接入的時候,D+、D-均是低電平。而在USB設(shè)備中,如果是高速設(shè)備,則會在D+上接一個1.5K的電阻到VCC,而如果是低速設(shè)備,則會在D-上接一個1.5K的電阻到VCC。這樣當(dāng)設(shè)備接入主機(jī)的時候,主機(jī)就可以判斷是否有設(shè)備接入,并能判斷設(shè)備是高速設(shè)備還是低速設(shè)備。

STM32F1自帶一個USB從機(jī)控制器,符合USB規(guī)范通信,PC主機(jī)和微控制器之間的數(shù)據(jù)傳輸是通過共享一個專用的數(shù)據(jù)緩沖區(qū)來完成的,該數(shù)據(jù)緩沖區(qū)能被USB外設(shè)直接訪問,這塊專用數(shù)據(jù)緩沖區(qū)的大小由所使用的端點(diǎn)數(shù)目和每個端點(diǎn)最大的數(shù)據(jù)分組大小所決定,每個端點(diǎn)最大可使用512字節(jié)緩沖區(qū),最多可用于16個單向或8個雙向端點(diǎn)。

USB模塊同PC主機(jī)通信,根據(jù)USB規(guī)范實(shí)現(xiàn)令牌分組的檢測,數(shù)據(jù)發(fā)送/接收的處理,和握手分組的處理。整個傳輸?shù)母袷接?a href="http://srfitnesspt.com/v/tag/1751/" target="_blank">硬件完成,其中包括CRC的生成和校驗(yàn)。每個端點(diǎn)都有一個緩沖區(qū)描述塊,描述該端點(diǎn)使用的緩沖區(qū)地址、大小和需要傳輸?shù)淖止?jié)數(shù)。當(dāng)USB模塊識別出一個有效的功能/端點(diǎn)的令牌分組時,(如果需要傳輸數(shù)據(jù)并且端點(diǎn)已配置)隨之發(fā)生相關(guān)的數(shù)據(jù)傳輸。USB模塊通過一個內(nèi)部的16位寄存器實(shí)現(xiàn)端口與專用緩沖區(qū)的數(shù)據(jù)交換。在所有的數(shù)據(jù)傳輸完成后,如果需要,則根據(jù)傳輸?shù)姆较?,發(fā)送或接收適當(dāng)?shù)奈帐址纸M。在數(shù)據(jù)傳輸結(jié)束時,USB模塊將觸發(fā)與端點(diǎn)相關(guān)的中斷,通過讀狀態(tài)寄存器和/或者利用不同的中斷來處理。USB設(shè)備架構(gòu)如圖所示。

圖片

USB的中斷映射單元:將可能產(chǎn)生中斷的USB事件映射到三個不同的NVIC請求線上:

(1)USB低優(yōu)先級中斷(通道20):可由所有USB事件觸發(fā)(正確傳輸,USB復(fù)位等)。在處理中斷前應(yīng)首先確定中斷源。

(2)USB高優(yōu)先級中斷(通道19):僅由同步和雙緩沖批量傳輸?shù)恼_傳輸事件觸發(fā),為保證最大的傳輸速率。

(3)USB喚醒中斷(通道42):由USB掛起模式的喚醒事件觸發(fā)。

注:USB和CAN共用一個專用的512字節(jié)的SRAM存儲器用于數(shù)據(jù)的發(fā)送和接收,因此不能同時使用USB和CAN(共享的SRAM被USB和CAN模塊互斥地訪問)。USB和CAN可以同時用于一個應(yīng)用中但不能在同一個時間使用。

22.2 實(shí)驗(yàn)例程

如果需要正常的使用STM32F1系列的USB模塊,就需要編寫USB驅(qū)動程序,這部分程序非常復(fù)雜,需要了解整個USB通信的詳細(xì)過程,針對這個問題,ST公司提供了一個官方的USB驅(qū)動庫,用戶可以通過直接移植官方驅(qū)動庫來實(shí)現(xiàn)USB讀寫控制。

我們現(xiàn)在直接利用官方的USB驅(qū)動源碼來通過計(jì)算機(jī)進(jìn)行SD卡和Flash的讀寫,這里我們需要對官方源碼進(jìn)行一些修改,用于實(shí)現(xiàn)這個效果。

22.2.1 USB源碼概述

USB Mass Storage類支持兩個傳輸協(xié)議:

(1)Bulk-Only傳輸(BOT)

(2)Control/Bulk/Interrupt傳輸(CBI)

MassStorage類規(guī)范定義了兩個類規(guī)定的請求:Get_Max_LUN和MassStorageReset,所有的MassStorage類設(shè)備都必須支持這兩個請求。

(1)Get_Max_LUN(bmRequestType=10100001 bandb Request=11111110b)用來確認(rèn)設(shè)備支持的邏輯單元數(shù)。MaxLUN的值必須是0~15。注意:LUN是從0開始的。主機(jī)不能向不存在的LUN發(fā)送CBW,本章我們定義MaxLUN的值為1,即代表2個邏輯單元。

(2)MassStorageReset(bmRequestType=00100001 bandb Request=11111111b)用來復(fù)位MassStorage設(shè)備及其相關(guān)接口。

支持BOT傳輸的MassStorage設(shè)備接口描述符要求如下:

(1)接口類代碼bInterfaceClass=08h,表示為MassStorage設(shè)備。

(2)接口類子代碼bInterfaceSubClass=06h,表示設(shè)備支持SCSIPrimaryCommand-2(SPC-2)。

(3)協(xié)議代碼bInterfaceProtocol有3種:0x00、0x01、0x50,前兩種需要使用中斷傳輸,最后一種僅使用批量傳輸(BOT)。

(4)支持BOT的設(shè)備必須支持最少3個endpoint:Control,Bulk-In和Bulk-Out。USB2.0的規(guī)范定義了控制端點(diǎn)0。Bulk-In端點(diǎn)用來從設(shè)備向主機(jī)傳送數(shù)據(jù)(本章用端點(diǎn)1實(shí)現(xiàn))。Bulk-Out端點(diǎn)用來從主機(jī)向設(shè)備傳送數(shù)據(jù)(本章用端點(diǎn)2實(shí)現(xiàn))。

ST官方的例程是通過USB來讀寫SD卡(SDIO方式)和Nand Falsh,支持2個邏輯單元,我們在官方例程的基礎(chǔ)上,只需要修改SD驅(qū)動部分代碼,并將對Nand Falsh的操作修改為對SPI Falsh的操作。只要這兩步完成了,剩下的就比較簡單了,對底層磁盤的讀寫,都是在mass_mal.c文件實(shí)現(xiàn)的,所以我們只需要修改該函數(shù)的MAL_Init、MAL_Write、MAL_Read和MAL_GetStatus等4個函數(shù),與我們的SD卡和SPI Falsh對應(yīng)起來即可。

22.2.2 源碼移植過程

(1)需要添加的文件如下表所示。

文件名 目錄 功能
usb_core.c ....\\USB\\CORE 用于處理USB2.0協(xié)議
usb_init.c 用于USB控制器的初始化
usb_int.c 負(fù)責(zé)USB的中斷處理
usb_mem.c 負(fù)責(zé)處理PMA數(shù)據(jù),即STM32內(nèi)部用于USB/CAN的專用數(shù)據(jù)緩沖區(qū)
usb_regs.c 負(fù)責(zé)USB控制寄存器的底層操作
usb_sil.c 為USB端點(diǎn)提供特殊簡化的讀寫訪問函數(shù)
usb_desc.c ...\\USB\\CONFIG 用于虛擬通信端口描述符的處理
usb_endp.c 用于非控制傳輸,處理正確傳輸中斷回調(diào)函數(shù)
usb_istr.c 用于處理USB中斷
usb_prop.c 用于處理所有虛擬通信端口相關(guān)事件,包括初始化,復(fù)位等
usb_pwr.c 用于管理USB的電源狀態(tài)
usb_scsi.c 與SCSI命令相關(guān)的所有處理
scsi_data.c 定義了SCSI數(shù)據(jù)
memory.c 定義USB通信的存儲區(qū)讀寫函數(shù)
mass_mal.c 定義了USB通信的讀寫操作底層函數(shù)接口
usb_bot.c 定義了BOT傳輸協(xié)議

(2)usb_prop.c文件修改

原文件

圖片

修改后文件

圖片

(3)memory.h文件修改

圖片

(4)mass_mal.h文件修改

圖片

(5)memory.c文件修改

圖片

(6)usb_bot.c文件修改

圖片

(7)mass_mal.c文件重寫

#include "platform_config.h"

#include "mass_mal.h"

#include "sdio_sdcard.h"

#include "w25q128.h"

long long Mass_Memory_Size[ MAX_LUN+1 ] ;

u32 Mass_Block_Size[ MAX_LUN+1 ] ;

u32 Mass_Block_Count[ MAX_LUN+1 ] ;

uint16_t MAL_Init( uint8_t lun )

{

u16 Status=MAL_OK ;  

   switch( lun )

   {

          case 0:    break;

          case 1:    break;

          default:return MAL_FAIL ;

   }

   return Status ;

}

uint16_t MAL_Write(uint8_t lun, uint64_t Memory_Offset, uint32_t *Writebuff, uint16_t Transfer_Length)

{

u8 STA ;

   switch( lun )

   {

          //磁盤0為 SPI FLASH盤

          case 0:

                 STA = 0 ;

                 W25QXX_Write( ( u8* )Writebuff, Memory_Offset, Transfer_Length ) ;

                 break ;

          //磁盤1為SD卡

          case 1:

                 STA = SD_WriteDisk( ( u8* )Writebuff, Memory_Offset>>9, Transfer_Length>>9 ) ;

                 break ;

          default:

                 return MAL_FAIL ;

   }

   if( STA!=0 )

          return MAL_FAIL ;

   return MAL_OK ;

}

uint16_t MAL_Read( uint8_t lun, uint64_t Memory_Offset, uint32_t *Readbuff, uint16_t Transfer_Length )

{

u8 STA ;

   switch( lun )

   {

          //磁盤0為 SPI FLASH盤

          case 0 :

                 STA = 0 ;

W25QXX_Read( ( u8* )Readbuff, Memory_Offset, Transfer_Length ) ;

break;

          //磁盤1為SD卡

          case 1 :

STA = SD_ReadDisk( ( u8* )Readbuff, Memory_Offset>>9, Transfer_Length>>9 ) ;

break;

          default:return MAL_FAIL ;

   }

   if( STA!=0 )

          return MAL_FAIL ;

   return MAL_OK ;

}

uint16_t MAL_GetStatus( uint8_t lun )

{

switch( lun )

{

          case 0:return MAL_OK;

          case 1:return MAL_OK;

          default:return MAL_FAIL;

}

}

(8)hw_config.h文件重寫

#ifndef HW_CONFIG_H

#define HW_CONFIG_H

#include "platform_config.h"

#include "usb_type.h"

typedef enum

{

DISABLE = 0,

   ENABLE = 1

}FunctionalState;

#define BULK_MAX_PACKET_SIZE 0x00000040 //包大小,最大64字節(jié)

void Led_RW_ON( void ) ; //LED開啟

void Led_RW_OFF( void ) ; //LED關(guān)閉

void Set_USBClock( void ) ; //USB時鐘配置函數(shù)

void Enter_LowPowerMode( void ) ; //USB進(jìn)入低功耗模式

void Leave_LowPowerMode( void ) ; //USB退出低功耗模式

void USB_Interrupts_Config( void ) ; //USB中斷配置

void USB_Port_Set( u8 enable ) ; //USB使能

void Get_SerialNum( void ) ; //獲取STM32的唯一ID

#endif

(9)hw_config.c文件重寫

#include "usb_lib.h"

#include "mass_mal.h"

#include "usb_desc.h"

#include "usb_pwr.h"

#include "usb_lib.h"

#include "usb_istr.h"

void USB_NotConfigured_LED()

{

}

void USB_Cable_Config( FunctionalState NewState )

{

}

void Led_RW_OFF()

{

}

void Led_RW_ON()

{

}

void USBWakeUp_IRQHandler()

{

EXTI->PR |= 1<<18 ;                            //清除USB喚醒中斷掛起位

}

void USB_LP_CAN1_RX0_IRQHandler()

{

USB_Istr() ;

}

void Set_USBClock()

{

RCC->CFGR &= ~( 1<<22 ) ;                  //USBclk=PLLclk/1.5=48Mhz

   RCC->APB1ENR |= 1<<23 ;                                          //USB時鐘使能

}

void Enter_LowPowerMode()

{

bDeviceState = SUSPENDED ;

}

void Leave_LowPowerMode()

{

DEVICE_INFO *pInfo = &Device_Info ;

   if( pInfo->Current_Configuration!=0 )

          bDeviceState=CONFIGURED ;

   else

          bDeviceState = ATTACHED ;

}

void USB_Interrupts_Config()

{

EXTI->IMR |= 1<<18 ;                               //開啟線18上的中斷

  EXTI->RTSR |= 1<<18 ;                          //line 18上事件上升降沿觸發(fā)

   NVIC_Init( 1, 0, USB_LP_CAN1_RX0_IRQn, 2 ) ;         //組2優(yōu)先級次之

   NVIC_Init( 0, 0, USBWakeUp_IRQn, 2 ) ;              //組2優(yōu)先級最高

}

void USB_Port_Set( u8 enable )

{

RCC->APB2ENR |= 1<<2 ;                        //使能PORTA時鐘            

   if( enable )

          _SetCNTR( _GetCNTR()&0xFFFFFFFD ) ;                   //退出斷電模式

   else

   {       

          _SetCNTR( _GetCNTR()|0x02 ) ;                               //斷電模式

          GPIOA->CRH &= 0xFFF00FFF ;

          GPIOA->CRH |= 0x00033000 ;

          PAout( 12 ) = 0 ;

   }

}

void IntToUnicode( u32 value, u8 *pbuf, u8 len )

{

u8 idx ;

   for( idx=0; idx

}

void Get_SerialNum()

{

u32 Device_Serial0, Device_Serial1, Device_Serial2 ;

   Device_Serial0 = *( u32* )0x1FFFF7E8 ;

   Device_Serial1 = *( u32* )0x1FFFF7EC ;

   Device_Serial2 = *( u32* )0x1FFFF7F0 ;

   Device_Serial0 += Device_Serial2 ;

   if( Device_Serial0!=0 )

   {

          IntToUnicode( Device_Serial0, &MASS_StringSerial[ 2 ] , 8 ) ;

          IntToUnicode( Device_Serial1, &MASS_StringSerial[ 18 ], 4 ) ;

   }

}

(10)platform_config.h文件重寫

#ifndef PLATFORM_CONFIG_H

#define PLATFORM_CONFIG_H

#include "sys.h"

#define USE_STM3210E_EVAL //當(dāng)前使用的版本

#endif

(11)usb_pwr.c文件修改(改寫Suspend函數(shù))

void Suspend(void)

{

uint32_t i=0 ;

   uint16_t wCNTR ;

   __IO uint32_t savePWR_CR=0 ;

   wCNTR = _GetCNTR() ;

for( i=0; i<8; i++ )

          EP[ i ] = _GetENDPOINT( i ) ;

   wCNTR |= CNTR_RESETM ;

   _SetCNTR( wCNTR ) ;

   wCNTR |= CNTR_FRES ;

   _SetCNTR( wCNTR ) ;

   wCNTR &= ~CNTR_FRES ;

   _SetCNTR( wCNTR ) ;

   while( ( _GetISTR()&ISTR_RESET )==0 ) ;

   _SetISTR( ( uint16_t )CLR_RESET ) ;

   for( i=0; i<8; i++ )

          _SetENDPOINT( i, EP[ i ] ) ;

   wCNTR |= CNTR_FSUSP ;

   _SetCNTR( wCNTR ) ;

   wCNTR = _GetCNTR() ;

   wCNTR |= CNTR_LPMODE ;

   _SetCNTR( wCNTR ) ;

   Enter_LowPowerMode() ;

}

(12)在sys.h文件中添加幾個重要的數(shù)據(jù)類型

typedef volatile uint8_t vu8;

#define __IO volatile

(13)stm32f103x.h文件中添加一個數(shù)據(jù)類型

typedef long long uint64_t ;

通過以上步驟,USB固件庫的移植就完成了,然后只需要調(diào)用固件庫的函數(shù)即可完成USB通信。

22.2.3 主函數(shù)編寫

#include "sys.h"
#include "delay.h"
#include "usart1.h"
#include "lcd.h"
#include "sdio_sdcard.h"
#include "w25q128.h"
#include "malloc.h"
#include "mass_mal.h"
#include "usb_lib.h"
#include "hw_config.h"
#include "usb_pwr.h"
#include "memory.h"
#include "usb_bot.h"


extern u8 Max_Lun ;                                            //支持的磁盤個數(shù)
int main()
{
  u8 USB_STA, Divece_STA, tct=0, offline_cnt=0;
   STM32_Clock_Init( 9 ) ;                                        //系統(tǒng)時鐘設(shè)置
  SysTick_Init( 72 ) ;                                        //延時初始化
  USART1_Init( 72, 115200 ) ;                                      //串口初始化為115200
  LCD_Init() ;                                            //初始化LCD
  W25QXX_Init() ;                                            //初始化W25Q128
  my_mem_init( SRAMIN ) ;                                        //初始化內(nèi)部內(nèi)存池
  //初始化SD卡
  if( SD_Init() )
    Max_Lun = 0 ;                                          //SD卡錯誤,則僅只有一個磁盤
  //SD 卡正常
  else
  {
    Mass_Memory_Size[ 1 ] = SDCardInfo.CardCapacity ;                        //得到SD卡容量(字節(jié)),當(dāng)SD卡容量超過4G的時候,需要用到兩個u32來表示
    Mass_Block_Size[ 1 ] = 512 ;                                  //因?yàn)槲覀冊贗nit里面設(shè)置了SD卡的操作字節(jié)為512個,所以這里一定是512個字節(jié)
    Mass_Block_Count[ 1 ] = Mass_Memory_Size[ 1 ]/Mass_Block_Size[ 1 ] ;
  }
  Mass_Memory_Size[ 0 ] = 1024*1024*12 ;                                //前12M字節(jié)
  Mass_Block_Size[ 0 ] = 512 ;                                    //設(shè)置SPI FLASH的操作扇區(qū)大小為512
  Mass_Block_Count[ 0 ] = Mass_Memory_Size[ 0 ]/Mass_Block_Size[ 0 ] ;
  delay_ms( 1800 ) ;
  USB_Port_Set( 0 ) ;                                          //USB先斷開
  delay_ms( 700 ) ;
  USB_Port_Set( 1 ) ;                                          //USB再次連接
  LCD_ShowString( 30, 10, "USB Connecting..." ) ;                            //提示USB開始連接
  Data_Buffer = mymalloc( SRAMIN, BULK_MAX_PACKET_SIZE*2*4 ) ;                    //為USB數(shù)據(jù)緩存區(qū)申請內(nèi)存
  Bulk_Data_Buff = mymalloc( SRAMIN, BULK_MAX_PACKET_SIZE ) ;                      //申請內(nèi)存
   //USB配置
   USB_Interrupts_Config() ;
   Set_USBClock() ;
   USB_Init() ;
  delay_ms( 1800 ) ;
   while(1)
  {
    delay_ms( 1 ) ;
    //狀態(tài)改變了
    if( USB_STA!=USB_STATUS_REG )
    {                  
      LCD_ShowString( 30, 30, "              " ) ;                        //清除顯示
      //正在寫
      if( USB_STATUS_REG&0x01 )
        LCD_ShowString( 30, 30, "USB Writing..." ) ;                      //提示USB正在寫入數(shù)據(jù)
      //正在讀
      if( USB_STATUS_REG&0x02 )
        LCD_ShowString( 30, 30, "USB Reading..." ) ;                      //提示USB正在讀出數(shù)據(jù)
      if( USB_STATUS_REG&0x04 )
        LCD_ShowString( 30, 50, "USB Write Err " ) ;                      //提示寫入錯誤
      else
        LCD_ShowString( 30, 50, "              " ) ;                      //清除顯示
      if( USB_STATUS_REG&0x08 )
        LCD_ShowString( 30, 80, "USB Read  Err " ) ;                      //提示讀出錯誤
      else
        LCD_ShowString( 30, 80, "                " ) ;                      //清除顯示
      USB_STA = USB_STATUS_REG ;                                  //記錄最后的狀態(tài)
    }
    //獲取USB連接狀態(tài)
    if( Divece_STA!=bDeviceState )
    {
      if( bDeviceState==CONFIGURED )
        LCD_ShowString( 30, 10, "USB Connected    " ) ;                      //提示USB連接已經(jīng)建立
      else
        LCD_ShowString( 30, 10, "USB DisConnected " ) ;                      //提示USB被拔出了
      Divece_STA = bDeviceState ;
    }
    tct ++ ;
    if( tct==200 )
    {
      tct = 0 ;
      if( USB_STATUS_REG&0x10 )
      {
        offline_cnt = 0 ;                                    //USB連接了,則清除offline計(jì)數(shù)器
        bDeviceState = CONFIGURED ;
      }
      //沒有得到輪詢
      else
      {
        offline_cnt ++ ;  
        if( offline_cnt>10 )
          bDeviceState = UNCONNECTED ;                            //2s內(nèi)沒收到在線標(biāo)記,代表USB被拔出了
      }
      USB_STATUS_REG = 0 ;
    }
  }
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • usb
    usb
    +關(guān)注

    關(guān)注

    60

    文章

    7846

    瀏覽量

    263300
  • PC
    PC
    +關(guān)注

    關(guān)注

    9

    文章

    2049

    瀏覽量

    153811
  • 接口技術(shù)
    +關(guān)注

    關(guān)注

    1

    文章

    273

    瀏覽量

    41328
收藏 人收藏

    評論

    相關(guān)推薦

    STM32 SD-USB讀卡器實(shí)驗(yàn)(神舟I號)

    STM32 SD-USB讀卡器實(shí)驗(yàn)(神舟I號
    發(fā)表于 03-21 15:20

    stm32的USB讀卡器實(shí)驗(yàn)源碼

    ***_bot.h"http://ALIENTEK戰(zhàn)艦STM32開發(fā)板實(shí)驗(yàn)50//USB讀卡器 實(shí)驗(yàn)//設(shè)置USB 連接/斷線//enable:0,斷
    發(fā)表于 07-04 02:29

    「正點(diǎn)原子STM32Mini板資料連載」第三十九章 USB 讀卡器實(shí)驗(yàn)

    庫版》關(guān)注官方微信號公眾號,獲取更多資料:正點(diǎn)原子第三十九章 USB 讀卡器實(shí)驗(yàn)上一章我們向大家介紹了如何利用 STM32 的 USB 來做一個觸控
    發(fā)表于 04-14 19:32

    「正點(diǎn)原子NANO STM32開發(fā)板資料連載」第34章 USB 讀卡器實(shí)驗(yàn)

    讀卡器(Slave)實(shí)驗(yàn)STM32F411 系列芯片都自帶了 USB OTG FS(FS,即全速,12Mbps),支持 USB Host和 USB
    發(fā)表于 04-24 16:52

    「正點(diǎn)原子NANO STM32F103開發(fā)板資料連載」第三十二章 USB 讀卡器實(shí)驗(yàn)

    二章 USB 讀卡器實(shí)驗(yàn)上一章我們向大家介紹了如何利用 STM32 的 USB 來做一個 USB 虛擬串口,本章我們將利用 STM32 的
    發(fā)表于 05-07 11:15

    USB讀卡器實(shí)驗(yàn)

    發(fā)表于 11-07 11:46 ?17次下載

    USB讀卡器實(shí)驗(yàn)源程序

    以前寫論文收集的一些資料,學(xué)習(xí)單片機(jī)、C語言的好資料?。。。?/div>
    發(fā)表于 07-08 14:26 ?18次下載

    STM32入門學(xué)習(xí)筆記之USB讀卡器實(shí)驗(yàn)1

    USB是英文Universal Serial BUS(通用串行總線)的縮寫,是一個外部總線標(biāo)準(zhǔn),用于規(guī)范電腦與外部設(shè)備的連接和通訊。是應(yīng)用在PC領(lǐng)域的接口技術(shù)。USB接口支持設(shè)備的即插即用和熱插拔功能。
    的頭像 發(fā)表于 02-16 15:59 ?2647次閱讀
    STM32入門學(xué)習(xí)筆記之<b class='flag-5'>USB</b><b class='flag-5'>讀卡器</b><b class='flag-5'>實(shí)驗(yàn)</b>1

    STM32入門學(xué)習(xí)筆記之USB讀卡器實(shí)驗(yàn)2

    USB是英文Universal Serial BUS(通用串行總線)的縮寫,是一個外部總線標(biāo)準(zhǔn),用于規(guī)范電腦與外部設(shè)備的連接和通訊。是應(yīng)用在PC領(lǐng)域的接口技術(shù)。USB接口支持設(shè)備的即插即用和熱插拔功能。
    的頭像 發(fā)表于 02-16 15:59 ?751次閱讀
    STM32入門學(xué)習(xí)筆記之<b class='flag-5'>USB</b><b class='flag-5'>讀卡器</b><b class='flag-5'>實(shí)驗(yàn)</b>2

    STM32入門學(xué)習(xí)筆記之USB讀卡器實(shí)驗(yàn)3

    USB是英文Universal Serial BUS(通用串行總線)的縮寫,是一個外部總線標(biāo)準(zhǔn),用于規(guī)范電腦與外部設(shè)備的連接和通訊。是應(yīng)用在PC領(lǐng)域的接口技術(shù)。USB接口支持設(shè)備的即插即用和熱插拔功能。
    的頭像 發(fā)表于 02-16 16:00 ?1392次閱讀