0% found this document useful (0 votes)
105 views

8051 C Programming

The document provides an overview of using the C programming language for microcontrollers. It discusses C basics, compilation flow, C extensions like inline assembly, interfacing C with other languages, examples of arrays and pointers, I/O circuitry, functions and header files, and multitasking and multithreading. The document also covers data types, variables, operators, control flow statements like if/else and loops, and using C with assembly code.

Uploaded by

Nilesh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
105 views

8051 C Programming

The document provides an overview of using the C programming language for microcontrollers. It discusses C basics, compilation flow, C extensions like inline assembly, interfacing C with other languages, examples of arrays and pointers, I/O circuitry, functions and header files, and multitasking and multithreading. The document also covers data types, variables, operators, control flow statements like if/else and loops, and using C with assembly code.

Uploaded by

Nilesh
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 56

Monday, October 08, 2012 1

C FOR MICROCONTROLLERS
R EVIEW OF C BASICS
C O M P I L AT I O N F L O W
C EXTENSIONS
I N - L I N E A S S E M B LY
I N T E R FA C I N G W I T H C

E XAMPLES
A R R AY S AND P OINTERS
I / O C IRCUITRY
F UNCTIONS AND H EADER F ILES
M U LT I TA S K I N G A N D M U LT I T H R E A D I N G

Monday, October 08, 2012 2


OF H I G H E R L E V E L L A N G UAG ES , C I S T H E C LO S EST TO

A S S E M B LY L A N G UAG ES

B I T M A N I P U L AT I O N I N S T R U C T I O N S

POINTERS ( INDIRECT ADDRESSING)

M O ST M I C R O CO N T R O L L E R S H AV E AVA I L A B L E C
CO M P I L E R S

W RITING IN C S I M P L I F I ES C O D E D E V E LO P M E N T FO R

L A R G E P R OJ EC T S .

Monday, October 08, 2012 3


C OMPILERS PRODUCE HEX FILES T H AT I S DOWNLOADE D TO
R O M OF MICROCONTROLLER
THE SIZE OF HEX FILE IS THE MAIN CONCERN
M I C RO CO N T RO L L E RS H AV E L I M I T E D O N - C H I P R O M
C O D E S PA C E F O R 8 0 5 1 I S L I M I T E D T O 6 4 K B Y T E S

C P R O G R A M M I N G I S L ES S T I M E C O N S U M I N G , B U T H A S L A R G E R
HEX FILE SIZE

T HE REASONS FOR WRITING PROGRAMS IN C


I T I S E A S I E R A N D L E S S T I M E C O N S U M I N G T O W R I T E I N C T H A N A S S E M B LY
C I S E A S I E R T O M O D I F Y A N D U P D AT E
Y O U C A N U S E CO D E AVA I L A B L E I N F U N C T I O N L I B R A R I ES
C C O D E I S P O R TA B L E T O O T H E R M I C R O C O N T R O L L E R W I T H L I T T L E O F N O
M O D I F I C AT I O N
Monday, October 08, 2012 4
program.c

compile

program.LST program.OBJ
contain the formatted source Reserved memory for global variables.
text along with any errors Public symbol (Variable) names.
detected by the compiler. External symbol (variable) references.
Library files with which to link.
Debugging information to help synchronize
source lines with object code.

build/make
program.M51
Monday, October 08, 2012 5
Like most high level languages, C is a modular
programming language (but NOT an object oriented
language)

Each task can be encapsulated as a function.

Entire program is encapsulated in “main” function.

Monday, October 08, 2012 6


Compiler directives and include files

Declarations of global variables and constants

Declaration of functions

Main function

Sub-functions

Interrupt service routines

Monday, October 08, 2012 7


All C programs consists of:
Variables
Functions (one must be “main”)
Statements

To define the SFRs as variables:


#include <REG51.h>

Monday, October 08, 2012 8


All variables must be declared at top of program, before the first
statement.

Declaration includes type and list of variables.

