娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年06月13日(星期五)

2019年06月13日 | 用stm32Cube生成103c8t6的usb驅(qū)動(dòng)

發(fā)布者:Yuexiang888 來源: eefocus關(guān)鍵字:stm32Cube  103c8t6  usb驅(qū)動(dòng) 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

開發(fā)板是用的stm32f103c8t6的核心板淘寶上最便宜最常見的那種(還是上圖吧) 

這里寫圖片描述

stm32f1系列的hal驅(qū)動(dòng)庫中把usb驅(qū)動(dòng)放在了“Middlewares(中間件)”文件夾下,且有“STM32_USB_Device_Library”和“STM32_USB_Host_Library”兩個(gè)驅(qū)動(dòng)庫。若是想直接利用驅(qū)動(dòng)庫新建工程可在這兩個(gè)庫的目錄下復(fù)制Core文件夾和Class文件夾下所需文件。


使用stm32cube直接生成工程: 

這里寫圖片描述


先勾選Peripherals的USB->Device才能在MiddleWares下的USB_Devics下選擇IP核,下拉后有六個(gè)選項(xiàng),分別對(duì)應(yīng)USB設(shè)備的六大分類:


分類 功能

AUDIO USB音頻設(shè)備

CDC(communication device class) 虛擬串口

Download Firmware Update 固件更新

Human Interface Device 人機(jī)接口

Custom Human Interface Device 傳統(tǒng)人機(jī)接口(鍵盤鼠標(biāo)類)

Mass Storage Class 大容量存儲(chǔ)設(shè)備

此處選擇CDC設(shè)備。需要注意的是,在RCC分類下的HSE必須被使能成外部晶振->Crystal/ceramic Resonator。要開啟USB核主時(shí)鐘必須達(dá)到48M,因?yàn)閁SB區(qū)域的時(shí)鐘為48M。這點(diǎn)可在時(shí)鐘樹的配置中很清楚看到。不過,若主時(shí)鐘沒有配置成48M或以上,在STM32Cube的Clock Configuartion界面會(huì)直接報(bào)錯(cuò),點(diǎn)進(jìn)去看會(huì)提示是否自動(dòng)設(shè)置時(shí)鐘,直接確認(rèn)就OK。 


這里寫圖片描述

PLL倍頻數(shù)位6的話,USB分頻設(shè)為1即可,若要開到72M的最高頻率,分頻數(shù)則要設(shè)為1.5。其余配置均保持默認(rèn)即可。


此處還開啟了SWD引腳用于代碼的下載。最終的引腳配置如圖: 


這里寫圖片描述

最后點(diǎn)擊生成代碼,工程名稱為:USBCDC 使用MDK-ARM/V5。下面的Stack Size可以改大些,USB CDC的RX和TX的Buffer默認(rèn)大小為2048,只是單純的收發(fā)測(cè)試的話,默認(rèn)大小也夠用,為避免造成內(nèi)存溢出導(dǎo)致的跑飛,此處設(shè)為0x1000。在Code generator界面最好勾選->為每個(gè)外設(shè)生成單獨(dú)的.c和.h文件 這個(gè)選項(xiàng)。這樣生成的外設(shè)驅(qū)動(dòng)能比較方便的移植,另外分類清晰,可讀性也較好,否則全部代碼都堆在main文件中。 


這里寫圖片描述

生成代碼后直接打開工程編譯。 


這里寫圖片描述

Middlewares分類下為USB內(nèi)核代碼,這些文件都不用改動(dòng)。 

Application下的stm32f1xx_it.c文件中含有目前工程中所開啟的所有中斷處理函數(shù)代碼,打開翻到這個(gè)文件的最下面可以看到,STM32Cube默認(rèn)為USB開啟了中斷:


/**

    * @brief This function handles USB low priority or CAN RX0 interrupts.

*/

void USB_LP_CAN1_RX0_IRQHandler(void)

