Vous êtes sur la page 1sur 9

keil C Programming Tutorial: Introduction

Introduction
The use of C language to program microcontrollers is becoming too common. And most of the time its not easy to buld an application in assembly which instead
you can make easily in C. So Its important that you know C language for microcontroller which is commonly known as Embedded C. As we are going to use Keil
C! Compiler" hence we also call it Keil C.
Keywords#
Keil C! compiler adds few more keywords to the scope C $anguage#
_at_ far sbit
alien idata sfr
bdata interrupt sfr16
bit large small
code pdata _task_
compact _priority_ using
data reentrant xdata
data/idata:
%escription# The &ariable will be stored in internal data memory of controller.
e'ample#
CODE:
unsigned char data x;
//or
unsigned char idata y;

bdata:
%escription# The &ariable will be stored in bit addressable memory of controller.
e'ample#
CODE:
unsigned char bdata x;
//each bit of the variable x can be accessed as follows
x ^ 1 = 1; //1st bit of variable x is set
x ^ 0 = 0; //0th bit of variable x is cleared

xdata:
%escription# The &ariable will be stored in e'ternal (A) memory of controller.
e'ample#
CODE:
unsigned char xdata x;

code:
%escription# This keyword is used to store a constant &ariable in code memory. $ets say you ha&e a big string which is not going to change anywhere in program.
*asting ram for such string will be foolish thing. So instead we will make use of the keyword +code+ as shown in e'ample below.
e'ample#
CODE:
unsigned char code str="this is a constant string";

pdata:
%escription# This keyword will store the &ariable in paged data memory. This keyword is used occasionally.
e'ample#
CODE:
unsigned char pdata x;

_at_:
%escription# This keyword is used to store a &ariable on a defined location in ram.
e'ample#
CODE:
unsigned char idata x _at_ 0x30;
// variable x will be stored at location 0x30
// in internal data memory

sbit:
%escription# This keyword is used to define a special bit from S,( -special function register. memory.
e'ample#
CODE:
sbit Port0_0 = 0x80;
// Special bit with name Port0_0 is defined at address 0x80

sfr:
%escription# sfr is used to define an /0bit special function register from sfr memory.
e'ample#
CODE:
sfr Port1 = 0x90;
// Special function register with name Port1 defined at addrress 0x0

sfr1:
%escription# This keyword is used to define a two se1uential /0bit registers in S,( memory.
e'ample#
CODE:
sfr16 P!" = 0x8#;
// 1!"bit special function register starting at 0x8#
// $P% at 0x8#& $P' at 0x83

using:
%escription# This keyword is used to define register bank for a function. 2ser can specify register bank 3 to 4.
e'ample#
CODE:
$oid function %& using #'
// code
(
// (untion named )function) uses register ban* # while executing its code

interrupt:
%escription# This keyword will tells the compiler that function described is an interrupt ser&ice routine. C! compiler supports interrupt functions for 45 interrupts -30
4!.. 2se the interrupt &ector address in the following table to determine the interrupt number.
.
e'ample#
CODE:
$oid )xterna*_+nt0%& interrupt 0'
//code
(

)emory )odels#
There are three kind of memory models a&ailable for the user#
!. !mall: All &ariables in internal data memory.
5. Compact: 6ariables in one page" ma'imum 57 &ariables -limited due to addressing scheme" memory accessed indirectly using r3 and r! registers.
4. large: All &ariables in e'ternal ram. &ariables are accessed using %8T(.
%epending on our hardware configuration we can specify the momory models as shown below#
CODE:
//(or Small +emory model
,prag-a s-a**
//(or ,ompact memory model
,prag-a co-pact
//(or large memory model
,prag-a *arge

8ointers in Keil C
8ointers in keil C is are similar to that of standard C and can perform all the operations that are a&ailable in standard C. In addition" keil C e'tends the operatability
of pointers to match with the /3! Controller architecture. Keil C pro&ides two different types of pointers#
!. 9eneric 8ointers
5. )emory0Specific 8ointers
9eneric 8ointers#
9eneric 8ointers are declared same as standard C 8ointers as shown below#
CODE:
char .ptr; //,haracter Pointer
int .nu-; //-nteger Pointer

9eneric pointers are always stored using three bytes. The first byte is the memory type" the second byte is the high0order byte of the offset" and the third byte is
the low0order byte of the offset. 9eneric pointers maybe used to access any &ariable regardless of its location.
)emory0Specific 8ointers#
)emory specific pointers are defined along with memory type to which the pointer refers to" for e'ample#
CODE:
char data .c;
//Pointer to character stored in $ata memory
char xdata .c1;
//Pointer to character stored in .xternal $ata +emory/
char code .c#;
//Pointer to character stored in ,ode memory

