Experiment 8051SBC with C51 compiler

Wichit Sirichote, wichit.sirichote@gmail.com

Run c program on 8051SBC with a popular C51 compiler. Sample startup code and test program.

The 8051SBC is a tool for studying both assembly and c programming. The hardware and monitor program are available for everyone to build and use it. The board is not only invaluable for learning but also can be used as a dedicated controller with eeprom boot loader. To use it as the controller, c coding is the right one. So I provide this page for those who want to use a popular c compiler for MCS51, the C51 with 8051SBC.

Getting Started

The 8051SBC has monitor program from 0x0000-0x7FFF (32kB) and SRAM from 0x8000-0xFFFF (32kB). The SRAM was mapped into both code and data memory. So we can test run the code in RAM and later we can save it to EEPROM and boot it. We must let the linker, a program that links object code and places the physical location of such code, know where to place the code in memory space.

Since we will run the compiled code in RAM, so the code memory must set to 0x8000. We have 32kB RAM, but from 0x8000 will be begin of the code, thus better to provide last block, say from 0xF000-0xFFFF for external data memory.

To modify such locations, we must find the startup code. Let's look in LIB folder, find the file STARTUP.A51.
Change the value at CSEG from 0000h to 8000h.

CSEG AT 8000h

And modify the space for external data memory.

XDATASTART EQU 0F000H ; the absolute start-address of XDATA memory
XDATALEN EQU 1000H ; the length of XDATA memory in bytes.

Save it to new name, say SBC8051.A51

Now let's edit new project, add the source program and startup file to the project editor window.

Figure 1: Add source program and startup file (startup file will be translated by A51 Assembler).

Interrupt vector relocation

Since the monitor program has moved 8051 interrupt vectors from 0x0000 to 0x8000, so we must set the OFFSET for interrupt vector to 32768 (0x8000). Then we can have the interrupt service routine within source code.

Figure 2: Set Offset value for interrupt vector.

Sample Program

Let's test the sample code, hello.c. We see that we don't have to set serial port for 9600 8n1, since the monitor program has set it already.

#include <stdio.h>

void main()
char i;
for(i=0; i<100; i++)
printf("\nhello worlds");

We can add the interrupt service routine within source code directly. See below how to use timer 0 to produce 10ms tick! The program shown below will print hello worlds and floating point number every second.

#include <stdio.h>
#include <reg52.h>

xdata char buffer[100];

float n1=1.291129;

char i=0;
char tick;

void timer0int (void) interrupt 1 using 1 {
TH0 |= 0xdc; // reload timer 0 with 0DC00H


void main()

EA = 1;
ET0 = 1; // or IE |= 0x82; /* set bit EA and Timer0 enable */
TMOD |= 0x01; /* timer 0 run 16 bit counter */
TR0 = 1; //or TCON |= 0x10; /* run timer 0 */


tick = 0;
P1 ^= 0x80; // toggle P1.7
printf("\n hello worlds %f",n1*1.27228);


1. Above sample code and startup file uses SMALL memory model. It uses internal RAM as the STACK and IDATA. For another model, please study memory segmentation in c51 user manual, then you can set the correct value for such location in startup file.
2. Above code was tested with uVision51 V1.32 (Keil V5.50).

Library and sample code for Onboard Peripherals (contributions are welcome)

1 May 2004

Recovered 17 December, 2015