Top Banner
IDE51-C (C Compiler for 8051 family with Integrated Development Environment and Simulator for 8051) User’s Manual SPJ Systems 114, Chitrashala Building 562, Sadashiv Peth Pune - 411 030 Tel. (91) (20) 5899048 Fax. (91) (20) 5899050 1
166
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: IDE51

IDE51-C(C Compiler for 8051 family with

Integrated Development Environment and

Simulator for 8051)

User’s Manual

SPJ Systems

114, Chitrashala Building

562, Sadashiv Peth

Pune - 411 030

Tel. (91) (20) 5899048

Fax. (91) (20) 5899050

1

Page 2: IDE51

Terms and Conditions for use of the software

For the purposes of this document, the term THE PRODUCT shall be used to refer to IDE51-C (C compiler for 8051 with Integrated Development Environment and Simulator for 8051).

Terms and Conditions :

1) You may make a backup copy of THE PRODUCT, and you may install THE PRODUCT on your computer systems hard disk, but only one copy of THE PRODUCT may be in use at any one time.

2) If you make any modifications to THE PRODUCT, the modified code shall, regardless of the extent of modification, remain the property of SPJ Systems. You may not remove or alter any copyright notices contained in the source files, documentation, executables or any part of THE PRODUCT.

3) You may not re-distribute any part of THE PRODUCT, or any materials which are based on, or otherwise derived from any portion of THE PRODUCT. Any and all copies of THE PRODUCT must be retained in your possession at all times.

4) You are granted permission to distribute any programs that you develop with THE PRODUCT, provided that they are not based on, or otherwise derived from any source code contained in THE PRODUCT.

5) You agree to use THE PRODUCT entirely at your own risk, and assume all responsibility for such use. The author and distributors of THE PRODUCT do not warrant it fit or suitable for any particular purpose.

===*===*===

2

Page 3: IDE51

CONTENTS :1. INTRODUCTION.......................................................................................................10

2. INSTALLATION.........................................................................................................11

3. GETTING STARTED.................................................................................................12

3.1 STARTING THE DEBUGGER :.....................................................................................163.2 RUNNING THE EXAMPLE :.........................................................................................173.3 THE FIRST STEP :......................................................................................................183.4 SIMULATING INPUT :................................................................................................183.5 STOP IT ! :.................................................................................................................18

4. CONFIGURING THE TARGET SYSTEM.............................................................19

4.1 LOAD CONFIGURATION :..........................................................................................194.2 SAVE CONFIGURATION :...........................................................................................194.3 VIEW / CHANGE CONFIGURATION :.........................................................................19

4.3.1 8279 Configuration:........................................................................................194.3.2 8155 Configuration:........................................................................................204.3.3 8255 Configuration:........................................................................................204.3.4 8253 Configuration:........................................................................................204.3.5 8251 Configuration:........................................................................................214.3.6 LCD Configuration:.........................................................................................214.3.7 Timer Configuration:.......................................................................................214.3.8 Memory Map:..................................................................................................214.3.9 Internal RAM :.................................................................................................224.3.10 Memory model :..............................................................................................22

5. RUNNING A PROGRAM.........................................................................................23

5.1 ADDING BREAKPOINTS:...........................................................................................235.2 SINGLE STEPPING :...................................................................................................235.3 CONTINUOUS RUN :..................................................................................................235.4 CPU RESET :............................................................................................................245.5 OTHER MENU OPTIONS WHILE RUNNING A PROGRAM :...........................................24

5.5.1 Adding Memory Watch :...................................................................................245.5.2 Adding SFR Watch Window :...........................................................................245.5.3 Adding C variables :.........................................................................................245.5.4 Adding I/O Watch :...........................................................................................265.5.5 Executing one statement :.................................................................................265.5.6 Switching to continuous run mode :.................................................................26

3

Page 4: IDE51

5.5.7 Simulating external interrupt (INT0/INT1) :....................................................265.5.8 Simulating serial port input :............................................................................265.5.9 Simulating input to peripherals :......................................................................275.5.10 Modifying the contents of External RAM :.....................................................275.5.11 Modifying the contents of Internal RAM :......................................................285.5.12 Modifying the value of a C language variable :.............................................285.5.13 Modifying the contents of an SFR :................................................................285.5.14 Modifying the contents of a register :.............................................................28

6. LANGUAGE REFERENCE.......................................................................................29

6.1 : COMMENTS :..........................................................................................................296.2 : IDENTIFIER :...........................................................................................................306.3 : KEYWORDS :..........................................................................................................306.4 : DATA TYPES :.........................................................................................................316.5 : TYPE CONVERSIONS :.............................................................................................326.6 : CONSTANTS :..........................................................................................................336.7 : OPERATORS :..........................................................................................................336.8 : FUNCTION PROTOTYPES :.......................................................................................336.9 : COMPILER CONTROL LINES :..................................................................................346.10 : ADDITIONAL FEATURES :.....................................................................................35

6.10.1 : Using Special Function Registers (SFR) :...................................................366.10.2 : Assembly language interface :.....................................................................366.10.3 : The asm keyword :........................................................................................376.10.4 : The peripheral keyword :.............................................................................376.10.5 : The BIT keyword :.......................................................................................376.10.6 : Declaring variables at specific address (in Internal / External RAM) :......386.10.7 : Pitfalls in using @ and @I :.........................................................................40

7. C31 LIBRARY FUNCTIONS REFERENCE...........................................................41

LIST OF FUNCTIONS IN ALPHABETICAL ORDER :............................................................41abs..............................................................................................................................45acos............................................................................................................................45asin.............................................................................................................................45atof.............................................................................................................................46atoi.............................................................................................................................46atol.............................................................................................................................46bcd2int.......................................................................................................................47ceil..............................................................................................................................47clr_double_baud........................................................................................................47clr_ri..........................................................................................................................47

4

Page 5: IDE51

clr_ti...........................................................................................................................48cos..............................................................................................................................48cosh............................................................................................................................48delay...........................................................................................................................49delay_ms....................................................................................................................49disable........................................................................................................................50disable_all..................................................................................................................50disable_ex0................................................................................................................51disable_ex1................................................................................................................51disable_rx..................................................................................................................51disable_ser.................................................................................................................52disable_t0...................................................................................................................52disable_t1...................................................................................................................52disable_t2...................................................................................................................53disp_lcd......................................................................................................................53dsp82791....................................................................................................................53dsp82792....................................................................................................................54enable.........................................................................................................................54enable_all..................................................................................................................54enable_ex0.................................................................................................................55enable_ex1.................................................................................................................55enable_rx...................................................................................................................55enable_ser..................................................................................................................56enable_t0....................................................................................................................56enable_t1....................................................................................................................56enable_t2....................................................................................................................57ex0_edge....................................................................................................................57ex0_level....................................................................................................................57ex1_edge....................................................................................................................58ex1_level....................................................................................................................58exp..............................................................................................................................58floor............................................................................................................................59flot2str........................................................................................................................59fmod...........................................................................................................................60frexp...........................................................................................................................60getbyte........................................................................................................................60getch...........................................................................................................................61getchar.......................................................................................................................61getchare.....................................................................................................................61go_idle.......................................................................................................................62

5

Page 6: IDE51

hi_nibb.......................................................................................................................62init8279......................................................................................................................62init_lcd.......................................................................................................................63init_ser.......................................................................................................................63inportb........................................................................................................................63int2bcd.......................................................................................................................64isalnum.......................................................................................................................64isalpha........................................................................................................................64isascii.........................................................................................................................65isdigit.........................................................................................................................65islower........................................................................................................................65isspace........................................................................................................................65isupper.......................................................................................................................66isxdigit........................................................................................................................66itoa_c31.....................................................................................................................66kbhit...........................................................................................................................67labs.............................................................................................................................67ldexp...........................................................................................................................67log..............................................................................................................................68log10..........................................................................................................................68long2bcd....................................................................................................................68lo_nibb.......................................................................................................................69ltoa_c31.....................................................................................................................69memset.......................................................................................................................69modf...........................................................................................................................69movmem.....................................................................................................................70outportb......................................................................................................................70peekb..........................................................................................................................70pokeb..........................................................................................................................70pow.............................................................................................................................71powerdown.................................................................................................................71printf..........................................................................................................................71printf2........................................................................................................................71printf2n......................................................................................................................71printfn........................................................................................................................71putchar.......................................................................................................................75puts.............................................................................................................................76scanf...........................................................................................................................76sendbyte.....................................................................................................................78ser_rdy.......................................................................................................................78

6

Page 7: IDE51

set_com_mode............................................................................................................78set_double_baud........................................................................................................79set_hi_ex0..................................................................................................................79set_hi_ex1..................................................................................................................79set_hi_ser...................................................................................................................80set_hi_t0.....................................................................................................................80set_hi_t1.....................................................................................................................80set_hi_t2.....................................................................................................................81set_lo_ex0..................................................................................................................81set_lo_ex1..................................................................................................................81set_lo_ser...................................................................................................................82set_lo_t0.....................................................................................................................82set_lo_t1.....................................................................................................................82set_lo_t2.....................................................................................................................83set_t0_mode...............................................................................................................83set_t1_mode...............................................................................................................83set_tcnt.......................................................................................................................84sin...............................................................................................................................84sinh.............................................................................................................................84sprint2n......................................................................................................................85sprintf.........................................................................................................................85sprintf2.......................................................................................................................85sprintn........................................................................................................................85sqrt.............................................................................................................................86sscanf.........................................................................................................................86start_timer0................................................................................................................87start_timer1................................................................................................................87stop_timer0................................................................................................................87stop_timer1................................................................................................................88strcat..........................................................................................................................88strcmp........................................................................................................................88strcpy..........................................................................................................................89strlen..........................................................................................................................89strlwr..........................................................................................................................89strncpy........................................................................................................................90strupr..........................................................................................................................90tan..............................................................................................................................90tanh............................................................................................................................91tolower.......................................................................................................................91toupper.......................................................................................................................91

7

Page 8: IDE51

ui2a_c31....................................................................................................................92ui2bcd........................................................................................................................92

8. ADVANCED PROGRAMMING TECHNIQUES...................................................93

8.1 WRITING SIMPLE ASSEMBLY LANGUAGE SUB-ROUTINES :.....................................938.2 ASSEMBLY LANGUAGE FUNCTION'S RETURN VALUE :.............................................948.3 ASSEMBLY LANGUAGE FUNCTIONS WITH PARAMETERS :.......................................95

8.3.1 Accessing parameters in large model programs :............................................958.3.2 Accessing parameters in small model programs :............................................96

8.4 CALLING C FUNCTIONS FROM ASSEMBLY LANGUAGE :...........................................978.4.1 Passing parameters (large model programs) :.................................................988.4.2 Passing parameters (small model programs) :................................................99

8.5 EXPANDING THE LIBRARY :....................................................................................1008.6 THE COMPILE PROCESS :.........................................................................................1018.7 MORE ABOUT ASSEMBLY LANGUAGE :..................................................................102

8.7.1 Labels :...........................................................................................................1028.7.2 Constants :......................................................................................................1028.7.3 String constants :............................................................................................1028.7.4 Bit operands :................................................................................................102

8.8 INTERRUPT FUNCTIONS :........................................................................................102

APPENDIX A : ERROR AND WARNING MESSAGES.........................................104

HOW CAN I SEE ALL OF THE ERROR / WARNING MESSAGES ?......................................104WARNING MESSAGES :.................................................................................................104

Warning : Can not open your .ASM include file filename.ext :..............................104Linker warning : Function func_name is undefined (assumed external) :..............105Parameter ‘paraname’ never used :........................................................................105Local variable ‘localname’ declared but never used :............................................105No declaration for function ‘funcname’ :................................................................105Global variable ‘globalname’ declared but never used :........................................105Function ‘funcname’ defined but never called :......................................................106

ERROR MESSAGES :......................................................................................................106Declaration Syntax Error :......................................................................................106Redeclaration of identifier OR function :................................................................106Too Many Identifiers :.............................................................................................106Unknown Identifier :................................................................................................106Invalid Identifier :....................................................................................................106Too many errors :....................................................................................................107Invalid Statement :...................................................................................................107Syntax error ! :.........................................................................................................107

8

Page 9: IDE51

Mismatch brackets :.................................................................................................107Too Many Brackets :................................................................................................107Statement Missing ; :..............................................................................................107Misplaced continue :................................................................................................107Misplaced else :.......................................................................................................108Misplaced break :....................................................................................................108do statement missing 'while' :..................................................................................108case outside of switch :............................................................................................108Colon Missing :........................................................................................................108Too Many Default Statements OR default May be Outside of switch :.................108Type Mismatch :......................................................................................................108Can't open library file :...........................................................................................109Can't open index file :..............................................................................................109Library file is bad :..................................................................................................109Index file is bad :.....................................................................................................109Unknown Peripheral name :....................................................................................109Too many 'goto' statements ! (max. 10) :.................................................................109Undefined label :.....................................................................................................110Undefined macro :...................................................................................................110Macro Parameters missing :...................................................................................110Too many/few parameters passed to macro :..........................................................110Macro definition syntax error :...............................................................................110Unexpected #else or #endif :...................................................................................110Too many macro definitions :..................................................................................110Too big macro definition :.......................................................................................111Syntax error in include statement (or file not found) :............................................111Macro has too many parameters :...........................................................................111Invalid Statement :...................................................................................................111Line Too Long ! :.....................................................................................................111Too many ifs :..........................................................................................................111Too many (> 128) SFR declarations :.....................................................................111'bit' type local var/para/array : not allowed :.........................................................111pointer to bit variable : not allowed :......................................................................112

APPENDIX B : LIMITATIONS OF THE COMPILER...........................................113

Appendix C : 10 ways to improve code efficiency..........................................................115

===*===*===

9

Page 10: IDE51

1. Introduction

Thank you for purchasing IDE51-C. Now you can write 8051 applications in C and debug (simulate) those without the target hardware. The simulator – which is part of the IDE51-C package - simulates some commonly used peripherals like 8255, LCD and so on.

How to use this manual:This manual is intended to be read from start to beginning, so you learn about all the features of this compiler. However, the library functions’ description may be skipped initially, and it can be referred to when you actually start writing applications.

The chapter 2 provides instructions to install the software. Chapter 3 gives you a general idea of the features of the software. After reading chapter 3, you may start actually using this software. Chapter 4 contains detail information about ‘Configuration’. Chapter 5 contains information about ‘Run’ menu options.

For any questions or comments about the product, please feel free to contact us at :

SPJ SYSTEMS 114, Chitrashala Building. 562, Sadashiv Peth Pune. Pin - 411 030. Tel. +91-20-5899048 Fax. +91-20-5899050 E-mail : [email protected] Web-site : http://www.spjsystems.com

10

Page 11: IDE51

2. Installation

The IDE51-C software CD (or floppy disk(s)) include an automatic installation program called SETUP.EXE. This software ships on one / two floppy disks or one CD. If you are installing using floppy disks, insert the disk labeled as “disk 1” in drive A or B and run SETUP.EXE from the floppy disk. If you have CD, insert it in your CD-ROM drive and run SETUP.EXE from the CD. This will start the installation and the setup program will ask you some questions. e.g. where do you want to install the software – in the default path or somewhere else. Please supply the answers to all the questions and complete installation. If you are installing IDE51-C with floppy disks, you may be prompted to insert the disk labeled “disk 2”. Please do so and click on the “OK” button.

Please read this manual carefully before you start using the software.

11

Page 12: IDE51

3. Getting Started

Once the software is installed, click on Start/Programs and you should see a new menu option “SPJ Systems’ IDE51-C”; when you select it, you should further see two sub-options: “Debugger” and “IDE”. If you click on “Debugger”, it will start the Simulator program. If you click on “IDE”, it will start the IDE program. To create your first project, click on the “IDE”.Once the IDE program starts, it will usually have automatically opened one of the example programs. To create your first project, compile it and debug it, follow these simple steps.

1) Select Project/Close from the menu. This will close the currently open project of the example program.

2) Select File/New File from the menu. This will create a blank program window, in which you can type the program. You may type the following:

#include <sfr31.h>#include <stdio.h>#include <standard.h>

void main () {init_ser() ;while(1) {

printf(“Hello world!\n”) ;}

}3) After typing the program, select File/Save As to save the new program file and

give it a suitable name e.g. first.c4) Select File/New Project from the menu. Type a name for your new project e.g.

first.prj in the Filename box and then click on the Open button.5) Now you should see the Project Settings window as shown in figure 1. Near the

top of this window, you see the title “Files in Project” and just below it, you will see a window which lists the files which are part of this project. In this window, the IDE automatically inserts a file with the same name as your project, but with extension .C. So you will see the name “first.c” already listed in this window. Every project must have one C file in it. A project can also optionally have one ASM patch file and one LIB file. If you need to add a file, you can click on the “Add a File” button. Similarly, to remove a filename from the list, you may select

12

Page 13: IDE51

the filename and then click on “Remove File” button. For our first project, just one C file is enough.

6) Further, there are several other options that you can set as per your needs. 7) This compiler supports almost all micro-controllers from the 8051 family. To set

some of the compiler options correctly, you may select a manufacturer from the list and then you may select the desired chip number from the list of micro-controllers. If you are not able to find the manufacturer / micro-controller name in the lists, still it is very likely that the compiler supports the chip that you want to use. In this case, select “Other” for manufacturer as well as for the micro-controller. For our example, you may select Intel/8031.

8) When you select the desired manufacturer/micro-controller, the compiler automatically “knows” whether the selected chip has 128 bytes internal RAM or 256 bytes. However, if you have selected “Other” as manufacturer and C, then you may need to manually specify whether your C has 128 bytes or 256 bytes Internal RAM.

9) This C Compiler supports two memory models – Large (select this if external data memory is available) and Small (select this if external data memory is not available). For our example, please select small memory model.

10) In case you selected Large memory mode, you need to tell the compiler how much external data RAM is available (specify external RAM start and end addresses) so the compiler will place all your variables within this space.