As )emory0Specific pointers are defined with a memory type at compile time" so memory type byte as re1uired for generic pointers is not needed. )emory0
Specific pointers can be stored using ! byte -for idata" data" bdata and pdata pointers. or 5 bytes -for code and 'data pointers..
The Code generated by keil C compiler for memory-specific pointer executes mroe quickly than the equivalent code generated for a generic pointer. This is
because the memory area accessed by the pointer is known at the compile time rather at run-time. The compiler can use this information to optimize memory
access. So f execution speed is your priority then it is recommended to use memory-specific pointers.
9eneric pointers and )emory0Specific pointers can be declared with memory area in which they are to be stored. ,or e'ample#
CODE:
//0eneric Pointer
char . idata ptr;
//character pointer stored in data memory
int . xdata ptr1;
//-nteger pointer stored in external data memory
//+emory Specific pointer
char idata . xdata ptr#;
//Pointer to character stored in -nternal $ata memory
//and pointer is going to be stored in .xternal data memory
int xdata . data ptr3;
//Pointer to character stored in .xternal $ata memory
//and pointer is going to be stored in data memory

,unctions in Keil C
Keil C compiler pro&ides number of e'tensions for standarad C function declerations. These e'tensions allows you to#
Specify a function as an interrupt procedure
Choose the register bank used
Select memory model
,unction %eclaration#
:(eturn;type< ,ucntion;name - :Arguments< . :)emory;model< :reentrant< :interrupt n< :using n<
"eturn_t#pe: The type of &alue returned from the function. If return type of a function is not specified" int is assumed by default.
$unction_name: =ame of function.
%rguments: Arguments passed to function.
>ptions#
These are options that you can specify along with function declaration.
&emor#_model: e'plicit memory model -'arge( Compact( !mall. for the function. E'ample#
CODE:
int add_nu-ber %int a/ int b& 0arge