{

  /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */


  /* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */

  HAL_PCD_IRQHandler(&hpcd_USB_FS);

  /* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */


  /* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */

}


從中斷函數(shù)函數(shù)名可以看出,USB和CAN是公用一個(gè)中斷向量的。在f1系列的參考文檔中也可以查到,CAN和USB占用同一段RAM,這兩個(gè)外設(shè)不能同時(shí)使用。


stm32f1xx_hal_msp.c文件只含有HAL_MspInit()這一個(gè)函數(shù),實(shí)現(xiàn)NVIC分組和系統(tǒng)中斷優(yōu)先級(jí)的設(shè)定(都是最高優(yōu)先級(jí)),并禁用JTAG和SWD使能(若在Cube配置中沒有開啟SYS->Serial Wire,則不會(huì)有這一句)。


usb_device.c文件初始化了一個(gè)USB句柄。由于是HAL庫的驅(qū)動(dòng),整體的代碼對(duì)于外設(shè)初始化和調(diào)用都是通過句柄。


/* USB Device Core handle declaration */

USBD_HandleTypeDef hUsbDeviceFS;

/* init function */                                        

void MX_USB_DEVICE_Init(void)

{

    USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS);

    USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC);

    USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS);

    USBD_Start(&hUsbDeviceFS);

}


去掉多余部分注釋(實(shí)話說Cube生成的工程注釋太多挺煩的),可以看出這是USB外設(shè)的初始化函數(shù);USBD_Init()里面包含了,檢測(cè)主機(jī)是否存在,復(fù)位USB類,設(shè)定USB設(shè)備描述符,還有USB設(shè)備狀態(tài)幾個(gè)步驟,最后初始化了單片機(jī)上面的USB底層驅(qū)動(dòng):端點(diǎn)號(hào)啊,全速模式啊,失能低功耗,外部供電關(guān)閉啊,blabalbal…然后會(huì)跑到USBD_LL_MspInit()中去開啟USB的引腳。USB引腳比較特殊,只要單片機(jī)內(nèi)的USB區(qū)域時(shí)鐘開啟,那PA12和PA11就只能作為USB的數(shù)據(jù)引腳使用。


USBD_RegisterClass()會(huì)連接CDC類驅(qū)動(dòng)到USB核,這點(diǎn)在HAL固件庫里有所體現(xiàn),USB的設(shè)備庫分成了兩層,一層為內(nèi)核文件,就是只要開啟了USB就要調(diào)用的,還有一層為“類”,對(duì)應(yīng)它的不同功能,詳見上面那個(gè)表格,只需根據(jù)需要將一類代碼加入工程即可。至于函數(shù)內(nèi)具體的細(xì)節(jié),則需要對(duì)應(yīng)驅(qū)動(dòng)庫的說明看了(不知是我人品不好還是怎么,在哪都找不到hal庫 usb的說明文檔,只能找到以前的標(biāo)準(zhǔn)庫的)。


USBD_CDC_RegisterInterface()則是不知道要干嘛了,進(jìn)入函數(shù)定義只能看到簡短的描述,@brief USBD_CDC_RegisterInterface(找不到文檔的痛(ㄒ_ㄒ))。最后一個(gè)倒是很容易看懂了‘USBD_Start()’開啟外設(shè)。


usb_conf.c文件則是關(guān)于USB的配置,這里除開HAL庫的部分,還有部分代碼是使用LL庫寫的(底層驅(qū)動(dòng)部分)。但USB協(xié)議部分都是包含在stm32f1x_hal_pcd.c和stm32f1x_hal_pcd_ex.cz這兩組文件中(為嘛不用stm32f1x_hal_usb.c文件名害得我一頓好找)。有興趣的可以詳細(xì)看看分析,只是要使用這個(gè)接口的話,也不用深究了。 

然后usb_desc.c文件也是關(guān)于協(xié)議這一塊(目前學(xué)的不深就不多說了)。但有一點(diǎn)要補(bǔ)充的,這個(gè)兩個(gè)文件里的代碼——不要?jiǎng)樱〔灰獎(jiǎng)樱〔灰獎(jiǎng)樱?p>