11) Code Offset is the address from where code will be generated. By default, it is 0 as 8051 reset vector is 0. However, if required, you can type a non-zero code offset. For example, if you want to download the code into the RAM address 0x2000 of target (like in our Maxi51 evaluation board), you may need to enter 2000 as code offset.

12) The standard 8051 has 5 interrupt sources and their corresponding vectors are at addresses 0x0003, 0x000b, 0x0013, 0x001b and 0x0023. So the compiler must leave these locations unused. By default, the compiler leaves first 0x0050 locations in program memory for interrupt vectors. However, some 8051 derivatives provide many more interrupt sources, so their vector locations can be beyond 0x0050. In such case, you can change the value from 0x0050 to whatever you desire.

13) If you want to use the simulator, you must check the option “Generate debug info” so the compiler generates the files needed by the simulator, so it can facilitate source level debugging.

14) By default, the compiler generates only BINary file – that is ROM image file. If you want Intel HEX format file, check the option “Generate HEX file”.

15) Check “Generate LST file” option to generate the listing file.

13

Page 14: IDE51

16) The compiler can insert C source lines (as comments) in the generated ASM code, if you check the corresponding option.

17) Check “Generate OMF file” option if you need the OMF file for debugging with an In Circuit Emulator.

18) If you are using the USB chips from Cypress/Anchor, the compiler needs to generate code little differently. So when you select Cypress or Anchor as manufacturer, the option “Using EZUSB chips?” is automatically checked. Similarly, if any other manufacturer is selected, then this option is automatically NOT checked. However, if you select “Other” as manufacturer, then you must manually either check or not check this option. When you check this option, the compiler assumes that the new SFR “MPAGE” at address 0x92 must be used to hold the high byte of address while using the “movx @Ri” instructions.

19) When you have set all the options correctly, click Ok.

14

Page 15: IDE51

Figure 120) Select Compile/Compile from the menu. This will invoke the compiler with

appropriate options. The compiling process may take a while. After that, the compiler's output will be displayed in ‘Compiler Output Window’. Browse through it, to make sure that there are no errors in your programs. (In case you detect any error in your program, just double click on the error message in the ‘Compiler Output Window’. This will automatically move the cursor into the Program file onto the line containing error. Correct the error and compile again.)

21) Select Run/Debugger from the menu. This will start the Simulator (WSIM51).22) The WSIM51-C will display four windows: Program Window, C Variable Watch

Window, SFR Watch Window, Serial Window. The program window contains

15

Page 16: IDE51

your program. Optionally you can open/close other windows i.e., External RAM Watch window, Internal RAM Watch window, IO Watch Window.

23) Select Configuration / View/Change Configuration / Memory Model / Small from the menu. We need to do this, because, we had selected the small memory model while compiling our program.

24) To single step through your program, Select Run/Single-Step from the menu or press F7. When you do so, a band appears on the first statement in the main() function. In our example, it is the “init_ser()” function call. It means, when you press F7 again, this statement will be executed (actually simulated). Press F7 again and the band moves to the next statement i.e. the printf statement inside the while(1) loop. The init_ser function initializes the serial port for 2400 or 4800 baudrate (assuming 12 MHz crystal). If you look inside the serial window, you can see the effect of the init_ser function call: you will see the baudrate as 2400 or 4800 and you will also see that serial input is now enabled.

25) Press F7 again. Now the printf statement will be executed. The printf function sends formatted output to the standard output device. The default standard output device is the on-chip serial port, so effectively, this statement outputs all characters in the string “Hello world!\n” to the on-chip serial port. As an effect, you can see the same string inside the serial output window.

26) Since the printf statement is inside an infinite loop, it will keep executing again and again, as long as you keep pressing F7. To stop the debugging, you may select Run/Terminate program from the menu.

3.1 Starting the debugger :

To run the debugger, select Program/SPJ Systems’ IDE 51-C/Debugger from start menu. The debugger will start and the screen should something like figure 2.You will see various windows as described below - Program Window: Displays the currently open file (if any). C Variable Watch Window: Displays the contents of the selected C variables.(This

is window will not be activated in case of WSIM51) SFR Watch Window: Displays the contents of 8051 internal registers. Serial Window: The Serial Window displays the output of 8051’s on-chip serial port.

The same can also be used to simulate input to the on-chip serial port. IO Watch Window: Similarly the I/O Watch Window can display the status /

activities of various peripherals (if any are connected.).

16

Page 17: IDE51

Figure 2

External RAM Watch window: This displays the contents of selected locations of the external RAM.

Internal RAM Watch window: This displays the contents of selected locations of the internal RAM.

3.2 Running the example :

In order to run (i.e. simulate) a program, two things are necessary. The first is that you must open the program file. The second is you must set the configuration to match with the target hardware. To do this, select Configuration / View/Change Configuration from the menu. Change the configuration as per your requirement. Set the addresses of the peripherals and appropriate internal RAM size (128/256 bytes). When you are done, select Save Configuration from Configuration menu. The configuration information is saved in a file with extension .cfg and name same as the open program file. When you do

17

Page 18: IDE51

this, you have done precisely the same two things necessary to run a program, so you are ready to run (simulate) the program.

3.3 The first step :

Now select Run/ Single step from the menu. That will actually start the opened program. Alternately, you can press the F7 key. You will see a greater than sign (>) on a particular line of the program. Actually, this is the first statement to be executed. When you press F7 again, this ‘>’ statement will be executed. It’s effect will be reflected in the various Watch Windows. This is how you single step through a program. If you are not interested in pausing after each statement, you may press Ctrl + F7. This will put you in continuous execution mode. Now your program is being run and you can see the results in Serial Port / Registers / Memory Watch / I/O Watch Windows.

3.4 Simulating input :

The simulator simulates number of peripheral devices, and it allows you to simulate input to these peripherals. For example, 8279 is supported by this simulator. The 8279 is used for keyboard and display interface.

To simulate keyboard entry, 8279 must be added to configuration. To do this select Configuration/View Change Configurations and add 8279 peripheral with appropriate address. Now right click in I/O Watch Window, select Edit from pop-up menu, select 8279 from a dialog box. You will be prompted to enter the scan-code expected from 8279. Do type in a value in the edit box and press OK

3.5 Stop it ! :

Finally when you are done, just press Run/Terminate. This will bring you back to stop mode. Now you may open another program, or change the configuration and so on. If you want to restart the new / same program, please remember to RESET first. To do this select Run option and then CPU Reset or press Reset button from the tool bar. This will simulate the action of a hardware reset signal to the 8051 CPU.

Thus you have learnt a few things in this example. Now you can try your own programs. If things are not clear, continue reading the next chapters. Otherwise you may keep this manual on your table, and refer to it as and when required.

18

Page 19: IDE51

4. Configuring the target system

In order to simulate your 8051 based hardware, the computer must know what is your hardware like. When we say “configuration” we mean “telling” the computer about your hardware. When you select Configuration form main menu, you will see 4 sub-options : “Load”, “Save”, “View/Change” and “Tab Size”. These are explained in detail in this chapter.

4.1 Load Configuration :

Allows the user to load a configuration file - a file in which all configuration parameters are stored. If you have already created a configuration file for your own hardware, you may load the file to set all configurable parameters as per your requirement.

4.2 Save Configuration :

Allows the user to save the configuration information in a file. Once you have set all the configuration parameters as per your hardware, you may choose this menu option. The configuration information is saved in a file with extension .cfg and name same as the open program file.

4.3 View / Change Configuration :

When you select this option, you will further see a list of options. Here we will see all of them one by one.

4.3.1 8279 Configuration:

This Software simulates 8279 which is Programmable Keyboard / Display Interface. If you are using 8279 in your target hardware, select 8279 option to configure it. First, you will have to check connect check-box and specify the address of 8279. Type the address of 8279 data register in 4 digit HEX format. Please note that, the address of 8279 command register is assumed to be this address plus one. e.g. suppose you enter 8279 address as 6000, then 6000 (HEX) is treated as the 8279 data register address and 6001 (HEX) is treated as the 8279 command register address.Then, you may specify the IRQ connection for 8279. i.e. in your hardware, you might connect the IRQ output of 8279 to 8051’s INT0, or to INT1 or you may not use the IRQ

19

Page 20: IDE51

output at all. You can specify any one of these choices here. Suppose, you have connected 8279’s IRQ output to 8051’s INT1 interrupt input. Then specify the same here. So that, when you simulate a key entry, INT1 will be automatically generated. (Provided it is enabled by your program)Usually 8279 is used for handling keyboard and 7 segment display. For such displays, the 7 segment code to character relation may be different depending on how you connect all of the 7 segments. That means, there is no universal 7 segment code for a character (unlike ASCII). To define your 7 segment codes write down the seven segment code (in code edit window), corresponding character (in char edit window) and press add. Repear the procedure for all the seven segment code that your program needs. The advantage of the facility is that, when you run your program, you may put 8279 in I/O watch, which will show you the characters corresponding to the code contained in 8279’s display RAM.

4.3.2 8155 Configuration:

8155 is an I/O Port. To configure the 8155, you have to select the 8155 menu option. If you are using 8155, check the connect check-box and enter the correct base address. i.e. you should type the address of 8155 command register. e.g. if you enter it as 8000 (HEX), then the simulator / debugger will assume following addresses for 8155 : 8000 -> 8155 Command register 8001 -> Port A 8002 -> Port B 8003 -> Port C 8004 -> Timer Low byte 8005 -> Timer High byte

4.3.3 8255 Configuration:

If you have as many as five 8255 chips connected to 8051 in your target hardware, you can configure it accordingly and simulate your program. To do this, check the connect check-box and enter the correct base address for the chip. e.g. suppose you enter the address of 8255 as 8000, then the simulator will assume following address :8000 -> Port A8001 -> Port B8002 -> Port C8003 -> Control register

4.3.4 8253 Configuration:

8253 is Programmable Interval Timer. Similar to 8255, you may enter the base address for 8253, if you want.

20

Page 21: IDE51

4.3.5 8251 Configuration:

8251 is Universal Synchronous/Asynchronous Receiver Transmitter. Similar to 8255, you may enter the base address for 8253, if you want.

4.3.6 LCD Configuration:

To connect LCD module to 8051 in your target hardware, select this option and check the connect check-box. Address : This is the base address of LCD as usual. e.g. if you enter the address as 4000, then the simulator assumes following address :4000 -> LCD command register4001 -> LCD data registerActual chars / line : This is the logical number of characters per line for the LCD. e.g. in case of a 16 char X 1 line LCD module, this should be entered as 8. Because, even though physically it is a single line display, it has 2 logical lines - each 8 characters wide.Display chars / line : This is the physical number of characters per line. e.g. in case of a 16 char X 1 line display, this should be entered as 16.

4.3.7 Timer Configuration:

The timer will be selected only if one of the peripheral with a timer (i.e. either 8155 or 8253) is included in the configuration, by giving its address. If any timer is used and this item is selected, you will see a sub-menu from which you will select either 8155 or one of the 8253. e.g. suppose, you selected 8155, then further you have 2 options :Prescaler : The simulator assumes that all these timers are getting clock input at the same frequency as that of 8051. But, in reality, it may not be so. e.g. the clock frequency input to 8155 timer may be half that of 8051 crystal frequency. To simulate this exactly, you may enter the value of pre-scaler as 2. In fact, you can change the prescaler value from 1 to ffff (Hex). The default value for pre-scaler is 1.Output connected to : The output of this timer may or may not be connected to one of the interrupts of 8051 (i.e. INT0 or INT1) in your target hardware. Exactly the same connection can be specified here.

4.3.8 Memory Map:

When you select this item, you will see 3 options :Program memory : Select this option to specify the amount of program memory available in the target hardware. You can specify up to 4 different banks of program memory by entering the starting and ending address.Data memory : Select this option to specify the amount of data memory available in the target hardware. You can specify up to 4 different banks of data memory by entering the starting and ending address.Overlap memory : Select this option to specify the amount of overlapped memory available in the target hardware. You can specify up to 4 different banks of overlapped

21

Page 22: IDE51

memory by entering the starting and ending address. Overlapped memory is that area of external memory, which can be used as read/write memory (using movx instruction) and also as program memory (using movc / ljmp / lcall instructions etc)

4.3.9 Internal RAM :

You can select either 128 bytes or 256 bytes Internal RAM.

4.3.10 Memory model :

Please note that, memory model specified while compiling and the memory model specified here must be same. Otherwise, the debugger may not be able to show the values of variables correctly.Please note that this option is available, only if you have purchased the C cross compiler also. Otherwise this option remains disabled.

22

Page 23: IDE51

5. Running A Program

After the compilation process, user can execute the program and can see the output of that program. It is also possible to debug through the program and set breakpoints at many places in the program. The Run menu has five options which contains the facility of adding breakpoints, debugging, execution of program and CPU reset.

5.1 Adding Breakpoints:

A simplest way to add or remove a breakpoint is to double click on a line where you want to add breakpoint. One can also select the Breakpoint sub-option from Run menu. After doing this, you will see a ‘[BR] ‘ breakpoint characters on the line in the program window. Thus you can browse through the entire program. For setting break-point at any statement, move the cursor to that line. Then press F12 or double click on that line. You will see ‘[BR]’ on the left hand side. This indicates that you have set a break-point at that line. To remove a break-point, you may use the same procedure : i.e. pressing F12 or double click actually toggles the break-point state.

5.2 Single Stepping :

Single stepping is another mode of executing your program. Through single stepping, each instruction is executed one by one. The contents of system registers are continuously displayed in Register window. Simultaneously user can see the memory and I/O watch. To single step through a program, select the sub-option Single Step. Alternately, you may just press F7 key for single stepping through the program. A colored band will be displayed on the very first executable instruction of your program. The next time you press F7, the statement displayed with a colored band gets executed and the band moves ahead (or sometimes even back) to the next statement.

5.3 Continuous Run :

When this option is selected, the program is run continuously. Off-course, you may stop the program execution any time by selecting Run/Terminate Program. Otherwise, the program execution continues till a break-point is encountered. When that happens, the

23

Page 24: IDE51

program execution stops automatically and you are back to single step mode. While the program is being run, various watch windows are updated at the end of each statement.

5.4 CPU Reset :

This option acts like a reset signal to 8051. It sets all the system registers of 8051 to the value which is actually set after resetting 8051. Also all the peripherals are set to their reset condition.

5.5 Other Menu options while running a program :

While your program is being run (either in continuous mode or in single step mode), you may need to add some watch variables, edit some memory locations, edit some variables. Here is the description of all these to do these:

5.5.1 Adding Memory Watch :

Click on the ‘X’ button from tool to get the External Memory Watch Window. For the Internal Memory Watch Window click on ‘IM’ button of tool bar. Alternatively, you can select View/External memory watch or View/Internal memory watch from the menu. When you do this, screen looks like figure 3. To add a watch in external / internal memory watch window, right click inside the window. A menu will pop-up. Select Add from the menu. You will be prompted to enter the memory address (Hex), type it and press enter or click Ok. The same address will appear in the memory watch window, followed by 16 values in HEX followed by their ASCII equivalent characters. These are the contents of 16 consecutive locations starting from the address you entered.

5.5.2 Adding SFR Watch Window :

If you want to see the contents of a Special Function Register (SFR), select this optionfrom ‘View’ menu or just click ‘R’ button of tool bar. When you do this, SFR Watch Window will appear. To modify the contents of a SFR, double click on the desired SFR. The name of the SFR will now appear in a new edit window. It will display the current contents in HEX, followed by the binary representation. You can change the contents and click Ok to save the new value.

5.5.3 Adding C variables :

If you want to see the value of a variable declared in your program, select this option from ‘View’ menu or click ‘C’ button of tool bar. Then you will get the ‘C Variable Watch Window’. To add the C variable, just do the right mouse click on the displayed message. Then select declared ‘C’ variable from the drop down list of all C variables, and clock ‘Add’. Please note, that the list contains the variables that are global variables and variables that are currently in active scope. e.g. if you are in the middle of a function,

24

Page 25: IDE51

then variable list contains global variables and local variables declared in the current function or it may be a parameter to the current function. However, if you selected a local variable, it’s value will be displayed, only so long as your program is inside the function. The moment you return from the function, the debugger will be unable to display it’s value. The debugger will flash the message “Out of scope” in front of the variable name in the watch window.

Figure 3The variable name will appear in the watch window, followed by it’s value. Please note, that the debugger knows the type of the variable, so it will display it’s value appropriately depending on it’s type. e.g. int and long int variables are displayed as decimal values followed by it’s HEX equivalent in a pair of parenthesis. char variables are displayed as ASCII character. Arrays of char are displayed as a character string enclosed in double quotes.Please note that you can add C Variable Watch Window only if you have loaded a .C file to debugger. If you have loaded a binary (.bin) or Hex (.hex) file, you can not add C

25

Page 26: IDE51

Variable Watch Window and hence can not observe values of C variables for an obvious reason that these files do not contain variable information.However if you have purchased WSIM51, i.e. Windows based Simulator, you can not load C file at all. Hence C Variable Watch Window is disabled.

5.5.4 Adding I/O Watch :

Select I/O Watch sub-option from ‘View’ menu. Again, do the right click to add, delete or edit an I/O watch.When you click to add a watch, a list of connected peripherals appears on the screen. i.e. a list of peripherals for which you have specified some valid address in the configuration will appear. You may select the desired peripheral from the list and then press <Enter>. It will be displayed in the I/O watch window. Depending on the type of peripheral selected, it’s information will be displayed in different format. e.g. if you select 8279, the contents of 16 (or 8) locations of it’s display RAM will be displayed in the I/O watch window. If you select LCD, whatever message is output to the LCD will be displayed. If you select 8155, the contents of PA, PB and PC will be displayed along with their port directions (Input / Output).

5.5.5 Executing one statement :

Select Run/Single Step (or Press F7) to do this.

5.5.6 Switching to continuous run mode :

Select Run/Run (or Press Ctrl F7) to do this.

