CH32V208系列是一款32位RISC-V设计的无线型微控制器。它的外部接口非常丰富,片上集成2Mbps低功耗蓝牙BLE 通讯模块、USB2.0全速设备+主机/设备接口。这次的作品就是基于蓝牙BLE和USB 主机功能实现的。
简单的说这个作品的原理是通过 USB Host 和键盘进行通讯,取得按键之后再通过BLE蓝牙发送出去。
作品设计是围绕 CH32V208进行的,目前公开的型号有如下几种,这次使用的是CH32V208WBU6,它是QFN68X8封装的,这个对于手工焊接稍微有难度,如果有可能最好使用加热焊台配合焊锡膏进行。选择这种封装的唯一原因是目前市场上还没有其他封装。
订货型号 | 封装形式 | 塑体宽度 | 引脚间距 | 封装说明 | 出货料盘 |
CH32V208GBU6 | QFN28X4 | 4*4mm | 0.4mm | 方形无引线 28 脚 | 托盘 |
CH32V208CBU6 | QFN48X5 | 5*5mm | 0.35mm | 方形无引线 48 脚 | 托盘 |
CH32V208RBT6 | LQFP64M | 10*10mm | 0.5mm | LQFP64M(10*10)贴片 | 托盘 |
CH32V208WBU6 | QFN68X8 | 8*8mm | 0.4mm | 方形无引线 68 脚 | 托盘 |
完整电路图如下:
需要特别注意的有下面几点:
1.E1 是一个天线,我是根据WCH官方提供的 LIB 导入到立创EDA完成的其中L1和C16。C17 的电容是来自官方评估板电路图,我并不知道为什么这样选择,也不知道是否需要进行调整;
2.和评估板相比,没有设计 OSC32IN/OUT 这一组晶振,它只在使用 BLE Client的时候才会用到,这次的设备是作为 BLE Server 的,因此不需要。外部使用了32Mhz 的晶振,CH32V208 内部带有可以设定的匹配电容,所以外部不需要。晶振是YXC(扬兴晶振)的X503232MSB2GI,从立创商城购买。
3.芯片工作电压为3.3V,沿用了多次使用的TLV1117芯片
4.板子带有一个USB母头和一个USB公头,前者用于连接USB键盘,后者用于取电
5.下面是一个负载消耗电流的设计。很多充电宝在小电流输出一段时间之后会自动切断输出,因此使用PA3 GPIO控制每隔一段时间拉一个大电流出来,这样能够维持充电宝的输出。
6.预留了下载按钮,这样可以方便烧写程序
7.最后是预留的调试接口,串口输出:
天线的设计来自WCH 官方提供的参考库,对应的 PCB 厚度为 1.6mm。
PCB 设计如下:
硬件介绍完毕,下面讲一下代码设计。官方提供了丰富的示例代码(比 CH567 多很多)。对于我们来说相当于将下面这两个示例代码合并在一起:
- BLE 蓝牙键盘的示例代码,位于 CH32V20xEVT\EVT\EXAM\BLE\HID_Keyboard。这个代码的功能是:模拟键盘设备,连接主机后定时上传键值;
- USB Host 连接USB键盘的代码,位于CH32V20xEVT\EVT\EXAM\USB\USBFS\HOST_KM。这个代码的功能是主机操作键鼠,获取键鼠上传的端点的数据并打印,支持U口下1级hub;
针对这次的设计有如下修改:
1. hidkbd_main.c使用1M作为串口调试波特率,在速度较低的情况下,发送调试信息可能会导致USB 方面的问题,所以这里使用比较高的波特率(我是用 CH343 制作USB串口调试器)避免调试代码干扰运行
#ifdef DEBUG
USART_Printf_Init( 1000000 );
#endif
2.使用 PA3 来控制三极管,进行电流消耗。在hidkbd_main.c中定义了一个变量Elsp进行计时
// 计时器用来每隔一段时间拉电流保证充电宝可以正常供电
volatile uint32_t Elsp=0;
app_km.c 文件中,有一个函数void TIM3_IRQHandler( ) 用于处理USB HID 的间隔事件,同样的,我们在其中更新Elsp,具体可以看 TIM3 的初始化相关代码,这个函数每隔9ms触发一次,我们在其中对Elsp进行自增。
在Main_Circulation() 函数中我们检查这个计时变量当10秒左右的时候拉一次PA3控制三极管输出大电流。
void Main_Circulation(void)
{
while(1)
{
USBH_MainDeal( );
TMOS_SystemProcess();
// 计时10秒左右拉高GPIO, 实现电流输出
if (Elsp>10000) {
DUG_PRINTF( "Set to High\r\n" );
POWERON();
}
if (Elsp>10100) {
DUG_PRINTF( "Set to Low\r\n" );
POWEROFF();
Elsp=0;
}
}
}
3.获得键盘数据的代码在 app_km.c 文件中的void USBH_MainDeal( void )函数。取得之后,通过HidDev_Report() 函数即可从BLE 蓝牙发送出去。
//LABZDebug_Start
// HID keyboard input report length
#define HID_KEYBOARD_IN_RPT_LEN 8
#define HID_RPT_ID_KEY_IN 0
#define HID_REPORT_TYPE_INPUT 1
uint8_t buf[HID_KEYBOARD_IN_RPT_LEN];
static uint8_t LastBuf[HID_KEYBOARD_IN_RPT_LEN];
DUG_PRINTF( "LastBuf:" );
for( i = 0; i < len; i++ )
{
DUG_PRINTF( "%02x ", Com_Buf[ i ] );
}
DUG_PRINTF( "\r\n" );
//if (memcmp(buf,LastBuf,HID_KEYBOARD_IN_RPT_LEN)!=0) { // False == 0
// memcpy(LastBuf,buf,HID_KEYBOARD_IN_RPT_LEN);
HidDev_Report(HID_RPT_ID_KEY_IN, HID_REPORT_TYPE_INPUT,
HID_KEYBOARD_IN_RPT_LEN, Com_Buf);
DUG_PRINTF( "SendData");
//}
//LABZDebug_End
3.4.13 外部晶振校准控制寄存器(HSE_CAL_CTRL)
偏移地址:0x00
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
HSEC[3:0] | HSE FAULT | Reser ved | HSEITRIM [1:0] | Reserved |
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Reserved
位 | 名称 | 访问 | 描述 | 复位值 | ||||
[31:28] | HSEC[3:0] | RW | HSE 内置匹配电容调节位: 111:22pF 110:20pF 101:18pF 100:16pF 011:14pF 010:12pF 001:10pF 000:8pF | 000b\ | ||||
27 | HSEFAULT | RW | HSE 失效检测禁用控制位: 1:忽略模拟输入的 HSE 失效检测信号 0:使用模拟输入的 HSE 失效检测信号 | 0 | ||||
26 | Reserved | RO | 保留。 | 0 | ||||
[25:24] | HSEITRIM[1:0] | RW | HSE 起振电流调节位。 | 01b | ||||
[23:0] | Reserved | RO | 保留。 | 0 | ||||
上面就是基于CH32V208 的USB键盘转BLE蓝牙的设计,本次设计使用立创EDA设计,硬件和软件都是完全开源的有兴趣的朋友可以尝试制作自己的专属设备。
工作的测试视频
本文提到的电路图和PCB设计(立创EDA绘制)
本项目完整代码下载