usb_cdc_if.c這里就是對(duì)與USB的CDC類的直接調(diào)用了。文件不是很大,里面定義了用戶的收發(fā)緩存,都是2048byte。然后有4個(gè)靜態(tài)函數(shù)和一個(gè)可供外部調(diào)用的函數(shù):


static int8_t CDC_Init_FS     (void);

static int8_t CDC_DeInit_FS   (void);

static int8_t CDC_Control_FS  (uint8_t cmd, uint8_t* pbuf, uint16_t length);

static int8_t CDC_Receive_FS  (uint8_t* pbuf, uint32_t *Len);

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)


見名生意,全速設(shè)備CDC類初始化、CDC類復(fù)位、CDC類控制、CDC類接收還有CDC類發(fā)送函數(shù)。初始化復(fù)位和控制這3個(gè)函數(shù)都沒什么好說的。


重點(diǎn)是CDC_Receive_FS 和CDC_Transmit_FS 這兩個(gè)函數(shù)。這里必須強(qiáng)調(diào)CDC_Receive_FS 是USB接收中斷回調(diào)函數(shù)。有必要提一下HAL庫和標(biāo)準(zhǔn)庫的一個(gè)區(qū)別:使用標(biāo)準(zhǔn)庫時(shí),在配置中斷時(shí),一般都是在啟動(dòng)文件中尋找中斷向量名,以此名字編寫中斷處理函數(shù)。函數(shù)里面有兩個(gè)重要的部分,一是清除中斷標(biāo)志位,二是實(shí)現(xiàn)用戶需要的功能。內(nèi)容部分都是要自己寫的。HAL庫中,對(duì)于中斷處理函數(shù)做了封裝,函數(shù)名和函數(shù)體都已經(jīng)寫好,進(jìn)入中斷處理函數(shù)就判斷中斷源,然后清除中斷標(biāo)志位,接著進(jìn)入中斷回調(diào)函數(shù)。唯一允許改動(dòng)的則是這個(gè)中斷回調(diào)函數(shù),它在庫中使用weak修飾,即允許user在工程的任何地方對(duì)該函數(shù)重定義,以實(shí)現(xiàn)所需的功能。CDC_Receive_FS則是CDC類對(duì)應(yīng)USB庫的中斷回調(diào)函數(shù)。


/**

  * @brief  CDC_Receive_FS

  *         Data received over USB OUT endpoint are sent over CDC interface 

  *         through this function.

  *           

  *         @note

  *         This function will block any OUT packet reception on USB endpoint 

  *         untill exiting this function. If you exit this function before transfer

  *         is complete on CDC interface (ie. using DMA controller) it will result 

  *         in receiving more data while previous ones are still not sent.

  *                 

  * @param  Buf: Buffer of data to be received

  * @param  Len: Number of data received (in bytes)

  * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL

  */

static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)

{

  /* USER CODE BEGIN 6 */

  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);

  USBD_CDC_ReceivePacket(&hUsbDeviceFS);

  return (USBD_OK);

  /* USER CODE END 6 */ 

}


從注釋也能看出,在從USB虛擬串口接收到任何數(shù)據(jù)后,都會(huì)將接收到的數(shù)組的指針和數(shù)組長度傳回此函數(shù)。若需要實(shí)現(xiàn)某些功能,只需在重設(shè)接收緩存前新增函數(shù)或者直接處理即可。 

而允許外部調(diào)用的那個(gè)CDC_Transmit_FS(),則是像串口發(fā)送函數(shù)那樣直接調(diào)用即可,輸入要發(fā)送的數(shù)組的指針和要發(fā)送的長度,然后就可以在電腦端的虛擬串口處直接接收到所發(fā)送的數(shù)據(jù)。