5.5.7 Simulating external interrupt (INT0/INT1) :

Select ‘Interrupt 0’ or ‘Interrupt 1’ sub-option from ‘CPU’ menu to simulate INT0 or INT1 respectively. Alternatively, you can click on the I0 or I1 buttons on the toolbar. Please note, that when you do this, the program control will immediately transfer to the vector location of the interrupt (Provided it is enabled by your program).

5.5.8 Simulating serial port input :

Activate the Serial Window using ‘S’ tool on toolbar (or select ‘Serial Watch’ sub-option from view menu.) The Serial Window contains various windows to display mode, baud-rate, output and edit windows to give inputs to serial port. These are described below.Mode/Baud Rate Window: This displays a mode and baud-rate at which the port is operating.Hex Input Section: Many times you need to give hex input to serial port. In that case you may need use this section. This contains the three controls:One small button (with caption 0 or 1.) This button is used to give 9 th bit input to processor. This is required in case of multiprocessor communication mode.

26

Page 27: IDE51

Edit Window: Enter the a hex code to give input to serial port.Accept Hex Input: When you have entered the Hex code and 9 th bit, press this button. When this button is pressed the input you have typed in, goes to processor.Note that all these controls will be disabled if you have not enabled receiver in your software.ASCII Input Window: This window is used to give ASCII input to serial port. Of course you can use Hex input window to do this, but in that case you need to type hex code of the character you want to input. In ASCII Input window, just type the character you want to input, it is automatically sent to serial port of the micro-controller. Please note that debugger will take the last character in this window and send it to serial port. If your typing speed is very fast, you will miss some characters.This window will be disabled if you have not enabled a receiver of 8051 in your program.

5.5.9 Simulating input to peripherals :

To simulate input to peripherals i.e. 8279/8155/8255/8251/8253, right click in IO Watch Window and select Edit from pop up menu. Select the peripheral to which you want to give input. When you do this, you will be prompted to enter the input value for the corresponding peripheral. e.g. if you select 8279, you will be prompted to enter the expected scan-code of the desired key in HEX. Similarly if you select the 8155, you will be prompted to enter the input expected on PA, PB, PC ports of 8155, depending on which of them are input ports.

5.5.10 Modifying the contents of External RAM :

Right click in External RAM Watch Window and Select edit from pop-up menu. A “Modify Memory Contents” dialog box appears as shown in figure 4.

Figure 4This displays the current contents of the memory. Go to the location you want using ‘Page Up’, ‘Page Down’, ‘Change Address’ buttons. Enter the new contents in the corresponding edit window and click OK.

27

Page 28: IDE51

5.5.11 Modifying the contents of Internal RAM :

Rigth click in Internal RAM Watch Window and Select edit from pop-up menu. A “Modify Memory Contents” dialog box appears.This displays the current contents of the memory. Go to the location you want using ‘Page Up’, ‘Page Down’, ‘Change Address’ buttons. Enter the new contents in the corresponding edit window and click OK.

5.5.12 Modifying the value of a C language variable :

Right click in C Variable Watch Window and select Edit from popup menu. Then select the name of the variable from the drop down list and press OK. Then you will get the new window with the current value of that variable, and you may change it to whatever you want. Finally, click OK, so that the typed value is stored in that variable.This option is available, only if you have purchased the WSIM51-C also. Otherwise, this option remains disabled.

5.5.13 Modifying the contents of an SFR :

Double click on the desired SFR from the SFR Watch Window. Then the current contents of that SFR will be displayed, and you may change it to whatever you want. Finally, clock OK, so that the typed value is stored in that SFR.

5.5.14 Modifying the contents of a register :

Double click on any of the register i.e. R0-R7, ACC, PSW, DPTR, P0-P3 and SP, in SFR Watch Window. Then the current contents of that register will be displayed, and you may change it to whatever you want. Finally, press <Enter>, so that the typed value is stored in that register.

28

Page 29: IDE51

6. Language ReferenceThis chapter describes the general syntax rules for the C language as implemented by this compiler. In order to keep your programs portable, we have tried to stick to ANSI standard C as far as possible, however there are some minor variations, limitations and also some extensions. Especially, to take advantage of the specific features of the 8051 micro-controllers, we have introduced some additional keywords (e.g. bit) Please note, that this is NOT an authoritative document describing the C language in general. Many books from reputed publishers are available to learn more about C language. Please also read the appendix “Limitations of the compiler” which lists certain limitations of this C compiler and some known bugs. It is highly recommended that you refer to the said appendix in the user’s manual file, as it contains latest information.

6.1 : Comments :

The character string "/*" marks the beginning of a comment and the string "*/" marks the end of it. e.g.

disp_lcd("Some message") ; /* This is a comment */ /* Comments may be spread over multiple lines */

However nested comments are not allowed. e.g.

/* comment line 1 /* line 2 */ last line */

This will produce an error, because the string "*/" after 'line 2' marks the end of comment, and hence the string "*/" appearing again after 'last line' will generate an error.

The C++ style of comments (//) is also supported. i.e. all stuff followed by “//” up to the end of the line is treated as comment.

29

Page 30: IDE51

e.g.disp_lcd("Some message") ; // This is C++ style comment

6.2 : Identifier :

An identifier is just the name you give to a variable, function, or other user defined objects. An identifier can contain letters (A...Z, a...z) and digits (0...9) as well as the underscore character (_). However an identifier can only start with a letter or an underscore. Case is significant. i.e. var1 is not the same as Var1. The maximum length of an identifier is 20 characters.

6.3 : Keywords :

Following is a list of keywords reserved by the compiler. These can not be used as identifier names.

break case char continue default do double else void float for goto if int interrupt long return short unsigned peripheral asm

30

Page 31: IDE51

struct union sizeof SFR bit BIT

Although double and sizeof are not supported in this version, still these are reserved keyword, because these may be supported in later versions.

6.4 : Data types :

The following table lists all the data types which are supported by this C compiler, their range of possible values, and their size (in bits) :

Type Size (Bits) Rangebit 1 0 or 1unsigned char 8 0 to 255char 8 -128 to 127unsigned int 16 0 to 65535int 16 -32768 to 32767unsigned long int 32 0 to 4294967295long int 32 -2147483648 to 2147483647float 32 3.4E-38 to 3.4E+38

Apart from these basic data types, you can declare one dimensional arrays of any of these types except the bit type. There are some more restrictions on the use of bit data type as follows : You can not declare arrays of bit type variables. bit type variables can not be passed as parameters. A bit type variable must be a global variable. It can not be declared as a local variable

or a parameter. There can be maximum 120 variables of bit type in any program. bit type variables always reside in Internal RAM, regardless of which memory model

you are using. While assigning a constant value to any bit variable, you can assign only one of the

two possible values : 0 or 1.

31

Page 32: IDE51

In expression, you can combine variables of different data types. e.g. you can add an integer variable to a floating point variable. However, the same is not applicable to bit data type. i.e. if one of the operands is a bit type variable, then the other operand also must be another bit type variable (not even a constant of some other type)

Only a certain operations can be performed on bit type variables. See the details below in section 6.6 Operators.

You can not declare a pointer to a bit variable.However, pointers (up to one level) to other data types can be declared.

6.5 : Type Conversions :

In an expression, if the two operands of a binary operator are of different types, then the compiler will attempt to convert one of the operands into the type of the other. The compiler uses some rules to do this as follows :

If either of the operands is of type ‘bit’, then compiler prints an error “type mis-match”, since it can not convert bit type to any other type or vice versa.

Otherwise, if either of the operands is of type ‘float’, then the other operand is converted to float type.

Otherwise, if either of the operands is of type ‘long int’ (or ‘unsigned long int’) then the other operand is converted to the same type.

Otherwise, if either of the operands is of type ‘int’ (or ‘unsigned int’) then the other operand is converted to the same type.

Thus ‘char’ type (or ‘unsigned char’ type) gets the lowest priority.

However, the compiler behaves differently for some operators i.e. += -= *= /= %= &= |= ^= <<= >>=For these operators, the result is to be written back onto the left hand side operand (which must be a variable). Hence, the compiler will ALWAYS convert the right hand side operand into the type of left hand side operand. e.g. if you write “x *= f” where x is of type int and f is of type float, then compiler will generate code to convert the value of ‘f’ into integer and then multiply the value of ‘x’ by it and finally store the result (which will be naturally int type) back into the variable x.

32

Page 33: IDE51

6.6 : Constants :

Integer constants may be written in decimal form (e.g. 123 or 30945) or in hexadecimal form with '0x' prefix (e.g. 0xff). Character constants must be enclosed in single quotation marks. e.g. 'A' or '?'. String constants must be enclosed in double quotation marks. e.g. "This is a string constant". Floating point constants are always considered to be of type float. Also floating point constants must be written with a decimal point, otherwise they may be considered as integer constants. e.g. "123" will be considered as "the integer value 123" whereas "123.0" will be considered as "the floating point value 123".

6.7 : Operators :

Following operators are supported by the compiler :

+ - * / % ++ -- = == ~ ! != < > <= >= & && | || ^ >> << += -= *= /= %= &= |= ^= <<= >>=However, on bit type variables, some of the operators can not be used. Here is the list of operators which can not be used with bit type variables : + - * / % ++ -- >> << += -= *= /= %= <<= >>=

6.8 : Function prototypes :

You may write function prototypes to declare a function. These declarators include information about the function parameters. e.g.

33

Page 34: IDE51

int func1 (char par1, int par2, long int par3) ;

The actual function definition may be written somewhere else as :

int func1 (char par1, int par2, long int par3) { /* write some code here */ } /* this is a valid function definition */

The old style of writing function definitions is NOT supported. e.g. this is not allowed :

int func1 (par1, par2, par3) char par1 ; int par2 ; long int par3 ; { /* some statements here */ } /* this is not a valid function definition */

6.9 : Compiler control lines :

#include directive may be used to include another file. However nesting of include files is not allowed. i.e. if file2 is #included in file1, then there may not be any #include statement in file2. The syntax is :

#include <file_name>

or

#include "file_name"

If the 'file_name' is enclosed in <>, then that file will be looked for in the directory in which C31 is installed. If 'file_name' is enclosed in "", then it will be looked for in the current directory.

34

Page 35: IDE51

#define and #undef directives may be used to define or undefine a macro. A macro may or may not have parameters. e.g.

#define max_output 2048

This statement defines the symbol 'max_output' to the value 2048. i.e. wherever you write the word 'max_output', it will be replaced by 2048 by the pre-processor before compiling. A macro with parameters can be defined as :

#define product(x,y) (x*y)

Here x and y are parameters. While using the macro you can substitute the x and y with anything else. e.g. if you write :

value = product(factor,123.45) ;it will be replaced by

value = factor*123.45 ;

#ifdef , #ifndef , #else and #endif directives may be used for conditional compiling. The syntax is :

#ifdef symbol_name set of statements 1 #else set of statements 2 #endif

If symbol_name is a defined macro name, then the #ifdef expression evaluates to true and the set of statements 1 will be compiled. Otherwise the set of statements 2 will be compiled . The #else and set of statements 2 is optional. The #ifndef expression evaluates to true, if symbol_name is not defined. Rest of the syntax is same as that for #ifdef.

6.10 : Additional features :

35

Page 36: IDE51

6.10.1 : Using Special Function Registers (SFR) :

You can access the SFRs of the micro-controller, by using the SFR declaration. 'SFR' is an additional keyword. It allows you to define a SFR. The syntax is : SFR sfr_name sfr_addr where 'sfr_name' is the name of the SFR you want to define (e.g. TMOD) and 'sfr_addr' is it's address (e.g. 0x89). There is no need to write a semicolon (;) after a SFR declaration. Thus the statement :

SFR TMOD 0x89

defines the SFR 'TMOD' with an address 89 Hex. Once a SFR is declared, you can use it in your C program as if it were a variable of type unsigned char. e.g. you may write TMOD = 0x11 ; This statement will generate code to write the value 11 (Hex) in TMOD. In fact we have already declared most of the SFRs for you in different header files. e.g. the file SFR31.H contains the declarations for all 8031/8051/8751 SFRs. If you include the file SFR31.H in your C program, you can use all 8031 SFRs as variables (of unsigned char type). Similarly there are other header files, which define the SFRs for the corresponding CPUs. We have supplied the files SFR32.H, SFR320.H, SFR535.H, SFR515.H for the CPUs 8032/8052/8752, 80320, 80535, 80515 respectively. If you are using any other derivative CPU of 8031, you can create your own header file for that CPU.

Thus you can use declared SFRs as global variables of unsigned char type. You can use these in any expressions, except that you can not use the & (address of) operator with these variables, because these are not really variables, but are pseudo-variables, and these are not indirectly accessible.

6.10.2 : Assembly language interface :

Parts of a program may be very time critical, e.g. you may like an interrupt service routine to finish in as small time as is possible. For this reason, you may like to write part of the program in assembly language. This is made possible by providing assembly language patch-up facility. You may write part of the program in assembly language in a SEPARATE FILE. When you invoke the compiler, use the /a option to specify the .ASM file name. i.e. include /Aasm_file_name in the command line before the C file name. You may not use ORG statement in assembly language patch file. If you must use, the ORG statement (e.g. to ljmp to ISR), use these at the end of the assembly language file. You can access global variables declared in C

36

Page 37: IDE51

program from assembly language. e.g. if 'var1' is declared as global variable in C program, then you can use the symbol '_var1' as the address of that variable. i.e. you must attach an underscore (_) to the left of the variable name. Please note that all variables reside in external data memory in case of large model. On the contrary, all variables reside in internal RAM in case of small model.

6.10.3 : The asm keyword :

This is an additional keyword, which allows you to insert assembly language statements directly into your C program. This keyword when used, must appear as the first word of a line. Everything following this keyword - up to the end of line - is directly copied into the .ASM output file. Please note that, no syntax checking is done by the compiler on this assembly language statement, it is done later on by the assembler.

6.10.4 : The peripheral keyword :

This is an additional keyword, introduced to specify the address of a standard peripheral. The C31 function library includes some hardware interface functions for some of the commonly used peripherals. In order to use these library functions, the compiler must somehow know the address of the peripheral being used. This keyword allows you to do so. The syntax is as follows :

peripheral periph_name = periph_addr

where periph_name is the name of the standard peripheral (e.g. "LCD") and periph_addr is it's address written as a constant hex number (e.g. "0x4000"). Please note that you must use this statement inside a function. Usually it is advisable to write all peripheral statements, right at the beginning of the function main(). Please note that the peripheral statement must NOT be followed by semicolon. Currently, there are 2 functions in the library - init_lcd() and disp_lcd() which are meant for the peripheral LCD. Similar functions (e.g. init_8255(), out_pa() etc.) will be added later on in the standard library.

6.10.5 : The BIT keyword :

The BIT keyword is an additional (non - ANSI) keyword. It can be used to define pseudo variables of bit type. e.g. suppose you are using bit 0 of P1 for some purpose - say to switch on a motor. Then you might like to assign a symbolic

37

Page 38: IDE51

name to P1.0. Exactly this can be done using the BIT keyword. The syntax for using it is :

BIT identifier_name value

Please note that a BIT statement is NOT followed by a semicolon. The identifier can be any legal identifier name - which is not previously declared. The value must take this forms :

sfr_name.bit_addr

where sfr_name can be the name of any bit accessible SFR of 8031 and bit_addr may be any value between 0 and 7.Here are some examples of correct and incorrect BIT statements :

BIT motor p1.0/* correct */

BIT limit_switch p3.6/* correct */

BIT motor p3/* wrong, because the bit_addr is missing */

BIT something dpl.2/* wring, because “dpl” is not a bit accessible SFR */

Once you have defined a symbol using the BIT keyword, then onwards, you can use it in your program as if it were a variable of “bit” type. e.g. if you have defined “motor” and “limit_switch” as above, you may write :

if (limit_switch) motor = 0 ;else motor = 1 ;

The above two statements are equivalent to checking bit 6 of P3 and accordingly either setting or clearing bit 0 of P1.

6.10.6 : Declaring variables at specific address (in Internal / External RAM) :

This compiler allows the programmer to declare a variable at a specific address. The syntax for doing so is as follows :

38

Page 39: IDE51

var_type @addr var_name ;or var_type @Iaddr var_name ;where ‘var_type’ is any legal data type (except bit) and ‘var_name’ is any legal identifier name and addr is any hexadecimal constant. In the first case, the variable ‘var_name’ is assigned an address = addr in external RAM, and in the later case, the variable ‘var_name’ is assigned an address = addr in internal RAM. Thus in a variable declaration, if the variable type is followed by @ followed by a hexadecimal constant address, then the variable will reside at the specified address in external RAM. On the other hand, if the variable type is followed by @I (there should not be any space between @ and I) followed by a hexadecimal constant address, then the variable will reside at the specified address in internal RAM. This is further illustrated in following example : unsigned char @0x6000 dat_8279 ; /* i.e. &dat_8279 is 0x6000 in external RAM */ unsigned char @0x6001 cmd_8279 ; /* i.e. &cmd_8279 is 0x6001 in external RAM*/ int @I0x2d var1 ; /* i.e. &var1 is 0x2d in Internal RAM */ unsigned char ch ; /* this is ordinary variable. It's address will be decided by the compiler. Also, whether it will reside in internal RAM or external RAM will depend on the memory model used */ void main () { cmd_8279 = ch ; /* an alternative without using @ would be outportb(0x6001,ch) ; */ var1 = dat_8279 ; /* an alternative without using @ would be var1 = inportb(0x6000) ; */ }Thus declaring variables at a specific address results in a great amount of saving in code size and also the clock cycles required. However using ‘outportb’ and ‘inportb’ functions is also perfectly legal.By using this feature, you can declare variables at any location in internal or external RAM. Thus, even if you are using small memory model, still you can forcefully keep some variables in external RAM at any address. Also, even if you are using large memory model, you can forcefully keep some variables in internal RAM at any address.

39

Page 40: IDE51

However, the compiler does NOT check whether the specified address is used by some other variable or temporary variable or stack or registers. Thus, it is the PROGRAMMER’s RESPONSIBILITY to specify a valid address, which is not used for any other purpose.

6.10.7 : Pitfalls in using @ and @I :

Great care must be taken while passing a variable as a parameter to a function. If a program is compiled in small model, then it assumes that all pointers are pointing to some Internal RAM location. On the other hand, if a program is compiled in large model, it assumes that all pointers are pointing to some External RAM location. Thus, if in a small model program, if a variable is forcibly put in some external RAM location, then the address of this variable may not be used in any expression. e.g. suppose the following lines are writtn in a small model program : int @0x4000 j ; do_something(&j) ; /* this may not work ! */This may NOT work, because address of the variable ‘j’ is 0x4000 in External RAM. The same will be passed to the function ‘do_something’. However, since the program is compiled in Small model, it assumes that the given address is in Internal RAM. i.e. the function ‘do_something’ will wrongly think that address of ‘j’ is 0x00 in internal RAM (It will ignore the higher byte of the address - 0x40).Similarly, consider the following lines written in a large model program : char @I0x23 str[5] ; strcpy(str,”XYZ”) ; /* this may not work */This will not work, because base address of the array variable ‘str’ is 0x23 in Internal RAM. The same will be passed to the function ‘strcpy’ as the first parameter (destination address) but, it will assume the destination address to be in External RAM because the program is compiled in large model.These points must be remembered by the programmer, while declaring variables at specific address.

40

Page 41: IDE51

7. C31 Library Functions Reference

List of functions in alphabetical order :

1) abs2) acos3) asin4) atof5) atoi6) atol7) bcd2int8) ceil9) clr_double_baud10) clr_ri11) clr_ti12) cos13) cosh14) delay15) delay_ms16) disable17) disable_all18) disable_ex019) disable_ex120) disable_rx21) disable_ser22) disable_t023) disable_t124) disable_t225) disp_lcd26) dsp8279127) dsp8279228) enable29) enable_all30) enable_ex031) enable_ex132) enable_rx33) enable_ser