Example: void main (void) {


int var, tmp;

Types:
int (16-bits in our compiler)
char (8-bits)
short (16-bits)
long (32-bits)

Monday, October 08, 2012 9


The following variable types can be signed or unsigned:
signed char (8 bits) –128 to +127
signed short (16 bits) –32768 to +32767
signed int (16 bits) –32768 to +32767
signed long (32 bits) –2147483648 to +2147483648

unsigned char (8 bits) 0 to + 255


unsigned short (16 bits) 0 to + 65535
unsigned int (16 bits) 0 to + 65535
unsigned long (32 bits) 0 to + 4294967295

Monday, October 08, 2012 10


A good understanding of C data types for 8051 can help
programmers to create smaller hex files
Unsigned char
Signed char
Unsigned int
Signed int

Monday, October 08, 2012 11


Assignment statement:

variable = constant or expression or variable

examples: upper = 60;


I = I + 5;
J = I;

Monday, October 08, 2012 12


Arithmetic: +, -, *, /

Relational comparisons: >, >=, <, <=

Equality comparisons: ==, !=

Logical operators: && (and), || (or)

Increment and decrement: ++, --

Example:
if (x != y) && (c == b)
{
a=c + d*b;
a++;
}

Monday, October 08, 2012 13


XL EQU 0x78 #include <reg51.h>
XH EQU 0x79
void main (void)
YL EQU 0x7A
YH EQU 0x7B {
ORG 0x0000 int x, y, z; //16-bit variables
LJMP MAIN z = x + y;
}
ORG 0x0030
MAIN: MOV A, XL
ADD A, YL
MOV XL, A
MOV A, XH
ADDC A, YH
MOV XH, A
NOP
END

Monday, October 08, 2012 14


adder.asm
assemble

adder.OBJ

build/make

project.M51

Monday, October 08, 2012 15


Use the #pragma CODE
compiler directive to get
assembly code generated in adder.c
SRC file.
compile

adder.SRC adder.OBJ
assemble
rename build/make look here in RAM
adder.asm
when debugging
project.M51
Symbol Table in M51 file:
------ DO
D:0008H SYMBOL x
D:000AH SYMBOL y
Map file shows where variables are stored. D:000CH SYMBOL z
One map file is generated per project. ------- ENDDO

Monday, October 08, 2012 16


x?040: DS 2
ORG 2
y?041: DS 2
ORG 4
z?042: DS 2
main:
; SOURCE LINE # 5
;{ ; SOURCE LINE # 6
; int x, y, z; //16-bit variables
; z = x + y; ; SOURCE LINE # 8
MOV A,x?040+01H
ADD A,y?041+01H
MOV z?042+01H,A
MOV A,x?040
ADDC A,y?041
MOV z?042,A
;} ; SOURCE LINE # 9
RET
; END OF main
END
Monday, October 08, 2012 17
AND &
OR |
XOR ^
left shift <<
right shift >>
1’s complement ~

Monday, October 08, 2012 18


Main: void main (void)
{
XRL A, #0xF0 ; invert bits 7-4
char x;
ORL A, #0x0C ; set bits 3-2 x = x ^ 0xF0;
ANL A, #0xFC ; reset bits 1-0 x = x | 0x0C;
x = x & 0xFC;
MOV P0, A ; send to port0 P0 = x;
}

Monday, October 08, 2012 19


While loop:

while (condition)
{ statements }

while condition is true, execute statements

if there is only one statement, we can lose the {}

Example:
while (1) ; // loop forever

Monday, October 08, 2012 20


For statement:

for (initialization; condition; increment) {statements}

initialization done before statement is executed

condition is tested, if true, execute statements


do increment step and go back and test condition again

repeat last two steps until condition is not true

for (n = 0; n<1000; n++)


n++ means n = n + 1

Monday, October 08, 2012 21


do
statements
while
(expression);

Monday, October 08, 2012 22


if (condition 1)
{statements 1}
else if (condition 2)
{statements 2}

else
{statements n}

Monday, October 08, 2012 23


switch (expression)
{
case const-expr: statements
case const-expr: statements
default: statements
}

Monday, October 08, 2012 24


small
Bit Addressable
Memory Model compact
Object
bit
large

code
data
idata Others
Memory bdata
Type xdata _at_
far alien
pdata
interrupt
_priority_
Special Function sfr
reentrant
sfr16
Registers sbit _task_
using

Monday, October 08, 2012 25


Small Model
In this model, all variables, by default, reside in the internal
data memory of the 8051 system—as if they were declared
explicitly using the data memory type specifier.
In this memory model, variable access is very efficient.
However, all objects (that are not explicitly located in another
memory area) and the stack must fit into the internal RAM.
Stack size is critical because the stack space used depends on
the nesting depth of the various functions.
Typically, if the linker is configured to overlay variables in the
internal data memory, the small memory model is the best
model to use.

Monday, October 08, 2012 26


Compact Model
Using the compact model, by default, all variables reside in a
single page of external data memory of the 8051 system—as if
they were explicitly declared using the pdata memory type
specifier. This memory model can accommodate a maximum of
256 bytes of variables. The limitation is due to the addressing
scheme used which is indirect through registers R0 and R1
(@R0, @R1).
This memory model is not as efficient as the small model and
variable access is not as fast. However, the compact model is
faster than the large model.
When using the compact model, the C51 Compiler accesses
external memory with instructions that use the @R0 and @R1
operands. R0 and R1 are byte registers and provide only the
low-order byte of the address.

Monday, October 08, 2012 27


Large Model
In the large model, all variables, by default, reside in external
data memory (which may be up to 64K Bytes). This is the same
as if they were explicitly declared using the xdata memory type
specifier.

The data pointer (DPTR) is used to address external memory. It


is important to note that memory access through the data
pointer is inefficient and slow, especially on variables that are
two or more bytes long. This type of data access mechanism
generates more code than the small model or compact model.

Monday, October 08, 2012 28


code
Program memory (64 KBytes); accessed by opcode MOVC @A+DPTR.
data
Directly addressable internal data memory; fastest access to variables (128
bytes).
idata
Indirectly addressable internal data memory; accessed across the full internal
address space (256 bytes).
bdata
Bit-addressable internal data memory; supports mixed bit and byte access (16
bytes).
xdata
External data memory (64 KBytes); accessed by opcode MOVX @DPTR.
far
Extended RAM and ROM memory spaces (up to 16MB); accessed by user
defined routines or specific chip extensions (Philips 80C51MX, Dallas 390).
pdata
Paged (256 bytes) external data memory; accessed by opcode MOVX @Rn.

Monday, October 08, 2012 29


code: program
memory accessed
by movc @a + dptr data

bdata

idata
xdata

Monday, October 08, 2012 30


New data types:

Example:
bit bit new_flag; //stored in 20-2F
sbit sbit LED = P1^6;
sfr sfr SP = 0x81; //stack pointer
sfr16 sfr16 DP = 0x82; // data pointer

#include <reg51.h>

Monday, October 08, 2012 31


Memory Model
#pragma small
#pragma compact
#pragma large

Monday, October 08, 2012 32


Memory Type
unsigned char code my_code;
unsigned char data my_variable;
unsigned char idata variable_name;
unsigned char bdata bdata_var;
unsigned char xdata variable;
unsigned char pdata page_variable;

Ctest2.c

Monday, October 08, 2012 33


Program defines two 256 element arrays in external
memory
First array is filled with values that increase by 2 each
location.
First array is copied to second array.
Similar to block move exercise done in assembly.

xdata_mov.c

Monday, October 08, 2012 34


Special Function Register Access
sfr
sfr name = address;

sfr16
sfr16 name = address;

sbit
sbit name = sfr-name ^ bit-position;
sbit name = sfr-address ^ bit-position;
sbit name = sbit-address;

Monday, October 08, 2012 35


Bit addressable object
bit
bit name = value;
bit flag_name = 0;

Monday, October 08, 2012 36


_at_
Variables may be located at absolute memory locations in your
C program source modules using the _at_ keyword.
memory_type type variable_name _at_ constant;
memory_type
Is the memory type for the variable. If this is excluded from
the declaration, the default memory space is used.
type
Is the variable type.
variable_name
Is the variable name.
constant
Is the address where the variable is located.

Monday, October 08, 2012 37


_at_
The following restrictions apply to absolute variable location
using the _at_ keyword:

Absolute variables cannot be initialized.

Functions may not be located at an absolute address.

Bit variables may not be located at an absolute address.

Monday, October 08, 2012 38


char xdata text[256] _at_ 0xE000;
/* array at xdata 0xE000 */

int xdata xyz _at_ 0x8000;


/* int at xdata 0x8000 */

char data abc _at_ 0x30;


/* char at data 0x30 */

ex_at.c

Monday, October 08, 2012 39


Write a program to add array from 30h internal memory
locations

Monday, October 08, 2012 40


The using function attribute specifies the register bank a
function uses.

The argument for the using attribute is an integer


constant from 0-3. Expressions with operators are not
allowed. The using attribute is not allowed in function
prototypes. The using attribute affects the object code of
the function as follows:
The currently selected register bank is saved on the stack at
function entry. The specified register bank is set. The former
register bank is restored before the function is exited.
ex_using.c

Monday, October 08, 2012 41


When it is more efficient, or easier, can insert assembly
code in C programs.

#pragma asm
put your assembly code here
#pragma endasm

ex_asm.c

Monday, October 08, 2012 42


When a C program is compiled, some code is created
that runs BEFORE the main program.
This code clears RAM to zero and initializes your
variables. Here is a segment of this code:
LJMP 0003h
0003: MOV R0, #7FH
CLR A
back: MOV @R0, A
DJNZ R0, back
...

Monday, October 08, 2012 43


Useful for storing data

type arr_name[dimension]

char temp_array[256]

Array elements are stored in adjacent locations in memory.

Monday, October 08, 2012 44


Pointers are variables that hold memory addresses.
Specified using * prefix.

int *pntr; // defines a pointer, pntr


pntr = &var; // assigns address of var to pntr

Monday, October 08, 2012 45


unsigned char *pointer0 ;
Note the asterisk prefix, indicating that the data held in this
variable is an address rather than a piece of data that might be
used in a calculation.
In all cases in the assembler example two distinct
operations are required:
Place address to be indirectly addressed in a register.
Use the appropriate indirect addressing instruction to access
data held at chosen address.
The ability to access data either directly, x = y, or
indirectly, x = *y_ptr, is extremely useful.

Monday, October 08, 2012 46


/* Demonstration Of Using A Pointer */
void function(void)
{
unsigned char c_variable ;
// Declare a c variable unsigned char
unsigned char *ptr ;
//Declare a pointer
c_variable = 0xff ; // Set variable equal to 0xff directly
// OR, to do the same with pointers:
ptr = &c_variable ;
// Force pointer to point at c_variable at run time
*ptr = 0xff ;
// Move 0xff into c_variable indirectly.
}
ex_pointer.c

Monday, October 08, 2012 47


The name of an array is a pointer to the first element:
*temp_array is the same as temp_array[0]
So the following are the same:
n = *temp_array;
n = temp_array[0];

and these are also the same:


n = *(temp_array+5);
n = temp_array[5];

Monday, October 08, 2012 48


Optimization level can be set by compiler control
directive:
Examples (default is #pragma (8, speed)
#pragma ot (7)
#pragma ot (9, size)
#pragma ot (size) – reduce memory used at the expense of
speed.
#pragma ot (speed) – reduce execution time at the expense of
memory.

Monday, October 08, 2012 49


AJMP/ACALL Maximizing (Linker Optimization) (Level 0-7)
The linker rearranges code segments to maximize AJMP and ACALL
instructions which are shorter than LJMP and LCALL instructions.
Case/Switch Optimizing (Level 4)
Code involving switch and case statements is optimized using jump tables or
jump strings.
Data Overlaying (Level 2)
Data and bit segments suitable for static overlay are identified and internally
marked. The linker has the capability, through global data flow analysis, of
selecting segments which can then be overlaid.
Extended Access Optimizing (Level 4)
Variables from the IDATA, XDATA, PDATA and CODE areas are directly
included in operations. Intermediate registers are frequently unnecessary.
Peephole Optimizing (Level 3)
Redundant MOV instructions are removed. This includes unnecessary
loading of objects from the memory as well as load operations with
constants. Complex operations are replaced by simple operations when
memory space or execution time can be saved.
Monday, October 08, 2012 50
Level 0
Constant Folding: The compiler performs calculations that reduce
expressions to numeric constants, where possible.This includes calculations
of run-time addresses.
Simple Access Optimizing: The compiler optimizes access of internal data
and bit addresses in the 8051 system.
Jump Optimizing: The compiler always extends jumps to the final target.
Jumps to jumps are deleted.

Level 9
Common Block Subroutines: Detects recurring instruction
sequences and converts them into subroutines. Cx51
evenrearranges code to obtain larger recurring sequences.
ex_opt.c

Monday, October 08, 2012 51


Add array of 10 bytes from 30h location and store result on 50h.
#include<reg51.h>
unsigned char data a[20] _at_ 0x30;
unsigned int data R _at_ 0x50;
void main (void)
{
char i;
int temp=0;
for (i=0;i<10;i++)
{
temp = temp + a[i];
}
R = temp;
}
Monday, October 08, 2012 52
Separate even, odd, positive and negative numbers.
#include<reg51.h> for(i=0;i<0x0a;i++)
unsigned char data x[10] _at_ 0x30; {
if((x[i]%2)==0)
unsigned char data Even[10] _at_ 0x40;
{ *j = x[i];
unsigned char data Odd[10] _at_ 0x50; j++; }
unsigned char data Pos[10] _at_ 0x60; else
unsigned char data Neg[10] _at_ 0x70; { *k = x[i];
void main (void) k++; }
if(x[i] < 0x80)
{
{ *l = x[i];
unsigned char i=0; l++; }
unsigned char *j, *k, *l, *m; else
j = &(Even[0]); { *m = x[i];
k = &(Odd[0]); m++; }
}
l = &(Pos[0]);
while(1);
m = &(Neg[0]); }
Monday, October 08, 2012 53
Sorting of an array
#include<reg51.h>
unsigned char data x[10] _at_ 0x30;
void main (void)
{
unsigned char i, j, temp;
for (i=9;i>0;i--)
{
for(j=0;j<i;j++)
{
temp = x[j];
if(x[j+1]<temp)
{ x[j]=x[j+1];
x[j+1]=temp; }
}
}
while(1);
}
Monday, October 08, 2012 54
There are two ways to create a time delay in 8051 C
Using the 8051 timer
Using a simple for loop
be mindful of three factors that can affect the accuracy
of the delay The 8051 design
The number of machine cycle
The number of clock periods per machine cycle
Compiler choice
C compiler converts the C statements and functions to
Assembly language instructions
Different compilers produce different code

Monday, October 08, 2012 55


Write an 8051 C program to toggle bits of P1 continuously forever with
some delay.

//Toggle P1 forever with some delay in between “on” and “off”


#include<reg51.h> //We must use the oscilloscope to
void main(void) //measure the exact duration
{
unsigned int x;
for (;;) //repeat forever
{
P1=0x55;
for (x=0;x<40000;x++); //delay size unknown
p1=0xAA;
for (x=0;x<40000;x++);
}
}

Monday, October 08, 2012 56

You might also like