The 51 MCU SCM is widely available via different channels. It typically comes without a microcontroller, but has a 11.0592 Mhz crystal. The tutorial uses an STC12C5A60S2 on the 51 MCU SCM. Since the internal oscillator of the STC12C5A60S2 is not very accurate, the crystal is quite useful, even for this tutorial. This short tutorial is about serial output. The author used a Debian GNU/Linux system, but the tutorial should work for other Linux distributions, *BSD or other Unices.
The tools we use are
The 51 MCU SCM has a STC12C5A60S2. Power is supplied via the power connector (which allows easy power-cycling using the switch on the 51 MCU SCM, which would not be possible when using the GND/VCC pin header), to write the program onto the µC and for serial output a Hobby Components HCCABL0015 serial interface cable is connected (green to P30, white to P31).
Depending on your operating system there might be an easy way to install SDCC 3.5.0 or newer using a package system or similar (e.g. apt-get install sdcc on Debian). While SDCC 3.4.0 should be sufficient for this tutorial, you might want to try a newer version in case you encounter any bugs.
SDCC binaries or a source tarball can be downloaded from its website.
stcgal can be found at its GitHub location, where there is also a download link for a zip archive. It is written in Python, and assuming the necessary libraries are installed, can be invoked directly without any need to be built first.
We present a simple Demo that repeatedly outputs "Hello World!" Here is the C code:
// Source code under CC0 1.0 #include <stdio.h> __sfr __at(0x88) TCON; __sfr __at(0x89) TMOD; __sfr __at(0x8b) TL1; __sfr __at(0x8d) TH1; __sfr __at(0x98) SCON; __sfr __at(0x99) SBUF; int putchar(int c) { while(!(SCON & 0x02)); SCON &= ~0x02; SBUF = c; return (c); } void main(void) { unsigned long int i = 0; // Configure UART for 9600 baud, 8 data bits, 1 stop bit. TMOD = 0x20; SCON = 0x40; TH1 = 256 - 11.0592 * 1000 * 1000 / 12 / 32 / 9600 + 0.5; TCON |= 0x40; SCON |= 0x02; // Tell putchar() the UART is ready to send. for(;;) { printf("Hello World!\n"); for(i = 0; i %lt; 147456; i++); // Sleep } }
SDCC is a freestanding, not a hosted implemenatation of C, and allows main to return void. In SDCC up to SDCC 3.6.0 putchar()
used to return void
. This is not standard compliant and was changed to int
in current SDCC versions. The printf()
from the standard library uses putchar()
for output. Since putchar()
is device-specific we need to supply it. In this case we want it to output data using UART0.
The demo can be compiled simply by invocing sdcc using sdcc -mmcs51 --std-c99 serial.c
assuming the C code is in serial.c. The option -mmcs51
selects the target port (mcs51). An .ihx file with a name corresponding to the source file will be generated.
Assuming the serial cable is connected, stcgal.py serial.ihx
will write the demo onto the board. You need to power-cycle the board after invoking stcgal. You can see the "Hello world" by using a terminal program configured for 9600 baud, no parity, 8 bits, 1 stop bit and no flow control.
stcgal is an STC MCU ISP flash tool for programming STC 8051 compatible microcontrollers written by Grigori Goronzy. STC microcontrollers have an UART / USB based boot strap loader (BSL), that stcgal communicates with. The port used can be specified using -p (e.g. stcgal -p /dev/ttyUSB2 test.ihx to write test.ihx onto the board attahced via the third USB serial port).
SDCC was initially written by Sandeep Dutta for the MCS-51, and has a relatively conservative architecture (see Sandeep Dutta, "Anatomy of a Compiler", 2000). It has been extended by various contributors and more recently, incorporated some cutting-edge technologies, in particular in register allocation (see Philipp Klaus Krause, "Optimal Register Allocation in Polynomial Time", 2013 and "Bytewise Register Allocation", 2015). However the mcs51 backend does not have all the fancy features and optimizations that some newer backends have.
SDCC is a C compiler that aims to be compliant with the C standards.
Important compiler options for MCS-51 developers include:
-c
to compile into object files to be linked later--std-c99
for compilation in C99 mode (some C99 features, e.g. variable-length arrays are not yet supported in sdcc though)--model-large
to use the xram for variables by default