41

Page 42: IDE51

34) enable_t035) enable_t136) enable_t237) ex0_edge38) ex0_level39) ex1_edge40) ex1_level41) exp42) floor43) flot2str44) fmod45) frexp46) getbyte47) getch48) getchar49) getchare50) go_idle51) hi_nibb52) init827953) init_lcd54) init_ser55) inportb56) int2bcd57) isalnum58) isalpha59) isascii60) isdigit61) islower62) isspace63) isupper64) isxdigit65) itoa_c3166) kbhit67) labs68) ldexp69) log70) log1071) long2bcd72) lo_nibb73) ltoa_c31

42

Page 43: IDE51

74) memset75) modf76) movmem77) outportb78) peekb79) pokeb80) pow81) powerdown82) printf83) printf284) printf2n85) printfn86) putchar87) puts88) scanf89) sendbyte90) ser_rdy91) set_com_mode92) set_double_baud93) set_hi_ex094) set_hi_ex195) set_hi_ser96) set_hi_t097) set_hi_t198) set_hi_t299) set_lo_ex0100) set_lo_ex1101) set_lo_ser102) set_lo_t0103) set_lo_t1104) set_lo_t2105) set_t0_mode106) set_t1_mode107) set_tcnt108) sin109) sinh110) sprint2n111) sprintf112) sprintf2113) sprintn

43

Page 44: IDE51

114) sqrt115) sscanf116) start_timer0117) start_timer1118) stop_timer0119) stop_timer1120) strcat121) strcmp122) strcpy123) strlen124) strlwr125) strncpy126) strupr127) tan128) tanh129) tolower130) toupper131) ui2a_c31132) ui2bcd

44

Page 45: IDE51

------------------------------------------------------------------

abs

------------------------------------------------------------------Function : Returns the absolute value of an integerSyntax : #include <stdlib.h> int abs(int x) ;Prototype in : math.hRemarks : abs returns the absolute value of an integer argument x.Return value : abs returns an integer in the range of 0 to 32767, with the exception that an argument of 32768 is returned as -32768.See also : labs

------------------------------------------------------------------

acos

------------------------------------------------------------------Function : Returns the arc cosine of the argument.Syntax : #include <math.h> float acos(float x) ;Prototype in : math.hRemarks : This function is NOT included in the library, but it is given in the form of source code. It’s source code can be found in SOURCE\CFILES\MATH.CReturn value : acos returns the arc cosine of x.See also : cos

------------------------------------------------------------------

asin

------------------------------------------------------------------Function : Returns the arc sine of the argument.Syntax : #include <math.h> float asin(float x) ;Prototype in : math.hRemarks : This function is NOT included in the library, but it is given in the form of source code. It’s source code can be found in SOURCE\CFILES\MATH.CReturn value : asin returns the arc sine of x.See also : sin

------------------------------------------------------------------

45

Page 46: IDE51

atof

------------------------------------------------------------------Function : Converts ASCII string to floating point numberSyntax : #include <stdlib.h> float atof(char *str) ;Prototype in : stdlib.hRemarks : atof converts the ASCII string str into a floating point number.Return value : atof returns the converted floating point value. If the string can not be converted, returns 0.See also : atol, atoi

------------------------------------------------------------------

atoi

------------------------------------------------------------------Function : Converts ASCII string to integer numberSyntax : #include <stdlib.h> int atoi(char *str) ;Prototype in : stdlib.hRemarks : atoi converts the ASCII string str into a integer number.Return value : atoi returns the converted integer value. If the string can not be converted, returns 0.See also : atol, atof

------------------------------------------------------------------

atol

------------------------------------------------------------------Function : Converts ASCII string to long integer numberSyntax : #include <stdlib.h> long int atol(char *str) ;Prototype in : stdlib.hRemarks : atol converts the ASCII string str into a long integer number.Return value : atol returns the long integer value. If the string can not be converted, returns 0.See also : atoi, atof

------------------------------------------------------------------

46

Page 47: IDE51

bcd2int

------------------------------------------------------------------Function : Converts BCD string to integer numberSyntax : #include <etc.h> int bcd2int (char str[10], int ndigits) ;Prototype in : etc.hRemarks : bcd2int converts the unpacked BCD string str into an integer number. It considers the first ‘ndigits’ digits of str.Return value : bcd2int returns the integer value.See also : int2bcd

------------------------------------------------------------------

ceil

------------------------------------------------------------------Function : Rounds up.Syntax : #include <math.h> float ceil (float x) ;Prototype in : math.hReturn value : ceil returns the smallest integer greater that or equal to x.See also : floor

------------------------------------------------------------------

clr_double_baud

------------------------------------------------------------------Function : Clears 'double baud rate'Syntax : #include <macros31.h> clr_double_baud() ;Prototype in : macros31.hRemarks : Clears bit 7 of PCON so that baud rate is not doubled.Return value : None.See also : set_double_baud

------------------------------------------------------------------

clr_ri

------------------------------------------------------------------Function : Clears receiver interrupt

47

Page 48: IDE51

Syntax : #include <macros31.h> clr_ri() ;Prototype in : macros31.hRemarks : Clears RI bit in SCON, so that serial port's pending receiver interrupt is cleared.Return value : None.See also : clr_ti

------------------------------------------------------------------

clr_ti

------------------------------------------------------------------Function : Clears transmitter interruptSyntax : #include <macros31.h> clr_ti() ;Prototype in : macros31.hRemarks : Clears TI bit in SCON, so that serial port's pending transmitter interrupt is cleared.Return value : None.See also : clr_ri

------------------------------------------------------------------

cos

------------------------------------------------------------------Function : Returns the arc cosine of the argument.Syntax : #include <math.h> float cos(float x) ;Prototype in : math.hRemarks : This function is NOT included in the library, but it is given in the form of source code. It’s source code can be found in SOURCE\CFILES\MATH.CReturn value : cos returns the cosine of x.See also : acos

------------------------------------------------------------------

cosh

------------------------------------------------------------------Function : Returns the hyperbolic cosine of the argument.

48

Page 49: IDE51

Syntax : #include <math.h> float cosh(float x) ;Prototype in : math.hRemarks : This function is NOT included in the library, but it is given in the form of source code. It’s source code can be found in SOURCE\CFILES\MATH.CReturn value : cosh returns the hyperbolic cosine of x.See also : cos

------------------------------------------------------------------

delay

------------------------------------------------------------------Function : Produces a delaySyntax : #include <standard.h> void delay (int count) ;Prototype in : standard.hRemarks : Produces a certain delay. Since the crystal frequency in the target system is not known, this function passes 'count' number of clock cycles only. Thus if you are using 8031 with 12 MHz crystal, you may say, that this function produces a delay of 'count' micro-seconds where 'count' is the integer parameter you pass to it. However if you are using a different crystal frequency and / or different CPU, it may not be so. The accuracy of this function is plus or minus 50 cycles. i.e. if you call delay function with count parameter = 20000, then it will return after 'n' clock cycles where 'n' will be > 19050 and < 20050.Also please note, that this functions produces a software delay. Thus, if interrupts are enabled, then this function may produce more delay than is expected. Because, if interrupt occurs during this function, then it will take some more time to execute but that time will not be counted by this function. Thus, if interrupts are enabled, the acuracy and repeatability of this function will be poor.Return value : None.

------------------------------------------------------------------

delay_ms

------------------------------------------------------------------Function : Produces a delaySyntax : #include <standard.h> void delay_ms (int count) ;Prototype in : standard.h

49

Page 50: IDE51

Remarks : Produces a certain delay. Since the crystal frequency in the target system is not known, this function passes 'count * 1000' number of clock cycles only. Thus if you are using 8031 with 12 MHz crystal, you may say, that this function produces a delay of 'count' milli-seconds where 'count' is the integer parameter you pass to it. However if you are using a different crystal frequency and / or different CPU, it may not be so. The accuracy of this function is plus or minus 2 cycles. i.e. if you call delay function with count parameter = 20, then it will return after 'n' clock cycles where 'n' will be >= 19998 and <= 20002.Also please note, that this functions produces a software delay. Thus, if interrupts are enabled, then this function may produce more delay than is expected. Because, if interrupt occurs during this function, then it will take some more time to execute but that time will not be counted by this function. Thus, if interrupts are enabled, the acuracy and repeatability of this function will be poor.Return value : None.

------------------------------------------------------------------

disable

------------------------------------------------------------------Function : Disables interruptsSyntax : #include <macros31.h> disable() ;Prototype in : macros31.hRemarks : Clears only bit 7 of IE, so that all interrupts remain disabled.Return value : None.See also : disable_all, enable

------------------------------------------------------------------

disable_all

------------------------------------------------------------------Function : Disables interruptsSyntax : #include <macros31.h> disable_all() ;Prototype in : macros31.hRemarks : Clears all bits of IE so that all interrupts remain disabled. Please note the subtle difference between disable() and disable_all().Return value : None.

50

Page 51: IDE51

See also : disable, enable_all

------------------------------------------------------------------

disable_ex0

------------------------------------------------------------------Function : Disables INT0 external interrupt.Syntax : #include <macros31.h> disable_ex0() ;Prototype in : macros31.hRemarks : Clears bit 0 of IE, so that external interrupt INT0 remains disabled.Return value : None.See also : enable_ex0

------------------------------------------------------------------

disable_ex1

------------------------------------------------------------------Function : Disables INT1 external interrupt.Syntax : #include <macros31.h> disable_ex1() ;Prototype in : macros31.hRemarks : Clears bit 2 of IE, so that external interrupt INT1 remains disabled.Return value : None.See also : enable_ex1

------------------------------------------------------------------

disable_rx

------------------------------------------------------------------Function : Disables receiver of serial portSyntax : #include <macros31.h> disable_rx() ;Prototype in : macros31.hRemarks : Clears bit 4 of SCON so that serial port's receiver remains disabled.Return value : None.See also : enable_rx

51

Page 52: IDE51

------------------------------------------------------------------

disable_ser

------------------------------------------------------------------Function : Disables serial port interrupt.Syntax : #include <macros31.h> disable_ser() ;Prototype in : macros31.hRemarks : Clears bit 4 of IE, so that serial port interrupt remains disabled.Return value : None.See also : enable_ser

------------------------------------------------------------------

disable_t0

------------------------------------------------------------------Function : Disables timer 0 interrupt.Syntax : #include <macros31.h> disable_t0() ;Prototype in : macros31.hRemarks : Clears bit 1 of IE, so that Timer 0 interrupt remains disabled.Return value : None.See also : enable_t0

------------------------------------------------------------------

disable_t1

------------------------------------------------------------------Function : Disables timer 1 interrupt.Syntax : #include <macros31.h> disable_t1() ;Prototype in : macros31.hRemarks : Clears bit 3 of IE, so that Timer 1 interrupt remains disabled.Return value : None.See also : enable_t1

52

Page 53: IDE51

------------------------------------------------------------------

disable_t2

------------------------------------------------------------------Function : Disables timer 2 interrupt.Syntax : #include <macros31.h> disable_t2() ;Prototype in : macros31.hRemarks : Clears bit 5 of IE, so that Timer 2 interrupt remains disabled.Return value : None.See also : enable_t2

------------------------------------------------------------------

disp_lcd

------------------------------------------------------------------Function : Displays a message on LCDSyntax : void disp_lcd(char *src) ;Prototype in : hardware.hRemarks : disp_lcd outputs each character of the string src to LCD module. In effect it displays the string src on LCD. In order to use this library function, you must define the address of LCD somewhere in your program by using the peripheral keyword.Return value : None.See also : init_lcd

------------------------------------------------------------------

dsp82791

------------------------------------------------------------------Function : Displays a string on 7 seg. display using 8279Syntax : #include <hardware.h> dsp82791(char str[8]) ;Prototype in : hardware.hRemarks : This function will output 8 characters from the parameters str to the display RAM of 8279. If you want to use this function, you must declare the address of 8279 using the peripheral keyword. e.g.peripheral 8279 = 0x4000

53

Page 54: IDE51

Return value : None.See also : dsp82792

------------------------------------------------------------------

dsp82792

------------------------------------------------------------------Function : Displays a string on 7 seg. display using 8279Syntax : #include <hardware.h> dsp82792(char str[16]) ;Prototype in : hardware.hRemarks : This function will output 16 characters from the parameters str to the display RAM of 8279. If you want to use this function, you must declare the address of 8279 using the peripheral keyword. e.g.peripheral 8279 = 0x4000Return value : None.See also : dsp82791

------------------------------------------------------------------

enable

------------------------------------------------------------------Function : Enables interruptsSyntax : #include <macros31.h> enable() ;Prototype in : macros31.hRemarks : Sets only bit 7 of IE, so that all interrupts may be enabled.Return value : None.See also : enable_all, disable

------------------------------------------------------------------

enable_all

------------------------------------------------------------------Function : Enables interruptsSyntax : #include <macros31.h> enable_all() ;Prototype in : macros31.h

54

Page 55: IDE51

Remarks : Sets all bits of IE so that all interrupts are enabled. Please note the subtle difference between enable() and enable_all().Return value : None.See also : enable, disable_all

------------------------------------------------------------------

enable_ex0

------------------------------------------------------------------Function : Enables INT0 external interrupt.Syntax : #include <macros31.h> enable_ex0() ;Prototype in : macros31.hRemarks : Sets bit 0 of IE, so that external interrupt INT0 gets enabled.Return value : None.See also : disable_ex0

------------------------------------------------------------------

enable_ex1

------------------------------------------------------------------Function : Enables INT1 external interrupt.Syntax : #include <macros31.h> enable_ex1() ;Prototype in : macros31.hRemarks : Sets bit 2 of IE, so that external interrupt INT1 gets enabled.Return value : None.See also : disable_ex1

------------------------------------------------------------------

enable_rx

------------------------------------------------------------------Function : Enables receiver of serial portSyntax : #include <macros31.h> enable_rx() ;Prototype in : macros31.hRemarks : Sets bit 4 of SCON so that serial port's receiver gets enabled.

55

Page 56: IDE51

Return value : None.See also : disable_rx

------------------------------------------------------------------

enable_ser

------------------------------------------------------------------Function : Enables serial port interrupt.Syntax : #include <macros31.h> enable_ser() ;Prototype in : macros31.hRemarks : Sets bit 4 of IE, so that serial port interrupt gets enabled.Return value : None.See also : disable_ser

------------------------------------------------------------------

enable_t0

------------------------------------------------------------------Function : Enables timer 0 interrupt.Syntax : #include <macros31.h> enable_t0() ;Prototype in : macros31.hRemarks : Sets bit 1 of IE, so that Timer 0 interrupt gets enabled.Return value : None.See also : disable_t0

------------------------------------------------------------------

enable_t1

------------------------------------------------------------------Function : Enables timer 1 interrupt.Syntax : #include <macros31.h> enable_t1() ;Prototype in : macros31.hRemarks : Sets bit 3 of IE, so that Timer 1 interrupt gets enabled.Return value : None.See also : disable_t1

56

Page 57: IDE51

------------------------------------------------------------------

enable_t2

------------------------------------------------------------------Function : Enables timer 2 interrupt.Syntax : #include <macros31.h> enable_t2() ;Prototype in : macros31.hRemarks : Sets bit 5 of IE, so that Timer 2 interrupt gets enabled.Return value : None.See also : disable_t2

------------------------------------------------------------------

ex0_edge

------------------------------------------------------------------Function : Makes INT0 edge sensitive.Syntax : #include <macros31.h> ex0_edge() ;Prototype in : macros31.hRemarks : Sets bit 0 of TCON, so that external interrupt INT0 becomes edge sensitive.Return value : None.See also : ex0_level

------------------------------------------------------------------

ex0_level

------------------------------------------------------------------Function : Makes INT0 level sensitive.Syntax : #include <macros31.h> ex0_level() ;Prototype in : macros31.hRemarks : Clears bit 0 of TCON, so that external interrupt INT0 becomes level sensitive.Return value : None.See also : ex0_edge

