4723浏览
查看: 4723|回复: 1

[参赛项目] 创客造|国产主控芯片打造 USB 提醒器

[复制链接]
本帖最后由 zoologist 于 2021-5-10 15:08 编辑

对于现在的电脑来说,USB是外部通讯的不二选择,通过这个接口可以引出键盘鼠标等等外部设备。这次尝试使用国产的CH55X 系列单片机来做一个 USB 提醒器,通过这个设备能够做到LED发光提示还有蜂鸣器声音提示。
首先介绍一下 CH55X 系列芯片是南京沁恒(WCH)出品的带有USB功能的系列单片机【参考1】,提起这家公司的名称大多数人会感到陌生,但是如果提起CH340/CH341芯片大家都会非常熟悉,这款低成本的USB串口转换芯片就是这家公司的产品。这次设计用到的 CH552 CH551/CH554 是同一个系列。他们主要的差别是:CH551是最低端的,工作频率是24Mhz,FLASH 10K (可以看作是单片机的 ROM),内存是512+256字节,只能做 USB DeviceCH552比前者配置稍微高了一些,FLASH空间有16K,内存有1K+256字节,只能做 USB DeviceCH554比前面都高级,FLASH 内存和 CH552 相同,但是可以当作 USB Host 使用能够实现解析USB键盘鼠标这样设备的工作。可以看出,相比 Atmel 32U4 (Arduino Leonardo),主要缺点是内存太小。但是胜在价格便宜,引脚简单(这样容易焊接)。在立创商城上面的芯片价格如下(CH552/4 不同封装引脚数量不同,所以价格是在一个范围内):

CH551G   2.475
CH552      2.7-2.78
Ch554      5.43-7.03
32u4        23.51

因此,如果CH55X系列芯片能够满足你的需求,能够大大降低成品的成本。同时, CH55X 系列单片机对于外围元件要求极低,无须晶振,只要合适的贴片电容即可工作起来。

