You are on page 1of 25

8051 PROGRAMMING IN C

C V.S. Assembly language

Advantage of C
Its easier to program in C compared to assembly.
C code can be easily ported to other microcontroller, while
assembly language can usually be used for 1 type of
microcontroller
There are lots of function libraries written in C
Advantage of assembly language
The hex file generated by assembly is usually smaller
Code efficiency is higher (faster)

C programming

C has become the standard for embedded system


programming
Object oriented language (C++, Java, C#) are
usually not as efficient as C
C is flexible
One of the main concerns in C programming for
embedded system is to generate a hex file that is
small in size
We need to pay attention to the size of variables
during programming

DATA TYPE
Following different Data types
unsigned char (8 bit :- Range 0-255)
signed char(8 bit:-Range -128 to +127)
unsigned int (16 bit Range= 0 to 65565)
signed int, (16 bit Range -32768 to to 32767)
sbit, ( 1bit)
bit ( 1 bit :-assigned address in bit addressable ram
space (20 to 2f)h)
sfr ( access special function registers in 51)

Time delay
Two methods to achieve time delay: Timer
Loop
When using loops in C, its difficult to determine the
exact time delay by means of calculation
For the same C code, different compilers usually will
generate different assembly codes
Thus the same C codes with different compilers might
generate different delays
The only way to know the exact delay is through
oscilloscope.

8-bit. Most popular data type, matches most registers.


Represent ASCII code or integers in the range of 0 ~ 255.
Example: write a C program to send the ASCII code of 0, 1, 2,
A, B, C to port 1
#include <reg51.h> // the definition of registers
void main (void)
{
unsigned char mynum[ ]= {1,2,3,'a','b','c'};
unsigned char z;
for (z = 0; z <=5; z++)
P1 = mynum[z];
//port 1 is denoted as P1
}

Unsigned char

An 8-bit number with the most significant bit representing sign


(+ or -)
Range: -128 ~ 127
Example: write a C program to send -3 to 3 to port 1
#include <reg51.h>
void main(void)
{
char mynum[] = {-3,-2,-1,0,1,2,3}; // signed char
unsigned char z;
for (z = 0; z<=6; z++)
P1 = mynum[z];
}

signed
char

Integer
Unsigned int
16-bit (needs two registers), range: 0 ~ 65535 (FFFFH)
E.g.: unsigned int a;
Example: write a C program to toggle all bits of P1 continuously
#include <reg51.h>
void main(void)
{
unsigned int i;
P1 = 0x00;
// turn off bit
for (i =0;i<60000 ;i++ ) // delay loop
P1 = 0xFF;
// turn on
for (i =0;i<60000 ;i++ ) // delay loop
}

Signed integer
Signed

int
16-bit, MSB represents sign.
- Range: -32768 ~ 32767
E.g.: int a;
Since int requires twice as many memory
space as char, use unsigned or signed int
only when the number cannot be
represented with unsigned or signed char.

Single bit :-sbit

Single bit, used to access single-bit addressable registers


Example: write a C program to toggle bit D0 of P1 50,000 times
#include <reg51.h>
sbit MYBIT = P1^0;
void main(void)
{
unsigned int z;// 50000 times, cannot use char
for (z=0; z<50000;z++)
{
MYBIT = 0;
MYBIT = 1;
}
}

bit
Used to access single bit of bit-addressable RAM
(20H 2FH)
Example: bit mybit = 0; // the compiler will assign a
RAM space to automatically
sfr
Used to access special function registers
example: sfr ACC = 0xE0; // the address of reg. A

Time Delay
Two methods to achieve time delay:
Loop
When using loops in C, its difficult to determine the
exact time delay by means of calculation
For the same C code, different compilers usually will
generate different assembly codes
Thus the same C codes with different compilers
might generate different delays
The only way to know the exact delay is through
oscilloscope.

I/O Programming :-Byte size

Example: write a program to get a byte of data from P0. If its less
than 100,send it to P1; otherwise send it to P2

Bit addressable I/O programming


Example: write a program to monitor bit P1.5. If it is high, send
55H to P0;otherwise send AAH to P2

SFR Registser

Example: read P0, send the result to P1; read in the value of P2.6

Logic operations
Logic

operators
And :- &&
Or :- ||
Not :- !
Example:

if (var1 < 3 && var2 == 1)


if (!(var > 5))

Bitwise logic operators


- Bit-by-bit logical operations: & (and), | (or), ^ (xor), ~ (not)

Shifting: << (shift to left) >> (shift to right)


Example

#include <reg51.h>
void main(void)
{
P0=0x35 & 0x0F;
P1=0x04 | 0x68;
P2=0x04 ^ 0x78;
P3=~0x55;
P0 = 0x35 << 3;

write a C program to bring in a byte of data serially


one bit at a timevia P1.0. LSB should come first
#include <reg51.h>
sbit P1b0 = P1^0;
sbin ACCMSB = ACC^7;
void main(void)
{
unsigned char x;
for (x=0; x<8; x++)
{
ACCMSB = P1b0;
ACC = ACC >> 1;
}
}

Data Conversion
Example: Write a C program to convert packed
BCD 0x29 to ASCII, send the result to P1 and P2
#include <reg51.h>
void main(void)
{
unsigned char x, y, z;
unsigned char packedBCD = 0x29;
x = packedBCD & 0x0F; // extract low nibble
P1 = x | 0x30; // unpacked BCDASCII
x = packedBCD & 0xF0; //extract high nibble
y = x>>4; // shift it to low nibble
P2 = y | 0x30; //unpacked BCD ASCII
}

Accessing ROM in C
To require the compiler store data in ROM, use the code keyword .
Without code keyword, all the data will be stored in RAM
The compiler will automatically allocate ROM space for the variables.
Example
#include <reg51.h>
void main(void)
{
code unsigned char mynum[] = ABCDEF;
unsigned char z;
for (z = 0; z<6; z++)
P1 = mynum[z];
}

Timer program in c
Write a program to toggle P1.5 every 250 ms. Use timer 0, mode 2 (8-bit auto
reload)
#include <reg51.h>
void T0M2delay25us(void);
sbit mybit = P1^5;
void main(void)
{
unsigned int x;
while(1)
{
mybit = ~mybit;
for (x = 0; x < 10000; x++)
T0M2delay25us();
}
}

void T0M2delay25us(void)
{
TMOD = 0x02; // timer 0, mode 2
TH0 = -23; // count 23 times,overflow.23*1.085=25 us
TR0 = 1; //start timer
while (TF0 = = 0); //wait till overflow not occurs
TR0 = 0;
TF0=0;
}

Timer -counter

Assume a 1 Hz external clock is being fed into pin T0 (P3.4). Write a


C program for counter T0 in mode 1 (16-bit) to display TH0 and TL0
on P2 and P1, respectively.
#include <reg51.h>
void main( )
{
T0 = 1; //(make T0 an input)
TMOD = 0x05; // 0000 0101 (C/T = 1, mode 1)
TL0 = 0;
TH0 = 0; //clear counters
while(1)
{
do
{TR0=1; //start timer
P1 = TL0;
P2 = TH0;
}while(TF0 = = 0);
TR0 = 0; //stop timer
TF0 = 0; //clear TF}
}

Write an 8051 C program to receive a byte of data


from serial port 0, then send it back to serial port 0.
Do this continuously.
#include <reg51.h>
void SerTx(unsigned char);
void SerRx(unsigned char *);
void main(void)
{
char byteBuf;
TMOD = 0x20; // timer 1, 8-bit auto-reload
TH1 = 0XFD; // or: TH1 = -3, 9600 baud
SCON = 0x50;
TR1 = 1; // start timer
while(1)
{
SerRx(&byteBuf); // read byte from serial port
SerTx(byteBuf); // send byte back to serial port
}
}

void SerTx(unsigned char x)


{
SBUF = x; // put the char in SBUF register
while(TI = =0); // wait until transmitted
TI = 0;
}
void SerRx(unsigned char * pX)
{
while(RI = =0); // wait until received
RI = 0;
*pX = SBUF; // copy the data in SBUF to (pX)
}

You might also like