57

Page 58: IDE51

------------------------------------------------------------------

ex1_edge

------------------------------------------------------------------Function : Makes INT1 edge sensitive.Syntax : #include <macros31.h> ex1_edge() ;Prototype in : macros31.hRemarks : Sets bit 2 of TCON, so that external interrupt INT1 becomes edge sensitive.Return value : None.See also : ex1_level

------------------------------------------------------------------

ex1_level

------------------------------------------------------------------Function : Makes INT1 level sensitive.Syntax : #include <macros31.h> ex1_level() ;Prototype in : macros31.hRemarks : Clears bit 2 of TCON, so that external interrupt INT1 becomes level sensitive.Return value : None.See also : ex1_edge

------------------------------------------------------------------

exp

------------------------------------------------------------------Function : exponential functionSyntax : #include <math.h> float exp (float x) ;Related Functions : float frexp (float value, int *eptr) ; float ldexp (float value, int exp) ; float log (float x) ; float log10 (float x) ; float pow (float x, float y) ;

58

Page 59: IDE51

float sqrt (float x) ;Prototype in : math.hRemarks : exp calculates the exponential function ex.frexp calculates the mantissa x (a float less than 1) and n (an integer) such that value = x . 2n. frexp stores n in the integer that eptr points to.ldexp calculates value . 2exp.log calculates natural logarithm of x.log10 calculates the base 10 logarithm of x.pow calculates xy.sqrt calculates +x.

Return value : All these functions on success, return the value they calculated.exp returns ex.frexp returns x (< 1) where value = x . 2n. ldexp returns value . 2exp.log returns natural logarithm of x.log10 returns the base 10 logarithm of x.pow returns xy.sqrt returns +x.

------------------------------------------------------------------

floor

------------------------------------------------------------------Function : rounds downSyntax : float floor (float value) ;Prototype in : math.hReturn value : floor finds the largest integer not greater than x. It returns this integer (as a float value).See also : ceil

------------------------------------------------------------------

flot2str

------------------------------------------------------------------Function : Converts floating point number to ASCII string.Syntax : void flot2str (float value, char *dest) ;Prototype in : etc.h

59

Page 60: IDE51

Remarks : flot2str converts a floating point number into ASCII string. The string is copied to dest.Return value : None.

------------------------------------------------------------------

fmod