我有嘗試過像串口輸出重定向那樣,使用CDC_Transmit_FS()函數(shù)重定向fputc欲實(shí)現(xiàn)printf函數(shù)通過虛擬串口的打印。但實(shí)測(cè)每次發(fā)送字符串或者長一點(diǎn)的符號(hào)什么的,就只能接收到第一個(gè)字符。重定向代碼還是貼出來吧,思路應(yīng)該是正確的,肯定還有哪些點(diǎn)沒注意到…如果有大佬看到的話,還勞煩指點(diǎn)迷津,不勝感激。


int fputc(int ch, FILE *f)   

{

  CDC_Transmit_FS((uint8_t *)&ch, 1); 

  return ch;

}


回到正題,剩下gpio.c文件還沒說,這里面只有一個(gè)MX_GPIO_Init() 函數(shù),用來開啟GPIOA和GPIOD兩組引腳的時(shí)鐘,GPIOA是USB的D+和D-引腳以及下載口SWDIO和SWCLK的時(shí)鐘,GPIOD則是HSE主時(shí)鐘的晶振引腳的時(shí)鐘了。


工程內(nèi)的主要代碼說完,再看主函數(shù)main()(依舊去除煩人的注釋)


int main(void)

{

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_USB_DEVICE_Init();

  while (1)

  {

  }

}


使用STM32Cube生成的代碼,都是一個(gè)樣:首先初始化hal庫,然后配置系統(tǒng)時(shí)鐘,開啟要用的GPIO口時(shí)鐘,然后初始化外設(shè),再加一個(gè)空的while循環(huán),只是幫助user初始化要用到的外設(shè),要實(shí)現(xiàn)其他功能,還要自己往里加。MX_USB_DEVICE_Init() 函數(shù)在前面說usb_device.c的時(shí)候講過,不再重復(fù)。


這里實(shí)現(xiàn)一個(gè)簡單的功能:把從虛擬串口接收到的數(shù)據(jù),原樣從虛擬串口輸出。只需在usb接收中斷回調(diào)函數(shù)中做簡單的處理,修改代碼如下:


static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)

{

  /* USER CODE BEGIN 6 */

  CDC_Transmit_FS(Buf,*Len);

  CDC_Transmit_FS((uint8_t *)"n",sizeof("n"));


  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);

  USBD_CDC_ReceivePacket(&hUsbDeviceFS);

  return (USBD_OK);

  /* USER CODE END 6 */ 

}


然后編譯。由于STM32Cube生成的代碼默認(rèn)調(diào)試工具為ST-LINK如果使用J-LINK,還需在Options中更改調(diào)試工具,并選成SW模式。下載完成后用一根micro-B接口的數(shù)據(jù)線連到電腦。補(bǔ)充一點(diǎn),需要先裝stm32的虛擬串口驅(qū)動(dòng),電腦才能識(shí)別(安裝完后重新插拔USB上電)。 

 這里寫圖片描述 

這時(shí)電腦上就會(huì)識(shí)別到虛擬串口(我也不知道我電腦為什么不是顯示stmicroxxx visual com port的標(biāo)志,可能win10系統(tǒng)的原因吧)。打開任意串口調(diào)試助手(波特率什么的隨意,因?yàn)閷?shí)際情況是通過usb總線傳輸?shù)臄?shù)據(jù),與波特率什么的無關(guān)) 

 這里寫圖片描述 

任意發(fā)送即可看到回復(fù)。 

[注]:在使用CDC_Transmit_FS函數(shù)發(fā)送數(shù)據(jù)時(shí),若len為64的整數(shù)倍,則需要在發(fā)送完成后在發(fā)送一個(gè)空幀;否則電腦端會(huì)直接丟去此次發(fā)送的數(shù)據(jù),這是由usb的協(xié)議所決定的,有興趣的可以看看官方這里給出的解釋在進(jìn)行USB CDC類開發(fā)時(shí),無法發(fā)送64整數(shù)倍的數(shù)據(jù),或詳細(xì)分析usb傳輸協(xié)議。


