Thursday, July 2, 2020

Getting started with the WCH CH551 and CH552

When I first read about the CH554 series of MCUs, I thought it would be interesting to test out some day.  Part of the attraction is that it's based on the 8051, which is a well-documented an widely used architecture.  The first assembly language I learned almost 40 years ago was for the 6502, so learning to program the 8-bit CISC should be relatively easy.

Instead of purchasing the bare chips for pennies at LCSC and putting together a breakout board, I bought a couple modules from Electrodragon.  I had learned that the CH551, CH552, and CH554 all used the same die.  I bought the CH551 and CH552 modules with the intention of eventually trying to hack them into working as a CH554.

For testing the modules, in addition to the CH554 SDK for SDCC on Linux, I've used Ch55xduino on Windows.  One thing not in the Ch55xduino documentation is driver setup.  The windoze version I'm using is 7E, and when I first inserted the CH551 module, I got a driver error.

Using Zadig to set the driver to libusb-win32 solved the problem.

The CH55xduino documenation also lacks pinout documentation for anything other than the reverence board.  To help, I've copied the pinouts from the CH552 datahseet.

The CH55x bootloader supports DFU, which is what the CH55xduino uploader uses the first time code is uploaded to the module.  Once the first sketch is uploaded, the CH55xduino core includes a CDC serial stack.  With my CH551 module no longer appearing as a DFU device, I had to use Zadig again to change the CDC Serial device to use the USB Serial (CDC) driver.  After that, the module appears as a COM port.

With the COM port selected in the Arduino IDE, subsequent uploads enter the bootloader by switching the baud rate to 1200bps.  If no COM port is selected, the upload tool looks for a CH55x device in DFU bootloader mode.  To enter the bootloader, it is necessary to pull the USB D+ pin up to 3.3V when power is applied.  The Electrodragon boards have a pinout for an upload jumper, which when shorted will connect the D+ pin (P3.6/UDP)to 3.3V through a 10k resistor.  On one of my modules I soldered pin headers and use a jumper to force it into upload mode.  On the other, I just used a low-value (270Ohm) through-hole resistor pushed into the holes.

Currently CH55xduino is not optimized for size, with a basic blink sketch requiring 5333 bytes of flash.  Officially, the CH551 is only supposed to have 10kB of available flash, so the CH55xduino overhead means less than 5kB is left for user code.  The CH551 actually seems to have 12kB available for flashing user code, which I think will be plenty if the CH55xduino core gets some optimization work.  Since I like to do low-level embedded coding, I'll be using SDCC from the command line most of the time.  The blink example in the CH554 SDK for SDCC compiles to 700 bytes, and I was able to get that down to 232 bytes after leaving out the UART initialization in debug.c. With a bit more optimization I think I can get the blink example down to 100 bytes or so.

One small surprise I found during my testing is that the Electrodragon CH551 and CH552 modules use different pins for the user LED.  On the CH551, use P3.0, working in open-drain mode so the LED light up when P3.0 is low.  On the CH552, drive P1.4 high to light the LED.  This is documented on the Electrodragon web site, but it is easy to forget when switching between the two modules.

I've already started to learn how to configure the standard MCS-51 UART, and have figured out how to directly manipulate the ports using the SFRs (Special Function Registers).   Once I've mastered how to program these cheap little devices, I'll follow up with another blog post revealing the details.


I recently found out that these modules do not fit well in a solderless breadboard.  The row spacing for the 0.1" headers on the CH551 is about 0.47", so the pins have to bend out slightly to plug into the breadboard.  On the CH552 module, the row spacing is about 0.52", so the pins have to bend out slightly to fit.


  1. Thanks for this post. I will be giving it a shot soon. I'm interested in using the ADC's of this unit.

    1. The ADC is disabled on the CH551, so you'll need a 552 or 554.

  2. Hi thanks for sharing, did you get the UART working?

    1. Yes, I was able to run the usb CDC example on my CH552. It uses the 2nd UART which is not enabled on the CH551. I may change it so it uses the first (standard 8051) UART instead.

  3. This is a great posting, thanks for your contribution...

  4. Love it. I'm gonna order a reel of these and play. I envision making usb converterz to adapt vintage hardware to usb and vice versa. First project that springs to mind is a usb to adc adapter, so i can use a moxern keyboard on my apple iigs.

    1. I just posted a new article I think you'll also enjoy.

    2. Thanks for your work documenting your experiences with these chips. They've been a great guide.

      One thing that I've found is that new devices have a new version of the bootloader, and librech551 doesn't work with it. However, VNPro (that's bundled with CH55xduino) and a handful of other tools do.

    3. I noticed the most recent batch I received in late 2020 came with bootloader v2.4. I've been using ch55xtool under Windoze and Linux for several months now and find it works very well.

  5. I bought a tang nano board with the CH552T on it, and I have severe problems using the serial port connected onboard. I wanted to do similar to this but cant make it talk serial (putty). Apparently putty hangs when it wants to trasmit, and does not show anything received. Any clues anyone?

  6. When trying to upload usb_jtag.bin using rather new WCHISP(V3.2), I get the error
    "Jump to BOOT from the user area, configuration bits cannot be modified!"
    Followed by
    "Unable to revamp CfgBit when entrance BOOT without power on"..

    Im not sure what this means.. I used FT_Prog to put it in boot mode. Do I need to add a continuous pullup to P3.1?