------------------------------------------------------------------Function : Calculates x modulo y, the remainder of x / y.Syntax : float fmod (float x, float y) ;Related functions : float modf (float x, float *ipart) ;Prototype in : math.hRemarks : fmod calculates x modulo y (the remainder f where x = iy + f for some integer I and 0 <= f < y.modf breaks x into two parts: the integer and the fraction. It stores the integer in ipart and returns the fraction.Return value : fmod returns the remainder f where x = iy + f (as described)modf returns the fractional part of x.

------------------------------------------------------------------

frexp

------------------------------------------------------------------Function : Splits a float number into mantissa and exponent.Syntax : float frexp (float number, int *power) ;Prototype in : math.hRemarks : See exp.

------------------------------------------------------------------

getbyte

------------------------------------------------------------------Function : Reads a byte from the serial port.Syntax : #include <standard.h> int getbyte() ;Prototype in : standard.hRemarks : Waits for some time or until a byte is available from the on-chip serial port of the 8031.Return value : If a byte was available, returns the received byte. Otherwise returns -1.

60

Page 61: IDE51

See also : ser_rdy, sendbyte

------------------------------------------------------------------

getch

------------------------------------------------------------------Function : Reads a byte from the 8279 based keyboard.Syntax : #include <hardware.h> int getch() ;Prototype in : hardware.hRemarks : Waits till a byte is available from the keyboard which is connected to 8279. When a key is pressed, reads it’s scancode from 8279. If you want to use this function, you must declare the address of 8279 using the peripheral keyword. e.g.peripheral 8279 = 0x4000Return value : Returns the scancode read from 8279.See also : kbhit

------------------------------------------------------------------

getchar

------------------------------------------------------------------Function : Reads a character from standard input device.Syntax : #include <stdio.h> char getchar () ;Prototype in : stdio.hRemarks : Waits till a character is available from the standard input device (which is on-chip serial port of 8051). When a character is available, reads it. This function is called by scanf function to get input.Return value : Returns the character read from standard input device.See also : scanf, getchare

------------------------------------------------------------------

getchare

------------------------------------------------------------------Function : Reads a character from standard input device.Syntax : #include <stdio.h> char getchare () ;Prototype in : stdio.h

61

Page 62: IDE51

Remarks : Waits till a character is available from the standard input device (which is on-chip serial port of 8051). When a character is available, reads it and also echoes it back to the standard output device (which is again on-chip serial port of 8051, unless the user redirects it by writing his own putchar function).Return value : Returns the character read from standard input device.See also : scanf, getchar

------------------------------------------------------------------

go_idle

------------------------------------------------------------------Function : Puts the CPU in idle mode.Syntax : #include <macros31.h> go_idle() ;Prototype in : macros31.hRemarks : Sets bit 0 of PCON, so that the CPU goes to idle mode in which it consumes less power.Return value : None.See also : powerdown

------------------------------------------------------------------

hi_nibb

------------------------------------------------------------------Function : Separates the high order nibbleSyntax : unsigned char hi_nibb (unsigned char ch) ;Prototype in : standard.hReturn value : Returns the high order nibble of ch.See also : lo_nibb

------------------------------------------------------------------

init8279

------------------------------------------------------------------Function : Initializes the 8279Syntax : void init8279 (int entry_mode, int no_of_chars, int scan_mode) ;Prototype in : hardware.hRemarks : Initializes the 8279 (Keyboard display controller). Possible values of entry_mode are LEFT_ENTRY or RIGHT_ENTRY. Possible values for no_of_chars are DISPLAY_8_CHAR or DISPLAY_16_CHAR. Possible values of scan_mode are ENCODED_SCAN or DECODED_SCAN. These symbolic constants

62

Page 63: IDE51

are also defined in hardware.h If you want to use this function, you must declare the address of 8279 using the peripheral keyword. e.g.peripheral 8279 = 0x4000Return value : NoneSee also : kbhit, getch, dsp82791, dsp82792------------------------------------------------------------------

init_lcd

------------------------------------------------------------------Function : Initializes the LCDSyntax : void init_lcd() ;Prototype in : hardware.hRemarks : init_lcd outputs initialization commands to LCD module. In effect it initializes the LCD module. In order to use this library function, you must define the address of LCD somewhere in your program by using the peripheral keyword.Return value : None.See also : disp_lcd

------------------------------------------------------------------

init_ser

------------------------------------------------------------------Function : Initializes the on-chip serial portSyntax : void init_lcd() ;Prototype in : standard.hRemarks : It initializes the serial port for a certain mode. If you are going to use printf function, you must first initialize the serial port. Calling this init_ser function is just one method of initializing the serial port.This function puts the Timer1 in 8 bit auto-reload mode, and it puts the serial port in mode 1 with receiver enabled. It sets the baudrate at 2400 assuming 12 Mhz crystal.The source code of this function is available to the users.Return value : None.See also : printf

------------------------------------------------------------------

inportb

------------------------------------------------------------------Function : Reads a byte from a hardware port.Syntax : unsigned char inportb(int portid) ;

63

Page 64: IDE51

Prototype in : standard.hRemarks : inportb reads a byte from a location in data memory whose address is specified by portid.Return value : inportb returns the value read.See also : peekb, outportb

------------------------------------------------------------------

int2bcd

------------------------------------------------------------------Function : Converts an integer number into a BCD string.Syntax : void int2bcd (int value, char *dest, int ndigits) ;Prototype in : standard.hRemarks : Converts value into an unpacked BCD string which is ‘ndigits’ digits long and places the string in ‘dest’Return value : NoneSee also : bcd2int

-----------------------------------------------------------------

isalnum

-----------------------------------------------------------------Function : Character classification functionSyntax : #include <ctype.h> bit isalnum (char c) ;Prototype in : ctype.hRemarks : isalnum is a function that classifies ASCII-coded character values. It returns 1 for true and 0 for false. Return value : isalnum returns 1 if c is a letter (A-Z or a-z) or a digit (0-9).

------------------------------------------------------------------

isalpha

------------------------------------------------------------------Function : Character classification functionSyntax : #include <ctype.h> bit isalpha (char c) ;Prototype in : ctype.hRemarks : isalpha is a function that classifies ASCII-coded integer values. It returns 1 for true and 0 for false.Return value : isalpha returns 1 if c is a letter (A-Z or a-z).

64

Page 65: IDE51

-----------------------------------------------------------------

isascii

-----------------------------------------------------------------Function : Character classification functionSyntax : #include <ctype.h> bit isascii (char c) ;Prototype in : ctype.hRemarks : isascii is a function that classifies ASCII-coded character values. It returns 1 for true and 0 for false.Return value : isascii returns 1 if c is in the range 32-127 (0x20-0x7F).

------------------------------------------------------------------

isdigit

------------------------------------------------------------------Function : Character classification functionSyntax : #include <ctype.h> bit isdigit(char c) ;Prototype in : ctype.hRemarks : isdigit is a function that classifies ASCII- coded character values. It returns 1 for true and 0 for false.Return value : isdigit returns 1 if c is a digit ('0'- 9').

-----------------------------------------------------------------

islower

-----------------------------------------------------------------Function : Character classification functionSyntax : #include <ctype.h> bit islower (char c) ;Prototype in : ctype.hRemarks : islower is a function that classifies ASCII-coded character values. It returns 1 for true and 0 for false.Return value : islower returns 1 if c is a lower-case letter (‘a’-‘z’).

------------------------------------------------------------------

isspace

------------------------------------------------------------------

65

Page 66: IDE51

Function : Character classification functionSyntax : #include <ctype.h> bit isspace (char c) ;Prototype in : ctype.hRemarks : isspace is a function that classifies ASCII-coded character values. It returns 1 for true and 0 for false.Return value : isspace returns 1 if c is a space, tab, carriage return, or newline.

------------------------------------------------------------------

isupper

--------------------------------------------------------------------Function : Character classification functionSyntax : #include <ctype.h> bit isupper (char c) ;Prototype in : ctype.hRemarks : isupper is a function that classifies ASCII-coded character values. It returns 1 for true and 0 for false.Return value : isupper returns 1 if c is an uppercase letter (‘A’-‘Z’).

------------------------------------------------------------------

isxdigit

------------------------------------------------------------------Function : Character classification functionSyntax : #include <ctype.h> bit isxdigit (char c) ;Prototype in : ctype.hRemarks : isxdigit is a function that classifies ASCII-coded character values. It returns 1 for true and 0 for false.Return value : isxdigit returns 1 if c is a hexadecimal digit (‘0’- 9’,‘A’-‘F’,‘a’-‘f’).

------------------------------------------------------------------

itoa_c31

------------------------------------------------------------------Function : Converts an integer into ASCII stringSyntax : #include <stdlib.h> void itoa_c31(int val, char *dest, int ndigits) ;Prototype in : stdlib.h

66

Page 67: IDE51

Remarks : itoa_c31 converts an integer number 'val' into ASCII string 'dest' containing exactly ndigits digits.Return value : None.See also : ltoa_c31

------------------------------------------------------------------

kbhit

------------------------------------------------------------------Function : Checks for a keySyntax : #include <hardware.h> int kbhit () ;Prototype in : hardware.hRemarks : kbhit checks whether there are any entries in the 8279 FIFO. It returns the number of entries in the FIFO. If it returns 0, it means that no keys are pending. If you want to use this function, you must declare the address of 8279 using the peripheral keyword.Return value : Returns the number of FIFO entries.See also : getch

------------------------------------------------------------------

labs

------------------------------------------------------------------Function : Gives long absolute value.Syntax : #include <stdlib.h> long int labs(long int x) ;Prototype in : stdlib.hRemarks : labs computes the absolute value of the parameter x.Return value : On success, labs returns the absolute value of x. There is no error return.See also : abs

------------------------------------------------------------------

ldexp

------------------------------------------------------------------

67

Page 68: IDE51

Function : Calculates value * 2power.Syntax : float ldexp (float value, int power) ;Prototype in : math.hRemarks : See exp.

------------------------------------------------------------------

log

------------------------------------------------------------------Function : Calculates natural logarithm of value.Syntax : float log (float value) ;Prototype in : math.hRemarks : See exp.

------------------------------------------------------------------

log10

------------------------------------------------------------------Function : Calculates base 10 logarithm of value.Syntax : float log10 (float value) ;Prototype in : math.hRemarks : See exp.

------------------------------------------------------------------

long2bcd

------------------------------------------------------------------Function : Converts a long int number into BCD string.Syntax : #include <stdlib.h> void long2bcd (long int value, char *dest, int ndigits) ;Prototype in : stdlib.hRemarks : long2bcd converts value into an unpacked BCD string having ‘ndigits’ digits. It puts the BCD string in ‘dest’.Return value : NoneSee also : int2bcd

------------------------------------------------------------------

68

Page 69: IDE51

lo_nibb

------------------------------------------------------------------Function : Separates the low order nibbleSyntax : unsigned char lo_nibb (unsigned char ch) ;Prototype in : standard.hReturn value : Returns the low order nibble of ch.See also : hi_nibb------------------------------------------------------------------

ltoa_c31

------------------------------------------------------------------Function : Converts a long integer into ASCII stringSyntax : #include <stdlib.h> void ltoa_c31(long int val, char *dest, int ndigits) ;Prototype in : stdlib.hRemarks : ltoa_c31 converts a long integer number 'val' into ASCII string 'dest' containing exactly ‘ndigits’ digits.Return value : None.See also : itoa_c31

------------------------------------------------------------------

memset

------------------------------------------------------------------Function : Sets n bytes a block of memory to byte c.Syntax : #include <mem.h> void *memset (void *s, int c, int n) ;Prototype in : mem.h, string.hRemarks : memset sets the first n bytes of the array s to the character c.Return value : memset returns s.

------------------------------------------------------------------

modf

------------------------------------------------------------------Function : Splits into mantissa and exponent.Syntax : float modf (float x, float *ipart) ;Prototype in : math.hRemarks : See fmod.

69

Page 70: IDE51

------------------------------------------------------------------

movmem

------------------------------------------------------------------Function : Copies a block of length bytes.Syntax : #include <mem.h> void movmem (void *src, void *dest, unsigned length) ;Prototype in : mem.hRemarks : movmem copies a block of length bytes from src to dest.Return value : None.

------------------------------------------------------------------

outportb

------------------------------------------------------------------Function : Outputs a byte to a hardware port.Syntax : void outportb (int portid, unsigned int value) ;Prototype in : standard.hRemarks : outportb is a function that writes the byte given by value to the location in data memory whose address is specified by portid.Return value : None.See also : inportb, pokeb

------------------------------------------------------------------

peekb

------------------------------------------------------------------Function : Returns a byte of memory.Syntax : char peekb (unsigned addr) ;Prototype in : standard.hRemarks : peekb returns the byte at the location in program memory whose address is specified by addr. Please note the difference between inportb and peekb functions. inportb reads from data memory whereas peekb reads from program memory.Return value : peekb returns the value read.See also : pokeb, inportb

------------------------------------------------------------------

pokeb

------------------------------------------------------------------

70

Page 71: IDE51

Function : Writes a byte to a memory locationSyntax : void pokeb(int addr, unsigned int value) ;Prototype in : standard.hRemarks : pokeb is a function that writes the byte given by value to the location in data memory whose address is specified by addr. Actually the functions outportb and pokeb are exactly equivalent.Return value : None.See also : peekb, outportb

------------------------------------------------------------------

pow

------------------------------------------------------------------Function : Computes x to the power of y.Syntax : #include <math.h> float pow (float x, float y) ;Prototype in : math.hRemarks : See exp.

------------------------------------------------------------------

powerdown

------------------------------------------------------------------Function : Puts the CPU in powerdown mode.Syntax : #include <macros31.h> powerdown() ;Prototype in : macros31.hRemarks : Sets bit 1 of PCON, so that the CPU goes to powerdown mode in which it consumes much less power.Return value : None.See also : go_idle

------------------------------------------------------------------

printf

printf2

printf2n

printfn

------------------------------------------------------------------

71

Page 72: IDE51

Function : Sends formatted output to the standard output deviceSyntax : int printf(char *format, ...) ;Related Functions : int sprintf (char *dest, char *format, ...) ; int sprintf2 (char *dest, char *format, ...) ; int sprintn (char *dest, char *format, ...) ; int sprint2n (char *dest, char *format, ...) ;Prototype in : stdio.hRemarks : The 4 printf* functions are slight variations of the printf function. Hence, whatever we say about printf function, the same is also applicable to printf2, printf2n and printfn functions unless otherwise specified.The printf function sends formatted output to the standard output device (which is the 8051’s on-chip serial port in case of this compiler). The sprint* functions are same as print* functions, except, they send the output to the argument dest instead of to the standard output device. The parameter format specifies how the output is to be formatted. This parameter is mandatory. After that, there may be a variable number of parameters.Format specifications have the following form : % [width] [.prec] [l/b] typewhere [flags] is an optional sequence of flag characters [width] is an optional width specifier [.prec] is an optional precision specifier [l/b] is an optional input size modifier type is the conversion type characterHere is a list of conversion type characters, the type of input argument accepted by each, and in what format the output will appear (assuming no flag characters, width specifiers, precision specifiers, or input size modifiers were included in the format specification). The effect of optional characters and modifiers is described later.

Type Character

Input Argument Format of output

d integer(int / unsigned int or long int / unsigned long int)

signed decimal integer

i integer(int / unsigned int or long int / unsigned long

signed decimal integer

72

Page 73: IDE51

int)u integer(int /

unsigned int or long int / unsigned long int)

unsigned decimal integer

f floating point (float) signed value in the form dddd.dddc character (char) single characters string pointer outputs characters until a null terminator is

found% none the ‘%’ character is printed

The optional flag character - can be used to get left justified output. If this is not specified, the output is right justified.

How the width specifier affects the output :

Width Specifier

How output width is affected

n n characters are always printed. If the output value has less than n characters, the output is padded with blank. If the output value has more than n characters, then it is truncated (not rounded) to first n characters only.

0n n characters are always printed. If the output value has less than n characters, the output is padded with zero. If the output value has more than n characters, then it is truncated (not rounded) to first n characters only.

However, please note that in this implementation of the compiler, the maximum allowed value of the width specifier is 10.How the precision specifier affects the output : The precision specifier affects the output of only floating point values. It determines, how many digits will be printed after the decimal point. If the precision is not specified at all, then a floating point value will be printed with 3 digits after the decimal point. If the precision is specified as .n then n digits

will be printed after the decimal point. If the output value has more than n digits after the decimal point, then the output will be truncated (NOT rounded). If it has less than n digits, then the output is padded with 0. However, please note that in this implementation of the compiler, the maximum allowed value of the precision specifier is 6.

73

Page 74: IDE51

The optional input size modifier – l or b – applies only if the type character is d or i or u. When input size modifier is not used, these type characters need a 2 byte argument and it is interpreted as signed or unsigned integer. If input size modifier l is specified (as in “%ld” or “%lu”) then a 4 byte argument (long int or unsigned long int) is needed. On the other hand, if input size modifier b is used (as in “%bd” or “%bu”) then single byte (char or unsigned char) argument is needed.

In this implementation of the compiler, the on-chip serial port of 8051 is considered as the standard output device. However, the user can change this with little effort. The printf function actually calls the function putchar to output each character. The source code of the putchar function is available to the users. If you want the standard output device to be something else (say LCD), you simply need to rewrite the putchar function. If you have written a function named as putchar somewhere in your C program, then the compiler will not link the default putchar function from the library. Then if you call printf function, it eventually calls putchar to send the output. In this case your putchar function will be called rather than the default putchar function (which is there in the library).

The printf function can convert integer numbers as well as floating point numbers into ASCII strings. If you are not using any floating point numbers, then you may call the function printf2 instead of printf. printf2 is same as printf, except, it does not allow the f type specifier. Thus printf2 results in somewhat smaller code size. Thus, if you are not using floating point numbers, you can use printf2 instead of printf to save code space.

The printf function needs quite some RAM for storing intermediate data. It uses the stack space to store these intermediate data. Thus a call to printf function will result in use of considerable stack space. If you are particularly short on memory, this may sometimes result in stack overflow and consequently mis-beheaviour of your program. So we have created one more variation of printf function : printfn. This function is same as printf, except, it uses 8 internal RAM locations (27H through 2EH) for storing some of the intermediate data. i.e. it uses lesser stack space (8 bytes less). However, if you have defined any variables in this RAM area (27H through 2EH) then you can not use printfn function, as it will damage the values of your variables. The RAM space 20H through 2Eh is normally used for bit type variables. Thus, even if you have declared as many as 56 bit type variables, then also internal RAM locations 27H thr. 2EH will be free, so you can use printfn function. However, if you have defined more

74

Page 75: IDE51

than 56 bit type variables and / or you have forefully placed some other variable in the RAM area 27H thr. 2EH, then you can not use printfn function.

The printf2n function is same as printfn function without support for floating point numbers. Thus using printf2n instead of printfn results in smaller code size.

The differences between the four functions can be summarized as below :Function Destroies locations 27H - 2EH ? Floating point numbers allowed ?printf No Yesprintf2 No Noprintfn Yes Yesprintf2n Yes No

NOTE : In any one program, you can call only one of these four functions. i.e. in one program, if you have called printf at least once, then you can not call any of printf2, printfn or printf2n function from the SAME program. Thus, for each application, you may decide, which of these four functions is suitable. Then, the same function can be called repeatedly any number of times.

Return value : All these four functions return the number of bytes sent to the standard output device.See also : sprintf, putchar. Also, please look at the file PRINT.C in EXAMPLES\PRINT directory.

------------------------------------------------------------------

putchar

------------------------------------------------------------------Function : Sends a byte to the standard output device (on-chip serial port.)Syntax : #include <stdio.h> char putchar (char ch) ;Prototype in : stdio.hRemarks : Sends the character ‘ch’ to standard output device - i.e. on-chip serial port of 8051 (i.e. SBUF). It also waits till the transmission is complete. That is, it will wait till the TI bit in SCON is set. Before returning, it clears the TI bit, so that you are ready to send the next byte.Please note, that as per conventions, it checks whether the character being sent is Line Feed character (0x0a). If so, it also sends the Carriage Return character (0x0d) to the standard output device.

75

Page 76: IDE51

The functions printf and puts call this function to send out each character. The source code of this function (in assembly language) is available to the users. The users may change this function as per their requirement, so as to direct the standard output to something else rather than the serial port.Return value : Returns the character ‘ch’.See also : printf, puts

------------------------------------------------------------------

puts

------------------------------------------------------------------Function : Sends a character string to standard output deviceSyntax : #include <stdio.h> char puts (char arr[]) ;Prototype in : stdio.hRemarks : Sends each character of the string ‘arr’ to standard output device (i.e. normally the on-chip serial port), until a null terminator character is found, (the null character is NOT output), and then output a newline character. Please note, that it calls the putchar function to output each character. Thus, if putchar function is re-written by the user to send the output to some other device, the output of puts will also go to the new device.Return value : Returns the last character written.See also : putchar

------------------------------------------------------------------

scanf

------------------------------------------------------------------Function : Performs formatted input.Syntax : #include <stdio.h> int scanf (char *format, ...) ;Related functions : int sscanf (char *src, char *format, ...) ;Prototype in : stdio.hRemarks : The scanf family of functions scan input fields, one character at a time, and convert them according to a given format. They accept a format string (i.e. the format parameter) that determines how the input fields are to be interpreted. They apply the format string to a variable number of input fields in order to format the input. Then they store the formatted input in the addresses given in arguments after the format.

76

Page 77: IDE51

When it encounters it’s first format specification in the format string, it scans and converts the first input field according to that specification, then stores the result in the location given by the first address argument; it then scans, converts and stores the second input field; then the third etc.The scanf function gets input from the standard input device i.e. normally the on-chip serial port. It actually calls the getchar function to read each character from the standard input device. If you write your own getchar function to read one character from some other device, then scanf takes all it’s input from this new device.The sscanf function reads the input from the first argument src.The format string :The format string, present in both scanf and sscanf, controls how each function will scan, convert and store it’s input fields. There must be enough address arguments for the given format specifications; if not the results are unpredictable and likely to disturb the entire system. Excess address arguments (more than required by the format) are ignored.The format string contains format specifications which direct it to read and convert characters from the input field into specific types of values and store them in the locations given by the address arguments. The format specifications have the following form :

% [l] type_character

Each format specification begins with a percent character (%). After the percent character, there may be an optional type modifier character (i.e. ‘l’) followed by mandatory type_character. The following table lists valid type characters, the type of input expected by each, and in what format the input will be stored :

Type Character

Input Type of argument

d decimal integer pointer to int (int *arg)i decimal integer pointer to int (int *arg)u decimal integer pointer to int (int *arg)f floating point (float) pointer to floatc character (char) pointer to characters character string pointer to character string% % character No conversion is done, the ‘%’ character is

stored

77

Page 78: IDE51

The optional type modifier character l can be used with d, I or u type characters; when used, it forces the scanf function to convert the input field into long int value instead of int; so the corresponding address argument must be pointer to long int.

Return value : Returns the last character written.See also : putchar

------------------------------------------------------------------

sendbyte

------------------------------------------------------------------Function : Sends a byte to the on-chip serial port.Syntax : #include <standard.h> void sendbyte (unsigned char ch) ;Prototype in : standard.hRemarks : Sends the character ‘ch’ to on-chip serial port (i.e. SBUF). It also waits till the transmission is complete. That is, it will wait till the TI bit in SCON is set. Before returning, it clears the TI bit, so that you are ready to send the next byte.Return value : None.See also : getbyte, ser_rdy

------------------------------------------------------------------

ser_rdy

------------------------------------------------------------------Function : Checks the on-chip serial port status.Syntax : #include <standard.h> int ser_rdy () ;Prototype in : standard.hRemarks : Checks whether a character is received on the on-chip serial port.Return value : If a character is received, returns non-zero (but the character remains in SBUF, you may use ‘getbyte’ to read it). Otherwise returns zero.See also : getbyte

------------------------------------------------------------------

set_com_mode

------------------------------------------------------------------Function : Sets the mode of serial port

78

Page 79: IDE51

Syntax : #include <macros31.h> set_com_mode(mode,sm2,ren) ;Prototype in : macros31.hRemarks : This macro writes sets and/or clears appropriate bits in SCON. In effect, it sets the serial port in the given 'mode', it sets the SM2 bit to 'sm2', and if 'ren' is 1, it enables the receiver.Return value : None.

------------------------------------------------------------------

set_double_baud

------------------------------------------------------------------Function : Sets 'double baud rate'Syntax : #include <macros31.h> set_double_baud() ;Prototype in : macros31.hRemarks : Sets bit 7 of PCON so that baud rate is doubled.Return value : None.See also : clr_double_baud

------------------------------------------------------------------

set_hi_ex0

------------------------------------------------------------------Function : Sets high priority for INT0Syntax : #include <macros31.h> set_hi_ex0() ;Prototype in : macros31.hRemarks : Sets bit 0 of IP so that external interrupt INT0 is gets a high priority.Return value : None.See also : set_lo_ex0

------------------------------------------------------------------

set_hi_ex1

------------------------------------------------------------------Function : Sets high priority for INT1Syntax : #include <macros31.h>

79

Page 80: IDE51

set_hi_ex1() ;Prototype in : macros31.hRemarks : Sets bit 2 of IP so that external interrupt INT1 is gets a high priority.Return value : None.See also : set_lo_ex1

------------------------------------------------------------------

set_hi_ser

------------------------------------------------------------------Function : Sets high priority for serial port interruptSyntax : #include <macros31.h> set_hi_ser() ;Prototype in : macros31.hRemarks : Sets bit 4 of IP so that serial port interrupt gets a high priority.Return value : None.See also : set_lo_ser

------------------------------------------------------------------

set_hi_t0

------------------------------------------------------------------Function : Sets high priority for timer 0 interruptSyntax : #include <macros31.h> set_hi_t0() ;Prototype in : macros31.hRemarks : Sets bit 1 of IP so that timer 0 interrupt gets a high priority.Return value : None.See also : set_lo_t0

------------------------------------------------------------------

set_hi_t1

------------------------------------------------------------------Function : Sets high priority for timer 1 interruptSyntax : #include <macros31.h> set_hi_t1() ;

80

Page 81: IDE51

Prototype in : macros31.hRemarks : Sets bit 3 of IP so that timer 1 interrupt gets a high priority.Return value : None.See also : set_lo_t1

------------------------------------------------------------------

set_hi_t2

------------------------------------------------------------------Function : Sets high priority for timer 2 interruptSyntax : #include <macros31.h> set_hi_t2() ;Prototype in : macros31.hRemarks : Sets bit 5 of IP so that timer 2 interrupt gets a high priority.Return value : None.See also : set_lo_t2

------------------------------------------------------------------

set_lo_ex0

------------------------------------------------------------------Function : Sets low priority for INT0Syntax : #include <macros31.h> set_lo_ex0() ;Prototype in : macros31.hRemarks : Clears bit 0 of IP so that external interrupt INT0 is gets a low priority.Return value : None.See also : set_hi_ex0

------------------------------------------------------------------

set_lo_ex1

------------------------------------------------------------------Function : Sets low priority for INT1Syntax : #include <macros31.h> set_lo_ex1() ;Prototype in : macros31.h

81

Page 82: IDE51

Remarks : Clears bit 2 of IP so that external interrupt INT1 is gets a low priority.Return value : None.See also : set_hi_ex1

------------------------------------------------------------------

set_lo_ser

------------------------------------------------------------------Function : Sets low priority for serial port interruptSyntax : #include <macros31.h> set_lo_ser() ;Prototype in : macros31.hRemarks : Clears bit 4 of IP so that serial port interrupt gets a low priority.Return value : None.See also : set_hi_ser

------------------------------------------------------------------

set_lo_t0

------------------------------------------------------------------Function : Sets low priority for timer 0 interruptSyntax : #include <macros31.h> set_lo_t0() ;Prototype in : macros31.hRemarks : Clears bit 1 of IP so that timer 0 interrupt gets a low priority.Return value : None.See also : set_hi_t0

------------------------------------------------------------------

set_lo_t1

------------------------------------------------------------------Function : Sets low priority for timer 1 interruptSyntax : #include <macros31.h> set_lo_t1() ;Prototype in : macros31.hRemarks : Clears bit 3 of IP so that timer 1 interrupt gets a low priority.

82

Page 83: IDE51

Return value : None.See also : set_hi_t1

------------------------------------------------------------------

set_lo_t2

------------------------------------------------------------------Function : Sets low priority for timer 2 interruptSyntax : #include <macros31.h> set_lo_t2() ;Prototype in : macros31.hRemarks : Clears bit 5 of IP so that timer 2 interrupt gets a low priority.Return value : None.See also : set_hi_t2

------------------------------------------------------------------

set_t0_mode

------------------------------------------------------------------Function : Sets timer 0 modeSyntax : #include <macros31.h> set_t0_mode(gate,c_t,mode) ;Prototype in : macros31.hRemarks : This function writes the appropriate byte in TMOD. If 'gate' is 1, then the GATE bit in TMOD (for Timer 0) will be set, otherwise it will be cleared. If 'c_t' is 1, then Timer 0 will be used as a counter, otherwise it will be used as a timer. 'mode' can be either 0,1,2 or 3.Return value : None.See also : set_t1_mode------------------------------------------------------------------

set_t1_mode

------------------------------------------------------------------Function : Sets timer 1 modeSyntax : #include <macros31.h> set_t1_mode(gate,c_t,mode) ;Prototype in : macros31.hRemarks : This function writes the appropriate byte in TMOD. If 'gate' is 1, then the GATE bit in TMOD (for Timer 1) will be set, otherwise it will be

83

Page 84: IDE51

cleared. If 'c_t' is 1, then Timer 1 will be used as a counter, otherwise it will be used as a timer. 'mode' can be either 0,1,or 2.Return value : None.See also : set_t0_mode

------------------------------------------------------------------

set_tcnt

------------------------------------------------------------------Function : Sets timer 0 or 1 count.Syntax : void set_tcnt(int tnum, unsigned int count) ;Prototype in : standard.hRemarks : This function sets the count (high and low) for timer 0 or 1. 'tnum' can be 0 or 1. 'count' is the count which will be loaded in either th0 and tl0 or th1 and tl1.Return value : None.

------------------------------------------------------------------

sin

------------------------------------------------------------------Function : Returns the sine of the argument.Syntax : #include <math.h> float sin (float x) ;Prototype in : math.hRemarks : This function is NOT included in the library, but it is given in the form of source code. It’s source code can be found in SOURCE\CFILES\MATH.CReturn value : sin returns the sine of x.See also : cos, asin

------------------------------------------------------------------

sinh

------------------------------------------------------------------Function : Returns the hyperbolic sine of the argument.Syntax : #include <math.h> float sinh (float x) ;Prototype in : math.hRemarks : This function is NOT included in the library, but it is given in the form of source code. It’s source code can be found in SOURCE\CFILES\MATH.C

84

Page 85: IDE51

Return value : sinh returns the hyperbolic sine of x.See also : sin

------------------------------------------------------------------

sprint2n

sprintf

sprintf2

sprintn

------------------------------------------------------------------Function : Sends formatted output to the destination stringSyntax : int sprintf(char *dest, char *format, ...) ;Prototype in : stdio.hRemarks : These 4 functions are slight variations of the sprintf function. Hence, whatever we say about sprintf function, the same is also applicable to sprintf2, sprint2n and sprintn functions unless otherwise specified.The sprintf function sends formatted output to the destination string (dest parameter). The second parameter format specifies how the output is to be formatted. The first and second parameters are mandatory.These sprintf family of functions beheave almost the same as printf family functions, except the difference in output location. The output of printf goes to standard output device (which is generally the on-chip serial port), but the output of sprintf goes into a character string pointed by the first parameter ‘dest’.For details about the format parameter, please see the description of printf.

The sprintf function needs quite some RAM for storing intermediate data. It uses the stack space to store these intermediate data. Thus a call to sprintf function will result in use of considerable stack space. If you are particularly short on memory, this may sometimes result in stack overflow and consequently mis-beheaviour of your program. So we have created one more variation of sprintf function : sprintn. This function is same as sprintf, except, it uses 10 internal RAM locations (25H through 2EH) for storing some of the intermediate data. i.e. it uses lesser stack space (10 bytes less). However, if you have defined any variables in this RAM area (25H through 2EH) then you can not use sprintn function, as it will damage the values of your variables. The RAM space 20H through 2Eh is normally used for bit type variables. Thus, even if you have declared as many as 40 bit type variables, then also internal RAM locations 25H thr. 2EH will be free, so you can use sprintn function. However, if you have defined more

85

Page 86: IDE51

than 40 bit type variables and / or you have forefully placed some other variable in the RAM area 25H thr. 2EH, then you can not use sprintn function.

The sprint2n function is same as sprintn function without support for floating point numbers. Thus using sprint2n instead of sprintn results in smaller code size.

The differences between the four functions can be summarized as below :Function Destroies locations 25H - 2EH ? Floating point numbers allowed ?sprintf No Yessprintf2 No Nosprintn Yes Yessprint2n Yes No

NOTE : In any one program, you can call only one of these four functions. i.e. in one program, if you have called sprintf at least once, then you can not call any of sprintf2, sprintn or sprint2n function from the SAME program. Thus, for each application, you may decide, which of these four functions is suitable. Then, the same function can be called repeatedly any number of times.

Return value : All these four functions return the number of bytes sent to the standard output device.See also : printf. Also, please look at the file PRINT.C in EXAMPLES\PRINT directory.

------------------------------------------------------------------

sqrt

------------------------------------------------------------------Function : Returns the square root of the argument.Syntax : #include <math.h> float sqrt (float x) ;Prototype in : math.hRemarks : This function is NOT included in the library, but it is given in the form of source code. It’s source code can be found in SOURCE\CFILES\MATH.CReturn value : sqrt returns the square root of x.

------------------------------------------------------------------

sscanf

------------------------------------------------------------------

86

Page 87: IDE51

Function : Reads formatted input.Syntax : #include <stdio.h> int sscanf (char *dest, char format, ...) ;Prototype in : stdio.hRemarks : See scanf.

------------------------------------------------------------------

start_timer0

------------------------------------------------------------------Function : Starts timer 0.Syntax : #include <macros31.h> start_timer0() ;Prototype in : macros31.hRemarks : Sets bit 4 of TCON to start timer0.Return value : None.See also : stop_timer0------------------------------------------------------------------

start_timer1

------------------------------------------------------------------Function : Starts timer 1.Syntax : #include <macros31.h> start_timer1() ;Prototype in : macros31.hRemarks : Sets bit 6 of TCON to start timer1.Return value : None.See also : stop_timer1

------------------------------------------------------------------

stop_timer0

------------------------------------------------------------------Function : Stops timer 0.Syntax : #include <macros31.h> stop_timer0() ;Prototype in : macros31.hRemarks : Clears bit 4 of TCON to stop timer0.Return value : None.See also : start_timer0

87

Page 88: IDE51

------------------------------------------------------------------

stop_timer1

------------------------------------------------------------------Function : Stops timer 1.Syntax : #include <macros31.h> stop_timer1() ;Prototype in : macros31.hRemarks : Clears bit 6 of TCON to stop timer1.Return value : None.See also : start_timer1

------------------------------------------------------------------

strcat

------------------------------------------------------------------Function : Appends one string to another.Syntax : char *strcat(char *dest, char *src) ;Prototype in : string.hRemarks : strcat appends a copy of src to the end of dest. The length of the resulting string is strlen(dest) + strlen(src).Return value : strcat returns a pointer to the concatenated strings.

------------------------------------------------------------------

strcmp

------------------------------------------------------------------Function : Compares one string to another.Syntax : int strcmp(char *s1, char *s2) ;Prototype in : string.hRemarks : strcmp performs an unsigned comparison of s1 to s2, starting with the first character in each string and continuing with subsequent characters until the corresponding characters differ or until the end of the strings is reached.Return value : strcmp returns a value that is < 0 if s1 is less than s2, = 0 if s1 is the same as s2 > 0 if s1 is greater than s2

88

Page 89: IDE51

------------------------------------------------------------------

strcpy

------------------------------------------------------------------Function : Copies one string into another.Syntax : char* strcpy(char *dest, char *src) ;Prototype in : string.hRemarks : copies string src to dest, stopping after the terminating null character has been moved.Return value : strcpy returns dest.

------------------------------------------------------------------

strlen

------------------------------------------------------------------Function : Calculates the length of a string.Syntax : #include<string.h> int strlen(char *s);Prototype in : string.hRemarks : strlen calculates the length of s.Return value : strlen returns the number of characters in s, not counting the null-terminating character.

------------------------------------------------------------------

strlwr

------------------------------------------------------------------Function : Converts uppercase letters in a string to lower-case.Syntax : char* strlwr(char*s);Prototype in : string.hRemarks : strlwr converts uppercase letters (A-Z) in string s to lower-case (a-z). No other characters are changed.Return value : strlwr returns a pointer to the string s.See also : strupr

89

Page 90: IDE51

------------------------------------------------------------------

strncpy

------------------------------------------------------------------Function : Copies a given number of bytes from one string into another, truncating or padding as necessary.Syntax : #include<string.h> char *strncpy(char*dest, char*src, int maxlen);Prototype in : string.hRemarks : strncpy copies up to maxlen characters from src into dest, truncating or null-padding dest. The target string, dest, might not be null-terminated if the length of src is maxlen or more.Return value : strncpy returns dest.------------------------------------------------------------------

strupr

------------------------------------------------------------------Function : Converts lower-case letters in a string to uppercase.Syntax : char *strupr(char*s);Prototype in : string.hRemarks : strupr converts lower-case letters (a-z) in string s to uppercase (A-Z). No other characters are changed.Return value : strupr returns s.See also : strlwr

------------------------------------------------------------------

tan

------------------------------------------------------------------Function : Trigonometric tangent function.Syntax : #include <math.h> float tan (float x) ;Prototype in : math.hRemarks : This function is NOT included in the library, but it is given in the form of source code. It’s source code can be found in SOURCE\CFILES\MATH.CReturn value : tan returns the tan of x.See also : cos, sin, tanh

------------------------------------------------------------------

90

Page 91: IDE51

tanh

------------------------------------------------------------------Function : Hyperbolic tangent function.Syntax : #include <math.h> float tanh (float x) ;Prototype in : math.hRemarks : This function is NOT included in the library, but it is given in the form of source code. It’s source code can be found in SOURCE\CFILES\MATH.CReturn value : tanh returns the hyperbolic tan of x.See also : cos, sin, tan

------------------------------------------------------------------

tolower

------------------------------------------------------------------Function : Translates characters to lower-case.Syntax : char tolower (char ch);Prototype in : ctype.hRemarks : tolower is a function that converts a character ch (in the range 0 to 255) to its lower-case (‘a’-‘z’) value (if it was uppercase (‘A’-‘Z’); all others are left unchanged.Return value : tolower returns the converted value of ch if it is uppercase; all others it returns unchanged.

------------------------------------------------------------------

toupper

------------------------------------------------------------------Function : Translates characters to uppercase.Syntax : char toupper (char ch);Prototype in : ctype.hRemarks : toupper is a function that converts a character ch (in the range 0 to 255) to its uppercase value (‘A’-‘Z’) if it was lower-case (‘a’-‘z’); all others are left unchanged.Return value : toupper returns the converted value of ch if it is lower-case; it returns all others unchanged.

------------------------------------------------------------------

91

Page 92: IDE51

ui2a_c31

------------------------------------------------------------------Function : Converts an unsigned integer into ASCII stringSyntax : #include <stdlib.h>void ui2a_c31(unsigned int val, char *dest, int ndigits) ;Prototype in : stdlib.hRemarks : ui2a_c31 converts an unsigned integer number 'val' into ASCII string 'dest' containing exactly ndigits digits.Return value : None.See also : itoa_c31

------------------------------------------------------------------

ui2bcd

------------------------------------------------------------------Function : Converts an unsigned integer number into a BCD string.Syntax : #include <stdlib.h>void ui2bcd (unsigned int value, char *dest, int ndigits);Prototype in : stdlib.hRemarks : Converts value into an unpacked BCD string which is ‘ndigits’ digits long and places the string in ‘dest’Return value : NoneSee also : int2bcd

92

Page 93: IDE51

8. Advanced Programming Techniques

8.1 Writing Simple Assembly Language Sub-routines :

It may be sometimes very convenient to write small functions in assembly language and call these functions from C language program. This section describes exactly how to do it. Let us take a simple example - it may not be useful in real life, but it nonetheless illustrates the method to be followed. This is how our example function goes :

_exmpl_func: ; Example function written in assembly language mov a,p0 ; read P0 data rlc a ; rotate left through Carry mov p0,a ; write back to P0 ret

In your C program, you might call this function, simply by writing :

exmpl_func() ;

Writing assembly language functions is as simple as that. You only need to remember a few rules : An assembly language function must start with a label, which is same as the name

of the function preceded by an underscore character ('_'). While calling such a function from C language program, you must omit the

underscore character. The assembly language function may modify the contents of any of the registers (R0

through R7) and Acc. Never switch register bank. Never change the contents of Stack Pointer (SP). Make sure that the PUSHs and

POPs are exactly matching. Never write into any location in internal or external data memory. Never access any location in internal / external data memory by using hardcoded

addresses. Always define global variable in your C program, so that the required space gets allotted to them. Use only the names of these variables as internal /

93

Page 94: IDE51

external data memory addresses. e.g. if you want to use a byte location in external data memory, you should declare a unsigned char type global variable in your C program as :

unsigned char asm_var ;

In your assembly language function, you can use it as :

mov dptr,#_asm_var ; load the addr. in DPTRmovx a,@dptr ; read the value

; do some processingmovx @dptr,a ; write back the value

If you stick to these rules, chances of "system crash" will be far too less !

8.2 Assembly Language Function's return value :

Suppose you want the assembly language function to return some value, follow these guidelines. In your C program you must put the function's declaration. e.g.

unsigned char some_func () ;

Then you may call this function as and when required. e.g.

value = some_func() + 25 ;

In assembly language you write,

_some_func: ; some code here ; finally compute the return value in Acc, ; and then store mov myacc,a ; the return value put in proper place ret

Note that the return value should be always put in the internal RAM location - myacc. Depending on the type of return value, you may write 1 to 4 bytes from location

94

Page 95: IDE51

onwards. e.g. in case of int type return value, you should write the LSByte of the return value at myacc and the MSByte should be written at (myacc + 1).

Please note that if a function’s return value is of type ‘bit’ then you should use the bit location ‘bit_acc’ instead of internal RAM location ‘myacc’. e.g. if you want to return 1 (bit type), then you must write : setb bit_acc retat the end of the function.

8.3 Assembly Language Functions with parameters :

If you want the assembly language function to take parameters, you must start and end the function in a specific manner. Again this is different for large model and small model programs. Let us consider large model programs first.

8.3.1 Accessing parameters in large model programs :

At the beginning, you must write these four lines :

push bpl push bph mov bpl,spl mov bph,sph

At the end, you must write these five lines :

mov spl,bpl mov sph,bph pop bph pop bpl ret

When a function is called from C language program, it's parameters are pushed onto EXTERNAL STACK which resides in external data memory. The last parameter is pushed first. To access these parameters, you should make use of bpl and bph. For example consider this C language statement :

95

Page 96: IDE51

some_func1(par1,par2) ;

Let us assume that par1 is of int type and par2 is of unsigned char type. The first parameter can be always found at the address contained in bph and bpl plus 1. e.g. to load the value of par1 in R3-R2 (MSByte in R3), you may write :

mov a,bpl add a,#1 mov dpl,a mov a,bph addc a,#0 mov dph,a ; DPTR = (bph)(bpl) + 1 = addr of par1 movx a,@dptr ; read lo byte of par1 mov r2,a ; put it in R2 inc dptr movx a,@dptr ; read hi byte of par1 mov r3,a ; put it in R3

Note that 'lower byte at lower address' philosophy is followed everywhere. The remaining parameters are stored at consecutive locations. e.g. par2 can be found at (bph)(bpl) + 3. Please note that you must never modify the contents of bpl, bph, spl or sph.

8.3.2 Accessing parameters in small model programs :

At the beginning, you must write these two lines :

push bp mov bp,sp

At the end, you must write these three lines :

mov sp,bp pop bp ret

When a function is called from C language program, it's parameters are pushed onto stack. The first parameter is pushed first. To access these parameters, you should make use of bp. For example consider this C language statement :

96

Page 97: IDE51

some_func1(par1,par2) ;

Let us assume that par1 is of int type and par2 is of unsigned char type. The last byte of the first parameter can be always found at the address ((bp) - 3). e.g. to load the value of par1 in R3-R2, you may write :

mov a,bp clr c subb a,#4 mov r0,a ; R0 = (bp) - 4 = addr of par1 mov a,@r0 ; read LSByte of par1 mov r2,a ; put it in R2 inc r0 mov a,@r0 ; read MSByte of par1 mov r3,a ; put it in R3

Note that 'lower byte at lower address' philosophy is followed everywhere. The remaining parameters are stored at consecutive locations - backward. e.g. par2 can be found at (bp) - 5.

Please note that you must never modify the contents of bp or sp.

8.4 Calling C functions from assembly language :

You can simply call C language function from assembly language by name, but by preceding it by an underscore character. e.g. if your C function is defined as :

void some_func () ;

You can call it from assembly language as :

lcall _some_func

8.4.1 Passing parameters (large model programs) :

If the C function takes any parameters, you should make use of spl and sph to pass parameters. Let us modify the above example and redefine the same function with parameters as :

97

Page 98: IDE51

void some_func (int par1, unsigned char par2) ;

For simplicity, let us assume that value of par1 is in R3-R2 (MSByte in R3) and value of par2 is in R4. The last parameter (par2 in this case) is pushed first. i.e. parameters are pushed in the reverse sequence. (sph)(spl) points to the Top of Stack (ToS) minus 1. First you should push the parameters into the external stack, then you call the function, then you should adjust the external stack. For the above example, this is how you do it :

mov a,spl clr c subb a,#2 mov dpl,a mov a,sph subb a,#0 mov dph,a ; DPTR = (sph)(spl) - total no. of bytes required ; for ALL parameters + 1 mov a,r2 ; lo byte of par1 movx @dptr,a inc dptr mov a,r3 ; hi byte of par1 movx @dptr,a inc dptr mov a,r4 ; par2 movx @dptr,a ; thus all parameters pushed ; now adjust stack pointer (sph,spl) mov a,spl clr c subb a,#3 ; decrement (sph)(spl) by total no. of mov spl,a ; byte required for ALL parameters mov a,sph subb a,#0 mov sph,a ; now call the function lcall _some_func ; now readjust the stack pointer (sph,spl) mov a,spl

98

Page 99: IDE51

add a,#3 ; increment (sph)(spl) by total no. of mov spl,a ; byte required for ALL parameters mov a,sph addc a,#0 mov sph,a ; that is all !

8.4.2 Passing parameters (small model programs) :

If the C function takes any parameters, you should make use of sp to pass parameters. Let us modify the above example and redefine the same function with parameters as :

void some_func (int par1, unsigned char par2) ;

For simplicity, let us assume that value of par1 is in R3-R2 (MSByte in R3) and value of par2 is in R4. The last parameter (par2 in this case) is pushed first. i.e. parameters are pushed in the reverse sequence. First you should push the parameters onto stack, then you call the function, then you should adjust the stack. For the above example, this is how you do it :

mov a,r4 push acc mov a,r2 push acc mov a,r3 push acc lcall _some_func mov a,sp clr c subb a,#3 ; decrement sp by total no. of mov sp,a ; bytes required for ALL parameters

8.5 Expanding the library :

Once you are at ease with writing assembly language functions, you may like to put it into library. The advantage of doing this is that you don't have to specify the 'assembly language patchup' everytime you compile. The SLIB program helps you to do this. The default library file is SPJ_C31L.LIB for large model and

99

Page 100: IDE51

SPJ_C31S.LIB for small model. However, it is not recommended to add functions to the default library. Instead, you may create a different library. The name of this library file can be then specified to the compiler as a command line option /L. To add your own modules to a library using SLIB.EXE, you need to follow a specific procedure :

If the name of the function you have written in assembly language is 'example', then create a file EXAMPLE.ASM. Further, the file EXAMPLE.ASM must have a specific structure :

MODULENAME : _exampleCALL_LISTCALL_LIST_END_example:; assembly language statements; which make the body of this subroutine

The first line must be MODULENAME : _modulename (which is example in this case). The second line must be CALL_LIST. The third, fourth etc. lines may contain names of other library functions which may have been called from the function example. e.g. if this function calls two more library functions _func1 and _func2, then you may write :

MODULENAME : _exampleCALL_LIST_func1_func2CALL_LIST_END_example:

The next line must be CALL_LIST_END. On the next line you must write the name of the function preceded by an underscore and immediately followed by a colon (:). Next line onwards you may write the body of the function. Finally save the file.

Now invoke SLIB to add this module in to the library. Suppose you want to create a library file MYOWN.LIB or if you have already created it and you want to this function “example” to it, the command line is :

slib myown.lib /a example.asm

100

Page 101: IDE51

If later on you make any changes in this 'example' module, you can again use SLIB to replace this module into the library. The syntax is :

slib myown.lib /r example.asm

A list of all modules contained in the library can be produced using SLIB. The syntax is :

slib myown.lib /l listfilename

where listfilename is the name of the file in which the list will go. If that file is already existing, it will be overwritten WITHOUT warning.

Once you have successfully added the module example in the library, then you can specify the name of this library to the compiler as a command line option, in order to use this function.

8.6 The compile process :

The compile process is a two stage process : First, C language to assembly language and second, assembly language to machine language. If input to C31 is EXAMPLE.C, then it actually produces EXAMPLE.ASM. This .ASM file is not complete, since there may be calls to some functions which are a part of library. The C31 then automatically invokes ASM31 which is assembler and linker combined together. Please note that you can not and should not invoke ASM31 from the DOS command line. The linker then loads the required functions from the library and the assembler finally converts this into machine codes file : EXAMPLE.BIN. Please note that the assembler is case-sensitive because it is used in conjunction with C compiler and C is a case sensitive language.

8.7 More about assembly language :

8.7.1 Labels :

All rules for an identifier name are also applicable to labels. The label name must be IMMEDIATELY followed by a colon (:).

101

Page 102: IDE51

8.7.2 Constants :

Constant values can be written in either decimal or hexadecimal. A value written in hexadecimal notation must be immediately followed by the character 'h'. e.g. 23h Moreover, if a hex constant value begins with characters 'a' to 'f', they must be preceded by 0. e.g. 0ffh. ASCII constants must be included in single quotes. e.g. mov a,#'Z'

8.7.3 String constants :

String constants can be defined using db directive. The string constants also must be enclosed in single quotes. e.g. db 'Hello world !'

8.7.4 Bit operands :

Bit operands must be written using the dot notation. e.g. bit 3 of p1 can be accessed as follows : setb p1.3If you have declared a bit variable in your C program, or if a symbol is declared using the BIT keyword, the same can be accessed from assembly language, by preceding an underscore to the name of the variable or symbol. e.g. if in the C program you have written,

bit flag ;BIT motor p1.0

then, from assembly language you may access these as :

setb _flag clr _motor

8.8 Interrupt functions :

You can define functions of a special type i.e. interrupt. A function which is intended to be an Interrupt Service Routine (ISR) must be declared of type interrupt. These are slightly different than ordinary functions. First the declaration syntax :

interrupt (intr_type) function_name () { /* body of function */ }

102

Page 103: IDE51

The 'intr_type' must be an integer, which specifies the type of interrupt for which this function is meant to be an ISR. The programmer is advised to used symbolic constants for this intr_type. These symbolic constants are defined in STANDARD.H e.g. INT_TMR0 is used for Timer 0 ISR. Ordinary functions end with a RET instructions. 'interrupt' type functions end with a RETI instruction instead. An interrupt type function must not have any parameters. A programmer is not supposed to call an interrupt type function. It will automatically get called when the corresponding interrupt occurs. Depending on the value of intr_type, the compiler automatically inserts a ljmp instruction at the appropriate interrupt vector location. This explains why an interrupt function can not have parameters. The interrupt vector location is calculated from the value of intr_type as follows :

Interrupt vector address = ((intr_type – 1) * 8) + 3 ;

When an interrupt function is invoked, the CPU context is automatically saved. Before returning from the interrupt function, the saved context is restored. All this is transparent to the programmer. i.e. he need not write any code to save and restore the CPU context, because that is automatically done by the compiler.

103

Page 104: IDE51

Appendix A : Error and Warning messages

This appendix describes all warning and error messages produced by the compiler. The description includes possible causes and remedy or suggestion.An Error message is produced by the compiler when the severity of the error makes it impossible for the compiler to produce the assembly language or machine code output. Thus if you encounter an error message while compiling, it indicates that the compiler is unable to produce the ROMable code file (.BIN)On the other hand, a Warning message is produced by the compiler, when it does not know whether it really is an error or not. It is expected that the programmer should decide it himself, and hence the compiler also prints sufficient information in the warning message. However, even if you encounter one or more warning messages, the compiler still completes the compile process and produces the ROMable code file (provided there are no Errors). The programmer may then analyze each warning message and then only decide whether to use the compiler output or to make changes in the source program and compile again.

How can I see all of the error / warning messages ?

When you run the compiler, it prints all of the warning and error messages on the Standard Output device i.e. generally the console. If there are too many warnings / errors, you may not be able to see all of them on the screen. In such a case, you may use output redirection to catch all the warning / error messages. i.e. these can be saved in a file - say C31.ERR. To do this, invoke the compiler as shown below :

c31 [options] filename.c > c31.err

When you do this, you will not see any warning / error messages on the screen. Instead these will go into the file “c31.err”. When the compile process is over, you can view the file “c31.err” using any text editor.

Warning Messages :

Warning : Can not open your .ASM include file filename.ext :

This warning message will be produced if you specified an assembly language patch-up file filename.ext by using the /A command line option, but the compiler could not find the

104

Page 105: IDE51

file. The most probable cause is a spelling mistake while typing the filename. Also, remember that there should be NO space between the /A and the patch-up file name.

Linker warning : Function func_name is undefined (assumed external) :

Where func_name indicates the name of a function, which was called from your C program, but it was neither defined in your C program, nor it could be found in the library. This may happen, if you have defined the function in your assembly language patch-up file.

Parameter ‘paraname’ never used :

Where paraname is the name of a parameter. This warning is usually displayed with a line number of the last line of a function in which the said parameter was defined.

Local variable ‘localname’ declared but never used :

Where localname is the name of a local variable. This warning is usually displayed with a line number of the last line of a function in which the said local variable was defined.

No declaration for function ‘funcname’ :

If a function is called in an expression and if it is not earlier defined or declared, this warning message will be printed.

Global variable ‘globalname’ declared but never used :

This warning is usually associated with the last line of your program. In your program, if you have declared a global variable, but you never actually used it, then this warning message is printed.Please note, that global variables can also be accessed through an assembly language patch or may be with the use of asm keyword. This kind of possible use of a global variable is ignored by the compiler. e.g. if you declared a global variable, never used it in any C statement, but have used it in an assembly language patch file, then also the compiler will print this warning message “declared but never used”. So the programmer must take care to find out, which variables are really unused and such variable declarations can be removed (or commented) from the program to save on RAM space.

105

Page 106: IDE51

Function ‘funcname’ defined but never called :

This warning is usually associated with the last line of your program. In your program, if you have defined a function, but you never actually called it, then this warning message is printed.Please note, that functions can also be accessed through an assembly language patch or may be with the use of asm keyword. This kind of possible use of a function is ignored by the compiler. e.g. if you defined a function, never called it from any C statement, but have used it in an assembly language patch file, then also the compiler will print this warning message “defined but never called”. So the programmer must take care to find out, which functions are really unused and such function definitions can be removed (or commented) from the program to save on code space.

Error Messages :

Almost all of the error messages also display the source file name and the line number which caused this error message. The meaning of all error messages are described below.

Declaration Syntax Error :

This error message is generally caused by an incorrect variable or function declaration or definition. Check the spellings and syntax of the given line number. Also see the list of supported data types.

Redeclaration of identifier OR function :

If a variable or function is defined more than once, then it causes this error message. However, 2 (or more) variables of the same name can exist, provided one of those is a global variable and the other one is a local variable or a parameter.

Too Many Identifiers :

If the compiler runs out of memory for the symbol table, it produces this error message. Check for any unused variables / functions and remove them if possible.

Unknown Identifier :

If you attempt to use a variable without declaring it, this error message will occur. Please check the spellings.

Invalid Identifier :

If an identifier is badly defined, this error will occur. Please see the rules of defining an identifier in “Language Reference” in this manual.

106

Page 107: IDE51

Too many errors :

If the compiler encounters too many error messages while compiling your program, it will print this message and stop the compile process. Please note, that this indicates that your program has not been completely compiled. i.e. there may be more errors which are not detected yet. Please correct the displayed errors and compile again.

Invalid Statement :

Syntax error ! :

If the general syntax rules of C language are not followed, one of the above two general error messages is printed. e.g. the “if” keyword must be followed by a valid expression enclosed in a pair of parenthesis. If this is missing, you may see this error message. This is just one example, there may be numerous situations under which you will see this message.

Mismatch brackets :

If in an expression, the parenthesis (‘(‘ and ‘)’) or the square brackets (‘[‘ and ‘]’) are not in matching pairs, this error will be printed. If, in your program the curly brackets are not in matching pairs, then also you will see the same error message.

Too Many Brackets :

An expression may contain any number of parenthesis or square brackets - provided they are in matching pairs. However, the more brackets in an expression, the more memory is required by the compiler. Thus when the compiler runs out of memory while sorting out an expression, this error message is printed.

Statement Missing ; :

In ‘C’ language, each statement must be followed by a semicolon. (barring a few exceptions like the SFR statement or the BIT statement etc.) If you forget to write the semicolon, you will see this error message.

Misplaced continue :

The ‘continue’ keyword must be used inside a loop. e.g. in a ‘for’ loop or a ‘do - while’ loop or in a ‘while’ loop. However, when the compiler encounters a ‘continue’ statement which is NOT inside the body of a loop, it will print this error message.

107

Page 108: IDE51

Misplaced else :

The else keyword must be used in conjunction with the ‘if’ keyword. Use of ‘else’ keyword without a corresponding ‘if’ will produce this error.

Misplaced break :

The ‘break’ keyword must be used inside a loop - e.g. in a ‘for’ loop or a ‘do - while’ loop or in a ‘while’ loop, or inside a ‘switch’ statement. However, when the compiler encounters a ‘break’ statement which is NOT inside the body of a loop or a ‘switch’ statement, it will print this error message.

do statement missing 'while' :

The ‘do’ keyword must have a corresponding ‘while’ at the end of the ‘do - while’ loop. If the ‘while’ keyword is missing, this error message is printed.

case outside of switch :

The ‘case’ keyword must be used inside a ‘switch’ statement. However, when the compiler encounters a ‘case’ statement which is NOT inside a ‘switch’ statement, it will print this error message.

Colon Missing :

The ‘case’ or ‘default’ keyword (inside a ‘switch’ statement) must be followed by a colon (‘:’) If this is missing, the compiler prints this error message.

Too Many Default Statements OR default May be Outside of switch :

The ‘default’ keyword must be used inside a ‘switch’ statement. However, when the compiler encounters a ‘default’ statement which is NOT inside a ‘switch’ statement, it will print this error message.Also, you may use the ‘default’ keyword only once in a single ‘switch’ statement. If you tried to use more than one ‘default’ in a single ‘switch’ statement, then also the same error message is printed.

Type Mismatch :

If the types of two operands are not ‘matching’ with each other, this error message will be printed. However, this does not mean that both the operands must be of the SAME

108

Page 109: IDE51

type. Even the types are not same, the compiler generates code to convert one of the operand into that of the other. However, this may not be always possible. e.g. a bit type variable can not be converted to any other type. Hence, for example, if you try to add ‘bit’ type variable into an ‘int’ type variable, it will produce this error.

Can't open library file :

Can't open index file :

The compiler automatically invokes the linker to link any unresolved functions. If the compiler is unable to open the library file (default library or user specified library), it prints this error message along with the name of the library file. Associated with each library file is an ‘index’ file. If the compiler is unable to open the ‘index’ file, then also it prints this error message along with the name of the index file.

Library file is bad :

Index file is bad :

The library file and corresponding index files are created and maintained by the library manager. These files have a specific structure. If a library or index file (either default or user specified) is not found to have the correct structure, this error message is printed.

Unknown Peripheral name :

If the peripheral name specified after the ‘peripheral’ keyword is not one of the standard peripheral names, this error will be printed. The currently defined standard peripherals are :

827981558255LCD

Please refer to Library Functions Reference for built in library functions for these peripherals.

Too many 'goto' statements ! (max. 10) :

In a single function, you may not write more than 10 ‘goto’ statements. If you attempt to use ‘goto’ more than 10 times in a function, this error message will be printed.

109

Page 110: IDE51

Undefined label :

If a label corresponding to a ‘goto’ statement is not defined till the end of the function, this error message will be printed.

Undefined macro :

If you try to undefine a macro (using #undefine) which is not defined at all, this error message will be printed.

Macro Parameters missing :

If you have defined a macro with parameters, you must pass the same number of parameters while using the macro. If in the macro call, the parameters are missing, this error message will be printed.

Too many/few parameters passed to macro :

If you have defined a macro with parameters, you must pass the same number of parameters while using the macro. If in the macro call, the no. of parameters passed is not same as the no. of parameters required, this error message will be printed.

Macro definition syntax error :

If a syntax error is detected in a macro definition, this error message will be printed. e.g. if you attempt to use a keyword as the macro name, this error message will be printed.

Unexpected #else or #endif :

The #else or #endif must have a corresponding #ifdef or #ifndef. If #else or #endif are found out of place, this error message will be printed.

Too many macro definitions :

As you keep defining macros, the compiler remembers all the macro definitions. But when the compiler runs out of memory to store any more macro definitions, this error message will be printed.

110

Page 111: IDE51

Too big macro definition :

If a macro definition is too big to fit in the available memory, this error message will be printed. Please note that, multi-line macro definitions are not supported in this version of the compiler.

Syntax error in include statement (or file not found) :

If the #include statement is not correctly written or if the compiler is unable to open the included file, this error message will be printed.

Macro has too many parameters :

A macro can not have more than 10 parameters. If you attempt to define a macro with more than 10 parameters, this error message will be printed.

Invalid Statement :

If an invalid preprocessor directive is encountered, this error message will be printed.

Line Too Long ! :

Any line in your program must not have more than 240 characters. If a line is found to have more than 240 characters, this error message will be printed.

Too many ifs :

The #ifdef or #ifndef statements can be nested. However, this version of the compiler does not support a nesting level of more than 10. If you attempt to nest more than 10 #ifdef or #ifndef statements, this error message will be printed.

Too many (> 128) SFR declarations :

Using the SFR keyword, you can define Special Function Registers (to be used as pseudo variables). However, you may not declare more than 128 SFRs. If you attempt to do so, this error message will be printed.

'bit' type local var/para/array : not allowed :

A ‘bit’ type variable must be declared as a global variable only. If you attempt to declare a bit variable as a local variable or as a parameter, this error message will be printed. Also, arrays of bit variables are not supported in this version of the compiler. If you attempt to declare an array of bit type variable, this error message will be printed.

111

Page 112: IDE51

pointer to bit variable : not allowed :

The current version of the compiler does not support pointer to bit type variable. If you attempt to declare a pointer to a bit type variable, this error message will be printed.

112

Page 113: IDE51

Appendix B : Limitations of the compiler

There are certain areas of the compiler that have known limitations or bugs. SPJ Systems will repair these problems in future versions of the C compiler. Until that version is released, you should be aware of these limitations. This appendix describes all such known limitations and known bugs which are reported and not corrected yet. You will also find some useful suggestions in order to use the compiler in a better and more efficient way, in Appendix C.

LIMITATIONS AND BUGS :

1) Scaler variables can not be initialized during declaration. e.g. int j = 5 ; /* this is not allowed */ int k ; /* this is ok */2) Only 1 or 2 dimensional arrays can be initialized during declaration, that too only if

it is a global variable. In case, you attempt to initialize an array which is declared as a local variable, the compiler will produce some "Assembler error" during the Assembler Pass #2. If you want to initialize a character array to a very long constant string, then you can write the string on multiple lines. e.g.

char arr[100] = “hello”\ “ world !” ; Please note the backslash at the end of first line. It indicates that string is continued on next line.3) While passing parameters to a function, the compiler checks only first 12 parameters