關(guān)鍵字:stm32Cube  103c8t6  usb驅(qū)動(dòng) 引用地址:用stm32Cube生成103c8t6的usb驅(qū)動(dòng)

上一篇:STM32時(shí)鐘樹與啟動(dòng)過程時(shí)鐘設(shè)置分析
下一篇:STM32使用TCP透傳方式與ONENET進(jìn)行連接的簡單教程

推薦閱讀

隨著人工智能的加速滲透,自動(dòng)駕駛技術(shù)無疑成為當(dāng)下最熱門的領(lǐng)域,除了傳統(tǒng)車企、互聯(lián)網(wǎng)巨頭紛紛入局外,一大批科技型初創(chuàng)企業(yè)也相繼涌現(xiàn)。據(jù)不完全統(tǒng)計(jì),在自動(dòng)駕駛技術(shù)研發(fā)領(lǐng)域,全世界已經(jīng)涌現(xiàn)出了超過240多家初創(chuàng)企業(yè),而作為全球最大的單一汽車消費(fèi)市場(chǎng),中國亦有不少初創(chuàng)企業(yè)迎風(fēng)而上。?蓋世汽車通過搜集整理企業(yè)工商信息,選取了24家最受資本市場(chǎng)...
赫聯(lián)電子亞太新增日本Hirose供應(yīng)商,專業(yè)的互連與機(jī)電產(chǎn)品授權(quán)分銷商赫聯(lián)電子(Heilind Electronics)日前宣布進(jìn)一步擴(kuò)充其亞太產(chǎn)品線,新增日本Hirose為供應(yīng)商。 Hirose是全球領(lǐng)先的工業(yè)連接技術(shù)供應(yīng)商,連接技術(shù)覆蓋醫(yī)療、工業(yè)和汽車市場(chǎng)。 Hirose Electric Co., Ltd是全球頂尖的連接器制造商,提供豐富的互連元件,包括RF、同軸、板對(duì)板、線對(duì)板、...
  從2013年一直快速發(fā)展的中國工業(yè)機(jī)器人市場(chǎng),這兩年卻踩了“急剎車”。2018年9月,工業(yè)機(jī)器人產(chǎn)業(yè)急轉(zhuǎn)直下,產(chǎn)量持續(xù)下滑。可喜的是,經(jīng)過一年多調(diào)整后,機(jī)器人產(chǎn)業(yè)正在慢慢走出頹勢(shì)。   工業(yè)機(jī)器人行業(yè)現(xiàn)狀   1、工業(yè)機(jī)器人產(chǎn)量增速連續(xù)兩月回正   2018年9月工業(yè)機(jī)器人進(jìn)入低谷期,產(chǎn)量同比減少16.4%,此后工業(yè)機(jī)器人產(chǎn)量持續(xù)下滑。下滑態(tài)...

史海拾趣

問答坊 | AI 解惑

模擬電路layout技藝-noise

[前言]: 這是我要向大家介紹的,這一系列的,第三篇關(guān)于ANALOG layout的文章,內(nèi)容實(shí)是我的讀書筆記 是我讀完《IC Mask Design》一些章節(jié)后,總結(jié)的一些心得。本著自己先看懂并贊同作者觀點(diǎn),而后再搜集 一些相關(guān)知識(shí),介紹給大家,供大家參照! ...…

查看全部問答∨

淺談示波器的存儲(chǔ)深度

得益于電子技術(shù)的發(fā)展,在國外三巨頭壟斷的示波器領(lǐng)域,國產(chǎn)示波器也如雨后春筍般涌現(xiàn)出來,優(yōu)秀國產(chǎn)示波器的代表:鼎陽(Siglent)科技和北京普源精電,如今得到了長足的發(fā)展,但由于信號(hào)傳輸?shù)逆溌菲款i以及IC封鎖,夾縫中生長的國產(chǎn)示波器注定暫 ...…

查看全部問答∨

