Interfacing CS1237 24-bit Sigma-Delta ADC to CH32V003 MCU using only Two-Wire SPI (Bidirectional SPI).
The CH32V003 is an ultra-cheap, 48 MHz 32-bit microcontroller developed by WCH. It's popular because it offers 32-bit performance for roughly $0.10 to $0.30, where usually that is the price point of very limited 8-bit microcontrollers.
While the CS1237 is a high-precision, low-power Analog-to-Digital Converter (ADC) designed by Chipsea and it's also a Very cheap device.
This firmware reads the 24-bit data from CS1237 continuously and convert it into signed raw value. The CS1237 communicates with the MCU over a single bidirectional data line for both control and data transfer:
- Using EXTI to detects falling edge on DRDY/DOUT (data ready)
- Clocks out 24 bits of ADC data (MSB first) via SPI BIDIMODE
- Sign-extends the 24-bit result to 32-bit signed integer
- Prints via UART and re-arms EXTI for the next sample
Having a non-standard SPI protocol, the cs1237 has been a challenge for embedded developers who want to avoid messy, inefficient code. Unlike conventional SPI peripherals that utilize a dedicated Chip Select (
The standard practice for this kind of protocol has to just been a software bit-banging. While bit-banging gives absolute control over the clock edges, it forcefully locks the CPU core in blocking loop structures, leaving little runtime availability for heavy signal processing, digital filtering, or proper UART communications.
This project resolves the conflict by harnessing the native, underutilized hardware Bidirectional SPI capabilities of the CH32V003. This architecture gains the timing safety of an explicit hardware gate while keeping data ingestion completely non-blocking.
It is highly recommended to use a proper low-noise external Voltage Reference
PC6 act as EXTI6 waiting for interrupt signal
│
▼
CS1237 pulls DRDY LOW → Data ready
│
▼
MCU detects falling edge on EXTI6
│
▼
MCU enables SPI (BIDIMODE, output disabled) → SCLK starts
│
▼
CS1237 shifts out 24 bits MSB first on each SCLK rising edge
│
▼
MCU sign-extends 24-bit value → prints via UART
│
▼
MCU re-enables EXTI → waits for next DRDY LOW
Being a Non-Standard SPI Protocol, we have to pays a lot of attention to its signal timing
| Parameter | Symbol | Min | Max | Unit |
|---|---|---|---|---|
| SCLK high/low pulse | t5 | 455 | — | ns |
| SCLK → data valid | t6 | — | 455 | ns |
| Data hold time | t7 | 227.5 | 455 | ns |
The microcontroller reads 3 Byte of data outputted by the CS1237, but stores it into 32 Bit Signed Integer Variable
pio run # Build
pio run --target upload # Flash via WCH-LinkE
pio device monitor # Monitor output at 9600 baudExpected output:
CH32V003 CS1237 ADC Reader
ADC: 1234567 # Example ADC Value
ADC: 1234890
ADC: 1234123| Bits | Name | Function | Default |
|---|---|---|---|
| [7] | — | Reserved (write 0) | 0 |
| [6] | REFO_OFF | 1 = disable internal reference | 0 |
| [5:4] | SPEED | 00=10Hz, 01=40Hz, 10=640Hz, 11=1280Hz | 00 |
| [3:2] | PGA | 00=1×, 01=2×, 10=64×, 11=128× | 11 |
| [1:0] | CH | 00=ChA, 10=Temp, 11=Internal short | 00 |
The CS1237 is popular in precision weight scales and bridge sensor applications. Most implementations use bit-banged GPIO or external converters. This project demonstrates that the CH32V003's SPI BIDIMODE peripheral can handle the protocol natively, no extra components, no bit-banging, just two wires.
Moreover, both of the device is popular in the ultra-cheap.....
CH32V003 (±$0.30) + CS1237 (±$0.50) ≈ $1 High-Res measurement front-end
It's CHEAP!