for type conversion.4) Type casting is not supported.5) Sometimes, the compiler does not recognize the unary minus operator correctly.

It is recommended to use the expression "(0 - something)" instead of just writing "-something". e.g.

x = -10 ; /* may produce error */ x = 0 - 10 ; /* will not produce error */ x = (-z) * 15 ; /* may produce error */ x = (0-z) * 15 ; /* will not produce error */6) In small model programs, constant strings may not be passed to user defined

functions. However, these can be safely passed to built in library functions (e.g. strcpy, disp_lcd, printf etc.)

113

Page 114: IDE51

7) Maximum 2 dimensional arrays are supported. Arrays with more than 2 dimensions are not supported.

9) Arrays of 'bit' type variables are not supported.10) Pointer to 'bit' type variable is not supported.11) 'bit' type variables must be used as global variables only. i.e. a local variable or a

function parameter can not be a 'bit' type variable.12) Pointer to pointer is not supported.13) Array of pointers is not supported.14) A member of a struct / union may not be a pointer.15) A member of a struct / union may not be a struct / union.

114

Page 115: IDE51

Appendix C : 10 ways to improve code efficiency

This appendix lists some useful suggestions in order to use the compiler in a better and more efficient way :

1) Small model produces smaller code, because all variabled reside in internal RAM. Manipulating internal RAM is much easier than external RAM. So, if you are able to fit all your data in 128 (or 256) bytes of RAM, it is advisable to compile your program using small model. If you need more data variables, however, you will have to use large memory model.