關(guān)于MAX1472

各位前輩,小弟現(xiàn)要做一個(gè)無線自動(dòng)對(duì)碼系統(tǒng),用MAX1472做發(fā)射芯片(433M),那位能給個(gè)帶放大的電路,最好能帶參數(shù),先在這里謝謝了!!E-mail:huaxf1980@yahoo.cn…

查看全部問答∨

wince喚醒時(shí)對(duì)驅(qū)動(dòng)做了些什么?

wince掛起時(shí),調(diào)用了驅(qū)動(dòng)的XXX_PowerDown 喚醒時(shí)調(diào)用了驅(qū)動(dòng)的XXX_PowerUp, 除了調(diào)用這兩個(gè)函數(shù)之外,是否還是用了其他的。比如IOControl 謝謝…

查看全部問答∨

學(xué)習(xí)ARM碰到的有關(guān)內(nèi)存頁式管理的疑問

頁式管理有內(nèi)存,外存之分。ARM存儲(chǔ)系統(tǒng)包括了SRAM,FLASH,ROM等。那哪一部分作為內(nèi)存(是SRAM嗎?),哪一部分作為外存。還是FLASH存儲(chǔ)的程序指令也可以由CPU直接取出執(zhí)行?(不用放到SRAM中)…

查看全部問答∨

各位兄弟幫幫忙,高手近來看看,wince調(diào)用ocx(c++)問題

我使用vs2005C#調(diào)用ocx(是evc生成)我應(yīng)該怎么調(diào)用了, 我在選擇項(xiàng)=->COM組建,加入時(shí)出現(xiàn)OCX自動(dòng)注冊(cè)失敗,只能在引用里把OCX加近來,不知道怎么調(diào)用,謝謝,…

查看全部問答∨

請(qǐng)大哥們幫幫小妹啊,5555555555

    我的筆記本是華碩A6K的,近日因?yàn)楣ぷ餍枰ㄎ沂亲龇b設(shè)計(jì)的,需要裝設(shè)計(jì)軟件)要升級(jí)內(nèi)存,之前用的是兩塊256M的內(nèi)存,一共是512M,用了2年一點(diǎn)問題也沒有。上周我買了塊南亞1G DDR333筆記本內(nèi)存(原裝也是這個(gè)型號(hào)和牌子),但是 ...…

查看全部問答∨

請(qǐng)問哪位開發(fā)過光纖燈飾的光源器?

麻煩大概說下其實(shí)現(xiàn)原理和主要的電子元件.謝謝!…

查看全部問答∨

iPhone真正暴力的拆機(jī)圖來!!!

網(wǎng)子:http://bbs.billwang.net/cgi-bin/forum/topic_show.cgi?id=363910&pg=1&bpg=1 有興趣的朋友可以去看看,別人設(shè)計(jì)的產(chǎn)品就是高!…

查看全部問答∨

收到開發(fā)板了,上圖

下午兩點(diǎn)多順豐就把開發(fā)板送來了,那個(gè)激動(dòng)啊,啥也不說了,直接上圖,感覺板子好小巧,,下載了幾個(gè)程序進(jìn)去,OLED顯示屏的效果真的不錯(cuò)。 , \\   [ 本帖最后由 beyondvv 于 2010-11-4 21:25 編輯 ]…

查看全部問答∨
小廣播
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 平南县| 乌拉特中旗| 马尔康县| 南丰县| 龙陵县| 英吉沙县| 舞钢市| 集安市| 濮阳县| 涿鹿县| 南汇区| 丰县| 奉新县| 恩施市| 马尔康县| 大邑县| 铜梁县| 延长县| 泸水县| 什邡市| 舞钢市| 张家口市| 泰顺县| 汾西县| 墨江| 岐山县| 北碚区| 安图县| 苗栗市| 安顺市| 内乡县| 余姚市| 安新县| 洛川县| 黄浦区| 巴马| 会理县| 民县| 涞水县| 凤山市| 永定县|