这次设计使用CH552G芯片是 SOP16 封装,同样的 CH554 也有SOP16封装可以直接替换(CO-Layout
创客造|国产主控芯片打造 USB 提醒器图1
电路设计如下:
创客造|国产主控芯片打造 USB 提醒器图3  主控部分

这个芯片使用C1/C2两个 0.1uF的电容即可工作,5V供电,从 VCC/VDD 引脚进入。上图中 V33 经过 R1 (10K)连接到 USB+引脚上,其中的 PAD1无须上键在这里作为开关使用用于控制芯片进入 Bootloader Mode
板子上还有一个 WS2812B MINI(3.5x3.5mm) 用于提供灯光提示,同样的这个元件无须外围配合,直接用CH55X P1.5即可控制:
创客造|国产主控芯片打造 USB 提醒器图2

外围有一个蜂鸣器,因为CH55X引脚提供电流有限,所以使用S8050这个三极管扩流,同时外加R3用于限流,主要是避免声音太大。CH55X  P3.4 Pin 用于控制蜂鸣器开关。因为该引脚是 PWM 引脚,因此这里即可以使用有源蜂鸣器和无源蜂鸣器。有源蜂鸣器的含义是“内部有震荡源”,类似于电动机,有了供电就能发声;与其相反,无源蜂鸣器含义是“内部没有震荡源”,因此需要用引脚电流变换来驱动它。对于有源蜂鸣器,P3.4当作普通的GPIO即可;对于无源蜂鸣器,需要设定为 PWM 然后给他设置占空比和频率(默认即可)。
创客造|国产主控芯片打造 USB 提醒器图4
PCB 设计如下:
创客造|国产主控芯片打造 USB 提醒器图5
切换为 3D 模式预览如下(这次设计的 Symbol使用的都是嘉立创的,所以自带了3D 模型,非常直观):
创客造|国产主控芯片打造 USB 提醒器图6
正面

创客造|国产主控芯片打造 USB 提醒器图7
背面

拿到手的 PCB和焊接后的照片如下:
创客造|国产主控芯片打造 USB 提醒器图8

接下来就开始软件设计了。这个芯片原本设计使用 C51 来进行变成,用户可以通过 Keil 这样的集成开发环境进行编程,但是对于我们来说C51还是过于复杂。这里使用 Github上的一个开源项目:ch55xduino【参考2】,能够让我们像开发 Arduino 一样为 CH551/2/4 进行开发。
首先介绍一下项目的安装:和其他的所有的第三方板卡一样, Preferences --> Additional Boards Manager URLs 中加入这个板卡的地址https://raw.githubusercontent.com/DeqingSun/ch55xduino/ch55xduino/package_ch55xduino_mcs51_index.json
创客造|国产主控芯片打造 USB 提醒器图9
之后打开 Boards Manager
创客造|国产主控芯片打造 USB 提醒器图10
搜索这个项目
创客造|国产主控芯片打造 USB 提醒器图11
Install 安装之后在 Boards Manager 中能够看到这个板卡,编译时,CH551使用 CH551 Board, CH552/4 使用 CH552 Board
创客造|国产主控芯片打造 USB 提醒器图13

接下来就是如何编译一个程序,可以在Example 中看到专用的例子,比如下面就是关于 USB 设备的例子:
创客造|国产主控芯片打造 USB 提醒器图12

打开一个例子尝试编译,完成后就需要做上传的准备工作了。刚拿到手 ,板子上没有Bootloader,需要短接板子背面 PAD 处(电路图中是0.1uF电容,实际上不上件预留为空),这样V33会通过10K 电阻后进入 D+ Pin,板子会进入 Bootloader Mode
创客造|国产主控芯片打造 USB 提醒器图14

属性如下:
创客造|国产主控芯片打造 USB 提醒器图15
使用 Zadig 给他安装一个驱动,勾选 Edit
创客造|国产主控芯片打造 USB 提醒器图16
重命名为 USB Module
创客造|国产主控芯片打造 USB 提醒器图17

安装之后:
创客造|国产主控芯片打造 USB 提醒器图18
编译后会自动搜索名为 USB Module”的设备并且上传
创客造|国产主控芯片打造 USB 提醒器图19

需要注意的是:如果你的代码没有实现 USB 串口,那么只能短接PAD让板子进入 BootLoader Mode再次上传。
了解了上面的知识,即可着手设计代码实现提醒器的功能。我们设计了2种提醒方式:LED和蜂鸣器,分别通过2个命令进行设置,形式如下:
1.     [cRGB]  R/G/B分别是红绿蓝的取值,例如,命令 [c123] (ASCII)  5B 63 31 32 33 5D (十六进制)会将 LED RGB 分别设置为 0x31 0x32 0x33;命令5B 63 FF 00 00 5D (十六进制)会设置为全红;
2.     [bThighTlow]  Vhigh和 Vlow 分别是设置的时间高位和地位,例如, 命令 [b12] (ASCII)  5B 62 31 32 5D (十六进制)将会设置蜂鸣器在 0x32 * 0x10 +0x32=0x342 (834秒)后响起来;命令5B 62 01 00 5D (十六进制)将会设置蜂鸣器在 0x01 * 0x100 +0x00=0x100 (256秒)后响起来;可以看出,可以设置最大 0xFFFF (65535秒)后响起来。

完整代码如下:

  1. #define BEEPERPIN 34
  2. #define LEDPIN 15
  3.         
  4. #define TX(LedColor) {\
  5.                   if (((LedColor)&0x80)==0) {\
  6.                        XdigitalWriteFast(1,5,HIGH);\
  7.                        (LedColor)=(LedColor)<<1;\
  8.                        XdigitalWriteFast(1,5,LOW);\
  9.                        XdigitalWriteFast(1,5,LOW);\
  10.                        XdigitalWriteFast(1,5,LOW);\
  11.                    }else{\
  12.                        XdigitalWriteFast(1,5,HIGH);\
  13.                        XdigitalWriteFast(1,5,HIGH);\
  14.                        XdigitalWriteFast(1,5,HIGH);\
  15.                        XdigitalWriteFast(1,5,HIGH);\
  16.                        XdigitalWriteFast(1,5,HIGH);\
  17.                        XdigitalWriteFast(1,5,HIGH);\
  18.                        XdigitalWriteFast(1,5,HIGH);\                       
  19.                        (LedColor)=(LedColor)<<1;\
  20.                        XdigitalWriteFast(1,5,LOW);\
  21.                        XdigitalWriteFast(1,5,LOW);\
  22.                        XdigitalWriteFast(1,5,LOW);\
  23.                        XdigitalWriteFast(1,5,LOW);\
  24.                        XdigitalWriteFast(1,5,LOW);\
  25.                        }\
  26.                   }
  27. #ifndef USER_USB_RAM
  28. #error "This example needs to be compiled with a USER USB setting"
  29. #endif
  30. #include "src/userUsbCdc/USBCDC.h"
  31. void setup() {
  32.   // 设置蜂鸣器Pin 为Low (停止发声)
  33.   pinMode(BEEPERPIN,OUTPUT);
  34.   digitalWrite(BEEPERPIN,LOW);
  35.   // 设置LED 控制Pin
  36.   pinMode(LEDPIN,OUTPUT);
  37.   digitalWrite(LEDPIN,LOW);  
  38.   USBInit();
  39. }
  40. byte Status=0;
  41. byte RValue,GValue,BValue;
  42. byte THigh=0,TLow=0;
  43. unsigned long CounterDown=0xFFFFFFFF;
  44. void loop() {
  45.   while (USBSerial_available()) {
  46.     // 接收来自USB串口的字符
  47.     char serialChar = USBSerial_read();
  48.   if ((serialChar == '[')&&(Status==0)) { Status=1; continue;}
  49.       if ((serialChar == 'c')&&(Status==1)) {Status=2; continue;}
  50.       if (Status==2) {RValue=serialChar; Status=3; continue;}
  51.       if (Status==3) {GValue=serialChar; Status=4; continue;}
  52.       if (Status==4) {BValue=serialChar; Status=5; continue;}
  53.       if (Status==5) {
  54.           if (serialChar == ']') {Status=6;continue;}
  55.           else {Status=0; continue;}
  56.       }
  57.       if ((serialChar == 'b')&&(Status==1)) {Status=7; continue;}
  58.       if (Status==7) {THigh=serialChar; Status=8; continue;}
  59.       if (Status==8) {TLow=serialChar; Status=9; continue;}
  60.       if (Status==9) {
  61.           if (serialChar == ']') {Status=10; continue;}
  62.           else {
  63.                 // 如果最后收到的字符不是 [ 那么需要重新开始
  64.                 Status=0; continue;
  65.           }
  66.       }
  67.   }
  68.   // 根据收到的 cRGB 设置 LED 颜色
  69.   if (Status==6) {
  70.     USBSerial_println_s("RGB");
  71.     USBSerial_println_i(RValue);
  72.     USBSerial_println_i(GValue);
  73.     USBSerial_println_i(BValue);
  74.     USBSerial_flush();
  75.     // 设置 WS2812 颜色, 特别注意这里和时许非常相关,具体数值都是示波器测量取得
  76.     //Send Green value from Bit7 to 0
  77.     TX(GValue);TX(GValue);TX(GValue);TX(GValue);TX(GValue);TX(GValue);TX(GValue);TX(GValue);
  78.     //Send Red value from Bit7 to 0
  79.     TX(RValue);TX(RValue);TX(RValue);TX(RValue);TX(RValue);TX(RValue);TX(RValue);TX(RValue);
  80.     //Send Blue value from Bit7 to 0
  81.     TX(BValue);TX(BValue);TX(BValue);TX(BValue);TX(BValue);TX(BValue);TX(BValue);TX(BValue);  
  82.    
  83.    // 重新设置为状态 0
  84.     Status=0;
  85.   }
  86.   
  87.   // 根据设置的延时开始倒计时
  88.   if (Status==10) {
  89.     if ((THigh==0)&&(TLow==0)) {
  90.         digitalWrite(BEEPERPIN,LOW);
  91.       }
  92.         // 设置触发时间
  93.     else CounterDown=(THigh*256+TLow)*1000UL+millis();
  94.     Status=0;
  95.   }
  96.    // 如果当前处于状态 0 并且设置的触发时间小于当前时间,那么就开始响
  97.    if ((Status==0)&&(CounterDown<millis())) {
  98.       // 对应 Pin 拉高,蜂鸣器开始发声
  99.       digitalWrite(BEEPERPIN,HIGH);
  100.       // 拉高之后会一直发声
  101.       CounterDown=0xFFFFFFFF;
  102.    }
  103. }
