日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

用国产CH32替代STM32,快来试试看!

發布時間:2023/12/19 74 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用国产CH32替代STM32,快来试试看! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

/* 作者: 羅冰? https://blog.csdn.net/luobing4365 */

隨著芯片價格瘋漲,項目的不可控性越來越大。特別是價格方面,達到了無法想象的地步了。

按我的記憶,之前項目中所用的STM32F103C8T6,價格在9元左右;而現在到立創商城上去查,單片價格到了驚人的109元!十幾倍的漲幅,哪個項目還敢用它?

因此,大部分公司,都在準備各種替代方案。

我們也一樣,預備使用CH32F103C8T6替代STM32F103C8T6。這兩種芯片引腳兼容,內部的資源差不多,理論上代碼移植也比較方便。

我就是這么想的,然后就被打臉了。

最大的原因在于,廠家提供的資料太少了!編程相關的CH32F103應用手冊,只有短短的31頁。我想看的USB設備控制器的寄存器細節,甚至都沒有。想想STM32豐富的應用資料、例程和各種視頻,感覺從新手級難度到了骨灰級難度了。

不過,再想想CH32這友好的價格,也就釋然了。

周末兩天,把之前的USB HID通信,在CH32F103C8T6上實現了,估計不久能很快地應用到項目中去。

預計也也有不少朋友有類似的需求,我把探索的過程記錄下來。

1. 固件下載

CH32F103的芯片,支持WCH-Link或者其他SW仿真工具下載,也支持使用WCHISPTool通過USB和串口下載。考慮到后續開發的時候需要調試,我使用的是WCH-Link進行下載。

如圖1所示,給出了WCH-Link的實物圖(摘自《WCH-Link使用說明-V1.3》)。

圖1 WCH-Link實物

由于我的目標是使用它下載程序到CH32F103C8T6中,只需要使用ARM模式就行了,不需要關注RISC-V模式。

拿到的WCH-Link,一般是RISC-V模式,需要將其切換到ARM模式。

模式切換的方法如下:

WCH-Link 斷電, 將圖一正面圖 1 中排針, TX 接 GND;

WCH-Link 上電, 切換模式成功后, 斷開 TX 和 GND;

后續使用時, WCH-Link 保持切換后的模式。

判斷的方法如下:

WCH-Link空閑時藍燈常滅,是為RISC-V模式;

WCH-Link空閑時藍燈常亮,為ARM模式。

在ARM模式下,Windows 10下是不需要安裝驅動的,而Win7有些情況下需要更換驅動,具體可以向廠家索取資料。

圖2是WCH-Link在Win7下的設備顯示。

圖2 WCH-Link的ARM模式

實際使用中,直接使用SWD協議的兩線以及GND就可以下載了。軟件的使用方法,可以參考官方提供的《CH32F103評估板說明書》,其中介紹了詳細的下載和仿真調試方法。

2. 碼編寫

使用CH32F103C8T6實現之前的USB HID雙向通信。

在經歷了若干款MCU編寫USB代碼后,對這塊內容已經比較熟悉了。簡單來說,只要在USB HID的示例上,修改各類描述符,添加需要的命令處理就可以了。

可惜的是,廠家提供的示例代碼非常少。CH32F103C8T6支持兩個USB端口,一個是可做全速主機或設備的USBHD,另一個是全速設備USBD。

提供的示例代碼中,USBD給出了VirtualCom的工程;USBHD給出了DEVICE、HOSG、HOST_Udisk三個示例。

USBD的工程,類似于STM32的Legacy Library;而USBHD的工程,則使用了沁恒電子自己的庫。

我的目標很明確,實在沒太多時間去研究沁恒電子的USB庫,因此采用了USBD的示例作為模板,進行開發。

由于USBD的工程與STM32的USB庫類似,我選擇深入研究下STM32的USB庫(畢竟資料更多,而且之前學習過)。

2.1 STM32的USB-FS Device Library

UEFI開發探索85中,曾經介紹過如何使用STM32F103C8T6制作HID設備。不過,對于所使用的的USB Library,并沒有討論。

STMF103的USB庫,可以在STSW-STM32121中找到,其應用文檔為UM0424。文檔中給出了非常詳盡的庫說明,如圖3為USB庫的代碼結構。

圖3 USB庫代碼結構

USB-FS-Device 庫主要分為兩層:

STM32_USB-FS_Device_Driver: 驅動層,訪問USB全速設備外圍和USB標準協議,兼容USB2.0標準,與STM32標準庫分離;這層不能由用戶修改;

Applicaton Interface:在庫和最終用戶層之間,提供完成的接口,可以由用戶修改;

驅動層的代碼,大部分情況下是不用修改的,它所包含的源文件說明如下:

USB-FS外圍部件接口:

usb_reg (.h, .c):硬件抽象層 usb_int.c:傳輸中斷服務函數 usb_mem(.h,.c):數據傳輸管理

USB-FS設備驅動中間層:

usb_init (.h,.c) :USB設備初始化全局變量 usb_core (.h , .c) :USB協議管理(兼容USB2.0規范第9章) usb_sil (.h,.c) :讀寫端點的簡化函數(USB-FS_Device外圍的抽象層) usb_def.h / usb_type.h:用于庫中的USB定義和類型 platform_config.h:評估板上用到的硬件定義

應用層代碼是提供給用戶修改用的,所需要實現的功能都在此層實現。它所包含的源文件說明如下:

usb_conf.h:配置文件 usb_desc (.h, .c):描述符 usb_prop (.h, .c):應用規范屬性 usb_endp.c:非控制端口的傳輸中斷處理函數 usb_istr (.h,.c):中斷處理函數 usb_pwr (.h, .c) :電源和連接管理函數

對照CH32F103C8T6提供的USBD例程,可以發現其結構與STM32的是一樣的。可以斷定,它是模仿了STM32的USB Library編寫了自己的庫函數接口。

這種設計方法,對習慣了STM32編程的工程師是非常好的。大部分情況下,可以直接把STM32的示例工程,直接移植到WCH的芯片上來(畢竟STM32的例程還是比較豐富的)。

本篇所實現的USB HID雙向通信,就是參考了STM32的CustomHID例程,在CH32F103的USBD例子上實現的。

2.2 代碼移植和修改

如圖4所示,給出了CH32F103的USBD工程的代碼結構。

圖4 CH32F103的USBD工程代碼

驅動層的代碼完全不用修改。為了確定此事,我對照著STM32的驅動層代碼,一個個函數研究了下,除去與芯片相關的部分,其實現代碼幾乎一致。

所要修改的代碼在應用層,也不是所有源文件需要修改,需要修改的文件包括三個:

usb_desc.c、usb_endp.c和usb_prop.c。

看過我UEFI開發探索和YIE002開發探索兩個系列博客的網友,應該了解之前我使用STM32開發USB HID設備的過程。而且相關的工程代碼,在博客中也提供了(UEFI開發探索85和YIE002開發探索09,前者使用Legacy Library,后者使用Cube Library開發。)。

實際的開發過程,與之前的開發過程類似,只不過由于芯片的不同,有些代碼需要進行移植。

2.2.1 usb_desc.c代碼修改

所要修改的是各種描述符,包括設備描述符、配置描述符、端點描述符等。

需要注意的地方,是CH32F103的最大包長度為8。如下給出了設備描述符和配置描述符等的代碼,其余的代碼與之前開發的STM32F103工程相同,就不再給出了。

#define LOBYTE(x) ((u8)(x & 0x00FF)) #define HIBYTE(x) ((u8)((x & 0xFF00) >>8)) #define?USBD_VID?????????????????????0x8765 #define USBD_PID 0x4321 /*?USB?Device?Descriptors?*/ const uint8_t USBD_DeviceDescriptor[CUSTOMHID_SIZ_DEVICE_DESC] = { 0x12, /*bLength */USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/0x10, /*bcdUSB */0x01,0x00, /*bDeviceClass*/0x00, /*bDeviceSubClass*/0x00, /*bDeviceProtocol*/0x08, /*bMaxPacketSize*/LOBYTE(USBD_VID), /*idVendor (0x1234)*/HIBYTE(USBD_VID),LOBYTE(USBD_PID), /*idProduct = 0x4321*/HIBYTE(USBD_PID),0x00, /*bcdDevice rel. 1.00*/0x01,1, /*Index of string descriptor describingmanufacturer */2, /*Index of string descriptor describingproduct*/3, /*Index of string descriptor describing thedevice serial number */0x01 /*bNumConfigurations*/ }; /* USB Configration Descriptors */ const uint8_t USBD_ConfigDescriptor[CUSTOMHID_SIZ_CONFIG_DESC] = { 0x09, /* bLength: Configuration Descriptor size */USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */CUSTOMHID_SIZ_CONFIG_DESC,/* wTotalLength: Bytes returned */0x00,0x01, /* bNumInterfaces: 1 interface */0x01, /* bConfigurationValue: Configuration value */0x00, /* iConfiguration: Index of string descriptor describingthe configuration*/0x80, /* bmAttributes: Self powered */0x32, /* MaxPower 100 mA: this current is used for detecting Vbus *//************** Descriptor of Custom HID interface ****************//* 09 */0x09, /* bLength: Interface Descriptor size */USB_INTERFACE_DESCRIPTOR_TYPE,/* bDescriptorType: Interface descriptor type */0x00, /* bInterfaceNumber: Number of Interface */0x00, /* bAlternateSetting: Alternate setting */0x02, /* bNumEndpoints */0x03, /* bInterfaceClass: HID */0x00, /* bInterfaceSubClass : 1=BOOT, 0=no boot */0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */0, /* iInterface: Index of string descriptor *//******************** Descriptor of Custom HID HID ********************//* 18 */0x09, /* bLength: HID Descriptor size */HID_DESCRIPTOR_TYPE, /* bDescriptorType: HID */0x10, /* bcdHID: HID Class Spec release number */0x01,0x00, /* bCountryCode: Hardware target country */0x01, /* bNumDescriptors: Number of HID class descriptors to follow */0x22, /* bDescriptorType */CUSTOMHID_SIZ_REPORT_DESC,/* wItemLength: Total length of Report descriptor */0x00,/******************** Descriptor of Custom HID endpoints ******************//* 27 */0x07, /* bLength: Endpoint Descriptor size */USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: */0x82, /* bEndpointAddress: Endpoint Address (IN) */0x03, /* bmAttributes: 00: Control endpoint 01: Isochronous endpoint 02: Bulk endpoint 03: Interrupt endpoint */0x40, /* wMaxPacketSize: 64 Bytes max */0x00,0x00, /* bInterval: Polling Interval *//* 34 */0x07, /* bLength: Endpoint Descriptor size */USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: *//* Endpoint descriptor type */0x02, /* bEndpointAddress: *//* Endpoint Address (OUT) */0x03, /* bmAttributes: Interrupt endpoint */0x40, /* wMaxPacketSize: 64 Bytes max */0x00,0x00, /* bInterval: Polling Interval */ };

2.2.2 usb_prop.c代碼修改

這是開發中的重點,原有的CHF103的USBD工程中,包括端口0的控制傳輸以及若干USB命令都沒有實現。

簡單來說,就是需要把端口0的控制傳輸代碼實現,以支持各種USB標準命令和USB類命令(主要是HID類)。

2.2.3 usb_endp.c代碼修改

usb_endp.c中主要實現的端點讀寫通信,也即對應上位機的ReadFile()和WriteFile()。

在usb_desc.c中的配置描述符中,包含了端點描述符的內容。我們聲明了端點2的IN和OUT作為讀寫接口。所實現的代碼如下:

uint8_t Receive_Buffer[0xff]; /******************************************************************************* * Function Name : EP2_IN_Callback * Description : Endpoint 2 IN. * Input : None. * Return : None. *******************************************************************************/ void EP2_IN_Callback (void) { } /******************************************************************************* * Function Name : EP2_OUT_Callback * Description : Endpoint 2 IN. * Input : None. * Return : None. *******************************************************************************/ void EP2_OUT_Callback(void) { uint32_t DataLength = 0;DataLength=USB_SIL_Read(EP2_OUT, Receive_Buffer); //讀取端點得到的數據SetEPRxStatus(ENDP2, EP_RX_VALID);if (Receive_Buffer[0] == 0xA0) //將第二個字節改為1返回,表示是采用端點發送的方式{Receive_Buffer[1]=0x1;}USB_SIL_Write(EP2_IN,Receive_Buffer,DataLength);SetEPTxStatus(ENDP2,EP_TX_VALID); }

至此,就完成了所有編程工作了。將其編譯下載到CH32F103C8T6的開發板上,就可以進行測試了。

3 .?測試

仍舊使用我之前開發的UsbHID上位機工具進行測試(UEFI開發探索74附帶的測試工具),結果如下:

圖4 CH32F103的USBD工程代碼

從圖5的測試可以看出,三種讀寫方式都實現了。

不得不承認,國產的單片機相比于國外的大廠來說,支持資料做得很不足。不過,從功能上來說,還是會有一些亮點的。比如CH32F103C8T6相比于STM32F103C8T6,3個串口保留了,而且還增加了一個USB HOST。

另外,即便是在正常的情況下(現在芯片短缺屬于不正常狀態),其價格也只有STM32F103C8T6的一半。這對于批量出貨的產品來說,是個不能忽視的優勢。

我相信隨著這波芯片短缺的影響,很多的廠商都會逐漸使用國產單片機了。這種變化,對軟硬件工程師來說,可是個不小的考驗。

開放了個人微信,歡迎大家添加,一起交流學習!

關于替換STM32的文章,之前發了很多,特此匯總,大家可以選擇性閱讀!

STM32漲價?那就用國產32替代吧!

用GD32替代STM32,是什么體驗?

GD32替換STM32,這些細節一定要知道。

在STM32價格瘋長下,哪些國產32可以替代?

GD32如何替換STM32?

STM32和GD32有什么區別?

-END-

我是張巧龍,一名教電子的大學老師,歡迎關注!

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的用国产CH32替代STM32,快来试试看!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。