reentrant: To indicate if the function is reentrant or recursi&e. This option is e'plained later in the tutorial.
interrupt: Indicates that function is an interrupt ser&ice routine. This option is e'plained later in the tutorial.
using: Specify register bank to be used during function e'ecution. *e ha&e three register banks in /3! architecture. These register banks are specified using
number 3 for ?ank 3 to 4 for ?ank 4 as shown in e'ample
CODE:
$oid function_na-e %& using #' //function uses 1an* #
//function code
(

Interrupt Ser&ice (outines#
A function can be specified as an interrupt ser&ice routine using the keyword interrupt and interrupt number. The interrupt number indicates the interrupt for which
the function is declared as ser&ice routine.
,ollowing table describes the default interrupts#
As /3! &endors create new parts" more interrupts are added. Keil C! compiler supports interrupt functions for 45 interrupts -304!.. 2se the interrupt &ector
address in the following table to determine the interrupt number.
The interrupt function can be declared as follows#
CODE:
$oid isr_na-e %$oid& interrupt # '
// -nterrupt routine code
(

8lease make sure that interrupt ser&ice routines should not ha&e any arguments or return type e'cept &oid.
(eentrant ,unctions#
In A=SI C we ha&e recursi&e function" to meet the same re1uirement in embedded C" we ha&e reentrant function. These functions can be called recursi&ely and
can be called simultaneously by two or more processes.
=ow you might be thinking" )*# special definition for recursi+e functions,
*ell you must know how these functions work when they are called recursi&ely. when a function is running there is some runtime data associated with it" like local
&ariables associated with it etc. when the same function called recursi&ely or two process calls same function" C82 has to maintain the state of function along with
its local &ariables.
(eentrant functions can be defined as follows#
CODE:
$oid function_na-e %int argu-ent& reentrant '
//function code
(

Each reentrant function has reentrant stack associated with it" which is defined by startup.A! file. (eentrant stack area is simulated internal or e'ternal memory
depending upon the memory model used#
Small model reentrant functions simulate reentrant stack in idata memory.
Compant model reentrant functions simulate reentrant stack in pdata memory.
$arge model reentrant functions simulate reentrant stack in 'data memory.
(eal0time ,unction Tasks#
Keil or C! pro&ides support for real0time operating system -(T>S. (T@! ,ull and (T@! Tiny. (eal0time function task are declared using ;task; and ;priority;
keywords. The ;task; defines a function as real0time task. The ;priority; keyword specify the priority of task.
,ucntions are declared as follows#
CODE:
$oid func %$oid& _tas1_ 2u-ber _priority_ Priority '
//code
(

where#
-umber# is task I% from 3 to 5 for (T@! ,ull and 3 to ! for (T@! Tiny.
Priorit## is priority of task.
(eal0time task functions must be declared with &oid return type and &oid argument list -say no arguments passed to task function..
?asic of a C program
As we already discussed" Keil C is not much different from a normal C program. If you know assembly" writing a C program is not a problem" only thing you ha&e
to keep in mind is forget your controller has general purpose registers" accumulators or whate&er. ?ut do not forget about 8orts and other on chip peripherals and
related registers to them.
In basic C" all programs ha&e atleast one function which is entry point for your application that function is named as +main+ function. Similarly in keil" we will ha&e a
main function" in which all your application specific work will be defined. $ets mo&e further deep into the working of applications and programs.
*hen you run your C programs in your 8C or computer" you run them as a child program or process to your Operating !#stem so when you e'it your programs
-e'its main function of program. you come back to operating system. *hereas in case of embedded C" you do not ha&e any operating system running in there. So
you ha&e to make sure that your program or main file should ne&er e'it. This can be done with the help of simple while-!. or for-AA. loop as they are going to run
infinitely. ,ollowing layout pro&ides a skeleton of ?asic C program.
CODE:
$oid -ain%&'
//2our one time initiali3ation code will come here
3hi*e%1&'
//while 1 loop
//4his loop will have all your application code
//which will run infinitely
(
(

*hen we are working on controller specific code" then we need to add header file for that controller. I am considering you ha&e already gone through +Keil
)icro&ision+ tutorial. After proBect is created" add the C file to proBect. =ow first thing you ha&e to do is adding the header file. All you ha&e to do is rig*t click in
editor window" it will show you correct header file for your proBect.
,igure below shows the windows conte't for adding header file to your c file.
*riting Cardware specific code
In harware specific code" we use hardware peripherals like ports" timers and uart etc. %o not forget to add header file for controller you are using" otherwise you
will not be able to access registers related to peripherals.
$ets write a simple code to ?link $E% on 8ort!" 8in!.
CODE:
,inc*ude 4")5x617h8 99header fi*e for 89:61
$oid -ain%&'
//main function starts
unsigned int i;
//-nitiali3ing Port1 pin1
P1_1 = 0; //+a*e Pin1 o/p
3hi*e%1&'
//-nfinite loop main application
//comes here
for%i=0;i41000;i;;&
; //delay loop
P1_1 = <P1_1;
//complement Port1/1
//this will blin* %.$ connected on Port1/1
(
(

Dou can now try out more programs. .Practice makes a man perfect./
In ne't section of this tutorial" we will learn how to mi' C and assembly codes.
Interfacing C program to Assembler
Dou can easily interface your programs to routines written in /3! Assembler. All you need to do is follow few programming rules" you can call assembly routines
from C and &ice0&ersa. 8ublic &ariables declared in assembly modules are a&ailable to your C program.
There maybe se&eral reasons to call an assembly routine like faster e'ecution of program" accessing S,(s directly using assembly etc. In this part of tutorial we
will discuss how to write assembly progarms that can be directly interfaced with C programs.
,or any assembly routine to be called from C program" you must know how to pass parameters or arguements to fucntion and get return &alues from a function.
Segment naming
C! compiler generates obBects for e&ery program like program code" program data and constant data. These obBects are stored in segments which are units of
code or data memory. Segment naming is standard for C! compiler" so e&ery assembly program need to follow this con&ention.
Segment names include module!name which is the name of the source file in which the obBect is declared. Each segment has a prefi' that corresponds to
memory type used for the segment. 8refi' is enclosed in 1uestion marks -E.. The following is the list of the standard segment name prefi'es#
%ata >bBects#
%ata obBects are the &ariables and constants you declare in your C programs. The C! compiler generates a saperate segment for each memory type for which
&ariable is declared. The following table lists the segment names generated for different &ariable data obBects.
8rogram >bBects#
8rogram onBects includes code generated for C programs functions by C! compiler. Each function in a source module is assigned a separate code segment
using the ,P",function_name,module_name naming con&ention. ,or e'ample" for a function name send_c*ar in file name uart/c will ha&e a segment name of
,P",!E-D_C0%",1%"T.
C! compiler creates saperate segments for local &ariables that are declared within the body of a function. Segment naming con&entions for different memory
models are gi&en in following tables#
,unction 8arameters
C! make use of registers and memory locations for passing parameters. ?y default C function pass up to three parameters in registers and further parameters
are passed in fi'ed memory locations. Dou can disable parameter passing in register using -O"E2P%"&! keyword. 8arameters are passed in fi'ed memory
location if parameter passing in register is disabled or if there are too many parameters to fit in registers.
8arameter passing in registers
C functions may pass parameter in registers and fi'ed memory locations. ,ollowing table gi&es an idea how registers are user for parameter passing.
.
,ollowing e'ample e'plains a little more clearly the parameter passing techni1ue#