复制代码

特别提一句:WS2812有很多版本,彼此之间在时序上有差别。比如,下面两种从Datasheet看就是有差别的,前者的代码(CH55xDuino)在后者(这次设计使用的)上会有问题:
  
WS2812D-F8
  
  
WS2812B-Mini
  
  
T0H
  
  
400±150ns
  
  
300±80ns
  
  
T0L
  
  
850±150ns
  
  
790±210ns
  
  
T1H
  
  
850±150ns
  
  
790±210ns
  
  
T1L
  
  
400±150ns
  
  
300±80ns
  
  
RES
  
  
>50us
  
  
>280us
  

所以,我在代码上重写了 WS2812 相关部分,因为对时序要求很高,所以最好使用汇编语言,但是因为我对 C51汇编很陌生,于是只能写成宏的方式。有兴趣的朋友可以尝试修改CH55xduino的库文件。

BOM 如下,不包括PCB10元左右,可以看到这个芯片在制作 USB 相关设备方面很有竞争力:
创客造|国产主控芯片打造 USB 提醒器图20

虽然CH55X系列芯片有诸多好处,但是还存在如下缺点:
1.      1.进入 BootLoader后,在 USB 3.0 的 USB口上经常会出现 Yellow Bang 的情况。可以尝试 Disable再Enable看看能否消除之。如果始终不行,推荐将板子使用一个 USB2.0 HUB和USB 3.0 相连,这个应该时芯片本身的 Bug(作为 USB 普通设备,不会遇到这个问题);如果一直存在这个问题,那么可以先卸载,然后再重新安装驱动试试;
2.      2.淘宝有很多CH552开发板,强烈建议在动手实验之前入手一个作为开发板,上面会有按钮,按下后插入USB端口直接进入 BootLoader模式,方便调试;
3.      3.淘宝购买后,拿到手请及时检查芯片,我在Taobao购买的 CH554 开发板拿到手几个月后再用时发现上面竟然是 CH552的芯片,因为他们封装相同,所以当时没有注意,再去找售后时发现店铺竟然已经关门。

参考:
1.     1. http://www.wch.cn/products/category/5.html单片机系列芯片选项指南



image025.png

zoologist  高级技匠
 楼主|

发表于 2021-1-16 13:38:29

工作的视频:


本文提到的完整代码。


本文提到的硬件设计文档


回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail