zoologist 发表于 2024-4-24 10:47:30

Ch32V305 上使用 Arduino

最近拿到一块 Ch32V305 的 EVT 板子,芯片的具体型号是CH32V305FBP6 ,作为 Ch32V3XX 系列的成员,它是 TSSOP20 封装,对于DIY 非常友好。

特别注意:和其他芯片不同,这款芯片必须使用 WCK LinkE 进行烧录去(无法像其他芯片一样直接使用 USB烧录,有点莫名其妙)。注意引脚接线,PA13接SWDIO,PA14接SWCLK。【参考1】换句话,正常情况下对于这款开发板,USB供电外加额外三根线连接起来 SWDIO /SWCLK/GND 就足够下载代码了。



烧写之后后面还可能出现 “Failed,the chip type is not matched or statusof chip is wrong! ”的问题(出现这种问题的一个原因是:你代码使用了 UART1,然后对于这个芯片来说 UART1 和烧录接口是在一起的会冲突),这种情况下解决方法是:断开开发板USB 供电,然后将 LinkE 的 RST 和开发板 NRST连接(多说一句,对于这个板子在烧写的时候有2种 Reset 方式:一种是By Power Off, 如果使用这种方式需要对开发板使用 LinkE 的 3.3V供电);另外一种方法是By Pin NRST,具体就是将 LinkE 的 RST 和开发板 NRST连接在一起。因为大多数时候我们需要调试 USB 功能,因此推荐后面这种方法)。然后使用 WCH-LinkUtility 这个工具下面这个功能先 Clear 一次,然后就可以烧录了。

接下来介绍如何使用 Arduino 编写代码,不过需要明确的一点是:目前 Arduino 支持还并不完善,在使用时会遇到各种各样的问题。项目地址在https://github.com/openwch/arduino_core_ch32 。
首先,将这个项目加入到"Additional Boards Managers URLs"中:
接下来在 Board Manger 中搜索安装这个板子:


之后就可以进行使用了。原始的库并不支持 USB 设备,这里需要我们直接编程:
#include "src\\userUsbKB\\ch32v30x_usbhs_device.h"
#include "src\\userUsbKB\\usbd_composite_km.h"

uint8_tKeyPress = {0x08, 0, 0, 0, 0, 0, 0, 0};
uint8_tKeyRelease = {0, 0, 0, 0, 0, 0, 0, 0};

void setup() {
Serial.begin(115200);
Serial.println("Start");
pinMode(D18, INPUT_PULLUP);
/* Initialize system configuration */
SystemCoreClockUpdate( );
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_2 );
//Delay_Init( );

/* Initialize USBHS interface to communicate with the host*/
USBHS_RCC_Init( );
USBHS_Device_Init( ENABLE );
USB_Sleep_Wakeup_CFG( );
}

unsigned long PressElsp = 0;
unsigned long ReleaseElsp = 0;

void loop() {
if ( USBHS_DevEnumStatus )
{

    /* Handle keyboard lighting */
    KB_LED_Handle( );

    if ((digitalRead(D18) == LOW) && (PressElsp == 0) &&(millis()-ReleaseElsp>100)) {
      USBHS_Endp_DataUp( DEF_UEP1, KeyPress, sizeof( KeyPress ), DEF_UEP_CPY_LOAD );
      PressElsp = millis();
      Serial.println("a");
    }

    if ((PressElsp != 0) && (millis() - PressElsp > 1000)) {
      USBHS_Endp_DataUp( DEF_UEP1, KeyRelease, sizeof( KeyRelease ), DEF_UEP_CPY_LOAD );
      PressElsp = 0;
      ReleaseElsp=millis();
      Serial.println("b");
    }
}
}

关键的代码如下,简单的说就是如果D18 触发,那么就发送键盘数据给PC,相当于按下了 Win键;1秒之后,再发送全为0的数据包,这个相当于发送抬起信息:
    if ((digitalRead(D18) == LOW) && (PressElsp == 0) &&(millis()-ReleaseElsp>100)) {
      USBHS_Endp_DataUp( DEF_UEP1, KeyPress, sizeof( KeyPress ), DEF_UEP_CPY_LOAD );
      PressElsp = millis();
      Serial.println("a");
    }

    if ((PressElsp != 0) && (millis() - PressElsp > 1000)) {
      USBHS_Endp_DataUp( DEF_UEP1, KeyRelease, sizeof( KeyRelease ), DEF_UEP_CPY_LOAD );
      PressElsp = 0;
      ReleaseElsp=millis();
      Serial.println("b");
}

有兴趣的朋友不妨尝试一下这个芯片,主要的优点是:速度足够快(最高 144Mhz),资源比较多(128KB Flash,32K 内存),体积小(TSSOP20封装),内置了USB High Speed (真 2.0)。目前的缺点是 Arduino开发环境并不完善,很多需要自己摸索。


参考:
1. https://www.wch.cn/bbs/thread-92358-1.html

zoologist 发表于 2024-4-24 11:05:54

工作的测试视频

https://www.bilibili.com/video/BV1YE421M7oQ/
页: [1]
查看完整版本: Ch32V305 上使用 Arduino