2) If you use more global variables (rather than local variables), then code size will be smaller. That is because, global variables reside at a fixed address (which is known at compile time). On the contrary, local variables and parameters reside in stack (either internal stack of 8051 or a simulated stack in external RAM) and their address is not known at compile time. That is why, accessing local variables or parameters requires more instructions compared to accessing global variables.

3) Wherever possible, use unsigned char data type instead of int. e.g. the count variable in a for loop etc. If the count does not exceed 255, you may use unsigned char type variable instead of int. Since the 8051 has instructions only to manipulate 8 bit data (and bits), it is easier to handle 8 bit data elements rather than 16 bit or 32 bits.

4) Internal RAM locations 0x20 through 0x2e are used by the compiler to place bit type variables, and location 0x2f is reserved by the compiler for bit type temporary variables. bit type variables are placed by the compiler at locations 20h.0, 20h.1 . . . 20h.7, 21h.0, 21h.1 and so on. Suppose you have declared only 11 bit type variables, then internal locations 20h and 21h will be used to store these variables. However, the locations 22h through 2eh will remain unused. With the help of @I notation, you can declare some variables in this unused space (if any). However, care must be taken so that no two variables will occupy the same location. CAUTION : please note, that if you use one of the printf family function, then they use internal RAM locations 0x27 through 0x2E.

5) Especially in large model programs, if you can keep some variables in the above mentioned free locations in internal RAM, that will result in some reduction in code size. In a large model program, all variables are placed in the external RAM by default. You can forcefully keep some of the frequently used variables in the free locations (if any) in the internal RAM.

6) Instead of using 'inportb' and 'outportb' functions, it is much efficient to use a variable declared at a specific address in external RAM. e.g. instead of writing :

115

Page 116: IDE51

outportb(0x6000,0) ; it is better to write : dat_8279 = 0 ; where 'dat_8279' is a variable defined as follows : unsigned char @0x6000 dat_8279 ;7) Wherever possible, use unsigned data types instead of signed. i.e. unsigned char

instead of char, unsigned int instead of int and unsigned long int instead of long int. Since the 8051 does not have any instructions to perform signed arithmetic, it is easier to perform arithmetic operations on unsigned number.

8) Whenever a variable is going to hold only two possible values (0 or 1, or TRUE or FALSE), it is efficient to use bit variable instead of int or char. Even a function's return value type could be bit.

9) To access a bit of a bit accessible SFR, you can make use of BIT declarations. e.g. to set bit 3 of P1, you can write either :

P1 |= 8 ; or BIT p1_3 p1.3 /* Define a BIT */ p1_3 = 1 ; /* set the bit */ The later method is much more efficient.10) If you need a software delay, it is more convinient, efficient and accurate to use the

library function ‘delay()’ or ‘delay_ms()’ instead of writing empty for loop etc. Please refer to the chapter “Library functions reference” for details about the ‘delay()’ and ‘delay_ms()’ functions.

---x---x---

116