Home
C51 Primer
Contents
1. TH1 Ox0f3 Timer 1 high byte reload value SMOD 0 F Osc 12 MHz and Timer 1 in mode 2 baudrate of 4800 Baud Timer 1 Interrupt is disabled after RESET TMOD 0x20 Load Timer Mode Control Register Timer 1 under software control with TRI as Timer in mode 2 8 bit auto reload SOCON 0x52 Serial connection in mode 1 1 Start 8 Data 1 stop bit start enabled Transmitter empty Receiver empty PCON 0x80 SMOD 1 to double baud rate TRI SA Timer 1 start KKKKKKKKKKKKKKKKKKKKKKK KKK KKK KK KKK KKK KKK KKK KKK KKK KKK KKK KKKKKKKKKKKKKKKKKKKKKK x Generate 2ms Timer Tick On Timer 0 KAKKKKAKKKAKKKAKKKAKKKKKKAKKKA e e E e e XKX XKX XKX XKX XKX XKX XKX XKX k k IA k k k k k k k kk k k Entered every timer0 overflow void timer0_init void TRO 0 DH TMOD 01 16 bit timer mode THO Oxf8 Reload with with count for 2ms time base at 12MHz kj TLO 0x82 TRO 1 Ja Start timer ST IENO 0x02 Z d Enable Timer 0 Ext0O interrupts www Phaedsys org page 134 of 194 Version 3 65 init_timer_0 VA KKAKKAKKKKKKKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKKK Timer0 Interrupt Service Routine S FRA XKX XXX XKX XKX XXX XKX XKX XKX XNXX KX XKX XKX XKX XKX XKX XKX XKX XKX XKX k k k k k k k An allowance really needs to be made for the fact that the timer is stopped during the re initialisation proces
2. ZS y_breakpoints ey 7 map_data ep Lee WS KKAKKKKKKKKKKKAKKKKAKKKAKKKAKKKKAKKKKKKAKKKKKKKAKKKAKKKKKKKKKKAKKKAKKKKKKKKKKKKJ unsigned char interp unsigned char x value x axis input X unsigned char wv value y axis input XL unsigned char const map base pointer to table base Zb Declare Local RAM unsigned char x_size i unsigned char wv size Z unsigned char x offset unsigned char y_offset unsigned char x_break_pointl x_break_point2 unsigned char y_break_pointl y_break_point2 unsigned char map_xlyl unsigned char map x2yl unsigned char map xlyz2 unsigned char map x2y2 unsigned char result H unsigned char result vil unsigned char result y2 unsigned char const mp j www Phaedsys org page 156 of 194 Version 3 65 unsigned char x templ x temp2 y_temp2 Get Size Of Map X size map base y_size map_base 1 Create Temporary Map Scanning Pointer map_base 2 x offset x size 1 mp map base unsigned char x_offset Locate Upper and Lower X Breakpoints KJA Find break point immediately below x value 4 while x_value lt mp amp amp x_offset 0 mp 7 x_offset Extract Upper And Lower X Breakpoints From Map x_break_pointl mp 0 x_break_point2 mp 1 x_temp2 x_break_point2 x_break_pointl bpt2 still in ACC Safety Check To Prevent Divide By Zero if x_temp2
3. IEX6 0 P13 0 EX6 1 Pl ss Oxfe Toggle P1 0 to show centre of PWM JAKKAKAKKKKAKKKKKKKKKKKKKAKKKAKKKKKKAKKKAKKKKKKKKKKAKKKK IAA IA IK k k k k k k k E CC4 Interrupt For Symmetrical PWM SS KKAAKKKAKKKAKKKKKKAKKKKAKKKKKKAKKKKKKAKKKAKKKKKKKKKKAKKKAKKKAKKKKAKKKKKKKKKKKKKKJ Interrupt at end of first on period of waveform to create next on point void symm PNM CC3 int void interrupt 13 using 2 Runtime here limits min max PWM DR CC3 symm_PWM_DR IEX6 0 P13 1 EX6 0 No further interrupts this period JAKKKKAKKKKKKAKKKAKKKKKKKKKKKKKKKKKAKKKAKKKKKKKKKKKKKAKKKAKKKAKKKKKKAKKKKKKKK X Modulate Symmetrical PWM With Analog Inputo SS KKAKKKKAKKKAKKKKKKAKKKKKKKKKKAKKKKKKAKKKAKKKAKKKKKKKKKAKKKAKKKKKKKKKKKKKKKKKKJ Duty ratio is calculated in background to prevent having to do floating point calculations in interrupts Note As PWM is symmetrical duty ratio cannot exceed 1 2 period void mod_symm_pwm void union unsigned int temp unsigned char tmp 2 t www Phaedsys org page 139 of 194 Version 3 65 t tmp 0 CRCH t tmp 1 CREL symm_PWM_DR 65536 t temp 2 5 analog_data 1 5 KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKKKK ks Drive TOC PWM s D AKKKKKKKKKKKAKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKAKKKKKKKKKKKKKKKKKKKKKKJ void configure pum void unsigned int temp unio
4. www Phaedsys org page 98 of 194 Version 3 65 a2 15 i2 main funcl func2 void timero0 int void interrupt 1 funcl 7 AAAAAAAAAAAAAAAAAAAAAAA End of Module This produces the linker map OVERLAY MAP OF MODULE MAIN2 MAIN2 SEGMENT DATA GROUP gt CALLED SEGMENT START LENGTH PR TIMERO_INT MAIN2 gt PR FUNC1 MAIN2 PR FUNC1 MAIN2 0017H OOOFH TC CSISTARTUP gt PR MAIN MAIN2 PR MAIN MAIN2 gt PR FUNC1 MAIN2 gt PR FUNC2 MAIN2 PR FUNC2 7MAIN2 0017H 00OFH D 0007H SYMBOL il Danger D 0017H SYMBOL al D 0007H SYMBOL 12 D 0017H SYMBOL a2 xx WARNING 15 MULTIPLE CALL TO SEGMENT SEGMENT PR FUNC1 MAIN2 CALLER1 PR TIMERO_INT MAIN2 CALLER2 C_C51STARTUP 9 4 8 Multiple Call To Segment Solution The solution is to i Declare funcl as REENTRANT thus void funcl void reentrant T ii Use OVERLAY linker option thus main2 obj 8 to main2 abs amp OVERLAY main funcl timerO_int funcl to break connection between main and funcl and timerO_int and funcl OVERLAY MAP OF MODULE MAIN2 ABS MAINZ SEGMENT DATA GROUP t CALLED SEGMENT START LENGTH www Phaedsys org page 99 of 194 Version 3 65 26 CSISTARTUP gt PR MAIN MAIN2 PR MAIN MAIN2 gt PR FUNC2 MAIN2 PR FUNC2 MAIN2 0017H OOOFH xxx WARNING 16 UNCALLED SEGMENT IGNORED FOR OVERLAY PROCESS SEGMENT PR FUNC1 MAIN2 This means that the saf
5. 0 x_temp2 Ensure denominator never zero Check For x_value Less Than Bottom Breakpoint Value if x_offset x_size 1 x_value lt x break pointi x_value x_break_pointl x_templ x_value x_break_pointl Locate Upper And Lower Y Breakpoints Check For 1D Map if y_size 0 y_offset y_size 1 mp map_base unsigned char x_size y_offset while y_value lt mp amp amp y_offset 0 y_offset mp Extract Upper And Lower Y Breakpoints y_break_pointl mp 0 y_break_point2 mp 1 if y_offset y_size 1 y_value lt y_break_point1 y_value y_break_pointl Get Map Values www Phaedsys org page 157 of 194 Version 3 65 map base x size tv size x size y_offset x offset map xlyl map base map x2yl map_base 1 Interpolate 2D Map Values K Defines used to remove need for function calling define x map_xlyl define y map x2yl define n x templ define d x_temp2 y x if CY result_yl unsigned char x unsigned char unsigned int n y d else result_yl unsigned char x unsigned char unsigned int n y d map_xly2 map_base x size E map x2y2 map base x size 1 tundef x undef y define x map xly2 define y map x2y2 Ne S if CY result vi unsigned char x unsigned cha
6. MOV z 0FFH i In this case the carry flag CY is checked directly removing the need to perform any integer operations as any addition resulting in a value over 255 sets the carry Of course this is no longer ISO C as a reference to the 8051 carry flag has been made P2C0001 i ZS ROY 1 MOV A x ADD A y MOV Z A 7 z LEGH rf JNB CY C0003 z Oxff C51 Version using the carry flag MOV Z OFFH i www Phaedsys org page 40 of 194 Version 3 65 2C0003 RET The situation of an integer compare for greater than 65535 Oxffff is even worse as long maths must be used This is almost a disaster for code speed as the 8051 has very poor 32 bit performance excepting the C537 517 509 390 The trick of checking the carry flag is still valid as the final addition naturally involves the two upper bytes of the two integers In any high performance 8051 system this loss of portability is acceptable as it allows run time targets to be met This again illistrates that good 8051 C may not be portable or pure ISO C The alternative using pure ISO C might mean that a different more powerful processor has to be used Thus bringing up unit costs This does not mean that solid good practice should be ignored It is just that there are some non standard architecture specific non ISO C extensions that can be used www Phaedsys org page 41 of 194 Version 3 65 5 Program Structure And Layout 5 1 Modular Programming In
7. reserved see 251 Also used by Chip con CCO1010 for TRAP A6 2 2 MOV QRO dataAddr Al 2 2 MOV GRI dataAddr A8 2 2 MOV RO dataAddr A9 2 2 MOV RI dataAddr AA 2 2 MOV R2 dataAddr AB 2 2 MOV R3 dataAddr AC 2 2 MOV R4 dataAddr AD 2 2 MOV R5 dataAddr AE 2 2 MOV R6 dataAddr AF 2 2 MOV R7 dataAddr Code Bytes Cycles Mnemonic www Phaedsys org page 182 of 194 Version 3 65 Code Bytes Cycles Code Bytes Cycles DO WBWWWWWWWOWWWWOYDNDDD 2 2 1 1 2 1 1 1 1 1 1 1 1 1 1 2 bO bO bo bo bO bO bo NS ra ra NK KD D PO bO bO bO boa bO bO bO bO bo bO bO Aa Aa bO LD 2 Ka Ka Kad kt Kei ee Ka ke Ka Ka Ka Ka ka b i 2 PO bO bO bO boa bo bO bO rA KA DAO KA KA KA D ANL C bitAddr ACALL codeAddr CPL bitAddr CPL C CJNE A value codeAddr CJNE A dataAddr codeAddr CJNE QRO value codeAddr CINE R1 value codeAddr CJNE RO value codeAddr CINE R1 value codeAddr CJNE R2 value codeAddr CINE R3 value codeAddr CJNE R4 value codeAddr CINE R5 value codeAddr CJNE R6 value codeAddr CINE R7 value codeAddr Mnemonic PUSH dataAddr AJMP codeAddr CLR bit Addr CLR C SWAP A XCH XCH XCH XCH XCH XCH XCH XCH XCH XCH XCH A data Addr A RO A GRI A RO A RI Oo Ob ba pa 9999 Si Q N Mnemonic POP dataAddr ACALL codeAddr SETB SETB bitAddr C DA A DJNZ dataAddr codeAddr XCHD A RO XCHD A QRI DJNZ DJNZ DJNZ DJNZ DJNZ DJNZ
8. www Phaedsys org page 89 of 194 Version 3 65 151 startup obj modulel obj module2 obj module3 obj C51L 1lib to exec abs CODE 8000H XDATA 4000H This vvill move all the variables in external RAM to 4000H and above and all the executable code to 8000H Even more control can be exercised over vvhere the linker places code and data segments By further specifying the module and segment names specific variables can be directed to particular addresses see 2 1 8 for an example 9 2 Stack Placement Unless you specify otherwise the linker will place the stack pointer to give maximum stack space Thus after locating all the sfr compiled stack and data items the real stack pointer is set to the next available IDATA address If you use the 8032 or other variant with 128 bytes of indirectly addressable memory IDATA above 80H this can be used very effectively for stack C_C51STARTUP SEGMENT CODE Declare segment in indirect area STACK SEGMENT IDATA RSEG STACK Reserve one byte DS dh EXTRN CODE 2C START PUBLIC C_STARTUP CSEG AT 0 2C STARTUP LUMP STARTUP1 RSEG C_C51STARTUP STARTUP1 ENDIF MOV SP STACK 1 Put address of STACK location into SP LUMP C_START Goto initialised data section 9 3 Using The Top 128 Bytes of the 8052 RAM The original 8051 design has just 128 bytes of directly indirectly addressable RAM C51 when in the SMALL model can use this for variables arrays structures and stack Abov
9. char receive_byte void Polled use of serial port if RI 1 Test for char received Ay rx_byte SOBUF Place char in rx_byte RI 0 clear flag Mi else rx byte 0 www Phaedsys org page 133 of 194 Version 3 65 return YS byte void send byte char tx byte Polled use of serial port TI S05 LA Clear TI flag SOBUF Ca byte Begin transmission while TI Wait until transmit flag is set KKKKKKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKKKKKKKKKKK This function initialises Serial Port 0 to run at 9600 Baud using the Siemens Baud rate generator see P76 of the 517 Manual x KKAAKKKKKKAKKKAKKKAKKKKAKKKKKKAKKKKKKAKKKAKKKKKKAKKKAKKKKKKAKKKAKKKKKKKKKKKKJ This method does not tie up timerl as on ordinary 8051 s void serial0 init BD void BD 1 Enable Baud rate generator PCON PCON 0x80 Set SMOD to double baud rate SOCON 0x50 Mode 1 Receiver enabled T 1 Set Transmit interupt flag for first run through PRINTF XI 1 KKAKKKKKKKKKKKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKKKK x This function initialises Serial Port 0 to run at 4800 Baud using the Timer 1 auto reload mode ke KKAAKKKKKKAKKKAKKKAKKKKKKAKKKAKKKKKKKAKKKAKKKAKKKKKKAKKKKAKKKKKKAKKKKKKKKKKKKJ To get 9600 baud with timerl requires an 11 059MHz crystal void serial0 init TI void
10. take the address of c_variable and put it into the reserved RAM i e the pointer In this case the pointer s RAM corresponds to RO and the amp equates loosely to the assembler 3 Move the data indirectly into pointed at C variable as per the assembler MOV A RO The ability to access data either directly x y or indirectly x y_ptr is extremely useful Here is C example Demonstration Of Using A Pointer unsigned char c_variable 1 Declare a c variable unsigned char ptr 2 Declare a pointer not pointing at anything yet main c_variable Oxff 3 Set variable equal to Oxff directly ptr amp c_variable 4 Force pointer to point at c variable at run time ptr Oxff 5 Move Oxff into c_variable indirectly Note Line 4 causes pointer to point at variable An alternative way of doing this is at compile time thus Demonstration Of Using A Pointer unsigned char c_variable 1 Declare a c variable unsigned char ptr amp c_variable 2 Declare a pointer intialised to pointing at c_variable during compilation main c_variable Oxff 3 Set variable equal to Oxff directly ptr Oxff 5 Move Oxff into c_variable ndirectly www Phaedsys org page 65 of 194 Version 3 65 Pointers with their asterisk prefix can be used exactly as per normal data types The statement XSyYyt3 could equally vvell perform vvith poi
11. unlike the 80C166 etc This method uses abstract pointers to create a call to address zero thus simulating a software reset However it should be remembered that all internal locations must be cleared before the CPU can be considered properly reset The return address must be reset as the stack still contains the return address from the call H H void main void RSEG PR main T1l USING 0 main SOURCE LINE 9 LA void code void Ox0000 SOURCE LINE 11 LCALL OOH 7 Jump to address ZERO 7 i SOURCE LINE 13 RET END OF main www Phaedsys org page 113 of 194 Version 3 65 12 5 The Compiler Preprocessor define This is really just a text replacement device It can be used to improve program readability by giving constants meaningful names for example define FUEL_CONSTANT 100 2 so that the statement temp FUEL_CONSTANT will assign the value 200 to temp NOTE the define is purely a textual replacement and care must be taken to ensure no side effects Unless the define is a single item eg define MAX_TEMP 10 The text should be in perenthasis as in the case define FUEL_CONSTANT 100 2 Many safety critical and high integrity coding guides mandate that ALL defines shall use perenthasis In the case of the example above without the parenthasis it could have many stange side effect temp FUEL_CONSTANT temp 100 2 Is quite clear but how about temp
12. 2 A Ol ka k k ka k ka ka ka ka ka bi bi WD bO bO Kai Kei Kei Kei Eet ki ki vo b i www Phaedsys org Mnemonic JB bitAdr codeAddr AJMP RET RL A ADD ADD ADD ADD ADD ADD ADD ADD ADD ADD ADD ADD codeAddr A value A dataAddr A RO A QRI A RO A RI P pa bs E Dp AAAAAD NI OO Ob WwW bO Mnemonic JNB bitAdr codeAdr ACALL codeAdr RETI RLC A ADDC ADDC ADDC ADDC ADDC ADDC ADDC ADDC ADDC ADDC ADDC ADDC A wert A dataAdr A RO A QRI A RO A Rl OD Ob ba Pi pe DD bi Gi d DO Si 9 N Mnemonic JC codeAdr AJMP codeAdr ORL ORL ORL ORL ORL ORL ORL ORL dataAdr A dataAdr value A wert A dataAdr A RO A GRI A RO A Rl P pa De Do pa n AAAAAA QI A bO page 180 of 194 Version 3 65 Code Bytes Cycles 2 CH Ol Kd Fi Fi Fi Fi Fi NO DO WOOD DY bO Kai Kei ki Kei ke Kei Eet Kei ke ke ki ki bi ka b i Code Bytes Cycles 60 2 61 62 63 64 on Ol Kd k k b i k k k k ka ka DO bO WDD bO Ka ka ka kat kat ka ka ka ka ka ka ka b i Ka no Code Bytes Cycles TO 2 71 N ONDO bO bO bO bh bO bO NON ra bO DN DY e e Fei Fi Ked Fei Fei Fi ki DN ki DO bO DLP www Phaedsys org Mnemonic JNC codeAdr ACALL codeAdr ANL dataAdr A ANL dataAdr value ANL A value ANL A dataAdr ANL A RO ANL A R1 ANL A RO ANL A RI ANL ANL ANL ANL ANL ANL D D De nn n 9999 Gi 9 N OO
13. MBCS MIEEE FRGS Technical Specialist PhaedruS SystmS chris phaedsys org http www phaedsys org http Quest phaedsys org A January 2006 A The Quest series at http QuEST phaedsys org contains this paper and papers on Embedded C in genreral Embnedded Debuggers testing strratergy etc www Phaedsys org page 9 of 194 Version 3 65 www Phaedsys org page 10 of 194 Version 3 65 1 Introduction C was the great universal language that all software engineers programmers and hackers had to learn However it was designed when memory was tight and long names were not used and keyboard buffers were short It tended to be a very terse language Full of short cuts Whilst it is widely quoted as being a high level language C does contain many such features that are in used in HLL structured programming defined procedure calling parameter passing powerful control structures etc However much of the power and danger of C lies in its ability to allow direct access to the actual bits bytes and words of the hardware To a great extent C is a high level assembly language As Andrew from Manchester said in a bar in Germany C is not a programmer s language it is a Software Engineers language Pascal is a programmer s language In other words C is a tool for a disciplined expert and lets the inexperienced programmer fall into many traps without warning Most programmers who are familiar with C will have been used to writing
14. SEGMENT DATA GROUP gt CALLED SEGMENT START LENGTH C_C51STARTUP gt PR MAIN MAIN PR MAIN MAIN 0024H 0001H gt PR FUNC1 MAIN gt PR FUNC2 MAIN gt PR FUNC3 MAIN gt PR _EXECUTE MAIN PR FUNC1 MAIN 0025H OOOBH PR FUNC2 MAIN 0025H 000BH PR FUNC3 MAIN 0025H 000BH 2 PR _EXECUTE MAIN 0025H 000EH t ZC LIB CODE D 0028H SYMBOL tex Execute s variables no longer D 0029H SYMBOL arrex overlaid with func4 os www Phaedsys org page 95 of 194 Version 3 65 D 0008H SYMBOL y D 0009H SYMBOL arr4 D 0013H SYMBOL y5 D 0014H SYMBOL arr5 xxx WARNING 16 UNCALLED SEGMENT IGNORED FOR OVERLAY PROCESS SEGMENT PR FUNC4 MAIN xxx WARNING 16 UNCALLED SEGMENT IGNORED FOR OVERLAY PROCESS SEGMENT PR FUNC5 MAIN Note The WARNING 16 s show that func4 5 have been removed from the overlay process to remove the hazard See section 8 4 2 6 on the UNCALLED SEGMENT IGNORED FOR OVERLAY PROCESS warning 9 4 5 Function Jump Table Warning Non hazardous Here two functions are called an array of function pointers The array jump_table exists in a segment called CO MAIN1 i e the constant area assigned to module main The problem arises that the two message string arguments to the printf s are also sited here This leads to a recursive definition of the function start addresses in the jump table While this is not in itself dangerous it prevents the real function refere
15. The authors previously have stated that not the definitive as from 1999 I expect there will PROGRAMMING there would not be a K amp R3 but in early 2001 they LANGUAGE left the door open Note the standard takes longer to ratify and publish that a book which is py ttt 78 why K amp R who were part of the US ANSI ISO committee anyway got their book out ahead of the standard MAKI AL OTe ren 23 1 3 ANSI C 1989 Eventually in 1989 due to the large number of people using C ANSI produced a USA standard that became the de facto world wide standard until 1990 This stabilized the language and gave everyone except Microsoft a standard with which to conform 23 1 4 ISO C90 1990 ISO IEC 9899 Programming Languages C At the end of 1989 ISO and IEC with all it s committees from many countries world wide adopted and ratified the US ANSI standard as an International Standard From this point in theory if not in practice ISO C superceded ANSI C as the definitive standard However it should be noted that the only difference between ISO and ANSI C during the 1990 s was the Chapter numbering One of the standards had an additional chapter before the actual www Phaedsys org page 166 of 194 Version 3 65 standard throwing all the chapters out by one Paragraph numbering was the same in both NOTE This version of ISO C is used for MISRA C also for most embedded compilers as later improvements such as multi byte characters and
16. executed in RAM starting from 0000H A complication was that the memory map had to be sw itched immediately prior to hitting OOOOH The solution was to place the map switching section at Oxfffd so that the next instruction would be fetched from 0x0000 thus simulating a reset Ideally all registers and flags should be cleared before this inclu inclu inclu mai de reg h de cemb537 h de lt stdio h gt n unsigned char tx_char rx_char i PA map2 v24ini_537 timer0O_init_537 hexload_ini EAL 1 while download_completed 0 while char received fl 0 receive_byte www Phaedsys org page 112 of 194 Version 3 65 tx byte rx byte Echo hexload send_byte tx_byte char received fl 0 real_time_count 0 while real time count lt 200 ti i unsigned char code void OxFFFD Jump to absolute address AAA AAA AAA AAA AAA AAA AAA End of Module NAME SWITCH Cause PC to roll over at FFFFH to simulate reset P4 DATA OESH CSEG AT OFFFDH MOV P4 02Fh_ END AA AAAAAAAAAAKAAAAAAKAAAA End of Module MAPCON There are other ways of doing this For instance the code for the MAPCON module could be located at link time thus CODE SWITCH OFFFDH so dispensing with the CSEG AT 12 4 Simulating A Software Reset In a similar vein to the above the 8051 does not possess a software reset instruction
17. lt 7 Check for end of array dest_array array_index string ptrit Move character by character into destination array array_index This is an example of C being somewhat inconsistent this ptr statement does not mean increment the thing being pointed at but rather increment the pointer itself so causing it to point at the next sequential address Thus in the example the character is obtained and then the pointer moved along to point at the next higher address in memory 7 3 4 Summary Of Arrays And Pointers To summarise Create An Uncommitted Pointer unsigned char x_ptr Create A Pointer To A Normal C Variable unsigned char x unsigned char x_ptr amp x Create An Array With No Initial Values unsigned char x_arr 10 Create An Array With Initialised Values unsigned char x_arr 0 1 2 3 Create An Array In The Form Of A String char x_arr HELLO www Phaedsys org page 69 of 194 Version 3 65 Create A Pointer To A String char string ptr HELLO Create A Pointer To An Array char x_arr HELLO char x_ptr x arr Force A Pointer To Point At The Next Location KALUE 7 4 Structures Structures are perhaps what makes C such a powerful language for creating very complex programs with huge amounts of data They are basically a way of grouping together related data items under a single symbolic name 7 4 1 Why Use Structu
18. 1 low 21H Bit Number 849 10 11 12 13 14 15 Bit locations in an integer www Phaedsys org page 103 of 194 Version 3 65 10 2 Support For 80C517 537 32 bit Maths Unit The Siemens 80C537 and 80C517A group have a special hardware maths unit the MDU aimed at speeding up number crunching applications 10 2 1 The MDU How To Use It To allow the 8051 to cope with 16 and 32 bit int and long multiplication and division the Siemens 80C517 variant has a special maths co processor MDU integrated on the cpu silicon A 32 bit normalise and shift is also included for floating point number support It also has 8 data pointers to make accessing external RAM more efficient The compiler can take advantage of these enhancements if the MOD517 switch is used either as a pragma or as a command line extension This will result in the use of the MDU to perform gt 8 bit multiplies and divides However a special set of runtime libraries is required from Keil for linking Using the MDU will typically yield a runtime improvement of 6 to 9 times the basic 8051 cpu for 32 bit unsigned integer arithmetic Optionally the blanket use of the 80C517 enhancements after MOD517 can be selectively disabled by the NOMDU and NODP pragmas Predictably NOMDU will inhibit the use of the maths unit while NODP will stop the eight data pointers being used 10 2 2 The 8 Datapointers To speed up block data moves between external addresses the 517A
19. 25 227 233 do Executable Code while condition is true Perform executable code while condition is true 8 bits 8sign 16 bits 16 sign 32 bits 32 sign Cycles 5 6 7 8 79 82 do case execute blocks of code determined by the value of a control variable No data measured Examples if a b Executable code execute code within braces if a equal to b for i 0 i gt end value i Executable code execute code until i is equal to end_value i e not greater than do Executable code while i lt end value execute code while i less than end_value switch x case 1 ytt break case 2 Y i break case 3 y yi break www Phaedsys org page 151 of 194 Version 3 65 Perform the operation determined by the value of x Examples for i 0 i gt end value i Executable code BE se SS THA break execute code until i is equal to end_value i e not greater than but if x is ever equal to i then break out of the loop immediately Accessing Bits Bit A single bit variable located in the Bit addressable memory area Sbit A single bit variable located in the bit addressable memory either in the user or sfr area When located in the user area sbit is a defined bit within a larger char or int variable Examples bdata char x x is an 8 bit signed number in the bit area sbit sign bit x 8 bit 8 is the s
20. 27 Ed McGrawHill 1992 ISBN 0 07 050814 3 PRQA Programming Research QA C static analysis tool www programmingresearch com Randel Brian The Origins of Digital Computers Springer Verlag 1973 Ritchie D M The Development of the C Language Bell Labs Lucent Technologies Murray Hill NJ 07974 USA 1993 available from his web site http cm bell labs com cm cs who dmr index html This is well worth reading Rumbaugh et al Object Orientated Modelling and Design Prentice Hall 1991 ISBN 0 13 630054 5 Simon David An Embedded Software Primer Addison Wesley 1999 ISBN 0 201 61569 Selis Gullekson amp Ward Real Time Object Orientated Modeling Wiley 1994 ISBN 0 417 59917 4 www Phaedsys org page 189 of 194 Version 3 65 Soligen amp Berghout The Goal Question Metric Method A practical Guide for Quality Improvement of Software Development McGraw Hill 1999 ISBN 0 07 709553 7 Sutter Ed Embedded Systems Firmware Demystified CMP Books 2002 ISBN 1 57820 09907 Vahid amp Givargis Embedded System Design A Unified Hardware Software Introduction Wiley 2002 ISBN 0 471 38678 2 Van Vilet Software Engineering Principals and Practice Pub Wiley 1993 ISBN 0 471 93611 1BN 0 471 93611 1 Watkins John A Guide To Evaluating Software Testing Tools V3 Rational Ltd 2001 Watson amp McCabe Structured Testing A testing Methodology Using the Cyclomatic Complexity Model Webster Bruce The Art of Ware Sun Tzu s Classic W
21. 3 65 www Phaedsys org page 80 of 194 Version 3 65 8 Accessing External Memory Mapped Peripherals Commonly extra IO ports are added to 8051s to compensate for the loss of Ports 0 and 2 This is normally done by making the additional device s appear to be just external RAM bytes Thus they are addressed by the MOVX A DPTR instruction Typically UARTS additional ports and real time clock devices are added to 8031s as xdata mapped devices The simplest approach to adding external devices is to attach the RD and or WR lines to the device Provided that only one device is present and that it only has one register no address decoding is necessary To access this device from C simply prefix an appropriately named variable with xdata This will cause the compiler to use MOVX A DTPR instructions when getting data in or out In actual fact the linker will try to allocate a real address to this but as no decoding is present the device will simply be enabled by WR or RD In practice life is rarely this simple Usually a mixture of RAM UARTS ports EEPROM and other devices may all be attached to the 8031 by being mapped into the xdata space Some sort of decoding is provided by discrete logic or more usually a PAL Here the various registers of the different devices will appear at fixed locations in the xdata space With normal on chip resources the simple data book name can be used to access them so ideally these external de
22. C51 The first three editions of this work started this chapter with This is possibly not the place to make the case for modular programming but a brief justification might be appropriate However the interviening years have indicated that this s the place where the case for modular programming must be made In anything but the most trivial programs the overall job of the software is composed of smaller tasks all of which must be identified before coding can begin As an electronic system is composed of several modules each with a unique function so a software system is built from a number of discrete tasks In the electronic case each module is designed and perfected individually and then finally assembled into a complete working machine With software there are many similar modeling techniques used for designing the structure and modules of the code A system any system properly applied is better than no system At one time graphical modeling was the answer and this spawned CASE Computer Aided Software Engineering abd CAD Computer Aided Design tools They were expensive promised the earth and with CASE largely failed to deliver Things have improved greatly Flow charts were in then out and back in and some say never went away Firstly remember that any tool is only as good as the person Customer using it You can make a complete mess with or without the design tools tool some would say that Cash the automated tools
23. Cash Entry Customer Card ci Proceed VVith Transaction Get Required Services Process Required Services further into similar charts containing several boxes ie C functions Some systems may have several layers of child charts such as the one shown www Phaedsys org page 43 of 194 Version 3 65 The interesting thing is that there are no actual implimentation details shown Get Pasvvord or Await Cash Card Entry are generic This is where modular software containing more than one file starts to become the obvious answer In this diagram it is just a Get password box However if all the source associated with this diagram were all in one file any change would result in a re compilation of the whole file By making the Get Password or Await Cash Card Entry a seperate file we get modularity and if there are any changes to the Get Password module only that file need to be re compiled The rest only needs to be re linked It also gives the added advantage that should a different password system be used only the one file requires modifications In this case there would probably be a selection of Get Password modules depending on the customer the algorithm or the hardware Thus the main code loop can be reused Note C had reuse long before the C and OOP crowd invented it The diagrams so far were generated using the Select Yourden tool The next diagram
24. Chain There have been some changes in the compile process over the years Many years ago programmers used terminals these were simply display screens with a keyboard No intelligence they certainly did not run programs That is they could only display characters Eg ASCII BAUDOT EBSIDIC etc They text based screen usually 32 60 Or 80 characters by 25 or 40 lines The 80 by 40 were high resolution As for colour there was green text or orange text or white text that s right monochrome The highlight of graphics in those days was setting a character to reverse video flash or bold Wow Sound What do you think the bell ess RE character was for The best you got was a keyboard EE B beep Pics TEDES e Editors were single vvindovv ok everything was a single window and there was no multitasking on screen but it was quite sophisticated Some like Vl and EMACS are still in vvidespread use today 2006 They had povverful and hard to master key bindings and macros vvhereby a Master could make multiple context sensitive replacements vvith a minimum of key strokes An art that still amazes and users can still out perform the average Windows user today MAKE File Having edited and saved ones files the next step vvas to compile the Usually by invoking cc filename c on the command line Windows users should think of a DOS Box that fill the entire screen no task bar and not mouse Som
25. DJNZ DJNZ RO code Addr RI codeAddr R2 codeAddr R3 codeAddr R4 codeAddr R5 codeAddr R6 codeAddr R7 codeAddr Code Bytes Cycles Mnemonic www Phaedsys org page 183 of 194 Version 3 65 Code Bytes Cycles FO Fl F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF www Phaedsys org Ka ba ka ka ba ka ka ka ka Ka bi Ka Ka Ka Di Fei 1 e e Ked bei Fei Ked Fei Fei Ked bei DO Ked eK eK DO Kei Kei kt ke eee ka ka ka ka ka b i b i b i b i 2 Kai kat Ft ka ka Fa Fa Fa ka ka ta ta b i b i b i MOVX A DPTR AJMP codeAddr MOVX A RO MOVX A QRI CLR A A data Addr MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV A RO A GRI A RO A RI Oo of ba nn n AAAAAD N Mnemonic MOVX DPTR A ACALL codeAddr MOVX RO A MOVX RI A CPL A dataAddr A MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV MOV QRO A RI A page 184 of 194 Version 3 65 21 Appendix L Refferences This is the full set of references used across the vyhole QuEST series Not all the references are referred to in all of the QuEST papers All of these books are in the authors own library and most have been reviewed for the ACCU The reviews for these books and about 3000 others are on http www accu org bookreviews public Andrews amp Ince Practical Formal Methods with VDM McGraw Hill 1991 ISBN 0 7 707214 6 Ball Stuart Debugging Embedded Microprocessor Systems Newne
26. Editor vvith multiple windows can be syntactically correct and do nothing syntax highlighting but itis impossible to spot mechanically auto indenting on line help As a final point ALL C compilers require the Hello World program to be run as an initialisation program With Keil compilers it could be Blinky it depends if you have an LED or a serial port actually it is probably easier to solder an LED on to a PCB than find a PC with an RS232 port on these days OK so technically it is not true that you must run hello world However it really is a Very Good Idea to run Hello World with printf and that is the ONLY time you should use printf in an 8051 program Why It is because it makes sure the compiler dongle license libraries etc are all correctly installed If it compiles and an debug the examples you know that you have a good chance that the compiler is correctly wer installed Then do run a simple test project of your own Simulator or Debugger just to make sure There have been quite a few times where the problem has been an incorrect installation www Phaedsys org page 16 of 194 Version 3 65 3 C51 Basics The 8051 Architecture The Keil C51 compiler has been written to allovv C programmers to get code running quickly on 8051 systems with a short learning curve However to get the best from the 8051 family some appreciation of the underlying hardyvare is desirable The most basic decision to be m
27. Harvey Operating Systems 2 Ed Addison Wesley 1990 ISBN 0 201 50939 3 Douglas BP Doing Hard Time Developing Rea Time Systems with UML Addison Wesley 1999 ISBNO 201 49837 5 Edwards Keith Real Time Structured Methods Systems Analysis Wiley 1993 ISBN 0 471 93415 1 Embley Kurtz Woodfield Object Orientated Systems Analysis Yourdon Press 1992 ISBN 0 13 629973 3 Fenton et al Software Quality Assurance and Measurement A world wide Perspective ITCP 1995 ISBN1 85032 174 4 Fertuck L Systems Analysis and Design with CASe tools Pub WCB 1992 Gamma Erich et al Design Patterns Elements of Reusable Object Orientated Software Addison Wesley 1994 ISBN 0 201 63361 2 Gansel Jack The art of Programming Embedded Systems Academic Press 1992 ISBN 0 12 274880 8 Gansel Jack The Embedded Muse Various editions Pub Jack Gansel http www ganssle com index htm Gerham Moote amp Cylaix Real Time Programming A Guide to 32 bit Embedded Development Addison Wesley 1998 ISBNO 201 540 0 Goldberg amp Rubin Succeeding with Objects Decision Frameworks for Project Management Addison Wesley 1995 ISBN 0 201 62878 3 Hatton Les Safer C Developing Software for High integrituy and Safety Critical Systems Mcgraw Hill 1994 ISBN 0 07 707640 0 Heath Steve Microprocessor Architectures RISC CISC amp DSP 2n0 ED Butterworth Heinemann 1995 ISBN 0 7506 2303 9 Heath Steve Embedded Systems Design Newnes 1997 IS
28. Internal chip CODE space Off chip memory is addressed by using ports 0 and 2 for data and address lines With external memory these ports can not be used for any other purpose which rather restricts the capabilities of the part On parts that have internal or on chip CODE space there is a way of selecting to use the internal or external memory This is achieved by the EA line When EA 1 the internal memory is used until the end of the internal memory is reached If the internal memory is less than 64K external memory will be accessed above the internal space It is for this reason that if the internal memory is less than 64K and there is no external memory the last byte of internal CODE space should not be used If it is the PC program counter will increment to the next instruction which is external This will make ports 0 and 2 act as the address and data bus This can wreak havoc if the ports are used as lO If the EA is set to 0 only the external memory is used The EA pin is usually tied high or low and not toggled by the program It has generally been possible to have more than 64K of CODE space This is done by using I O lines from a port as additional adress lines to switch overlayed blocks of memory Usually in the range 32k to 64K with common code in 0 to 32k A fourth memory area is also off chip eXternal DATA starting at X 0000 This is box 4 in fig1 This exists in an external RAM device and like the C 0000 segment can exte
29. M Beach Issue II not issued M Beach Issue III 1994 M Beach Based on Keil C51 V3 02 Issue 3 5 January 2002 Chris Hills Revised for Keil C51 V6 Major re write Issue 3 6 October 2003 Chris Hills Revised for Keil C51 V7 and academic year One of the main changes since Issue III is the change in C syntax between C51 V4 and C51 V5 The declaration for variables before Version 5 was code unsigned char name xdata int name This was changed for version 5 to unsigned char code name int xdata name bl banked linker is now standard floating point maths improved www Phaedsys org page 8 of 194 Version 3 65 The other major visable change is the uVision IDE The uVuision 1 series IDE was a 16 bit system that ran under Win 3 1 and os NT This was available with Version 5 compilers This was replaced by uVision 2 which was a completely new 32bit native system The current IDE uVision3 is a major re write of uV2 but externally it looks very similar It is not until you use it that you realise that there are many enhancements All the tools remain command line driven This permits their use as in the past with most forms of make other IDE s and script files Disclaimer and contact details This book has been written by several humans and therefore may have errors and omissions Should you find any errors and omissions please email the current editor Chris Hills at chills phaedsys org Eur Ing Chris Hills BSc hons C Eng MIEE
30. MANAGEMENT REQUIREMENTS FOR DEFENCE SYSTEMS PART 1 REQUIREMENTS Def Stan 00 56 part 2 SAFETY MANAGEMENT REQUIREMENTS FOR DEFENCE SYSTEMS PART 2 GUIDANCE Def Stan 00 58 part 1 HAZOP Studies on Systems Containing Programmable Electronics Part 1 Requirements Def Stan 00 58 part 2 HAZOP Studies on Systems Containing Programmable Electronics Part 2 General Application Guidance QuEST Series see http QUEST phaedsys org QuESTO Design and Documentation for Embedded Systems QuEST 1 Embedded C Traps and Pitfalls QuEST2 Embedded Debuggers QuEST 3 Advanced Embedded Testing For Fun QuEST 4 C51 Primer QAl SCIL Level QA2 Tile Hill Embedded C Style Guide QA3 QUuEST C QA4 PC Lint amp DAC MISRA C Compliance Matrix www Phaedsys org page 193 of 194 Version 3 65 PhaedruS Systems Chris phaedsys org http www phaedsys org www Phaedsys org page 194 of 194 Version 3 65
31. PWM Waveform void symm_PWM_init void T2CON 0 Clear configuration register T21l 0 Timer 2 12MHz 24 2us count T210 S10 3 T2PS 1 2 prescale for 2us count Additional prescale possible on BB step XP T2CM 1 Timer 2 compare capture in mode 1 T2R1 1 Autoreload off CCO T2RO 0 mode 1 CRC into Timer2 at rollover Set initial reload value 4096us 2048 steps CRC 2 symm_PWM_period ET2 1 Enable timer2 overflow interrupt EX3 1 Enable capture interrupt for PWM drive CCEN 0 CRC CC2 unused CCEN 0x80 CC3 is symmetrical PWM output www Phaedsys org page 138 of 194 Version 3 65 IPO 0 Initialise interrupt priorities IP1 0 IP1 0x20 Make CC3 T2 Overflow interrupts priority 3 P10 0 RK KR AR IK KKK KKK KKK KK KKK RA RA IAA IA AA IA A A KK X x Timer 2 Overflov Interrupt S KKAAKKKAKKKAKKKKKKAKKKAKKKKKKKKKKKKKAKKKAKKKKKKKKKKAKKKKAKKKKKKKKKKKKKKKKKKKKKJ Interrupt at centre point of waveform to create next off point A good example of where C now givesoverhead when compared with assembler 7 USING gives single cycle registerbank switch like 166 void timer2_overflow void interrupt 5 using 2 Runtime here limits min max PWM DR P1 0x01 Toggle P1 0 to show centre of PWM TF2 0 Clear interrupt request flag CC3 CRC symm_PWM_DR
32. Q G bO Mnemonic JZ codeAddr AJMP codeAddr XRL dataAdr A XRL dataAdr value XRL A value XRL A dataAddr XRL A RO XRL A GRI XRL A RO XRL A RI XRL XRL XRL XRL XRL XRL Oo Ob ba P pa pe Dp bi 999 Si Q N Mnemonic JNZ codeAddr ACALL codeAddr ORL C bitAddr JMP A DPTR MOV A value MOV dataAddr value MOV QRO value MOV RI1 value MOV RO value MOV RI value MOV R2 value MOV R3 value MOV R4 value MOV R5 value MOV RG value MOV R7 value page 181 of 194 Version 3 65 Code Bytes Cycles Mnemonic 80 2 2 SJMP codeAddr 81 2 2 AJMP codeAddr 82 2 2 ANL C bitAddr 83 1 2 MOVC A A PC 84 1 4 DIV AB 85 3 2 MOV dataAddr dataAddr 86 2 2 MOV dataAddr RO 87 2 2 MOV dataAddr GRI 88 2 2 MOV dataAddr RO 89 2 2 MOV dataAddr RI 8A 2 2 MOV dataAddr R2 8B 2 2 MOV dataAddr R3 8C 2 2 MOV dataAddr R4 8D 2 2 MOV dataAddr R5 SE 2 2 MOV dataAddr R6 8F 2 2 MOV dataAddr R7 Code Bytes Cycles Mnemonic 90 3 2 MOV DPTR valuel6 91 2 2 ACALL codeAdr 92 2 2 MOV bitAdr C 93 1 2 MOVC A A DPTR 94 2 1 SUBB A value 95 2 1 SUBB A dataAddr 96 1 1 SUBB A RO 97 1 1 SUBB A QRI 98 1 1 SUBB A RO 99 1 1 SUBB A R1 9A 1 1 SUBB A R2 9B 1 1 SUBB A R3 9C 1 1 SUBB A R4 9D 1 1 SUBB A R5 9E 1 1 SUBB A R6 OF 1 1 SUBB A R7 Code Bytes Cycles Mnemonic AO 2 2 ORL C bitAddr Al 2 2 AJMP codeAddr A2 2 l MOV C bitAddr A3 l 2 INC DPTR A4 l 4 MUL AB A5
33. See his paper cited above This comment from one of the authors dents the mantra of many disciples that The Book is The Definitive Reference K amp R later published a new edition K amp R 2nd Ed in line with ANSI C 1989 Something else should be borne in mind when reading K amp R 1 edition It was written by experienced operating systems programmers for experienced UNIX programmers by this time UNIX was a multi user multi task OS K amp R is not and never was an introductory text on C for novices let alone 8 bit embedded systems programmers www Phaedsys org page 165 of 194 Version 3 65 Having debunked K amp R 1 Edition one should heed the commandment found in some form in most faiths honour they parents K amp R 1 edition is the root of C and the source from which it all flowed If you can find a copy or K amp R 279 edition buy one and dip into it but do not use it as a definitive reference or use it to teach people Many ten or twenty years ago did learn from it but then it was the definitive and only work 23 1 2 K amp R 2 edition 1988 K amp R 279 edition gives the syntax changes and improvements in C over the decade since K amp R1 EEN and it brought K amp R into line with the ANSI C 1989 THE standard If you want a K amp R for practical use this is the edition to have You should remember it is not despite public pressure be a K amp R3 as all the authors have moved on to new things in the last decade
34. The Software Engineering Laboratory SEL 94 102 Software Measurement Guidebook Revision 1 SEL 95 102 Software Process Improvement Guidebook Revision 1 SEL 98 001 COTS Study Phase 1 Initial Characterization Study Report OSEK Network Management Concept and Application Programming Interface Version 2 50 31st of May 1998 Operating System Version 2 1 revision 1 13 November 2000 OIL OSEK Implementation Language Version 2 2 July 27th 2000 Communication Version 2 2 2 18th December 2000 BCS Standard For Software Component Testing Draft 3 3 1997 MOD Defence Standards Def Stan 00 13 REQUIREMENTS FOR THE ACHIEVEMENT OF TESTABILITY IN ELECTRONIC AND ALLIED EQUIPMENT Def Stan 00 17 MODULAR APPROACH TO SOFTWARE CONSTRUCTION OPERATION AND TEST MASCOT Def Stan 00 31 obsolete THE DEVELOPMENT OF SAFETY CRITICAL SOFTWARE FOR AIRBORNE SYSTEMS www Phaedsys org page 192 of 194 Version 3 65 Def Stan 00 42 part 2 RELIABILITY AND MAINTAINABILITY ASSURANCE GUIDES PART 2 SOFTWARE Def Stan 00 54 Part 1 REQUIREMENTS FOR SAFETY RELATED ELECTRONIC HARDWARE IN DEFENCE EQUIPMENT PART 1 REQUIREMENTS Def Stan 00 54 part 2 REQUIREMENTS FOR SAFETY RELATED ELECTRONIC HARDWARE IN DEFENCE EQUIPMENT PART 2 GUIDANCE Def Stan 00 55 Part 1 REQUIREMENTS FOR SAFETY RELATED SOFTWARE IN DEFENCE EQUIPMENT PART 1 REQUIREMENTS Def Stan 00 55 Part 2 REQUIREMENTS FOR SAFETY RELATED SOFTWARE IN DEFENCE EQUIPMENT PART 2 GUIDANCE Def Stan 00 56 Part 1 SAFETY
35. Think in terms of chars rather than ints Get the best out of the various pointer types Get a modular structure into programs Access on and off chip ports and peripherals Deal with interrupts Use registerbanks Deal with the stack Understand RAM overlaying Interface C to assembler code Use some of the special versions Use efficient C Help the optimiser to produce the smallest fastest code The C51 Primer Will Not Help You 1 Program in ISO C get a good reference Look on the Association of C and C Users web site www accu org where they have independent reviews of several thousand C C and SW Engineering book reviews includinig an embedded section Take care as many C books are actually PC C books and specific to usually Microsoft C or C these days NOTE Whilst many swear by the Kernighan amp Ritchie book it is not really the best book to learn C for embedded use The K amp R book is more of a language definition it was written over 25 years ago for UNIX programmers It has now been superseded by the International ISO C standards in 1989 and 1999 The syntax used in the K amp R First Edition is now obsolete and should not be used The K amp R 2nd Edition followed the ISO C www Phaedsys org page 7 of 194 Version 3 65 1989 standard and was written in 1987 published in 1988 so you can see how old it is now The language has moved on 2 Write portable code simply use the compiler without using
36. ad Convert void void Capture init void extern void control pum void KKAKKKKAKKKKKKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKK k This function initialises the A D convertor P103 of 517 manual KKAKKKKAKKKKKKAKKKAKKKAKKKKKKKKKAKKKAKKKKKKAKKKAKKKAKKKKKKKKKKAKKKKAKKKKKKKKKKKKJ void ad init void ADCONO amp 0x80 Clear register but preserve BD bit ADCONO 0x01 Single conversion internal Start Channel 0 KKAKKKKKKKKKKKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKKKK k This function will perform three conversions on the A D convertor reading values from channels 0 3 G KKAAKKKAKKKKKKAKKKAKKKKKKAK KKK KKKAKKKAKKKKKKAKKKAKKKKAKKKAKKKAKKKKKKKKKKKKKKKKKKKJ Channel 0 is read using the 10 bit programmable reference method void ad_convert void unsigned char i forti dd T ck ADCONO amp 0x80 Preserve BD bit 80C537 only ADCONO i DAPR 0 while BSY Ir analog datalil float ADDAT 5 255 KKKKK KKK KKK KKK KKK KKK KKK KKK KK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKKKKKKKKKKK These routines will transmit and receive single characters by Polled use of the serial Port 0 D Fe KR A e E A RRA E e A AA A AA RAR I AAA k k k k k k k k k k k kk k k Note In real applications an interrupt driven serial port is usually preferable to avoid loss of characters
37. be short and fast These are now often written in C but it was quite common in the past to use assembler Assembler is still used for interrupts so that they are as fast and small as possible NOTE interrupts can be set to use one of the four sets of register banks using the using keyword This means that there does not have to be a register save and restore in the interrupt making the interrupt faster By default the program uses bankO so careful use of the 4 banks can greatly enhance performance The problem is that like all these tips there is no hard and fast set of rules Usually data can be passed from background to foreground or vice versa via global variables and flags This essentially simple program model can be very successful if some care is taken over the order and frequency of execution of particular sections The background called functions must be written so that they can either complete quickly or if to long for a single slice they run a particular section of their code on each successive entry from the background loop Thus each function is entered a decision is taken as to which section of code do this time the code is executed and finally the program is exited Usually with some special control flags set up to tell the routine www Phaedsys org page 56 of 194 Version 3 65 program what to do next time Thus each functional block must maintain its own control system to ensure that the right code is run on any part
38. block capable of supplying enough RAM for the needs of the single biggest function In C51 this process is performed by the linker s OVERLAY function In simple terms this examines all functions and generates a special data segment called DATA GROUP able to contain all the local variables and parameters of all C51 functions As an example if most functions require only 4 byes of local data but one particular one needs 10 the DATA_GROUP will be 10 bytes long Using the registers as a location for temporary data means that a large number of locals and parameters can be accommodated without recourse to the DATA_GROUP this is why it may appear smaller than you expect The overlayer works on the basis that if function 1 calls function 2 then their respective local data areas may not be overlaid as both must be active at the same time A third function 3 which is also called by 1 may have its locals overlaid with 2 as the two cannot be running at the same time www Phaedsys org page 91 of 194 Version 3 65 main Sieg funcz2 funcs func Ge Zone fance Zone Gg func8 func9 funclo As funcA refers to func2 and func2 refers to func3 etc A 2 3 and 4 cannot have their locals overlaid as they all form part of the same path Likewise as funcB refers to funcs5 and func6 refers to func7 etc B 6 7 and 4 cannot have their locals overlaid However the groups 2 3 4 5 6 7 and 8 9 10 may have their locals overl
39. follow the normal interrupt spacing of 8 bytes the 8 in the 8 n 3 formula Fortunately the INTERVAL pragma copes with this The interrupt formula is in reality INTERVAL n INTVECTOR and so pragma INTERVAL 6 Change spacing www Phaedsys org page 62 of 194 Version 3 65 www Phaedsys org page 63 of 194 Version 3 65 7 Pointers In C51 Whilst pointers can be used just as in PC based C there are several important extensions to the way they are used in C51 These are mainly aimed at getting more efficient code 7 1 Using Pointers And Arrays In C51 One of C s greatest strengths can also be its greatest weakness the pointer The use and more appropriately the abuse of this language feature is largely why C is condemned by some as dangerous 7 1 1 Pointers In Assembler For an assembler programmer the C pointer equates closely to indirect addressing In the 8051 this is achieved by the following instructions MOV RO 40 Put on chip address to be indirectly MOV A RO addressed in RO MOV RO 40 Put off chip address to be indirectly MOVX A GRO addressed in RO MOVX A DPTR Put off chip address to be indirectly addressed in DPTR CLR A MOV DPTR 0040 Put off chip address to be indirectly MOVC A A DPTR addressed in DPTR In each case the data is held in a memory location indicated by the value in registers to the right of the 7 1 2 Pointers In C51 The C equivalent o
40. function did not work the lesser interrupts simply waiting until the RETI The solution was to hijack the unused A D converter interrupt IADC and attach the second section of the interrupt function to it Then by deliberately setting the IADC pending flag just before the closing the second section could be made to run immediately afterwards As the priority of the ADC interrupt had been set to a low level it was interruptable Primary Interrupt Attached In CCO Input Capture www Phaedsys org page 111 of 194 Version 3 65 tdce in At Bien Ena IADC EADC Lower priority section attached to ADC interrupt tdc_in IADC EADC Low t interrupt 8 h priority section may not be interrupted ble lower priority section attached to ADC interrupt 1 1 Force ADCinterrupt Enable ADC interrupt L TA t Low priority interrupt 10 0 0 Prevent further calls T T priority section which must be interruptable and guaranteed to follow high priority section above In the decade or so since the first edition and some 500 new variants later there is now the CC1010 from Chipcon that has the TRAP instruction Op code A5Sh for break points and debugging 12 3 Code Memory Device Switching This dodge was used during the development of a HEX file loader for a simple 8051 monitor After receiving a hexfile into a RAM via the serial port the new file was to be
41. has 8 datapointers These are only used by C51 in the memory and stering manipulation library functions like memcpy and strcpy for example The general MOD517 switch will enable their use Note that the strcat routine does not use the additional data pointers If the extra pointers are to be used both in background and interrupt functions the DPSEL register is automatically stacked on entry to the interrupt and a new DPSEL value allocated for the duration of the function 10 2 3 800517 Things To Be Aware Of The 80C517 MDU is used effectively like a hardware subroutine as it is not actually part of the 8051 cpu As such it is subject to normal sub routine rules regarding re entrancy If as an example both a background program and an interrupt routine try to use the MDU simultaneously the background calculation will be corrupted This is because the MDU input and output registers are fixed locations and the interrupt will simply overwrite the background values To allow the background user to detect corruption of the MDU registers the MDEF bit is provided within the ARCON register After any background use of the MDU a check www Phaedsys org page 104 of 194 Version 3 65 should be made for this flag being set If so the calculation must be repeated Appropriate use of the NOMDU pragma could be used instead Note the compiler does not do this the user must add the following code to overcome the problem pragma MOD
42. in A 40h in to the external RAM whose address is F contained in the DPTR register 8000H ie put 40h in to external data address 08000h The above addressing mode forms the basis of the LARGE model MOVX RO 080H MOVX A RO www Phaedsys org page 20 of 194 Version 3 65 This alternative access mode to external RAM forms the basis of the COMPACT memory model Note that if Port 2 is attached to the upper address lines of the RAM it can act like a manually operated paging control The important point to remember is that the PSEN pin is active when CODE instructions are being fetched The external READ and WRITE are active when MOVX move external DATA instructions are being carried out www Phaedsys org page 21 of 194 Version 3 65 Jiro lol Dina 3 2 Hardware Memory Models Although we are concerned with the software the hardware is never far away This section will show the three basic hardware set ups External XDATA external CODE and the Von Neumen method for being able to write to the external CODE space so that boot loaders can write code to memory Note this method is not used for internal FLASH or OTP code memory 3 2 1 External DATA This is the basic wiring for external data Port 0 has 8 bits of the Data but also the lower 8 bits of the address bus Thus to de multiplex the bus a latch must be used In this case a 74LS373 The ALE is used to latch the address Thus Port 2 and the out
43. in circuit emulators etc It may be linked with object files from either Intel PLM51 or ASM51 using the Keil L51 linker The final output is Intel OMF51 Versions gt 2 3 of the compiler will produce an extended Intel OMF51 object file if the DEBUG OBJECTEXTEND command line switches are used This passes type and scope information into the OMF51 file which any debugger in circuit emulator should be able to use The extensions to the original Intel format are a proprietary Keil development but have been widely copied by IAR et al 14 2 HEX Files For EPROM Blowing To blow EPROMS an additional stage is usually necessary to get a HEX file This is an ASCII representation of the final program without any symbol information Almost every EPROM programmer will understand Intel HEX The OH51 OHS51 utility performs the conversion from the linker s OMF51 file to the standard 8bit Intel HEX format 14 3 Assembler Output Optionally a valid A51 assembler C source listing file can be produced by C51 if the SRC command line switch is used This has the original C source lines interleaved with the assembler and is very useful for getting to know how the compiler drives the 8051 Do not be tempted to try hand tweaking the compiler s efforts Whilst you may be able to save the odd instruction here and there you will create a totally unmaintainable program It is much better to structure source code so that you write efficient code from the start Simple
44. interrupt for igno CC4EN 0x05 CC4 port 1 4 is output compare mode 1 big IPO 0 Initialise interrupt priorities IP1 0 H IP1 0x26 Make CC4 interrupt 3 priority IPO Ox3A Input capture is 2 priority KKKKKKKKKKKKKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKK Input Capture Interrupt On Port1 0 CC Ge KKAKKKKKKKAKKKAKKKKAKKKAKKKAKKKKAKKKAKKKAKKKKKKKKKKAKKKKKKAKKKAKKKKKKKKKKKKKKKKKKKK On every negative edge at P1 0 this routine is entered Frequency calculation is possible using frequency 1000007 Timer2 Count Time this T2 last www Phaedsys org page 136 of 194 Version 3 65 timer2 500007 CRC last CRC A new pulse is generated at a fixed angle after the interrupt using CC4 output compare This is the basis for ignition and injection timing in engine management systems The maths unit is essential for keeping run times short EJ void CCO int void interrupt 10 using 3 unsigned int temp Calculate Input Frequency frequency 500000 unsigned long CRC time_last_360 time_for_360 CRC time_last_360 temp CRC unsigned int unsigned long unsigned long time_for_360 marker_angle 255 EAL 0 marker_time temp EAL 1 5 time_last_360 CRC KKKKKKKKKKKKKKKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKKKKKKKKKK X Generate marker pulse after CCO i
45. is disabled after RESET TMOD 0x20 E Load Timer Mode Control Register Timer 1 under software control with TRI as Timer in mode 2 8 bit auto reload www Phaedsys org page 129 of 194 Version 3 65 SOCON 0x52 R Serial connection in mode 1 1 Start 8 Data 1 stop bit start enabled Transmitter empty Receiver empty PCON 0x80 E SMOD 1 to double baud rate TRL ah Timer 1 start This should be placed in a module preferably called main c and compiled with gt C51 main c This produces a file main obj Next link main obj with the printf function held in a C51S LIB library and fix the location of the program gt L51 main obj c5lp lib c5ls lib to exec abs To yield an Intel OMF51 format file named exec abs If you are using an EPROM programmer you will need an Intel HEX file Use OHS51 EXE for this gt OHS51 exec abs to give exec hex an Intel HEX file Basically this is all there is to producing a working C51 program Some refinements might be to make sure that the C51LIB DOS environment variable has been set to indicate where the C51S LIB is located To do this make sure that you have SET C51LIB C51P LIB in your autoexec bat file Likewise if you also add SET C51INC C51P INC the long and untidy pathname for stdio h can be eliminated If C51 has been installed properly this should have already been done www Phaedsys org page 130 of 194 Vers
46. is a little different to the one above This was generated by the DA C that reverse engineered the C source code This example has gone a little to the extreme to demonstrate the point As with all things common sense should be used eject_Cash _card eject c Process _ services services c Process lt roceed trans action p process c process c Main get services main c services c _ await_cash _card_Entry waitcard c get_pas sword get_password c This is the basic layout of the empty C functions As can be seen there is one C function per file The exceptions are the Process and Services files This is because the Process file has the option to either proceed or not and the Services file would contine both the list of services availavle as well as the interface to them Thus if the services were to change only the one module would need changing Apart from making the program more manageable in that file listings are shorter and functionality is contained there are other benefits Data security Many variables can be made local to the one file With data overlaying enabled see Linker manual this saves much space on an 8051 Simply put the linker can overlay local parameters in the same memory space As a General Rule only make a variable Global if you really have to Global variables take up permanent residence in the very limited memory There are also similar arguments for functions
47. look at the ROM memory models These are for the CODE space This does not include any data unless constants have been placed in to CODE space as follows unsigned char code constant 1 3 unsigned char code array_1 3 CAT A Kat VE RE Multi dimensional arrarys are also permited unsigned char code array 3 5 Kat TRT Fesch Pe e ee ZU Le W TT hsp A LECH WE DI YE www Phaedsys org page 24 of 194 Version 3 65 D At run time you can not use array as an l value that is array 1 1 X is illegal since it s in ROM Do remember that for arrays in C the firsr ellerment is always 0 So the above array has elerments 0 0 to 2 4 3 3 1 1 ROM SMALL This is used where the total program CODE size is less than 2K In this mode all assembler CALL and JMP are coded as ACALL and AJMP These are smaller and faster instructions that the LCALL and LJMP Thus smaller and faster code is produced For some of the smaller 8051 family members this is an ideal model 3 3 1 2 ROM COMPACT Compact is used where the the program CODE may be up to 64K but no function will be larger than 2K In this modle all CALL instructions are coded as the longer LCALL but the JMP instructions remain as the shorter and faster AJMP 3 3 1 3 ROM LARGE The LARGE model sets both the CALL and the JMP at the longer and slower LCALL and LIMP In this model the program may be 64K as in the compact but the functions can be over 2K in fact they could be up to 64
48. lovvest address The linker must then be used to fix the address of the whole block in memory Source File MAIN C pragma ORDER unsigned char xdata RTC_secs unsigned char xdata RTC_mins unsigned char xdata RTC_hours main RTC mins 1 Linker Input File MAIN LIN main obj amp to main amp XDATA 2XD2MAIN Ofa00h The alternative _at_ control forces C51 to put data objects at an address given in the source file Fix Real Time Clock Registers Over Memory Mapped Device Fix each item individually unsigned char xdata RTC_secs at Oxfa00 unsigned char xdata RTC mins at Oxfa0l unsigned char xdata RTC hours at Oxfa02 main RTC_mins 1 which hopefully is self explanatory www Phaedsys org page 88 of 194 Version 3 65 9 Linking Issues And Stack Placement This causes some confusion especially to those used to other compiler systems 9 1 Basic Use Of L51 Linker The various modules of a C program are combined by a linker After compilation no actual addresses are assigned to each line of code produced only an offset is generated from the start of the module Obviously before the code can be executed each module must be tied to a unique address in the code memory This is done by the linker L51 in the case of Keil RL51 for Intel is a utility which assigns absolute addresses to the compiled code It also searches library files for the actual code for any standard functions
49. may be called C51 does this automatically ii The local variables in the service routine must not be shared with locals in the background loop code the L51 linker will try to re use locations so that the same byte of RAM will have different significance depending on which function is currently being executed This is essential to make best use of the limited internal memory Obviously this relies on functions being executed only sequentially Unexpected interrupts cannot therefore use the same RAM 6 2 1 The Interrupt Function Type To allow C coding of interrupts a special function type is used thus timerO0 int interrupt 1 using 2 unsigned char templ unsigned char temp2 executable C statements Firstly the argument of the interrupt statement 1 causes a vector to be generated at 8 n 3 where n is the argument of the interrupt declaration Here a LJMP Umer Int will be placed at location OBH in the code memory Any local variables declared in the routine are not overlaid by the linker to prevent the overwriting of background variables Logically with an interrupt routine parameters cannot be passed to it or returned When the interrupt occurs compiler inserted code is run which pushes the accumulator B DPTR and the PSW program status word onto the stack Finally on exiting the interrupt routine the items previously stored on the stack are restored and the closing P causes a RE
50. netet en s 185 29 TM KEE 191 www phaedsys org page 5 of 194 Version 3 65 www Phaedsys org page 6 of 194 Version 3 65 0 About The C51 Primer If you ve looked at a few 8051 datasheets other 8051 books or flicked through the chapters in this guide you may be left thinking that it is necessary to be an 8051 expert to produce workable programs with C51 This is not the case In fact many hobbiests have turned out 51 systems at home using only basic tools It is perfectly possible to write real commercial programs with nothing more than a reasonable knowledge of the ISO C language the 8051 extensions and some appreciation of hardware However to get the maximum performance from the 8051 family knowing a few tricks is very useful This is particularly true if you are working on a very cost sensitive project where needing more memory can result in an unacceptable cost After all if cost was not a consideration we would all be using ARM9 or PowerPC s Whilst the C51 Primer is really aimed at users of the Keil C51 Compiler it is applicable in part to compilers such as IAR and Tasking This edition of the C51 Primer will use the Keil C51 PK51 package version 7 5 released in 2005 The C51 Primer Will Help You Find your way around the basic 8051 architecture Make a sensible choice of memory model and special things to watch out for Locate things at specific addresses Make best use of structures Use bit addressable memory
51. next number 7 is greater than the square root of 25 so the process stops The remaining numbers are all prime 2357111317 1923 For each C operation the number of cycles to execute typical examples is given for all supported data types To give some idea of execution times with a 12MHz 8031 one cycle is lus Please note that timings for long and float operations are considerably reduced on the Siemens 80C537 due to its 32 bit maths unit Cycle Table Key Unsigned Char 8 bits Char 8 sign Unsigned Int 16 bits Int 16 sign Unsigned Long 32 bits Long 32 sign float float 32 bits IEEE single precision Notes Timings include parameter loading pre amble where appropriate Clock speed assumed to be 12MHz lus cycle if not otherwise stated The small memory model was used so that no off chip ram was employed Basic C Mathematical Functions Addition 8 bits 8 sign 16 bits 16sign 32 bits 32 sign float www Phaedsys org page 144 of 194 Version 3 65 Cycles 3 3 6 6 63 5 Subtraction 8 bits 8 sign 16 bits 16 sign 32 bits Cycles 4 4 7 7 64 8 Multiplication 8 bits 8 sign 16 bits 16 sign 32 bits Cycles 10 13 46 48 160 Division 8 bits 8 sign 16 bits 16sign 32 bits Cycles 8 19 26 39 1611 Modulo 8 bits 8 sign 16 bits 16 sign 32 bits Cycles 3 3 6 6 63 Examples a b c azbic Complex Mathematical Functions sin x float Cycles 1553 cos x float Cycles 1433 tan x float Cycl
52. or two bytes that might be expected The end result is that pointers can be used without regard to the actual location of the data For example xdata char buffer 10 code char message HELLO void main void char s char td s d message buffer while s 15 0 d st Yields RSEG XD T1 buffer DS TO RSEG CO T1 message DB SH E TE L O 000H xdata char buffer 10 code char message HELLO void main void RSEG PR main T1l USING 0 main SOURCE LINE 6 7 char Ze s char a 3 7 T s message SOURCE LINE 11 MOV s 02 05H MOV s 02 01H HIGH message MOV s 02 02H LOW message H d buffer SOURCE LINE 12 MOV d 02 02H MOV d 02 01H HIGH buffer MOV d 02 02H LOW buffer 2C0001 7 S while s 15 NO SOURCE LINE 14 MOV R3 s202 MOV R2 s202t01H MOV R1 s 02 02H LCALL C_CLDPTR JZ 2C0003 dijte s www Phaedsys org page T6 of 194 Version 3 65 7 SOURCE LINE 15 INC s 02 02H MOV A s 02 02H JNZ 2C0004 INC s 02 01H 2C0004 DEC A MOV R1 A LCALL 2 C_CLDPTR MOV R7 A MOV R3 d202 INC d 02 02H MOV A d 02 02H MOV R2 d202t01H JNZ 2C0005 INC d 02 01H 2C0005 DEC A MOV R1 A MOV A R7 LCALL C_CSTPTR TA SOURCE LINE 16 SJMP 2C0001 i SOURCE LINE 17 C0003 RET END OF main END As can be seen the pointers s and d are composed of three bytes not two as might be exp
53. other changes for C99 were not needed and in many cases not easy to implement At the time of writing early 2003 there were still only two C99 compilers available ISO C Amendment 1 1993 Multi byte Characters ISO C Technical Corrigendum 1995 6 T1 Work on the new standard starts Due to the fact that many things eg MISRA C reference ISO C 90 the author has managed to persuade BSI British Standards Institute to make ISO C90 with Amendment 1 and TC1 available again at a comparatively low price of 30 about 45US 23 1 5 ISO C99 ISO IEC 9899 1999 The IS0 C99 is now the definitive international work on the Language It is not what I would call readable though It was some months after the ISO C99 was finished that ANSI and all the other National Bodies around the world adopted it A copy of ISO C is a useful document to have if only to win bets at lunchtime ISO C99 IS09899 1999 This can be obtained correct as of early 2001 for 18 US as a PDF from www techstreet com ncitsgate html which is where I and most of the UK standards panel got my copy It prints out to 537 pages I printed it out on a double sided photocopier via the network on A4 double sided and it is quite usable The good news is at the time of writing November 2001 It is likely that a book publisher in partnership with the ACCU see www accu org will turn both the C and C standards in to books at around the 30 mark www Phaedsys
54. programs within large machines running MS Windows Unix Linux or other RTOS Even in the now cramped 640KB of MSDOS considerable space was available so that the smallest variable in a program will usually be an int at least 16 bits Most interfacing to the real world will be done via system interrupts and operating system function calls Therefore the C that was written is concerned only with the manipulation and processing of variables strings arrays etc It rarely has to manipulate hardware In the modern 8 bit microcontroller however the situation is somewhat different Taking the 8051 as an example the total program size might only occupy 4 or 8K bytes and use only 128 bytes of RAM Real devices such as ports special function registers that access peripherals and directly accessing the hardware must be addressed by the application usually in C Though some still try and do in line assembler in the C more of which later Interrupts have to be written and serviced which require vectors at absolute addresses Special care must be taken with a routine s data memory allocation if over writing of data is to be avoided One of the fundamentals of C is that parameters are passed toa function and results returned to the caller via the stack This means a function can be called from both interrupts and the background process without fear of its local data being overwritten The ability to call a function from several possibly overlapping place
55. required that the parameters were placed between the brackets in the function name as they would be in a function call Thus the prototype for the function above would be unsigned char get_password unsigned char status Whilst the C 89 did require the parameter types it did not require that the parameters be names as well So the prototype for the call above could be www Phaedsys org page 48 of 194 Version 3 65 unsigned char get passvord unsigned char However his way lies madness The parameter name should always be included and to be absolutely correct the new ISO C99 typedefs as per MISRA C Rule 13 should be used as well giving a prototype of UINT8_T get_password UNIT8_T status This prototype system could make matters worse if incorrectly used have seen the problem of inter module maintenance on a grand scale A multi module program had some functions changed All the programmer did was copy the new function prototype and recompile Then in any module that did not compile he pasted the new prototype Next he did went to each error and pasted the new function call The problem was in most cases he forgot to remove the original now incorrect prototype The program was littered with redundant prototypes and in some cases unused data The other problem was that as the old function prototype was in some of the modules they did not complain where there were calls to the old function that had been missed Thi
56. sign 32 bits 32 sign float Cycles 1 1 5 5 59 59 140 Multiply tyvo operands and store result in first one 8 bits 8sign 16 bits 16 sign 32 bits 32 sign float Cycles 1 1 5 5 59 59 140 J Divide two operands and store result in first one 8 bits 8sign 16 bits 16 sign 32 bits 32 sign float Cycles 1 1 5 5 59 59 140 Example a b E Make a equal to b if a b check whether a is equal to b at 3 S a is equal to itself 3 a 10 a is equal to itself divided by 10 Relational And Logical Functions These are used to test data and are usually used with if and other control statements amp amp AND 8 bits 8sign l6bits 16 sign 32 bits 32 sign float Cycles 6 6 8 8 28 28 28 LI OR 8 bits 8sign l6bits 16 sign 32 bits 32 sign float Cycles 6 6 8 8 28 28 28 gt Greater than 8 bits 8sign 16 bits 16 sign 32 bits 32 sign float Cycles 5 9 7 11 85 88 302 lt Less than www Phaedsys org page 147 of 194 Version 3 65 8 bits 8sign 16 bits 16 sign 32 bits 32 sign float Cycles 5 9 7 11 85 88 302 gt Greater than or equal to 8 bits 8sign 16 bits 16 sign 32 bits 32 sign float Cycles 5 9 7 11 85 88 302 lt Less than or equal to 8 bits 8sign 16 bits 16 sign 32 bits 32 sign float Cycles 5 9 7 11 85 88 302 Examples ifla gt byu executable code 1 if a 1 amp amp b 2 executable code 1 else Alternative executable code Execute code 1 if a is equal to 1 and b equal to 2
57. the majority of people learn C in a Unix or PC environment with plenty of memory real or virtual disk space native debugging tools and the luxury of a screen keyboard and usually a multi tasking environment Because C was originally designed for compact operating systems it can directly manipulate the hardware and memory addresses not always in the way expected by the programmer This can be very dangerous in normal systems let alone embedded ones C permits the user to do many unorthodox things A prime example is to declare 2 arrays of 10 items A 10 and B 10 Then knowing that in the particular implementation in use they are placed together in memory use the A reference for speed step from A 0 to A 19 This is the sort of short cut that has got C abad name Yes I have seen this done The syntax of C and its link with UNIX famous for its terse commands means that many programmers try to write C using the shortest and most compact methods possible This has led to lines like while I d s or typedef boll func M m This has given C the reputation for being a write only language and the domain of hackers www Phaedsys org page 164 of 194 Version 3 65 As C was developed when computing was in its infancy and there were no guidelines for SW engineering In the early days many techniques were tried that should by now have been buried Unfortunately some of them live on 23 1 From K am
58. the result always 8 bits The unsigned int casts ensure that a 16 bit multiply is used by C51 unsigned char z unsigned char x unsigned char y z unsigned int y unsigned int x gt gt 8 Here the two eight bit numbers x and y are multiplied and then divided by 256 The intermediate 16 bit unsigned int result is permissible because y and x have been loaded by the multiplier library routine as int s www Phaedsys org page 123 of 194 Version 3 65 16 6 Calculations which consist of integer operands but which always produce an 8 bit char due to careful scaling result thus unsigned int x y unsigned char z z x y 256 will always work as C51 will equate z to the upper byte least significant of the integer result This is not machine dependant as ANSI dictates what should be done Also note that C51 will access the upper byte directly thus saving code 16 7 Floating Point Numbers One operand is always pushed onto an arithmetic stack in the internal RAM In the SMALL model the 8051 stack is used but in other models a fixed segment is created at the lowest available address above the register bank area In applications where on chip RAM is at a premium full floating point maths really should not be used Fixed point is a far more realistic alternative www Phaedsys org page 124 of 194 Version 3 65 17 Conclusion The foregoing should give a fair idea how the C51 compiler can be
59. used in real embedded program development Its great advantage is that it removes the necessity of being an expert in 8051 assembler to produce effective programs Really for the 8051 C51 should be viewed as a universal low to medium level language which both assembler and C programmers can move to very simply Access to on and off chip peripherals is painless and the need for assembler device drivers is removed Well constructed C programs will lend themselves to being re used and eventually you should be able to create your own libraries of functions and core modules This is for me a strange conculsion as it effectively comes halfway through this paper However that is the nature of embedded engineering The end never is So always constrtuct your programs well because they will probably have a life far longer than you ancicipate www Phaedsys org page 125 of 194 Version 3 65 www Phaedsys org page 127 of 194 Version 3 65 18 Appendix A Constructing A Simple 8051 C Program Please note this is a program from the original C51 Primer In time it will be converted to C51 V7 and MISRA C compliance Often the most difficult stage in 8051 C programming is getting the first program to run Even if you are not having to grapple with C as a new language the business of dealing with special function registers interrupts and memory mapped peripherals can be a bit daunting This simple program contains all the basic steps required to get a
60. versions Compilation and more particularly linking errors are reduced as there is effectively only one external reference for each global item in the entire program For structures and unions the template only appears once again reducing the potential for compilation and linking problems 5 5 Task Scheduling 5 5 1 Applications Overview When most people first started to learn to program it was often using interpreted BASIC on a home computer or a PC The programs are not usually too complicated they start when you type RUN and finish at END or STOP In between the start and stop the computer appears to be totally devoted to executing your simple program When it is finished you are simply thrown back to the BASIC editor or operating environment Most modern computers a use a multi process operate system such as Unix Linux or Microsoft Windows This can appear to run many programs at once your program is just one of many apparently running at the same time In an 8051 system often there is no operating system to run the program The other thing to realize is that when you say print file on a PC with an operating system e g MS Windows is that the data is sent to another program called a printer device driver In an 8051 program you would have to right your own printer driver Now you have two programs that need to run apparently at the same time www Phaedsys org page 55 of 194 Version 3 65 Who do you achieve
61. 0x56 0x6C 0x6F Vu With large objects like the above it is obviously important to state a memory space When working in the SMALL model in particular it is very easy to fill up the on chip DATA RAM vvith just a single tablel RAM constants vvould be unsigned char scale factor unsigned int fuel constant 128 t OxFD34 These could however have their values modified during program execution As such they are more properly thought of as initialised variables see section 3 2 2 4 2 Variables 4 2 1 Uninitialised Variables Naturally all variables exist in RAM the configuration of which is given in section 2 1 1 Note the MISRA C guide Rule 30 says that all variable shall have been asigned a value before use It is always a good idea to set all variables to a known value le set pointers to NULL and other variables to O or a set error condition Thus if they are not set elsewhere before use it is would be possible to detect this However as this takes time in startup it is some times not a good idea Many embedded systems are required to come alive in a very short and precise time The setting in the uVision IDE will determine the overall memory model or the pragma memory_mode line in the file In all examples in this guide the pragma line will be used to highlight the global model in use In this case all variables are placed within the on chip RAM However specific variables can be forced elsewhere as follows pragma SMA
62. 1 SOURCE LINE 21 SETB test_flag A if 1 testbit test flag SOURCE LINE 23 JBC test flag C0003 d Pl Oxff H SOURCE LINE 24 MOV P1 0FFH i j SOURCE LINE 25 H T SOURCE LINE t 27 C0003 RET END OF main END See pages 9 17 in the C51 Manual 11 3 EA Bit Control pragma Whilst the interrupt modifier for function declarations remains unchanged a new directive DISABLE allows interrupts to be disabled for the duration of a function Note that this can be individually applied to separate functions within a module but is given as a pragma rather than as part of the function declaration Although not verified yet DISABLE gives the user some control over the EA or EAL bit 11 4 16 Bit sfr Support Another new feature is the 16bit sfr type Within expanded 8051 variants in particular many 16 bit timer and capture registers exist Rather than having to load the upper and lower bytes individually with separate C statements the sfrl6 type is provided The actual address declared for a 16 bit sfr in the header file is always the low byte of the sfr Now to load a 16 bit sfr from C only a single int load is required Be warned 8 bit instructions are still used so the 16 bit load read is not indivisible odd things can www Phaedsys org page 108 of 194 Version 3 65 happen if you load a timer and it overflovvs during the processi Note that usually only timer 2 or above has the high low bytes ar
63. 10 FUEL_CONSTANT temp 10 100 2 In this case precedence gives 200 2 10 but then am sure you knew that However if it had been define BASE 50 define FUEL_CONSTANT 100 BASE then temp miles FUEL_CONSTANT The answer would have been miles 100 50 and NOT miles 150 www Phaedsys org page 114 of 194 Version 3 65 13 C51 Library Functions One of the main characteristics of C is its ability to allow complex functions to be constructed from the basic commands To save programmer effort many common mathematical and string functions are supplied ready compiled in the form of library files 13 1 Library Function Calling Library functions are called as per user defined functions Le include ctype h char test_byte result isdigit test_byte where isdigit is a function that returns value 1 true if the test byte is an ASCII character in the range 0 to 9 The declarations of the library functions are held in files with a h extension see the above code fragment Examples are ctype h stdio h string h etc These are included at the top of the module which uses a library function Many common mathematical functions are available such as In log exp 10x sin cos tan and the hyperbolic equivalents These all operate on floating point numbers and should therefore be used sparingly The include file containing the mathematical function prototypes is math h L
64. 3 3 3 Choosing The Best Memory Configuration Model With the memory models a decision has to be made as to which one to use With the choice of three ROM or CODE sizes and three DATA models there are potentially 9 variations In fact with the ability to change the model locally there are an infinite number of models but that will be covered later IHowever thiongs are not as bad as they first appear The first choice is the ROM This should be relatively simple Especially as it is not a problem to change this just point and click in the output tab on www Phaedsys org page 26 of 194 Version 3 65 the KEIL IDE The changes here are relatively minor With the selection of the DATA models it is more problematic as two of the modes require XDATA which would require additional physical memory and the loss of ports 0 and 2 not a minor change in the design Some parts now have on chip EDATA or XDATA which makes the dilema a little easier Single chip 8051 users may only use the SMALL model unless they have an external RAM fitted which can be page addressed from Port 0 and optionally Port 2 using MOVX A RO addressing This permits the COMPACT model While it is possible to change the global memory model half way through a project it is not recommended There are other versions of the 8051 family that now have large amounts of additional Aux Extra or additional on chip Xdata memory on chip that can be used with the other memory models so s
65. 3 65 5 4 Standard Templates and Version Control When constructing an application the source should always be thought through and the modules planned particularly the interfaces between modules In order to keep track of the modules standard templates should be used In fact the templates should be used for any code written event the temporary code I once worked on a large project doing some maintenance There were thirty of us do the maintenance I noticed that one of the executables was called FTBO2 I could not work out why so I asked the team leader who asked the project leader who though back in to the mists of time about 5 years and explained The code we were working on was the origional demo software constructed as part of the feasability study the FTBO2 stood for Flying Test Bed 02 You should always work assuming that the code will go on for ever This may seem onourous but if standard templates are used it takes only a seconed to do The appendix contains some suitable templates Using the templates the majority of the work is done for you However even more can be done automatically The templates in the appendaix have VCS keywords embedded in them These keywords wil be expanded wil be expanded by the VCs software to automatically put in things like Author file name revision number history etc The format of the templates but generally all the vcs use similar key words so they should be easliy adaptable 5 4 1 Vers
66. 5 5 5 1 Applications OVEIVICW nana aaa nanen anen even nene even eee 7 nene pene eee penne ne pene nene nene eee nenen 55 5 5 2 Simple 8051 multi task SYSteMS ENEE 56 5 5 3 Simple Scheduling A Partial Solution 58 6 C language Extensions For 8051 Drooramming sss sese sese esse eee eee enen eee pene nene ene eee eee 60 6 1 Accessing 8051 On Chip Peripherals AA 60 612 Interi uplSi ee vetes den s dendi eege dee dushe eta t s Eed ethet ST 61 6 2 1 The Interrupt Function Type NEEN 61 6 2 2 Using C51 With Target Monitor DEDUGGETS EE 61 6 2 3 Coping Interrupt Spacings Other Than 8 62 Pointers In GDA isha son ras cc ee REENEN Eege ee ee Ee 64 7 1 Using Pointers And Arrays In Ch 64 www phaedsys org page 3 of 194 Version 3 65 7 11 Pointers M Ass mbler ishi ndasi dis ro de tts oes LEES ee 64 12 Pointers NCS sesi tohen Teen hd eros dove d nohet 64 7 2 Pointers To Absolute Addresses ENEE 66 71 8 Arrays And Pointers Two Sides Of The Same Con 67 23 Uninitialised Arrays cc cecccctdeetetcctsccdecnswetexttecedegsavans tees e de da gat adet ed aia 67 1 9 2 InitialiseG ATYQYS nive ededed ser pn veh ges ecet eater Eege e Tan detare 67 1 353 USING ATE QY Sa seni he cots S e e u e ha e E Se shack ty 68 7 3 4 Summary Of Arrays And Pointers nun nana nana ana anen nenen eee eee eee penne nene eee e ten enen 69 T SHTUCIUT S na leese n dt a eg eege nee ven Esse 70 1 4 1 Why Use Structutes 2 ia ceniodorer odes te tan
67. 517 include reg517 h long x y Z func while 1 eg gg 32 bit calculation if MDEF 0 If corruption has break occurred then repeat else exit loop 10 3 87C751 Support The Philips 87C751 differs from the normal 8051 CPU by having a 2k code space with no option for external ROM This renders the long LJMP and LCALL instructions redundant To cope with this the compiler must be forced to not generate long branch instructions but to use AJMPs and ACALLs instead 10 3 1 87C751 Steps To Take 1 Invoke C51 with C51 myfile c ROM SMALL NOINTVECTOR or use pragma ROM SMALL 2 Use the INIT751 A51 startup file in the LIB directory 3 Do not use floating point arithmetic integer or long divides printf scanf etc as they all use LCALLs 4 A special 87C751 library package is available which will contain short call versions of the standard library routines 10 3 2 Integer Promotion Automatic integer promotion within IF statements is incorporated in version gt 3 40 to meet recent ANSI stipulations in this area This makes porting code from Microsoft or Borland PC C compilers much easier Thus any char s within a conditional statement are pre cast to int before the compare is performed This makes some sense on 16 bit machines where int is as efficient as char but in the 8051 char is the natural size for data and so some loss of efficiency results Fortunately
68. 65536 t temp pwm_duty_ratio 100 Initial duty ratio 255 1 CMO CMI CMSEL 0 CMSEL d Assign CMO to compare timer CMSEL diq Assign CM1 to compare timer www Phaedsys org page 135 of 194 Version 3 65 CMEN 0 CMEN e Enable port 4 0 as PWM front CMEN a Enable port 4 1 as PWM rear KKK KKK KKK KKK KKK KKK KKK KKK KK KKK KKK KKK KKK KKK KKK KKK KKK kk kek kk kk kek kk KA kek AKK KA E M This function initializes the Output Compare Input Capture System on Timer2 Port 1 Two captures are enabled CCO captures an event on Pin 1 0 CC1 will be triggered by a write to the low order Byte CCLI a KKAKKKKKKKKKKKAKKKAKKKKKKAKKKAKKKKKKAKKKKKKAKKKAKKKKKKKKKKAKKKKKKKKKKKKKKKKKKKJ The capcom unit when attached to timer2 is suitable for frequency YA measurement and pulse generation XI void Capture CCO init void T2CON 0 7 T211 0 Timer 2 12MHz 24 2us count T210 Les T2PS 1 2 prescale for 2us count CTCON BL T2CM 1 Timer 2 compare capture in mode 1 T2R1 Dr No autoreload off CCO CCEN 0 5 CCEN 0x01 Input capture on CCO CCEN Ox0C Timer 2 latched into CCl on write inte DCL 7 CCEN 0x80 CC3 is output compare I3FR 0 Z CCO is initially ve edge triggered Pl 0x01 Put port 1 0 high for input capture EX3 1 A Enable capture interrupt for road speed EX2 1 i Enable output compare
69. A variation of this is to declare a pointer to zero and use a variable as an offset thus char xdata ptr main unsigned int i unsigned char x ptr char 0x0000 for i 0 i lt 0x40 i x ptr i This results in rather more code as an addition to the pointer must be performed within each loop 8 4 The volatile Storage Class A common situation with external devices is that values present in their registers change without the cpu taking any action A good example is a real time clock chip the time changes continuously without the cpu writing anything Consider the following unsigned int xdata milliseconds 0x8000 Pointer to RTC chip time milliseconds gt 1 Get RTC register value x array time time milliseconds gt 2 Second register access optimised out y array time Here the value retrieved from the array is related to the value of milliseconds a register in an external RTC If this is compiled it will not work Why Well the compiler s optimiser shoots itself in the foot by assuming that because no WRITE occurred between 1 and 2 millisec cannot have changed Hence all the code generated to make the second access to the register is optimised out and so y x The solution is declare milliseconds as volatile thus unsigned int volatile xdata milliseconds 0x8000 Now the optimiser will not try to remove sub
70. Again library routines have to do the donkey work An interesting development has been the Siemens 80C537 717 509 abd the Dallas 390 which have an extended arithmetic instruction set For instance 32 by 16 divide and integer instructions Indeed this device might be a good upgrade path for those 8051 users who need more number crunching power and who might be considering the 80C196 or C16 family A suite of runtime libraries is included with the Keil C51to allow the compiler to take advantage of the enhancements This uses the MOD517 directive to the compiler In uVision2 this is an automatic selection whent he target choice is made For older versions and command line use pragma MOD517 www Phaedsys org page 37 of 194 Version 3 65 4 4 2 Special Function Bits A major frustration for assembler programmers coming to C is the inability of ISO C to handle bits in the bit addressable BDATA area directly Commonly bit masks are needed when testing for specific bits with chars and ints From C51 version 3 however it is possible to force data into the bit addressable area starting at 0x20 where the 8051 s bit instructions can be used directly from C An example is testing the sign of a char by checking for bit 1 Here the char is declared as bdata thus char bdata test put char into bit addressable data sbit sign test 7 the sign bit 7 is defined as sign variable To use this char bdata test sbit s
71. BNO 7506 3237 2 Hills C A Embedded C Traps and Pitfalls Chris Hills Phaedrus Systems September 1999 quest phaedsys org www Phaedsys org page 187 of 194 Version 3 65 Hills C A Embedded Debuggers Chris Hills amp Mike Beach Hitex UK Ltd April 1999 http www hitex co uk amp quest phaedsys org Hills C A Tile Hill Style Guide Chris Hills Phaedrus Systems 2001 quest phaedsys org Hills CA amp Beach M Hitex SCIL Level A paper project managers team leaders and Engineers on the classification of embedded projects and tools Useful for getting accountants to spend money Download from www scil level org HMHO Home Office Reforming the Law on Involuntary Manslaughter The governments Proposals www homeoffice gov uk consult Icbill pdf Jacobson et al Object Orientated Software Engineering A Use Case Driven Apporach Addison Wesely 1992 ISBN 0 201 55435 0 Johnson S C Johnson Lint a Program Checker in Unix Programmer s Manual Seventh Edition Vol 2B M D McIlroy and B W Kernighan eds AT amp T Bell Laboratories Murray Hill NJ 1979 Jones A History of punched cards Douglas W Jones Associate Professor of Computer Science at the University of Iowa http www cs uiowa edu jones cards index html see also http www cwi nl dik english codes punched html Jones Derek The 7 2 Urban Legend MISRA C Conference 2002 http www knosof co uk Kaner Bach amp Pettichord Lesso
72. By making functions that are only used in one file static they will only be visible in the one file www Phaedsys org page 44 of 194 Version 3 65 static unsigned char proceed unsigned char code This is rather like the encapsulation the OO programmers like It does help the C programmer because only the functions declared as extern will be available outside the file This gives a defined interface to a file and permits internal changes to a file without having to make changes outside the file For this to work well more thought must be given to the functions used as interfaces so that the possibility of changes to them is kept to a minimum The use of static functions also makes smaller faster programs as the compiler knows that the function will only be used in the one file and smaller faster jumps can be used 5 2 Accessibility Of Variables In Modular Programs A typical C51 application will consist of several functional blocks each contained in their own source files Each block will contain a number of functions which operate on and use variables in RAM Individual functions will ideally receive their input data via parameter passing and will return the results similarly Within a function temporary variables will be used to store intermediate calculation values At one time as it used to be done years ago in assembler all variables even the temporary ones would be defined in one place and will remain accessible to every routine It a
73. E SEGMENT DATA OVERLAYABLE does just that The best advice is to write the C that calls the assembler and then compile with the SRC switch to produce an assemblable equivalent Then look at what C51 does when it calls your as yet unwritten assembler function If you stick to the parameter passing segment name generated by C51 you will have no problems Example Of Assembler Function With Many Parameters C Calling Function Within the C program that calls this function the following lines must be added to the calling module source file external reference to assembler routine extern unsigned char write_ee_page char unsigned www Phaedsys org page 119 of 194 Version 3 65 char unsigned char dummy unsigned char number eeprom_page_buffer ee_page_length char current_ee_page number write_ee_page current_ee_page eeprom_page_buffer ee_page_length End dummy The assembler routine is NAME EEPROM NRITE PUBLIC _WRITE_EE_PAGE Essential PUBLIC _WRITE_EE_PAGE END_ADDRESS PUBLIC _WRITE_EE_PAGE END_BUFFER d P6 EQU OFAH Port 6 has watchdog pin E AA AA ANA NA KSSSSSSSSS Declare CODE And DATA Segments For Assembler Routine gt gt gt gt gt gt gt gt gt gt gt KRE PR _WRITE_EE_PAGE WRITE_EE SEGMENT CODE DT _WRITE_EE_PAGE WRITE_EE SEGMENT DATA OVERLAYABLE Z E AK KSSSSSS Declare Memory Area In Internal RAM For Local Variables Etc gt gt gt gt gt gt SA RS
74. EG DT _WRITE_EE_PAGE WRITE 7 NRITE EE PAGEEND ADDRESS DS 2 _WRITE_EE_PAGE END_BUFFER DS 1 7 7 RAAR RARR AARAA ANAA EARRA AAEREN AAA AAA ANANA NA AAAA AARAA AARAA e ee AEA ees lt lt lt lt lt lt lt lt lt lt lt lt lt lt lt EEPROM Page Write Function gt gt gt gt gt gt gt gt gt gt gt gt gt gt E E E Ce E e EE e E EE E e EE Ee RSEG 2PR2 NRITE EE PAGEZHRITE U Be NRITE EE PAGE CLR EA MOV DPH R6 Address of EEPROM in R7 R6 MOV DPL R7 E MOV A R3 Length of buffer in R3 DEC A ADD A R7 Calculate address of last MOV _WRITE_EE_PAGE END_ADDRESS 01H A byte in page in XDATA CLR A ADDC A R6 MOV _WRITE_EE_PAGE END_ADDRESS A Z LA MOV A R5 Address of buffer in IDATA in R5 MOV RO A Z ADD A R3 pa MOV 7 NRITE EE PAGEZEND BUFFER A LA LOOP MOV A GRO H MOVX DPTR A INC RO 7 INC DPTR S MOV A RO CJNE A _WRITE_EE_PAGE END_BUFFER LOOP MOV DPH _WRITE_EE_PAGE END_ADDRESS H www Phaedsys org page 120 of 194 Version 3 65 MOV DPL _WRITE_EE_PAGE END_ADDRESS 01H DEC RO 4 LA CHECK XRL P6 08 Refresh watchdog on MAX691 MOVX A DPTR H CLR G SUBB A GRO E JNZ CHECK E 7 SETB EA Z RET Return to C calling program 7 END 15 2 Parameter Passing To Assembler Functions In the assembler example the parameter current ee page was received in R6 and R7 Notice that the high byte is in the lower register R6 The fact that the 8051 stores high bytes at the l
75. Entered Password Keyed Data Service Request Get Required Services lt Message 2 Cash Limit Cash Card Data clearly shows the structure of the software as opposed to the system this point if each box is a single function or a collection of functions in effect a module In some methods the actual data or control information passed between these functions would be shown These functional boxes can be either single functions is source code or broken down KS CS A Valid Password Entered Password Cash Card Data E VA j Transaction Services Required S 8 Cash Amoun er Customer Details Card Inserted Eject Card VA Ze gt Process Cash Card Entry Process Requi red Services lt Cash Card gt Account Information Print Slips Cash gt 3 Bank Transaction Control Transaction Main Program The next level down is what happens inside the main circle As can be seen this has broken the system down in to descrete operations linked by data and control flows This is top down modeling Now the functionality and indeed functions start to appear The view changes slightly for the next diagram However this It is not clear at Loop Await Cash Get Process Eject Card Password Transaction With
76. F8 FC FE FF 2 0000 0 DI EF PI gt E 2 0000 1 Al DD EF F7 E S 3 6864 0 A9 EO FO F8 FC FE FF 3 6864 1 51 CO EO FO F8 FC FE FF 4 0000 0 Al DD EF F7 z 4 0000 1 43 BB DD EF IF o E S 4 096 0 9F DC EE TF 3 4 096 l 3E B9 DC EE T 5 0000 0 SA D5 EA F5 E E 5 0000 1 13 A D EA F5 S S z 5 5296 0 7D DO E8 F4 FA FD 5 5296 1 AO DO E8 F4 FA FD 6 0000 0 12 CC Ep F3 www Phaedsys org page 176 of 194 Version 3 65 25 Appendix J ICE Connect your design If you had a simple virtually overhead free method of being able to put an ICE on to any of your prototype or production boards you would use it wouldn t you There is such a system It will work with any 8051 design that has ports 0 and 2 available as address and data lines This does not mean that there must be external memory just that porst 0 and 2 are not used for signals The method is ICEConnect a simple 2 way by 15 set of pads that are required on the PCB These are the 8 multiplexed address data lines the upper 16 bits of address line PSEN ReaD WRite and ReSeT Connector assignment www Phaedsys org This method only requires tobe able to monitor the ADO 7 and D8 15 It does however require control of Read Write PSEN and Reset These lines have to be redirected This is systems works well with most 8051 s where there is not ICE or in the case of high integrity systems th
77. H PR FUNC2 MAIN OOOFH OOOBH PR FUNC3 MAIN OOOFH OOOBH Danger func4 s local 2 PR FUNC4 MAIN OOOFH OOOBH func4 s data with 2 PR _EXECUTE MAIN OOOFH OOQEH execute s its gt C_LIB_CODE caller PR FUNC5 MAIN OOOFH OOOBH func5 s local data overlaid with execute s www Phaedsys org page 94 of 194 Hoverlaid Version 3 65 its caller RAM Locations Used D 0012H SYMBOL tex execute s locals overlap D 0013H SYMBOL arrex func4 and func5 s OK D 000FH SYMBOL y D 0010H SYMBOL arr4 D 000FH SYMBOL y5 D 0010H SYMBOL arr5 Incidentally the overlay map shows which functions referred to which other functions By checking what L51 has found against what you expect overlay hazards may be spotted 9 4 4 Indirectly called functions solution Use the overlay command when linking thus main obj to exec abs amp OVERLAY main func4 func5 _execute func4 funcS Note The tilde sign means Ignore the reference to funcdl5 from main The P means Manually generate a reference between intermediate function execute and func4 5 to prevent overlaying of local variables within these functions Please make sure you understand exactly how this works The new linker output is MS DOS MCS 51 LINKER LOCATER L51 V2 8 INVOKED BY L51 MAIN OBJ TO EXEC ABS OVERLAY MAIN FUNC4 FUNCS _EXECUTE FUNC4 FUNCS OVERLAY MAP OF MODULE EXEC ABS MAIN
78. K It is up to the programmer to work out if there is any saving to be gained by using the COMPACT model over the LARGE It is not usually worth spending a great deal of time agonising over 3 3 2 RAM Memory Models Having chosen the ROM model for the CODE we shall move on to the RAM DATA memory models These are a little more complex than the ROM models and will require a little more thought Note that whilst these models are like the ROM models global it is possible to locally place data in specific membory and specific C functions into a different model This will be explained later The Source Browser under the View menu on uV2 will be useful to see what variables are in which data space 3 3 2 1 RAM SMALL www Phaedsys org page 25 of 194 Version 3 65 This is the fastest model All variables will reside in the internal data However internal data is often limited to 256 bytes including register banks and stack Of this 265 bytes only the first 128 bytes are directly addressable The second 128 are only indirectly addressable If all the CODE memory is on chip this is the smallest and fasted configuration For the 8051 31 specifically there is no IDATA so the total amount available is 128 bytes of DATA Only the 128 Bytes of directly addressable DATA will be available using this memory model even when using an 8052 derivative Note that when optimising the C51 compiler will use Register banks 1 3 as ordinary memory if they user is not
79. KK KKK KKK KKK KKK KKK KKK KKK KKK KKKKKKKKKKKKKK E Global Definitions x www Phaedsys org page 131 of 194 Version 3 65 KKAAKKKAKKKKKKAKKKAKKKKKKAKKKAKKKKKKAKKKAKKKAKKKKKKAKKKKAKKAKKKAKKKKKKKKKKKKJ CCMx PWMS xdata float pwm_period 42 5 Initial period in us variable located in XDATA xdata float pwm_duty_ratio 50 Initial ratio in xdata unsigned int pwm_prescale 0 Analog Inputs xdata float analog_data 4 Floating point array xdata unsigned char rx_byte xdata unsigned char channel 0 xdata unsigned char channel 1 I Oo Timer0 Overflow Timebase xdata unsigned int real_time_count 0 Timed Pulse Generation xdata unsigned char marker_angle 128 data unsigned int marker time 0 unsigned int time_for_360 0 unsigned int time_last_360 0 xdata unsigned int frequency 0 xdata unsigned int analog datal 0 jet Port 1 Bit Definitions Nj sbit P10 0x90 CCO sbit P13 0x93 ZC CE3 sbit P14 0x94 Z O Symmetrical PWM Generation xdata unsigned int symm_PWM_DR 256 Integer ratio from background xdata unsigned int symm_PWM_period 2048 PWM Period 4096us KKKKKKKKKKKKKKKKKKKKKKKKK KKK KKK KKK KKK KKK KKK KKK KKK KKKKKKKKKKKKKKKKKKKKKKKKKKK x General Definitions x KKAKKKKAKKKAKKKKKKAKKKKKKKKKKKKKAKKKAKKKAKKKKA KKK KKKKAKKKAKKKAKKKAKKKKKKKKKKKKKKJ define FOREVER 1 CMS PWM Control define
80. Keil have provided pragma NOINTPROMOTE to disable this feature In this case explicit casts should be used if another data type might result from an Operation www Phaedsys org page 105 of 194 Version 3 65 To show why this pragma is important this C fragment s code sizes are influenced thus char c unsigned char cl c2 int i main if char c Oxff c 0 if char c 1 c 1 i char c 5 if char cl lt char c2 4 cl 0 Code Sizes 47 bytes C51 v3 20 49 bytes C51 v3 40 INTPROMOTE 63 bytes C51 v3 40 NOINTPROMOTE Again this goes to show that C portability compromises efficiency in 8051 programs www Phaedsys org page 106 of 194 Version 3 65 11 Miscellaneous Points 11 1 Tying The C Program To The Restart Vector This is achieved by the assembler file STARTUP A51 This program simply places a LIMP STARTUP at location C 0000 Lowest EPROM location The startup routine just clears the internal RAM and sets up the stack pointer Initialisation routines might also take place between UMP MAIN and Main if global variables that are created and initialised in your application for example char x 10 in this case startup a51 is going to call init aS1 and then it is finally going to call main LJMP main PN In fact this need be the only assembler present in a C51 program 11 2 Intrinsic Functions There are a number of special 8051 assembler instructio
81. LL unsigned char xdata engine_speed signed char xdata big_variable_array 192 www Phaedsys org page 33 of 194 Version 3 65 This will have engine speed placed in an external RAM chip Note that no initial value is written to engine speed so the programmer must not read this before writing it with a start value This xdata placement may be done to allow engine speed to be traced on the fly by an in circuit emulator for example In the case of the array it would not be sensible to place this in the on chip RAM because it vvould soon get filled up vvith only 128 bytes available In this case as the array is indirectly addressed the array could reside across DATA and IDATA This is a very important point never forget that the 8051 has very limited on chip RAM Another example is pragma LARGE function unsigned char data paral unsigned char data local_variable Here the passed parameters are forced into fast directly addressed internal locations to reduce the time and code overhead for calling the function even though the memory model would normally force all data into XDATA In this case it would be better to declare the function as SMALL even though the prevailing memory model is large This is extremely useful for producing a few fast executing functions within a very big LARGE model program On a system using paged external RAM on Port 0 the appropriate directive is pdata See notes in section 2 1 3
82. MOTOR OFF 0 sbit Motor Control PIAT sbit Motor State P1 2 Motor MOTOR_ON Motor MOTOR_OFF if MOTOR OFF Motor State 4 4 3 Converting Between Types One of the easiest mistakes to make in C is to neglect the implications of type within calculations or comparisons Taking a simple example unsigned char x 10 unsigned char y 5 unsigned char z SA Roy Gy Results in z 50 However unsigned char x 10 unsigned char y 50 unsigned char Z x y j N results in z 244 The true answer of 500 0x1F4 has been lost as z is unable to accommodate it The solution is of course to make z an unsigned int However it is always a good idea to explicitly cast the two unsigned char operands up to int thus unsigned char x unsigned char y unsigned int z z unsigned int x unsigned int y C51 since Version 3 will automatically promote chars to int in it s natural state This is called Interget Promotion Rule and is a requirement of the compiler for ISO comformance It could be argued that on any small microcontroller you should always be aware of exactly what size data is at al times It is possible to disable this feature in most versions of the Keil C51 compiler Why would you wanrt to do that Well assuming that you do know the maximum size of www Phaedsys org page 39 of 194 Version 3 65 your data and that there are suitable check for our of range data it is faster and th
83. OBJ H K Ci Program Files Di get passvvord ad PROTEUS Di get_password c They can also assign L Ca PVCS Di get passvvord LST 1 RECYCLED Q get_password OBJ lables to versiois thus EHM Dampa 5 transfer Q main c you can check out S S 1 ACCU Di main OBJ whole sets of files as EE Geer 4 BOOK Q process c VI Or Release 2 1 GEN Q process LST d e 1 GPT D services ad with a single command CB inex eee eee 3 cbipva D services LST Some VCS let you set L a Sage D services 0BJ up make and compilers eleng Sch ig so that you can issue a d S ca EIS command such as Make Releasel or make v1 34 and you can isnstantly well as fast as the compiler can run produce V1 34 In other words you can almost instantly reproduce any version of the software you have created since you started to use Working Directory D WORK HITEX c51pv4 source cashcard User ID unknown www Phaedsys org page 54 of 194 Version 3 65 the system They can also branch that is hold several parallel version of a file This Can be a god send if you have to do maintain several different versions of an application at the same time Most VC Scan also intergrate in to compiler IDES case tools error reporting tools etc and can be used for most types of files not just source files VCS cost from free to the standard packages at about a third of the cost of a Keil DK51 and on to the rolls Royce packages at
84. Pulse_Width 25 50us marker pulse define PWM_Resolution 0 1666667 Smallest PWM time is at 12MHz Cursor Positioning Escape Codes For VI52 code char Linen Oxlb Y 0x20 0x20 0 code char Linel Oxlb Y 0x21 0x20 0 code char Line2 Oxlb Y 0x22 0x20 0 code char Line3 Oxlb Y 0x23 0x20 0 code char Line4 Oxlb Y 0x24 0x20 0 code char Line5 Oxlb Y 0x25 0x20 0 code char Line6 Oxlb Y 0x26 0x20 0 code char Line7 Oxlb Y 0x27 0x20 0 code char Linen Oxlb Y 0x28 0x20 0 code char Line9 4 0xlb Y 0x29 0x20 0 code char Lineloll Oxlb Y 0x2a 0x20 0 code char Linell Oxlb Y 0x2b 0x20 0 code char Linel2 Oxlb Y 0x2c 0x20 0 code char Linel3 Oxlb Y 0x2d 0x20 0 code char Linel4 Oxlb Y 0x2e 0x20 0 code char Linel5 Oxlb Y 0x2f 0x20 0 www Phaedsys org page 132 of 194 Version 3 65 code char Clear 0x0C 0 code char double_bell 0x07 0x07 0x07 0 Z 1 kkkkkkkkkkk kk KA ke kk kk Ak Ak kk kk KA kek kk KA ke kek kk kk ke kk kk ke kk kk ke kek KKK KA KKK N Function Prototypes ai KKAKKKKAKKKKAKKAKKKAKKKKKKAKKKAKKKKAKKAKKKAKKKKAKKKKKKAKKKKAKKKKKKAKKKKKKKKKKKKJ void ad init void void serial init void void serial init BD void void serial nit TI void void send byte unsigned char void
85. RINTF PRINTF MCS 51 LINKER LOCATER L51 V2 8 DATE 04 08 92 PAGE 2 2 PR PRINTF PRINTF 0020H 0 0001H 1 0009H 0014H gt C_LIB_CODE gt PR PUTCHAR PUTCHAR PR FUNC2 MAIN1I 0008H 0001H gt PR PRINTF PRINTF xxx WARNING 13 RECURSIVE CALL TO SEGMENT SEGMENT CO MAIN1 CALLER PR FUNC1 MAIN1 xxx WARNING 13 RECURSIVE CALL TO SEGMENT SEGMENT CO MAIN1 CALLER PR FUNC2 MAIN1 9 4 6 Function Jump Table Warning Solution The solution is to use the OVERLAY command when linking thus mainl obj amp to mainl abs amp OVERLAY CO MAIN1 funcl func2 main funcl func2 This deletes the reference to funcl amp 2 from the CO MAIN1 segment and inserts the true reference from main to funcl amp func2 The linker output is now thus OVERLAY MAP OF MODULE MAIN1 ABS MAIN1 SEGMENT BIT GROUP DATA GROUP gt CALLED SEGMENT START LENGTH START LENGTH www Phaedsys org page 97 of 194 Version 3 65 26 CSISTARTUP gt PR MAIN MAIN1 PR MAIN MAIN1 gt CO MAIN1 t C_LIB_CODE gt PR FUNC1 MAIN1 gt PR FUNC2 MAIN1 PR FUNC1 MAIN1 0008H 0001H gt CO MAINI gt PR PRINTF PRINTF 2 PR PRINTF PRINTF 0020H 0 0001H 1 0009H 0014H t C_LIB_CODE gt PR PUTCHAR PUTCHAR PR FUNC2 MAIN1 0008H 0001H gt CO MAIN1 gt PR PRINTF PRINTF 9 4 7 Multiple Call To Segment Warning Hazardous This warning generally occurs when a function is called from bo
86. TI to be used rather than a normal RET 6 2 2 Using C51 With Target Monitor Debuggers Many simple 8032 target debuggers place the monitor s EPROM code at 0 with a RAM mapped into both CODE and XDATA spaces at 0x8000 The user s program is then loaded into the RAM at 0x8000 and as the PSEN is ANDed with the RD pin the program is executed This poses something of a problem as regards interrupt vectors C51 L51 assume that the vectors can be placed at 0 Most monitors for the 8032 foresee this problem by redirecting all the interrupt vectors up to 0x8000 and above i e they adda www Phaedsys org page 61 of 194 Version 3 65 fixed offset of OX8000 Thus the timer 0 overflow interrupt is redirected by a vector at C 0x000B to C 0x800B Before C51 v3 40 the interrupt vector generation had to be disabled and assembler jumps had to be inserted However now the INTVECTOR control has been introduced to allow the interrupt vector area to be based at any address In most cases the vector area will start at Ox8000 so that the familar 8 n 3 formula outlined in section 5 2 1 effectively becomes 8 n 3 INTVECTOR To use this pragma INTVECTOR 0x8000 Set vector area start to 0x8000 void timero0 int void interrupt 1 J GOOD ET This produces an LJMP Omer Int at address C 0x800B The redirection by the monitor from C 0x000B will now work correctly 6 2 3 Coping Interrupt Spacings Other Than 8 Some 8051 s do not
87. The C51 Primer An introduction to the use of the Keil C51 Compiler on the 8051 family Edition 3 6 17 January 2006 First version by Mike Beach Editor for Edition 3 6 5 Chris Hills PhaedruS Systems www phaedsys com O Copyright Phaedrus Systems 2002 2003 2006 amp Hitex UK Ltd 1994 2002 All Rights Reserved No Part of this publication may be transmitted transcribed stored in a retrieval system and translated into any language in any form by any means without the written permission of PhaedruS Systems Ltd www phaedsys org page 2 of 194 Version 3 65 Contents 0 About The GS1PrIMET EE 7 So ged gitcbiencaducecsdcunddzcccaueees a 8 Lk E e 11 2 Gompuer Chalm EE 14 3 C51 Basics The 8051 Architecture ANEREN 17 3 1 8051 Memory ConfiguratioNnS EEN 17 3 1 1 Physical Location Of The Memory Spaces cesse serene 17 3 2 Hardware Memory Models AANEREN 22 9 2 ER NEE 22 8 2 Ext rnal Code ra is r ves sit eaa n ap e Eege ndoh EES dee 23 9 2 9 Write to GODE Space ada se c vv vet stenda soni esetad shtesa ode de Ea E as br nda nde dost ose sis dshete 28 3 3 Possible Memory Models AAA 24 3 3 1 ROM Memory Models uk nenen eT enen e nese nene bese ee ne eee ene e eee nene eee ee nene eee e nene eee 24 3 3 2 RAM Memory Model iniesta nene nete nene nese nene ese nene eee nene vOe eee nene eee nenen netet 25 3 3 3 Choosing The Best Memory Configuration Model aaanaaaaaaenen ee see eee ne eee e pene neneve ene
88. The spaces between the standard SFR s are used by 8051 manufactures for their own use such as CAN interfaces USB A to D and many other peripherals As the SFR block is not really conventional RAM but a series of hard wired registers Where there is no SFR defined there is no empty register or memory byte for the user Another convention is that if an SFR address ends in O or 8 the bits in the register are directly and individually addressable This means that bits can be set without have to mask and write the whole byte However only the standard set of SFR s are fixed which means that whilst the individual silicon manufacturers have their own standards they are not portable So the CAN registers in a Philips 8051 will probably not be in the same place as the CAN registers in an Atmel part A second memory area exists between 80H and OFFH This is the IDATA space The IDATA is only indirectly addressable MOV A Ri and is prefixed by I This is box 2 in figl and it effectively overlays the directly addressable SFR area This constitutes an extended on chip RAM area and was added to the 8051 design when the 8052 appeared As it is only indirectly addressable it is best left for stack use which is by definition always indirectly addressed via the 8 bit stack pointer SP Just to confuse things the normal directly addressable DATA RAM from 0 80H can also be indirectly addressed by the MOV A Ri instruction Therefore the whole area from 0 t
89. XD functionname module_name PDATA PD functionname module_name Thus the parameter receiving area of a LARGE model function test in module MOD1 C would be XD TEST MOD1 The code is PR TEST MOD1 And so on A knowledge of this is useful for assembler interfacing to C51 programs See section 14 www Phaedsys org page 86 of 194 Version 3 65 8 6 Excluding External Data Ranges From Specific Areas This very much follovvs on from the previous section Occasionally a memory mapped device such as real time clock chip is used as both a source of time values and RAM Typically the first 8 bytes in the RTC s address range are the time counts seconds minutes etc vvhilst the remaining 248 bytes are RAM Left to its own devices the L51 linker will automatically place any xdata variables starting at zero If the RTC has been mapped at this address a problem occurs as the RTC time registers are overwritten In addition it would be convenient to allow the registers to be individually named One approach is to define a special module containing just a structure which describes the RTC registers In the main program the RTC registers are accessed as elements in the structure The trick is that when linking the XDATA segment belonging to the special module is forced to a specific address here zero This results in the RTC structure being at zero with any other XDATA variables following on The basic method could also be used to
90. XECUTE A pointer to the required function is passed When L51 analyses the program it cannot establish a direct link between execute and func4 5 because the function pointer received as a parameter breaks the chain of references this function pointer is www Phaedsys org page 92 of 194 Version 3 65 undefined at link time Thus L51 overlays the local segments of func4 func5 and execute as if they were all references from main Refer to the overlay diagram above if in doubt The result is that the locals of func4 5 will corrupt the locals used in execute This is clearly VERY dangerous especially as the overwriting may not be immediately obvious it may only appear under abnormal operating conditions once the code has been delivered include lt reg517 h gt JAKKKKAKKKKKKAKKKAKKKKKKKAKKKKKKKKKAKKKAKKKAKKKKKKAKKKKKKK Ka OVERLAY HAZARD 1 Indirectly called functions KKAAKKKAKKKKAKKAKKKAKKKKKKAKKKAKKKKKKAKKKAKKKKKKKKKKKKKKKKKKJ char funci void 1 Function to be called directly char x y arrllol for x 10 6 oe LO HH ef arr x x return x char func2 void Function to be called directly C Code char func3 void 1 Function to be called directly C Code return x char func4 void Function to be called indirectly char x4 y4 arr4 10 Local variables for x4 0 x4 lt 10 x4 arr4 x4 x4 return x4 char func5
91. a r ve os see s nd ese se sode t doret erdh rr non 70 1 4 2 Arrays TE 71 TA S Mitialis d Structures irn ene q n d noi des o ndod b te n e 12 1 4 4 Placing Structures At Absolute Addresses NEE 72 T 4 5 Pointers TO StrUCtures is p s v duo si so ndie n od ndave dynd n dhee e Eer pure t o it 13 7 4 6 Passing Structure Pointers To Functions AE 73 7 4 1 Structure Pointers To Absolute Addresses 14 TAEA Patos y k EEEE T E gege Ze Ee Kees Es 75 1 6 Generic eT TT 15 fT Spaced Pointers In OS ss ves iiivesn s e erdh dE dd Eege EE t TI 8 Accessing External Memory Mapped Peripherals REENEN ENEE 81 8 1 The XBYTE And SWORD Macros AAA 81 8 2 Initialised XDATA Pointers AANEREN 82 8 3 Run Time xdata Pointers nd su aradeg naene on e de Seabees an iiaae ae EAE ad Ee s aro eaae 84 8 4 The volatile Storage Class ugarie tione ieran nene eren E ae aeaaea nenen eee nene neve nente 85 8 5 Placing Variables At Specific Locations The Linker Method Aua 85 8 6 Excluding External Data Ranges From Specific Areas AAA 87 8 7 missing ORDER and AT now in CBL sss e esse neneve sene e ever eee teve sere eee eee ee eve mere ete vene e eneve nenes 87 8 8 Using The at and ORDER Controls AAA 88 9 Linking Issues And Stack Placement 89 9 1 Basic Use OGBL Linker i tare cion 2 savcecadsdcnebtacterecthaescecesenvnccedsdseancassdiuecseeconde die v s indet c s 89 9 2 5tack Placement ics isht se coni e sis v sh ne edi a E
92. about the cost of a Series 3 BMW Most and certainly all 8051 embedded applications will only require the standard packages There are several free unix RCS on the internet Whilst not essential a VCS is very useful and if you have many versions of source or many applications with lots of modules VCS can be well worth the money The Keil C51 will intergrate any VCS that has a command line interface Keil currently supplies interfaces for MKS PVCS and Source Safe systems Incidetally all VCs assume that you will be writing modular software In the ATM example shown I would use a VCS so I could maintain several different password modules services modules etc apart from using it to hold the other source modules Thus I could almost instantly make a version od the software with any combination of password system and services More to the point if I have to fix a bug in the password system or enhance it I onluy have to remake the one module and move the build labe on it to the newer version I could then either compiler the one file and use the previous object files or rebuild the whiole project using the origional source Summary If the Source templates are used with modular software and provided the necessary module name defines and globals are placed in the file or header as required the overall amount of editing required over a major project is usefully reduced With the use of a VCS there is also a ful audit trail and instant recovery to older
93. ack space in data memory The rule is three chars ints or pointers However only two longs or floats may be passed Though one char may be passed with the longs and floats Incidentally the return parameter is always passed in a register NOTE This does not apply if the first parameter is a bit Therefore bits should be passed as the third parameter Thus it is a balancing act It is faster and consumes less memory if only a limited number of variables are passed as parameters However globals always take space but may save space as they only appear once rather than in several guises if the data has to be passed through several functions there are more than three functions This is becasuse if there will be several spaces allocated in the compiled stack for each function call I E if there are www Phaedsys org page 45 of 194 Version 3 65 three functions there will be three places in memory where space is provided for that parameter Globals are always available and visable The use of local variables can aid encapsulation and data hiding which is better for modula programming this is because there is an easliy defineds interface between source files Pointers of course are the grey area as they can be used where only two or three bytes ofa pointer need to be passed in order to give access to a large array of many bytes The correct use of the pointer variable declaration can hide access to an array that is permanently in memory Onl
94. ade is which memory model to use For general information on the C language number and string representation please refer to a standard C textbook 3 1 8051 Memory Configurations The physical memory layout of the 8051 is Harvard where most normal computers use Von Neuman However several silicon vendors have further confused this with on chip external memory ie internal external memory During 2001 which is recent in terms of 8051 history several silicon vendors brought out a new memory configuration that can address up to 8M bytes of memory without bank switching We will start with the traditional 8051 memory map All others are a superset of this one 3 1 1 Physical Location Of The Memory Spaces Initially perhaps the most confusing thing about the 8051 is that there are three sometimes four different memory spaces all of which appear to start at the same address The CODE and the DATA memory are distinct and separate This is Harvard architecture Most programmers are used to the Von Neuman memory configuration used in most other microcontrollers such as the 68HC11 This is a single plane memory where areas are located at sequential addresses XDATA Within the 8051 CPU the first area is the DATA This is on chip es e RAM This is box 1 in fig 1 This starts at D 0x00 the D prefix BETA implies DATA segment and ends at O7fH 127 decimal This RAM je S can be u
95. aedruS SystemS was offereing a bundle of C90 and MISRA C for 50 Uk Pounds www Phaedsys org page 170 of 194 Version 3 65 www Phaedsys org page 171 of 194 Version 3 65 24 Appendix G Timers amp Delays I will get around to doing this shortly www Phaedsys org page 173 of 194 Version 3 65 www Phaedsys org page 174 of 194 Version 3 65 Appendix H Serial Ports and Baud rates From day one all 8051 s have had at least one serial UART Note this is not RS232 but serial It can with the right hardware drivers be RS232 RS485 current loop or any one of several serial formats In this case we are going to look at the basic set up for serial communications Once you have this running you can communicate with your application The first step is to calculate the baud rate This can be any rate you like but the commonly used standard settings are 110 300 600 1200 2400 4800 6900 19200 38400 56700 and 115200 To generate the pulses a timer must be used except in a few cases where there is a baud rate generator peripheral provided TI is commonly used for baud rate generation There are several modes for timers but the most common way of setting up serial communuitcations is to use Timer 1 in 8 bit auto re load mode That is an 8 bit number is used to generate the delay and it automatically rests and goes round again The 8 bit number is stored in register TH1 The equation to find the value for THl is TH1 256 xtal Constan
96. aid as they are never active together being attached to sequential branches of the main program flow This is the basis of the overlay strategy However a complication arises with interrupt functions Since these can occur at any time they would overwrite the local data currently generated by whichever background or lower priority interrupt function was running were they also to use the DATA_GROUP To cope with this C51 identifies the interrupt functions and called functions and allocates them individual local data areas 9 4 2 Impact Of Overlaying On Program Construction The general rule used by L51 is that any two functions which cannot be executing simultaneously may have their local data overlaid Re entrant functions are an extension of this in that a single function may be called simultaneously from two different places In 99 of cases the overlay function works perfectly but there are some cases where it can give unexpected results These are basically i Indirectly called functions using function pointers ii Functions called from jump tables of functions iii Re entrant functions incorrect or non declaration thereof Under these conditions the linker issues the following warnings MULTIPLE CALL TO SEGMENT UNCALLED SEGMENT RECURSIVE CALL TO SEGMENT 9 4 3 Indirect Function Calls With Function Pointers hazardous Taking i first Here func4 and funcs5 are called from main by an intermediate function called E
97. al RTC Registers is BL51 main obj rtcbytes obj XDATA XD RTCBYTES Oh NOTE Older compilers may still use L51 and the newer V6 and up PK51 user may use LX51 instread of BL51 See section 7 6 for further examples of this placement method 7 4 5 Pointers To Structures Pointers can be used to access structures just as with simple data items Here is an example Define pointer to structure struct sensor_desc sensor_database Use Pointer To Access Structure Elements sensor_database gt gain 0x30 sensor_database gt offset 0x50 sensor_database gt temp_coeff 0x60 sensor_database gt span 0xC4 sensor_database gt amp_gain 0x21 Note that the which normally indicates a pointer has been replaced by appending gt to the pointer name Thus name and name gt are equivalent 7 4 6 Passing Structure Pointers To Functions A common use for structure pointers is to allow them to be passed to functions without huge amounts of parameter passing a typical structure might contain 20 data bytes and to pass this to a function would require 20 parameters to either be pushed onto the stack or an abnormally large parameter passing area By using a pointer to the structure only the two or three bytes that constitute the pointer need be passed This approach is recommended for C51 as the overhead of passing whole structures can tie the poor old 8051 CPU in knots This would be achieved thu
98. amples with the code produced define XBYTE define XWORD unsigned char volatile 0x20000L unsigned int volatile zi 0x20000L main char x Ine y3 x XBYTE 0x8000 0000 908000 MOV DPTR 08000H 0003 EO MOVX A DPTR 0004 FF MOV R7 A 0005 8F00 R MOV KRI y XWORD 0x8000 sizeof int 0007 908000 MOV DPTR 08000H 000A EO MOVX A DPTR 000B FE MOV R6 A 000C A3 INC DPTR 000D EO MOVX A DPTR 000E FF MOV R7 A 000F 8E00 R MOV y R6 0011 8F00 R MOV y 01H R7 0013 2C0001 0013 22 RET However the address indicated by word reg is fixed and can only be defined at compile time as the contents of the square brackets may only be a constant Any alteration to the indicated address is not possible vvith these macro based methods This approach is therefore best suited to addressing locations that are fixed in hardyvare and unlikely to change at run time Note the use of the volatile storage class modifier This is essential to prevent the optimiser removing data reads from external ports See section 7 4 for more details Note the header file absacc h must be included at the top of the source file as shown above This contains the prototype for the XBYTE macro see page 9 15 in the C51 manual 8 2 Initialised XDATA Pointers www Phaedsys org page 82 of 194 Version 3 65 In many cases the external address to be pointed at is known at compile time but may need to be altered at some p
99. any extensions NOTE 100 portable code is difficult to write for the 8051 and will be inefficient Although C is widely claimed as portable the vast majority of embedded applications will never be ported other than to another usually more powerful part in the same family Also to make good use of the system many 8051 specific extensions must be used If you write portable C program it will probably be much slower and larger than it need be 3 Set up each and every on chip peripheral on all of the 400 plus well it was 400 at the time it is now 2006 about 600 different 8051 variants Some are however covered in the appendices don t expect the number to rise much now as other parts havebcome more popular This guide should be read in association with a good C reference and is not meant to be a definitive work on the C language It covers most of the Keil 8051 specific language extensions and those areas where the CPU architecture has an impact on coding approach 0 1 History The C51 Primer was first concived and written by Mike Beach in 1989 as a guide to both the 8051 and the Keil compiler it ran to some 70 pages Since it s initial publication it has been given away with all Keil C51 compiler sold by Hitex put on the Hitex web site and the Phadsys web site since 2002 when it was expanded from 70 to nearly 200 pages IT can be found on numerous other web sites and has become one of the standard texts on the 8051 Issue I 1991
100. aration like char volatile variable_name will create a variable may be updated by something other than the application This stops the compiler optimising out the variable reads where apparfently nothing has written since the last read The Special Function Registers SFR are by default Volatile One less obvious case in point was a memory test routine that wrote to to the memory and then imediately read it back The compiler not a Keil one speeded up the memory test by optimising out the write and subsiquent read to the memory location The memory test was fast but it never touched the physical memory Defineing the variable as Volatile forced the compiler to give the behaviour required www Phaedsys org page 32 of 194 Version 3 65 Note the declaration unsigned char volatile const name is valid This tells the compiler that the variable is a constant and the application can not change it but something else i e the hardware might change it Obviously any large lookup tables should be located in the CODE area a declaration might be unsigned char code default base fuel PW mapt 0x08 0x08 0x00 0x00 0x00 0x09 0x41 0x80 0xC0 OxFF 0x00 0x00 0x13 0x1A 0x26 0x33 0x80 OXFF 0x00 0x00 0x00 0x09 0x41 0x80 OX66 OX66 0x00 0x00 0x00 0x05 0x4A 0x46 0x40 OX40 0x00 0x00 0x00 0x08 0x43 0x43 OX3D 0x3A 0x00 0x00 0x00 0x00 0x2D 0x4D 0x56 0x4D 0x00 0x00 0x00 0x00 0x21
101. art up The variable is only visable in this function but is not destroyed at the end of the function call and retauns its value for the next time the function is called four variables only visable in this BLOCK WITHIN the function note this can be done in a for while do or if block as wel as a block simpley decalred betewwn two long int prime_1 long int prime_2 long int key_a long int key_b prime 1 gen_randon_prime prime 2 gen random prime key a prime 1 1 prime 2 1 key_b prime_1 temp_1 temp Kev lt key_a key_b statements return temp Kev fekkkkkk end of Code www Phaedsys org page 47 of 194 Version 3 65 5 3 Building a C51 Modular Program The text thus far has shown the architecture and the idiosyncrasies of the 8051 and the various ways of addressing the 8051 memory spaces We have covered the various ways of allocating data memory in C We have also covered the reasons for modular programming Next we will cover the practicalities of writing a modular program 5 3 1 The Problem As explained in the ATM example previous section there are a lot of advantages in using multiple modules Not least the fact that changing one line of code only requires re compilation of that file but not all the others and just re linking The problem is how to ensure that the all the data required is passed cleanly and in a well defined manne
102. at have to test the code and production part in situ on a production board This is system is used in all maner of racing cars medical equipment and aerospace systems As you can see there is no reason not to automatically design in the ICEConnect system into any 8051 system that can use it There is also a demultiplexed version that is used with some ASICS page 177 of 194 Version 3 65 oegaeggzgegrzeggea www Phaedsys org page 178 of 194 Version 3 65 26 Appendix K 8051 Instruction set in Hex order Code Bytes Cycles Mnemonic 00 l l NOP 0l 2 2 AJMP codeaddr 02 3 2 LJMP codeaddr 03 l l RR A 04 l l INC A 05 2 l INC dataAddr 06 l l INC RO 07 l l INC GRI 08 l l INC RO 09 l l INC RI OA l l INC R2 OB l l INC R3 UC l l INC R4 OD l l INC R5 OE l l INC R6 OF l l INC R7 Code Bytes Cycles Mnemonic 10 3 2 JBC bitAdr codeAddr 11 2 2 ACALL codeAddr 12 3 2 LCALL codeAddr 13 1 1 RRC A 14 1 1 DEC A 15 2 1 DEC dataAddr 16 1 1 DEC RO 17 1 1 DEC QRI 18 1 1 DEC RO 19 1 1 DEC R1 1A 1 1 DEC R2 1B 1 1 DEC R3 1C 1 1 DEC R4 1D 1 1 DEC R5 lE 1 1 DEC R6 1F 1 1 DEC R7 www Phaedsys org page 179 of 194 Version 3 65 Code Bytes Cycles 20 3 2 DO N Fi Fi Fi Fi Fi Fi Fi Fi F i DD ta k DO k kt bai F i kat bai bt bai Fi Fa k ka ka bi b i Code Bytes Cycles 30 3 2 CA N KA ki ki ki ka ki ka ki ki ka No bi ka ka b i KA ki ee eee Fei ki ke ka ka ka b i b i 3F Code Bytes Cycles
103. bler function call would not work The solution was to declare an uncommitted memory specific pointer to the DATA area At run time the absolute address of the register here 0x18 was assigned to the pointer The return value was then picked up via the pointer after exiting the assembler section Example Of Accessing Specific Registers In C char data dptr Create pointer to DATA location Define Address Of Register define RO_bank3 0x40018L Address of RO in bank 3 4 gt DATA space char x y Execute main dptr char RO_bank3 Point at RO bank3 x 10 dptr 0 x Write x into RO bank3 we S tze 3 Get value of RO bank3 An alternative might have been to declare a variable to hold the return value in a separate module and to use the linker to fix that module s DATA segment address at 0x18 This method is more robust and code efficient but is considerably less flexible 12 2 Making Use Of Unused Interrupt Sources One problem with the 8051 is the lack of a TRAP or software interrupt instruction While C166 users have the luxury of real hardware support for such things 8051 programmers have to be more cunning A situation arose recently where the highest priority interrupt function in a system had to run until a certain point from which lesser interrupts could then come in Unfortunately changing the interrupt priority registers part way through the interrupt
104. ddress This might occur if for example the registers of a memory mapped real time clock chip are to be grouped together as a structure The template in this instance might be Contents Of RTCBYTES C Module struct RTC unsigned char seconds unsigned char minutes unsigned char hours H unsigned char days Z Hu struct RTC xdata RTC chip Create xdata structure There are two ways of doing this The more common method now used is the at keyword This was introduced in version C51 3 4 struct RTC xdata RTC_chip _at_ 0x200 Create xdata structure at X 0x0200 The AT keyword can be used to place data in any memory space There is more information on the _at_ keyword in section 8 7 The other method is uses the linker A trick using the linker is required here so the structure creation must be placed in a dedicated module This module s XDATA segement containing the RTC structure is then fixed at the required address at link time This can be used to place not only structures but modules containing anything else at a fixed point Using the absolute structure could be Structure located at base of RTC Chip MAIN C Module extern xdata struct RTC_chip www Phaedsys org page 72 of 194 Version 3 65 Other XDATA Objects xdata unsigned char time_secs time_mins void main void time_secs time_mins RTC_chip seconds RTC_chip minutes Linker Input File To Locate RTC_chip structure over re
105. dering in the 8051 if they find the idea of the MSB being at the low address odd In embedded C the commonest use of a union is to allow fast access to individual bytes of longs or ints These might be 16 or 32 bit real time counters as in this example Declare Union union clock long real_time_count Reserve four byte int real_time_words 2 Reserve four bytes as int array char real_time_bytes 4 Reserve four bytes as char array dG Real Time Interrupt void timerO_int void interrupt 1 using 1 clock real_time_count Increment clock if clock real_time_words 1 0x8000 Check lower word only for value Do something if clock real_time_bytes 3 0x80 Check most significant byte only for value Do something 7 6 Generic Pointers C51 offers two basic types of pointer the spaced memory specific and the generic Up to version 3 00 only generic pointers were available www Phaedsys org page 75 of 194 Version 3 65 As has been mentioned the 8051 has many physically separate memory spaces each addressed by special assembler instructions Such characteristics are not peculiar to the 8051 for example the 8086 has data instructions which operate on a 16 bit within segment and a 20 bit basis For the sake of simplicity and to hide the real structure of the 8051 from the programmer C51 uses three byte pointers rather than the single
106. e code is smaller In previous sections it was highlighted that the 8051 is an 8 bit MCU It can handle 8 bit chars far faster than 16 bit ints So where you know the sizes of your data and be very sure you do switch off the Integer Promotion for faster smaller code There will be no warnings unless you are using Lint 4 4 4 A Non ISO Approach To Checking Data Type Overflow A very common situation is where two bytes are to be added together and the result limited to 255 i e the maximum byte value With the 8051 being byte orientated incurring integers must be avoided if maximum speed is to be achieved Likewise if the sum of two numbers exceeds the type maximum the use of integers is needed In this example the first comparison uses a proper ISO approach Here the two numbers are added byte wise and any resulting carry used to form the least significant bit of the upper byte of the notional integer result A normal integer compare then follows Whilst C51 makes a good job of this a much faster route is possible as shown in the second case include lt reg51 h gt unsigned char x Y Z Add two bytes together and check if the result has exceeded 255 void main void RSEG PR main T USING 0 main if unsigned int x unsigned int y gt Oxff MOV A x ADD A y MOV R7 A CLR A RLC A MOV R6 A SETB IS MOV A R7 SUBB A 0FFH MOV A R6 SUBB A 00H JE 2C0001 Z z Oxtt ISO C version
107. e 128 80H direct addressing will result in access of the sfrs Indirect addressing MOV A RO does not work However with the 8052 and above the area above 80H can when indirectly addressed be used as additional storage The main use of this area is really as stack Data in this area is addressed by the MOV A Ri instruction As only indirect addressing can be used there can be some loss of efficiency as the Ri register must be loaded with the required 8 bit address before any access can be made Left to its own devices C51 will not use this area other than for stack Unusually the 8051 stack grows up through RAM so the linker will place the STACK area at the top of the area taken up with variables parameter passing segments etc If your application does not need all the stack area allocated it is possible to use it for variables This is simply achieved by declaring some variables as idata and using RAMSIZE 256 when linking www Phaedsys org page 90 of 194 Version 3 65 Such is human nature that most people will not think of using idata until the lower 128 bytes actually overflovvs and a panic driven search begins for more memoryl As has been pointed out idata variables are rather harder to get at because of the loading of an Ri register first However there is one type of variable which is ideally suited to this the array or pointer addressed variable The MOV A Ri is ideal for array access as the Ri simply contain
108. e e e e E e e E E e e A e e e e E A e e k k k k k k k k k k k k k k k k k This program initialises the peripheral functions and then loops around reading the A D converter and transmitting values down the serial port void main void Enter from reset vector serial0_init_T1 Initialise serial port 0 timerl baudrate generator ad_init Initialise A D converter capture_CCO_init Initialise input capture T2 for freq measurement and timed pulse generation symm_PWM_init Generate symmetrical PWM on CC3 P1 3 may only be present if capture_CCO_init is commented out pwm_init Initialise TOC PWM on CMx timerO_init Initialise timer 0 overflow 2ms interrupt EAL 1 Enable interrupts initialise_screen Write startup message to terminal Loop Forever while FOREVER P6 0x08 Refresh MAX691 watchdog every background loop This is attached to port 6 bit 3 ad_convert Read all analog channels print_info Send analog values etc to terminal mod_pwm Modulate PWMO with analog channel 0 input mod_symm_pwm Modulate symm PWM with analog channel 0 input www Phaedsys org page 141 of 194 Version 3 65 www Phaedsys org page 142 of 194 Version 3 65 20 Appendix C C51 Version 6 Code Comparison The following competitive benchmarks for the Keil C51 compiler were run in June 2001 to compare the output generated by the Ke
109. e external form is seen To do this each source module must somehow identify itself to the include file This is very simply done with define statements A define is placed at the top of each module giving the name of the module Thus in the top of password c the first line should be something like define PASSWORD C include lt inttype h gt lt gt denotes system or library header include password h mn denotes local or application header Thus password h will contain the following ifdnef _PASSWORD_H define _PASSWORD_H tifdef PASSNORD C UNIT8 T get passvord UNIT8 T status INT32_T password_flags else extern UNIT8_T get_password UNIT8_T status extern INT32_T password_flags tendif tendif When included in its home module Password c the ifdef else endif will cause the preprocessor to see the local declarations When placed in any other modules ie that do not have _PASSWORD_C defined the preprocessor will see the external equivalents There are a couple of points with regard to the extern on the function and the check for the home file Firstly that by implication all function prototypes are extern As an embedded Engineer the word implied should not be in your vocabulary Things should www Phaedsys org page 50 of 194 Version 3 65 be explicit This was discussed extensively in both the C and embedded circles in late 2000 and the view was it is better to be explicit than i
110. e of you may have noticed missed out Lint and the pre processor Well yes and no It depends on your system In the very beginning CC was not the compiler It was a script of batch file To build a program you would normally use MAKE a program that would read a makefile for the project and process it This would list all the c source files and the related header files for each You did this manually The project build instructions would be included in the makefile This would include Lint It was assumed by Kernigan Ritchie Thompson and Johnson to be part of the compiler chain NOTHING HAS CHANGED You should ALWAYS use lint when compiling C or C for that matter The pre processor whilst a separate module was usually included in the cc but as Lint has many more uses it was not The cc compiler called the pre processor and up to three compiler modules i e two or three pass These produced various intermediate files that were deleted during there run and not usually seen by the programmer The compiler turned out assembly Hex convertor www Phaedsys org page 14 of 194 Version 3 65 language However some of these were two pass assemblers This was required to work out the forward references The assembly was assembled in to object code The multiple object modules were then linked with the libraries to form an executable The final line was a clean that removed all the intermediate files In the very early day
111. e overlaying of Tunc with other background functions will not occur Removing the link only with the interrupt would solve this main2 obj 8 to main2 abs amp OVERLAY timerO_int funcl Another route would be to disable all overlaying but this is likely to eat up large amounts of RAM very quickly and is thus a poor solution main2 obj amp to main2 abs amp NOOVERLAY With the MULTIPLE CALL TO SEGMENT WARNING the only really safe solution is to declare funcl as REENTRANT with the duplicate function a good second The danger of using the OVERLAY command is that a less experienced programmer new to the system might not realise that the interrupt is restricted as to when it can call the function and hence system quality is degraded 9 4 9 Overlaying Public Variables All the preceding examples deal with the overlaying of locals and parameters at a function level A case occurred recently in which the program was split into two distinct halves the divide taking place very early on To all intents and purposes the 8051 was able to run one of two completely different application programs based on some user input during initialisation Each program half had a large number of public variables some of which were known to both sides but the majority of which were local to one side only This is almost multitasking This type of program structure really needs a new storage class like GLOBAL with public meaning available to a ce
112. e the code in the top of the password c file is extern int system_flags defined in another module extern unsigned char get_password unsigned char status function visable in other modules three functions only visable in THIS file static long calculate_key void static long gen_randon_prime long int password_flags variable visable in other files www Phaedsys org page 49 of 194 Version 3 65 the get passvvord would go into the passvvord h file but the static local functions would not This is for two reasons Firstly they are only used in the password c file and secondly that it will create a compile error when password h is used in any other c file So we are looking at the following for our password h header file extern unsigned char get_password unsigned char status We also have the line long int password_flags variable visible in other files This gives us another problem that is connected with the line extern int system_flags defined in another module These variables need to be extern in all files bar the one in which they are defined The trick is however to use conditional compilation This will prevent the original declarations and the external versions being seen simultaneously When included in their home modules i e when password h is included in password c the compiler only sees the original declarations Whereas when included in a anyother module only th
113. ec abs PDATA 0 XDATA 100H Note that the normal XDATA area now starts at OX100 above the zero page used for PDATA Failure to do this properly can result in very dangerous results as data placement is at the vvhim of PORT21 3 5 Local Memory Model Specification 3 5 1 Overvievv From C51 version 3 20 it has been possible for memory models to be assigned to individual functions Within a single module functions can be declared as SMALL COMPACT or LARGE thus pragma COMPACT This has set the whole file to COMPACT A SMALL Model Function void fsmall void small printf HELLO This function has no memory modifier and is COMPACT XX As per the pragma at the top of the file PEJ void func void printf HELLO A LARGE Model Function void flarge void large printf HELLO Main Caller void main void fsmall Call small function flarge Call large function func call to compact function In the example above the main and any other function not specifically changed is COMPACT fsmall is locally set to SMALL and flarge is locally set to LARGE Note on main Whilst the ISO C standard defines 2 mains int main argv argc and int main void www Phaedsys org page 30 of 194 Version 3 65 In self hosted embedded systems i e where there is no operating system void main void is permitted 3 5 2 Point To Watch In Multi Model Progra
114. ecaeteteceteaectecdasg aene a aa Arae aa a E Aaaa apaa daera Bine aT 107 11 1 Tying The C Program To The Restart Vector 107 11 2 Intrinsic Functions s eege ees see ENEE Edge e 107 L1 38 EA Bit Control TED Ta sis sete ala yE nderohen red n dd o udh s e 108 www phaedsys org page 4 of 194 Version 3 65 Lt TOBICSIKSUPPOT das ee cute REENERT ENEE 108 11 5 Function Level Optimisation ENEE 109 V1 6 In Line Functions in C8 cis i cic cbei ctetiedecdctieczensedcueodeneddetecnseces cntdeateneeccdeettdeacetaadedecte 109 12 Some C51 Programming Tricks Au 111 12 1 Accessing RO etc directly from CB 111 12 2 Making Use Of Unused Interrupt Sources ENEE 111 12 3 Code Memory Device Syvitoh in Ga NEEN 112 12 4 Simulating A Software ROSE tuna ANEN 113 12 5 The Compiler Preprocessor define AEN 114 13 C51 library FuncHonS is vese vera vure od se ete 30 vde EE EE EES 115 18 1 Library Function Calling ci sisenc ve dushe Zeg edd EES eg ee 115 13 2 Memory Model Specific LibYAT IOS AA 115 14 Outputs Froni Bh eessen n s indet oshte Ee od s inte etapat akut TT 117 14 1 Object FIlSSI anus ende dis e ses Se d shme besoi kat l v kada ste set EENEG EEN EE EEEE EEE 117 14 2 HEX Files For EPROM Blowing ANEN 117 14 3 Assembler Output icc she sunis sine cd se sd d ea s 117 15 Assembler Interfacing To C PTOGTAMS ENEE 119 15 1 Assembler Function Example ENEE 119 15 2 Parameter Passing To Assembler Punctions ENEE 121 15 3 Paramet
115. ecial version of the Keil C51 compiler can actually compile programs that are defeated by some of the unrestricted free low end or generic compilers One area in particular springs to mind That of Data Overlaying Data overlaying is the art of using the same physical memory to hold several different items of data on the grounds that the use of the data is mutually exclusive This s something that should NEVER be done manually the slightest mistake causes data corruption However by using full calling tree analysis it can be done This is what the Keil compiler does rigorously Therefore the compiler can overlay a lot of the data As the DATA space in an 8051 is limited this can make all the difference It is often the DATA space that runs out before the code space External data space is available but at a cost not only in speed of access but the hardware as well At home it may not may much difference but in a commercial world a pound or a couple of USD may not seem like much but if your production run is over a thousand boards then it is a costly mistake on that one point alone The other point is the Keil C51 compiler along with most other commercial compilers are very well tested with industry standard test suites Test suites that are well out of the reach of individuals and small companies They are usually tested with the assistance of the chip manufacturers and other tool vendors www Phaedsys org page 13 of 194 Version 3 65 2 Compiler
116. ected In making s point at the message in the code space an 05 is loaded into s ahead of the actual address to be pointed at In the case of d 02 is loaded These additional bytes are how C51 knows which assembler addressing mode to use The library function C_CLDPTR checks the value of the first byte and loads the data using the addressing instructions appropriate to the memory space being used This means that every access via a generic pointer requires this library function to be called The memory space codes used by C51 are CODE 05 XDATA 02 PDATA 03 DATA 05 IDATA 01 7 7 Spaced Pointers In C51 Considerable run timesavings are possible by using memory spaced pointers By restricting a pointer to only being able to point into one of the 8051 s memory spaces the need for the memory space code byte is eliminated along with the library routines needed to interpret it DATA BDATA IDATA pointers are 1 byte long whereas XDATA PDATA CODE pointers are 2 bytes long A spaced pointer is created thus char xdata ext_ptr www Phaedsys org page 77 of 194 Version 3 65 to produce an uncommitted pointer into the XDATA space or char code const_ptr which gives a pointer solely into the CODE space Note that in both cases the pointers themselves are located in the memory space given by the current memory model Thus a pointer to xdata which is to be itself located in PDATA would be declared thus
117. efficient C will produce the best 8051 code www Phaedsys org page 117 of 194 Version 3 65 www Phaedsys org page 118 of 194 Version 3 65 15 Assembler Interfacing To C Programs The calling of assembler routines from C51 is not difficult provided that you read both this and the user manual 15 1 Assembler Function Example The example below is taken from a real application where an EEPROM was being written in a page mode Because of a 30us timeout of this mode the 25us run time of the C51 code was viewed as being a bit marginal It was therefore decided to code it in assembler If an assembler coded function is to receive no parameters then an ordinary assembler label at the beginning of the function is simply called like any C function Note that an extern function prototype must be given after the style of C51 File extern void asm_func void ASI File ASM_FUNC MOV A 10 8051 assembler instructions Should there be parameters to be passed C51 will place the first few parameters into registers Exactly how it does this is outlined in section The complication arises when there are more parameters to be passed than can be fitted into registers In this case the user must declare a memory area into which the extra parameters can be placed Thus the assembler function must have a DATA segment defined that conforms to the naming conventions expected by C51 In the example below the segment DT _WRITE_EE_PAGE WRITE_E
118. element strings Cycles 913 Concatenate the string pointed at by source onto another string pointed at by destination result strcmp destination source 8 element strings Cycles 152 Compare two strings pointed at by source with another string pointed at by destination If equal value of 1 is returned result strlen source 8 element string Cycles 505 Find the length of the source string In addition to these functions a range of other string and character functions are provided to perform tasks such as atoi ascii to integer atof ascii to floating point itof integer to floating point isalpha test for alpha character isdigit test for digit isalnum test for alpha numeric many other pre defined routines Examples char x 10 char y String of chars strepy x y Copies string pointed at by y to the empty array x Note C does not check that x is actually big enough to hold the string www Phaedsys org page 150 of 194 Version 3 65 Program Control if condition Code else Alternative Code Perform one of either two blocks of code depending on the result of a specified condition 8 bits 8sign l6bits 16 sign 32 bits 32 sign float Cycles 3 3 6 6 79 79 131 for i 0 i lt end value i i 1 Executable Code Repeat executable code until i end_value 8 bits 8sign 16 bits 16 sign 32 bits 32 sign Cycles 15 17 23
119. ems are not like this Typically they will consist of some frequently used code the execution of which is caused by or causes some real world event This code is fed data from other parts of the system whose own inputs may be changing rapidly or slowly Code which contributes to the system s major functionality must obviously take precedence over those sections whose purpose is not critical to the successful completion of the task However most embedded 8051 applications are very time critical with such parts being attached to interrupts The need to service as many interrupts as quickly as possible requires that interrupt code run times are short With most real world events being asynchronous the system will ultimately crash when too many interrupt requests occur per unit time for the cpu to cope with Fast runtimes and hence acceptable system performance are normally achieved by moving complex functions into the background loop leaving the time critical sections in interrupts This gives rise to the problem of communication between background code and its dependant interrupt routine www Phaedsys org page 57 of 194 Version 3 65 The simple system is very egalitarian vvith all parts treated in the same vvay When the CPU becomes very heavily loaded vvith high speed inputs it is likely that major sub functions vvill not be run frequently enough for the real vvorld interrupt code to be able to run vvith sufficiently up to date informat
120. en best used elsewhere Also access is generally faster to ROMmed constants than RAM ones if the RAM is external to the chip as ROM MOVC A DPTR instruction cycle is much faster than the RAM MOVX A DPTR Examples of EPROMed constant data are unsigned char code coolant_temp unsigned char code look up tablel5 unsigned int code pressure 4 Ox02 JET 21 731 411 7 Note that const does not mean code Objects declared as const but not CODE will actually end up in the data memory area determined by the current memory model const unsigned char tens 1 10 100 1000 T will be stored in the heap never on the stack if it is outside the scope of a function It will exist in DATA if you use the small model and XDATA if you use the large model The keyword const is a compiler system prevents the data being changed by the program The key word CODE stops the data being changed by the fact that it is physically impossible to write to CODE space We will see later that it is possible to wire CODE space so it can be written to Also some FLASH parts do permit the changing of CODE space However code space should not normally be changed Tip Use const in function prototypes when passing in a value that should not be changed in the function eg func const char count An associated key word is volatile This is used where a variable is not changed by an application but by the hardware Thus a decl
121. er Passing In Reoistersg ENEE 121 16 General Things To Be Aware Of 123 EE 123 EE 123 Ie E AE SIE IE E A A ERE E ts E AI E E Mocha A sofas EL chee tates ho 123 i E EE 123 16 6 E EE E ETA sod it tele A E ess oa E 123 E N eet EE 124 16 7 Floating Point Numbers iisen nienia doke e dd ndoh PENE ar rE EC 124 17 GONCIUSIOM ki sod esi u ov s bre vo nn not sore sh d v n hene od h 125 18 ee 129 19 Appendix EE 131 20 hee E Gi via nente inde Pas do hd n e ada Ste te Pot 143 20 1 Be EE 143 20 2 VVhetston E deed ee ged nate he does T ne Pone ba eschen 143 20 3 The Sieve of Eratosthenes ENEE 144 al Appendik RE 156 22 Appendix E Tile Hill Embedded C Style Guide AANEREN 161 23 Apendix F A Standard History of 164 23 1 From K amp R to ISO C99 A Standard History of 165 23 151 K amp R 1 Edition 1978 EE 165 23 1 2 K amp R eene geed des Ses 166 e ANSL C 1989 EE 166 29 14 1ISO C90 1990 EE 166 23 1 5 ISO C99 ISO IEC 9899 opp 167 23 1 6 ISO IEC 9899 1999 TC 2001 168 23 2 The Future Back to C Why C is not Chi 168 23 3 What to read for Embedded CH 169 24 Appendix G Timers amp Delays sese sees ee ever ee ereenn nenen eee nene veme neneve ene eee emen nner 173 25 Appendix H Serial Ports and Baud rates ENEE 175 26 Appendix J ICE Connect your design 177 21 Appendix K 8051 Instruction set in Hex order 179 28 Appendix L Refferencess iiinis rin nar e eee neneve ene a nese rere nenen ee eneve venes teve ne teve da
122. erve code space Control of register bank switching Support of enhanced or special family variants The Keil C51 compiler contains all the necessary C extensions for microcontroller use This C compiler builds on the techniques pioneered by Intel but adds proper C language www Phaedsys org page 12 of 194 Version 3 65 features such as floating point arithmetic formatted unformatted 10 etc It is in fact an implementation of the ISO C standard specifically for 8051 processors It should be noted that the Keil C51 in common with at the time of writing in early 2006 virtually all other compilers are IS09899 1990 compliment that is C90 plus the main Technical Amendment Al and the Technical Corrigendum TC1 and TC2 The Keil compiler is not C99 compliant nor is it or any other 8 or 16 bit target compiler ever likely to be Untill some of the bugs in the C99 are fixted it is unlikelyu that any compiler will be complient to the C99 or later ISO c standartd This does render the possibility of writing portable ISO C However the resultant application would be somewhat large and slow compared to one that used the 8051 specific extensions It is also possible that it would be too slow and large to actuall work on an 8051 t is for this reason that generic compilers that are ported to the 8051 are usually a very poor substitute for one that has been written for 8051 from the start In some cases it has been found that the 2 or 4 or 8 K limited sp
123. es Keil C51 Keil C51 Keil C51 Compiler c Version 6 12 Version 6 12 Version 5 02 Memory Model LARGE LARGE LARGE ROM Model LARGE LARGE LARGE Optimization Level 9 SIZE 8 SPEED SG SIE Exe Time 12MHz 8051 4 647 secs 4 445 secs 4 493 secs Exe Time 25MHz DS320 0 973 secs 0 915 secs 0 941 secs Module Code Size 3596 bytes 5446 bytes 4306 bytes Dynamic XDATA 186 bytes 186 bytes 189 bytes Total Code Size 8618 bytes 10486 bytes 9236 bytes www Phaedsys org page 143 of 194 Version 3 65 20 3 The Sieve of Eratosthenes The Sieve of Eratosthenes is a standard benchmark used to determine the relative speed of different computers or in this case the efficiency of the code generated for the same computer by different compilers The sieve algorithm was developed in ancient Greece and is one of anumber of methods used to find prime numbers The sieve works by a process of elimination using an array that starts with 2 and keeps all the numbers in position The process is 234567891011 12131415 16 17 1819 20 21 22 23 24 25 Starting after 2 eliminate all multiples of 2 234567891011 12131415 16171819 20 21 22 23 24 25 Starting after 3 eliminate all multiples of 3 234567891011 12131415 16 17 18 19 20 21 22 23 24 25 Starting after 5 eliminate all multiples of 5 234567891011 12131415 16171819 20 21 22 23 24 25 Continue until the next remaining number is greater than the square root of the largest number in the original series In this case the
124. es 2407 9570 exp x float Cycles 3002 7870 sqrt x www Phaedsys org page 145 of 194 63 32 sign 64 32 sign 160 32 sign 1624 32 sign 63 140 float 146 float 131 float 134 float 140 Version 3 65 float Cycles 42 2860 log x float Cycles 45 6050 Other Maths Functions are cosh Hyperbolic cosine sinh Hyperbolic sine abs find absolute value rand generate a random number Examples x sin 3 1415926 2 find the sine of PI 2 X sqrt 2 find square root of x Bitwise Functions These allow direct bit by bit operations to be performed amp AND 8 bits 8sign 16 bits 16 sign 32 bits 32 sign Cycles 3 3 6 6 63 63 Inclusive OR 8 bits 8sign 16 bits 16 sign 32 bits 32 sign Cycles 3 3 6 6 63 63 A Exclusive OR 8 bits 8sign 16 bits 16 sign 32 bits 32 sign Cycles 3 3 6 6 63 63 NOT Invert 8 bits 8sign 16 bits 16 sign 32 bits 32 sign Cycles 3 3 6 6 63 63 Examples a b amp Oxfe make a equal to a bit wise AND with OxFE 11111110 a b10x01 make a equal to a bit wise OR with 0x01 00000001 www Phaedsys org page 146 of 194 Version 3 65 Two Operand Functions Make left side equal to right side test for left being equal to right Add two operands and store result in first one 8 bits 8sign 16 bits 16 sign 32 bits 32 sign float Cycles 1 1 5 5 59 59 140 Subtract two operands and store result in first one 8 bits 8sign 16 bits 16
125. ewpoint does no harm whatsoever 16 1 Always use 8 bit variables the 8051 is strictly an 8 bit machine with no 16 bit instructions char will always be more efficient than int s 16 2 Always use unsigned variables where possible The 8051 has no signed compares multiplies etc hence all sign management must be done by discrete 8051 instructions 16 3 Try to avoid dividing anything but 8 bit numbers There is only an 8 by 8 divide in the instruction set 32 by 16 divides could be lengthy unless you are using an 80C537 16 4 Try to avoid using bit structures Until v2 30 C51 did not support these structures as defined by ANSI Having queried this omission with Keil the explanation was that the code produced would be very large and inefficient Now that they have been added this has proved to be right An alternative solution is to declare bits individually using the bit storage class and pass them to a user written function 16 5 The ANSI standard says that the product of two 8 bit numbers is also an 8 bit number This means that any unsigned chars which might have to be multiplied must actually be declared as unsigned int s if there is any possibility that they may produce even an intermediate result over 255 However it is very wasteful to use integer quantities in an 8051 if a char can do the job The solution is to temporarily convert cast a char to an int Here the numerator potentially could be 16 bits but
126. example the on chip memory is applied to an operating system The compact model is rarely used on its own but more usually in combination with the SMALL switch reserved for interrupt routines COMPACT is especially useful for programs with a large number of medium speed 8 bit variables for which the MOVX A RO is very suitable It can be useful in applications where large stack is required meaning that data needs to be off chip Note that register variables are still used so the loss of speed will not be significant in situations where only a small number of local variables and or passed parameters are used www Phaedsys org page 27 of 194 Version 3 65 3 3 3 3 LARGE Total RAM up to 64KB 128 or 256 bytes on chip Permits slow access to a very large memory space and is perhaps the easiest model to use Again not often used on its own but in combination localised use of the SMALL model As with COMPACT register variables are still used and so efficiency remains reasonable 3 3 4 What data goes where In summary there are five memory spaces available for data storage each of which has particular pros and cons Keywords can be used to place specific variables in specific memory locations overriding the global memory model This gives the Software Engineer the ability to fine tune the porgram of a very high degree Here are some recommendations for the best use of each DATA 128 bytes SMALL model default location Best For Fre
127. explicitly using them usually for inrterupts The Overlay Variables compiler switch should be used if possible in this model Note that the stack size is critical in this model and therefore will limit the nesting of C functions Therefore few larger functions may be better than lots of small ones that could lead to deeper nesting Not only is this the fastest model it also results in smaller code as the addessing is direct or 1 byte pointers This model also tends to lead to occurrences of the Linker warning L128 complaining about data segment overflow 3 3 2 2 RAM COMPACT The COMPACT model uses the PDATA bank for variables This is the first 256 bytes of XDATA It is addressed via Port 0 using indrect addressing through RO and R1 Whilst this may seem to give no more memory than the SMALL model remember the stack will still be in IDATA and in the DATA memory the first 48 bytes are reserved for the register banks and bit addressable data Also as we will see later specific data can be forced back into the DATA area 3 3 2 3 RAM LARGE The LARGE model puts all the data into XDATA and uses the 16 bit DPTR to access them indirectly This is less efficient than the other forms of addressing and also uses longer slower instructions This makes the CODE larger as well as slower This mode gives up to 64K of data space Though XDATA can be banked and is available in some 8051 derivatives with a greater range than 64K using special commands
128. f the RAM is to be used some may say overcomel the 8051 user has to decide both the program and data models Not only as in the PC are address and pointer ranges considered but tee joss tira or Jesi lusvcesst Us hee reel data locations and storage en strategies for the several 8051 om data memories Some memories Det setts etre are best used for direct and others o FETISH C le Rik DETR ghee indirect addressing Also a Na frequently used variables vvill be better in ram that is accessed fast vvhere as other data may be quite da Code na Tip Na my happy in slower memory and in Sut M Ho it the case of constants eg look up tables they can be put in to the Re Be _ ROM Rel T Bel P CR an Pe E e Te Pais ya g If mg pak E pk ea Fer This often seems somevvhat overwhelming However if taken 2 Jl real b step at a time it is not A basic understanding will cover most usage It is really only when pushing the limits in depth knowledge is required However some thought before and durring programming will pay off in the long run As with all the settings they can be obtained by point and click in the uVision IDE by command line and optionally by pragma in the source files themselves The memory model settings in the Keil uVision IDE are found by right clicking on the Target in the project window and selecting options onthe pop up menu 3 3 1 ROM Memory Models Firstly we shall
129. f the indirect instruction is the pointer The register holding the address to be indirectly accessed in the assembler examples is a normal C type except that its purpose is to hold an address rather than a variable or constant data value It is declared by unsigned char pointero Note the asterisk prefix indicating that the data held in this variable is an address rather than a piece of data that might be used in a calculation etc In all cases in the assembler example two distinct operations are required i Place address to be indirectly addressed in a register ii Use the appropriate indirect addressing instruction to access data held at chosen address www Phaedsys org page 64 of 194 Version 3 65 Fortunately in C the same procedure is necessary although the indirect register must be explicitly defined whereas in assembler the register exists in hardware 1 Define a variable which will hold an address unsigned char pointer 2 Load pointer variable with address to be accessed indirectly pointer amp c_variable 3 Put data Oxff indirectly into c variable via pointer pointer Oxff Taking each operation in turn 1 Reserve RAM to hold pointer In practice the compiler attaches a symbolic name to a RAM location just as with a normal variable 2 Load reserved RAM with address to be accessed equivalent to MOV RO 40 In English this C statement means
130. for details on how to best locate variables 4 2 2 Initialised Variables The MISRA C guide Rule 30 says that all variable shall have been asigned a value before use To force certain variables to a start value in an overall system setup function for example it is useful to be able to declare and initialise variables in one operation This is performed thus unsigned int engine_speed 0 function E Here the value 0 will be written to the variable before any function can access it To achieve this the compiler collects together all such initialised variables from around the system into a summary table A runtime function named C_INIT is called by the startup obj program which writes the table values into the appropriate RAM location thus initialising them startup obj comes from startup a51 and assembly file This is automatically included by the linker unless a local startup a51 is used to override it www Phaedsys org page 34 of 194 Version 3 65 Immediately afterwards the first C program main is called Therefore no read before vvrite can occur as C INIT gets there first The only point to note is that you must modify the startup a51 program to tell C_INIT the location and size of the RAM you are using For the large model XDATASTART and XDATALEN are the appropriate parameters to change User defined Power On Initialization of Memory With the following EQU statements the initializati
131. gma Usage By including the line pragma SMALL as the first line in the C source file The RAM small memory model will be set for the whole source file the pragma is in See Section 2 1 3 for details on specific variable placement SMALL is the default model and can be used for quite large programs provided that full use is made of PDATA and XDATA memory spaces for less time critical data Special note on COMPACT model usage The COMPACT model makes certain assumptions about the state of Port 2 The XDATA space is addressed by the DPTR instructions which place the 16 bit address on Ports 0 and 2 The COMPACT model uses RO as a 8 bit pointer which places an address on port 0 Port 2 is under user control and is effectively a memory page control The compiler has no information about Port 2 and unless the user has explicitly set it to a value it will be undefined although generally it will be at Oxff The linker has the job of combining XDATA and PDATA variables and unless told otherwise it puts the PDATA COMPACT default space at zero Hence the resulting COMPACT program will not work It is therefore essential to set the PPAGE number in the startup a51 file to some definite value zero is a good choice The PPAGEENABLE must be set to 1 to enable paged mode Also when linking the PDATA ADDR control must be used to tell L51 where the PDATA area is thus www Phaedsys org page 29 of 194 Version 3 65 L51 modulel obj module2 obj to ex
132. help you make a mess more eficiently Print Si For most 8051 designs the software structures can usually Bank be drawn using paper Transaction and pencil have Bank Computer only used a tool in this case for clarity of the drawings Keyed Data b gaa Cash Card Message Bank Service Till Account Information For the 8051 using mainly C or assembler the structured or modular design methods should be used Structured or modular designed software is the C equivelent of the Object Orientated Programming used with C Ada and the like Both Structured and OO programming share many concepts and good modular programming has many of the attributes of OOP but due to the differences in the way the languages work can not have all of them www Phaedsys org page 42 of 194 Version 3 65 For the 8051 a structured method like Yourdon one of the more popular would be used The Yourden method has several views of the software and it is worth looking at these as an example as to why modular programing should be used on all systems The top diagram shown here is a top level Context diagram This shows all the inputs and outputs to a system In this case an ATM This defines the outer limits of the system It could equaly be an Automitive engine control or a washing machine In the case of my car there are mor similarites than would care to acknowledge lt Message _ Get Password
133. hin a processor are represented by either bits bytes words or long words corresponding to 1 8 16 and 32 bits per variable C51 variables are similarly based for example bit 1 bit Dr ze 2 signed char 8 bits Qe tee 12a unsigned char 8 bits Dr 255 signed int 16 bits 0 32768 unsigned int 16 bits 0 65535 signed long 32 bits D 2 147483648x109 unsigned long 32 bits 0 4 29496795x109 float 32 bits 1 176E 38 to 3 4E 38 pointer 24 16 8 bits Variable address There is also a type called short However as in this implimentation short is the same size as an int it is not required nor used There is a myth that short is always 16 bits and more portable than int This is not correct and the size of short is not precisly defined Short should not be seen in an 8051 program Misra C rule 13 requires the use of typedefs for standard types Further to this ISO C99 recommends a similar thing and specifies a header file called inttypes h This contains the following types int8_t uint8_t int16_t uint16_t int32_t and uint32_t that would be defined in C51 as typedef signed char int8_t typedef unsigned char uint8 C typedef signed int intl6_t www Phaedsys org page 36 of 194 Version 3 65 typedef unsigned int uint16 t typedef signed long int32_t typedef unsigned long uint32_t There are in ISO C99 also two pointer types which could be used for generic pointer and signed and unsigned 64 bit types wh
134. iables unsigned char input_x_val unsigned char input_y_val unsigned char sine_value Routine To Be Tested extern interp unsigned char unsigned char unsigned char const Global Variables unsigned int angle Dummy Harness Program void main void while 1 for angle 0 angle lt 0x100 anglett sine value interp angle 0 sine_table www Phaedsys org page 159 of 194 Version 3 65 www Phaedsys org page 160 of 194 Version 3 65 22 Appendix E Tile Hill Embedded C Style Guide When writing C there are two types of guide available and programmers often confuse them Firstly the style guide which will be described here Style is the layout and making it look pretty uniform and readable It is not about a safe use of C as such The other type of guide covers the safe use of C or a safe subset There are many of these available They are often industry specific however there is one which has escaped into widespread use The MISRA C guide or to give it it s full title The Motor Industry Software Reliability Association Guidelines For The Use Of The C Language In Vehicle Based Software MISRA C is available from MIRA and also from PhaedruS SystemS It is a very readable set of rules that make sense for most C programming embedded or not The Style Guide History The Tile Hill style guide has been produced not because it is The Best or Only Way but because every time we mentioned ti
135. ibrary files contain many discrete functions each of which can be used by a C program They are actually retrieved by the linker utility covered in section 8 These files are treated as libraries by virtue of their structure rather than their extension The insertion or removal of functions from such a file is performed by a library manager called LIB51 13 2 Memory Model Specific Libraries Each of the possible memory models requires a different run time library file Obviously if the LARGE model is used the code required will be different for a SMALL model program Thus with C51 6 different library files are provided C51S LIB SMALL model C51C LIB COMPACT model C51L LIB LARGE model www Phaedsys org page 115 of 194 Version 3 65 plus three additional files containing floating point routines as well as the integer variety C51 library functions are registerbank independent This means that library functions can be used freely vvithout regard to the current REGISTERBANKO or USING status This is a major advantage as it means that library functions can be used freely vvithin interrupt routines and background functions vvithout regard to the current register bank www Phaedsys org page 116 of 194 Version 3 65 14 Outputs From C51 14 1 Object Files Being closely related to the original Intel tools C51 defaults to the Intel object file format This is a binary file containing the symbolic information necessary for debugging with
136. ich are not appropreate to the 8051 For most embedded work especially on the 8051 whether the variable is a character or integer is imaterial What is often far more important is the size of the data Typical declarations would be unsigned char xdata battery_volts int idata correction_factor t bit flag 1 Or using the ISO C typedef s uint8_t xdata battery_volts intl6_t idata correction factor bit flag 1 Note There is no ISO C typedef for bits Also bit variables are always placed in the bit addressable memory area of the 8051 see section 2 1 1 for this reason bits can not have a memory location modifier By definition they must be in BDATA With a processor such as the 8086 int is probably the commonest data type As this is a 16 bit processor the handling of 16 bit numbers is generally the most efficient The distinction between int and unsigned int has no particular impact on the amount of code generated by the compiler since it will simply use signed opcodes rather than the unsigned variety For the 8051 naturally enough the char should be the most used type Again the programmer has to be aware of the thoroughly 8 bit nature of the chip Extensive use of 16 bit variables will produce slower code as the compiler has to use library routines to achieve apparently innocuous 16 by 8 divides for example The use of signed numbers has to be regulated as the 8051 does not have any signed arithmetic instructions
137. icular entry Taskl static uint8_t flag switch flag case 1 sectionl break case2 section2 break default error Do remember though that this code is also taking up time and the scheduler itself will affect performance Commercial RTOS will have figures for task or context swapping etc You will have to determine your own An alternative is to control overall execution from a real time interrupt so that each job is allocated a certain amount of time in which to run If a timeout does occur that task is suspended and another begins This is more complex as the state of the tasks has to be saved somewhere and quickly It does give the flexibility that tasks can be allocated different run times l e The task loads a time to the interrupt counter In the Round robin system all functional blocks are considered to be of equal importance and no new block can be entered until its turn is reached by the background loop Only interrupt routines can break this with each one having its own priority Should a block need a certain input signal it can either keep watching until the signal arrives so holding up all other parts or it can wait until the next entry next time round the loop Now there is the possibility that the event will have been and gone before the next entry occurs This type of system is OK for situations where the time critical parts of the program are small In reality many real time syst
138. ign test 7 void main void test 1 if test amp 0x80 Conventional bit mask and amp test LE test was ve if sign 1 Use sbit test 1 gt test was ve Results in the assembler RSEG BA T2 test DS 1 sign EQU test 7 MOV test 0FFH if test amp 0x80 Conventional bit mask and amp MOV A test JNB ACC 7 2C0001 Z best d test was ve MOV test 01H 7 2C0001 if sign 1 Use sbit JNB sign C0003 t tests kre test was ve MOV test 01H 7 200003 RET Here using the sbit the check of the sign bit is a single JNB instruction which is a lot faster than using bit masks and amp s in the first case The situation with ints is somewhat more complicated The problem is that the 8051 does not store things as you first expect The same sign test for an int would still require bit 7 to be tested This is because the 8051 stores int s high byte at the lower address Thus bit 7 is the highest bit of the higher byte and 15 is the highest bit of the lower High byte Low Byte Bit locations in an integer 7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 www Phaedsys org page 38 of 194 Version 3 65 Another useful place bit types can be used is in the SFR s that end on O or 8 For example the 10 ports Port 1 may be defined in a header file as sfr PI 0x90 this can then be bit used as follovvs define MOTOR ON li define
139. ign bit Now to test whether x is negative the state of sign_bit need only be tested if sign_bit x is negative sign bit 0 Gives JNB sign_bit POSITIVE CLRB sign bit POSITIVE Or using a non sbit method if x lt 0 x is negative sign bit 0 Gives MOV A x ANL A 080H IZ POSITIVE ANL x 07FH POSITIVE www Phaedsys org page 152 of 194 Version 3 65 Handling 8051 Ports and SFRs Examples Pl Oxff H vrites value ff to port 1 ADCON 0x80 Z OR 80 hex into ADCON P1 0 1 S set bit 0 of port 1 Getting Data In And Out Of C Programs In The 8051 printe string SK SY Print the characters numbers and or strings contained within to the serial and thence to a terminal VTI100 etc 16 8 bit characters Cycles 3553 scan amp xX Store incoming characters from terminal into memory buffers indicated within Note that the Kr implies the address of buffer x 16 8 bit characters Cycles Not measurable but similar to printf Examples value 1 3 000 value_2 4 256 printf Results Are f amp f value 1 value 2 Results Are 3 000 amp 4 256 is printed on terminal screen Here the numerical values of the two numbers are substituted into the two f symbols char keyboard_buffer 20 scan amp keyboard_buffer read incoming characters from terminal keyboard into memory starting at the address of ke
140. il Version 5 and Version 6 compilers The source code used for the Whetstone and Dhrystone benchmarks is included with the Keil evaluation compiler 20 1 Dhrystone Dhrystone is a general performance benchmark test originally developed by Reinhold Weicker in 1984 This benchmark is used to measure and compare the performance of different computers or in this case the efficiency of the code generated for the same computer by different compilers The test reports general performance in Dhrystone per second Like most benchmark programs Dhrystone consists of standard code and concentrates on string handling It uses no floating point operations It is heavily influenced by hardware and software design compiler and linker options code optimizing cache memory wait states and integer data types E Keil C51 Keil C51 Keil C51 Compiler R F Version 6 12 Version 6 12 Version 5 02 Memory Model LARGE LARGE LARGE ROM Model LARGE LARGE LARGE Optimization Level 9 SIZE 8 SPEED 6 SIZE Exe Time 12MHz 8051 1 112 secs 1 029 secs 1 096 secs Exe Time 25MHz DS320 0 258 secs 0 234 secs 0 254 secs Module Code Size 1717 bytes 2163 bytes 1905 bytes Dynamic XDATA 5523 bytes 5523 bytes 5538 bytes Total Code Size 5197 bytes 5614 bytes 5269 bytes 20 2 Whetstone Whetstone is a benchmark test which attempts to measure the speed and efficiency at which a computer performs floating point operations The result of the test is given in units called whetston
141. ing Guide for ISO IEC 15288 WDTR 18037 1 Programming languages their environments and system software interfaces Extensions for the programming language C to support embedded Processors IEC 61508 FCD Functional Safety or Electrical Electronic Programmable Electronic Safety Relegated Systems Part 1 General Requirements Part 2 Requirements for Electrical Electronic Programmable Electronic Safety Relegated Systems Part 3 Software Requirements Part 4 Definitions and Abbreviations Part 5 Examples of methods for the determination of SIL Part 6 Guidelines for the application of parts 2 and 3 Part 7 Over View of Technical Measures ISO IEC JTC 1 N6981 Functional Safety and IEC61508 A basic Guide www Phaedsys org page 191 of 194 Version 3 65 IEEE You may be wondering where ANSI C is ANSI C became ISO C 9899 1990 and ISO 9899 has been the International standard ever since See A Standard History of C in Embedded C Traps and Pitfalls 1016 1998 Recommended Practice for Software Design Descriptions 5001 1999 The Nexus 5001 Forum Standard for a Global Embedded Processor Debug Interface NASA http sel gsfc nasa gov website documents online doc htm SEL 8 1 305 Recommended Approach to Software Development Rev 3 SEL 84 101 Manager s Handbook for Software Development Rev 1 SEL 93 002 Cost And Schedule Estimation Study Report SEL 94 003 C Style Guide August 1994 Goddard Space Flight Centre SEL 94 005 An Overview Of
142. ingle chip may not always mean small memory modle these days As with the ROM model selection the data memory model can be selected in the IDE is is also possible to force individual modules functions and variables into spesific data models This will be covered later 3 3 3 1 SMALL Total RAM 128 bytes 8051 31 This model is rather restricting in the case of 8051 31 especially as they do not have IDATA only the 128 bytes of DATA The SMALL model will support code sizes up to about 4K but a constant check must be kept on stack usage The number of global variables must be kept to a minimum to allow the linker OVERLAYer to work to best effect With 8052 32 versions the manual use of the 128 byte IDATA area above 80H can allow applications up to about 10 12K but again the stack position must be kept in mind Very large programs can be supported by the SMALL model by manually forcing large and or slow data objects in to an external RAM if fitted Also variables which need to be viewed in real time are best located here as dual ported memory emulators like the Hitex range can read their values on the fly This approach is generally best for large time critical applications as the SMALL global model guarantees that local variables and function parameters will have the fastest access while large arrays can be located off chip 3 3 3 2 COMPACT Total RAM 256 bytes off chip 128 or 256 bytes on chip Suitable for programs where for
143. into the bit addressable area starting at 0x20 where the 8051 s bit instructions can be used An example is testing the sign of a char by checking for bit 1 Here the char is declared as bdata thus bdata char test_char sign_bit is defined as sbit sign bit test char 7 to use this test_char counter if sign_bit test_char is negative the opcodes executed are MOV A counter MOV test_char A JNB 0 DONE Z Negative DONE All of which is a lot faster than using bit masks and amp s The important points are that the bdata tells C51 and L51 that this variable is to be placed in the bit addressable RAM area and the shit sign_bit test_char 7 tells C51 to assume that a bit called sign_bit will be located at position 7 in the test_char byte Byte Number test_char 20H Start Of BDATA area Bit Number 0 1 2 3 4 5 6 7 lt sign bit Byte Number 21H Bit Number 8 9 10 11 12 13 14 15 Byte Number 22H Bit Number 16 17 18 19 20 21 22 23 24 The situation with ints is somewhat more complicated The problem is that the 8051 does not store things as you first expect The same sign test for an int would require bit 7 to be tested This is because the 8051 stores int s high byte at the lower address Thus bit 7 is the highest bit of the higher byte and 15 is the highest bit of the lower Byte Number test_int high 20H Bit Number 0 1 2 3 4 5 6 7 Byte Number test_int
144. ion 3 65 19 Appendix B Driving The 8051 For Real Please note this is a program from the original C51 Primer In time it will be converted to C51 V7 and MISRA C compliance The following example program does the following typical 8051 tasks i Read a port pin value ii Write a port pin value iii Generate a periodic timer interrupt iv Transmit data via the serial port v Write to a memory mapped port It is suggested that to get started you steal sections from the following program Although the Siemens 80C537 has been used as the basis for this the approaches used are applicable to all 8051 variants include lt stdio h gt ZS include standard io libs XI include lt reg517 h gt include 80C517 register set Kp tinclude lt math h gt ZS include mathematical prototypes Si include lt string h gt ZS include string handling functions pragma MOD517 ZS Use 80C537 extensions W The 8051 areas covered are 1 Serial Port Polled Mode Baudrate generation from timer Baudrate generation from baudrate generator 2 Analog To Digital Convertor Reading values into an array 3 Frequency Measurement Input Capture CCO 4 Time Pulse Generation Output compare CC4 5 Symmetrical PWM Generation CC3 and timer2 overflow 6 Zero CPU Overhead Asymmetric PWM Generation CMx Compare Timer 7 Accessing Memory Mapped Ports Via pointers With XBYTE KKKKKKKKKKKK KKK KKK KKK KKK KKK KKK KKK K
145. ion Control The comments in the last section do of course assume that you are using a VCS You are aren t you Good For those of you who do not a VCS system is basically a application specific database Most have an interface that looks like the MS Windows File Explorer Files are copied in to them The file can be checked out and worked on and then checked in Most word processors will when saving a file move the origional to a bak or back up file A VCS system will continue to do this such that all the old back ups are numbered and kept This means that any version of the SS PVCS Version Manager ATM RSP File Project Folder Actions View Options Window Help SEO EE all software can be Folders E Files ia retieved Select All Deselect All D Select All Deselect All EAM HUT D D atm Opt z L eject c MC BC45 Di atm plg Lin Ga BORLAND D atm Uv2 VCS systems can do a L main c 2 crypto Q atm Uw L ein Ca dac Q atm Uv2 Bak great deal more than just process c 2 dev Q card ade S L in Ca devback Q card adg store the versions AS I services c L Qa DTEXT23 D card dep R s Leg Qa GAMES D card ses mentioned they vvill i C Java WorkShop DQ card sev 2 W I 29 keil Q eject ad update keyvvords in file L Files Locked by unknown da LDRA D eject c L 2 MMYVA D ejectLsT information blocks paors D eject
146. ion from the background Thus system transient response is degraded 5 5 3 Simple Scheduling A Partial Solution The problems of the simple loop system can be partially solved by controlling the order and frequency of function calling One approach is to attach a priority to each function and allow the scheduler to decide the next task to be executed based on the flags set The real world driven interrupt functions would override this steady progression so that the most important highest priority jobs are executed as soon as the current job is completed This kind of system can yield useful results provided that no single function takes too long Main vhile Switch Priority case 1 case 2 case 3 default task5 Unfortunately all these tend to be bolt ons added late in a project when run times are getting too long Usually what had been a well structured program degenerates into spaghetti code full of fixes and special modes designed to overcome the fundamental mismatch between the demands of real time events and the response of the program Moreover the individual control mechanisms of the called functions generate an overhead which simply contributes to the runtime bottle neck The reality is that real time events are not orderly and predictable Some jobs are naturally more important than others However inconvenient the real world produces events that must be responded to immediately It i
147. is one infamous review that starts I did not pay money for this book and I would suggest that no one else should either There is a list of books in the reference appendix However remember Most C books are written for the desktop programmer not for embedded systems I would still get K amp R 1 edition as a historical reference but not as a first C book to learn from I have an ISO C standard but that is not a book to learn from either You do not buy a dictionary to learn how to write novels www Phaedsys org page 169 of 194 Version 3 65 One thing to be wary of is that if the book is written by an academic it is likely to have been written for his course It may well refer to development boards and other equipment made by him at the university and not generally available Also it may assume you are doing or have done other courses and modules in the collage and therefore miss out useful information because you will get it on the other course Not all books written by academics are like this but do take care when buying Incidentally if anyone wants the ISO C99 standard the best place to get it from is a US web site www techstreet com ncitsgate html Note At the time of writing summer 2003 BSI were looking at publishing the ISO C and C standards at 30 printed but loose leaf Stop press PhaedruS SystemS are now able to offer the C90 standard on which most embedded compilers and MISRA C are based As of October 2005 Ph
148. ision IDE is still a single mouse click whether it is all C all assembler or mixed assembler and C modules Indeed the Keil C51 compiler suite will still work with the Intel PL M compiler making it possible to mix PL M C and Assembler modules This makes the Keil Environment suitable for transitioning from PLM or assembler to C for legacy projects However it should be noted that inline assembler should eb avoided where possible Students and command line enthusiasts should note that in the bottom window of the Target gt Options dialogues is the command line that the Keil IDE feeds to the compiler and linker Students should try at least once to use these strings in a batch file to build one program to see how the system works under the hood Understanding the mechanisms will help you know what is happening and can assist when things don t go as expected www Phaedsys org page 15 of 194 Version 3 65 In short the IDE simple collects and automates many tools into one interface A knowledge of what is under the hood is useful IDE with project control automated make Do note that whilst there is a Lint on the integrated tools utilities on line help compiler side there is no equivalent on the integrated debuggers assembler side This is because whilst there is a structure to C with if else while do for controls and matching between function prototypes definitions and uses there is E nothing similar for assembler The assembler
149. it kod r sdo EEERES kret doret de shba EE d e 90 9 3 Using The Top 128 Bytes of the 8052 RAN AA 90 9 4 151 Linker Data RAM Over la Vi Qa ANE 91 9 4 1 Ov rlaying Principl s TEE 91 9 4 2 Impact Of Overlaying On Program Construction 92 9 4 3 Indirect Function Calls With Function Pointers hazardous esse sese eee sees 92 9 4 4 Indirectly called functions solution EE 95 9 4 5 Function Jump Table Warning Non hazardous nana E 96 9 4 6 Function Jump Table Warning Soluti ON nun an nana nana ana aaa ne enen eee ene te pene eee eee nenen eee enen 97 9 4 7 Multiple Call To Segment Warning Hazardous sese eee eee nene e nene pene eee nenen 98 9 4 8 Multiple Call To Segment Solution 99 9 4 9 Overlaying Public Variables AANEREN REENEN 100 10 Other CS Extensions ss ses sh siont oni dend she e sond s gidd s EE dee yes 103 10 1 Special Function Bits wz Tee SEENEN 103 10 2 Support For 8005177537 32 bit Maths Ur 104 10 2 1 The MDU How To eeh aaa aann nena ever enen eee ene eee enen neneve neneve pemet ve d Raag NONS 104 10 2 2 The 8 Datapoint rs ee so n sisut oss vosh nisu EEN ESA date k d rd p SEENEN EENS 104 10 2 3 80C517 Things To Be Aware CO 104 10 3 87CC79 V SUPPO EE 105 10 3 1 87C751 St psiTo Take spiano aen eege EENS Aeae are e rE tadien te rides 105 10 3 2 Integer PrOMOHON sd se rr e ara ae teea aa arr sinan aa RE shta RER edem s dhee 105 11 Miscellaneous Points iects ecctecietecetedscns
150. l paper Hitex DE 2002 Buchner F The Tessy article for the ESC II Brochure Hitex DE 2002 Burden Paul Perilous Promotions and Crazy Conversions in C PR Ltd MISRA C Conference 2002 http www programmingreasearch com Burns amp Wellings Real Time Systems and Their Programming Languages Addison Wesley 1989 ISBN 0 201 17529 0 Chen Poon amp Tse Classification tree restructuring methodologies a new perspective IEE Procedings Software Vol 149 no 2 April 2002 pp 65 74 Clements Alan 68000 Family Assembly Language Pub PWS 1994 Coalman et al Object Orientated Development The Fusion Method Prentice Hall 1994 ISBNO 13 101040 9 Computer Weekly RAF JUSTICE How the Royal Air Force blamed two dead pilots and covered up problems with the Chinook s computer system FADEC Computer Weekly 1997 Cooling J Real Time Software Systems ITC Press 1997 ISBN 1 85032 274 0 Cooling J Software Design for Real time Systems ITC Press 1991 1 85032 279 1 COX B Software ICs and Objective C Interactive Programming Environments McGraw Hill 1984 Dasgupta Subrata Computer Architecture A Modern Synthesis Volume 1 Foundations Wiley 1989 ISBN 0 471 61277 4 Dasgupta Subrata Computer Architecture A Modern Synthesis Volume 2 Advanced Topics Wiley 1989 ISBN 0 471 61276 6 www Phaedsys org page 186 of 194 Version 3 65 Defenbaugh amp Smedley C through Design Franklin Beedle 8 Associates 1988 ISBNO 938661 10 8 Deitel
151. lowing high level language programming on its new 8051 in the shape of PLM51 This compiler was not perfect having been adapted from PLM85 8085 but Intel were realistic enough to realise that a full stack based implementation of the language was simply not on Note Intel discontinued PLM51 in 1986 at Version 1 4 PhaedruS SystemS still has a copy of this we use for compatibility testing The solution adopted was to simply pass parameters in defined areas of memory Thus each procedure has its own area of memory in which it receives parameters and passes back the results Provided the passing segments are internal the calling overhead is actually quite small Using external memory slows the process but is still faster than using an artificial stack The drawback with this compiled stack approach is that re entrancy is now not possible This apparently serious omission in practice does not tend to cause a problem with typical 8051 programs though IT programmers used to megabytes of memory recoil in horror at the thought of no re entrancy The later Keil C51 versions do allow selective re entrancy so that permitting re entrant use of a few critical functions does not compromise the efficiency of the whole program C ona microcontroller is practical for among other things Control of on and off chip peripheral devices Servicing of interrupts Easily supporting different ROM RAM configurations A very high level of optimisation to cons
152. lso meant that very variable held a permanent place in memory When memory was tight variables got reused by other functions for other purposes Very dangerous as the programmer had to manually work out when a vartiable space was not going to be used The closest you can get to that in C is a Union or explicit addressing of memory With the use of C data memory can be used far more effectively and safely Data can be made local to a function file or global Data can be passed so that it is local to several linked functions Further to this data can be dynamic or static Ram space not the variable name used for local data that only has a life during a particular function can be reused by other temporary data This is known as data overlaying and it can save a considerable amount of space It is however very carefully done by the compiler not the programmer There is a view that there should be no global variables at all Variables should always be passed as parameters in function calls This is not possible in embedded systems because many variables will be registers for IO SFR s etc or other peripherals and buffers It is a good idea to keep global variable to a minimum this is essential in applications that have more than one file as data control becomes impossible and memory wasted With the Keil C51 compiler if the functions can be kept to three or fewer parameters the compiler will work faster and registers used rather than the compiled st
153. me style guides we were asked if we had one When we told people to search the net look in libraries etc they usually said Can you send us the one you use Well this is it the one we use To get the folk law out of the way first It is called the Tile Hill guide becausewhilst writing it I had to pass close to Tile Hill in Coventry UK and it is a play on the legendary Indian Hill Recommended C Style and Coding Standards from AT amp T Bell labs My copy is Version 6 dated 1990 I do not claim that the Tile Hill Guide is better or replaced the Indian Hill document I just produced my own guide to the style I use because people asked for one The Tile Hill Embedded C Style Guide is freely availavble seperately in electronic form from http quest phaedsys org At the time of writing the Indian Hill guide was available from several places Also the NASA C sytle Guide from Jack Ganssel also has an embeded project guide available from http www ganssle com index htm The style guide rational The idea behind the style guide and the reason they are misussed is free will C is a free format language One white space has the same wieght as 50 white spaces This assumes that you are using black on white For those of you useing DOS screesn it is black spaces in the case of Jon lilac spaces Effectivly this means that the programmer isd free to laout the source code as he or she sees fit What is more there is no technical reason why the programme
154. mplied in this case The other point Keil supports FILE and some may be tempted to use it in the header but it is not of practical to use in this context as its value cannot be used for a define name Besides even if it was possible it would not be Good Practice We have slipped another guard in here as well that requires explanation ifdnef _PASSWORD_H define _PASSWORD_H tendif This has the effect of including a header file only once This is important It does marginally cut down compile time but is not why it is done lt stops circular redefinition s might put a define in my header file define MAX 128 but later in another header file define MAX 256 this will cause problems Worst still if re include my original header file will get the sequence define MAX 128 define MAX 256 define MAX 128 The problem is that for a period MAX was 256 and may have had an influence of one many or no other data or defines before MAX was reset to 128 A very difficult bug to find It can also mask other serious problems On one project when some multiply included header files were unwrapped the program would not compile The multiple definitions were masking a very deep seated bug By only including module specific header files in those modules that actually need to access an item in another module data is only visible to other parts of the program that need it It also means that maintenance is easier If
155. ms A typical C51 program might be arranged with all background loop functions compiled as COMPACT whilst all fast interrupt functions treated as SMALL The obvious approach of using the pragma MODEL or command line option to set the model can cause odd side effects The problem usually manifests itself at link time as a MULTIPLE PUBLIC DEFINITION error related to for instance putchar The cause is that in modules compiled as COMPACT C51 creates references to library functions in the COMPACT library whilst the SMALL modules will access the the SMALL library When linking L51 finds that it has two putchars etc The solution is to stick to one global memory model and then use the SMALL function attribute covered in the previous section to set the memory model locally Example pragma COMPACT void fast func void SMALL function code from two different libraries www Phaedsys org page 31 of 194 Version 3 65 4 Declaring Variables and Constants 4 1 Constants The most basic requirement when writing any embedded program is to know how to allocate storage for program data Constants are the simplest as they can reside in the code EPROM ROM OTP etc area or as constants held in RAM and initialised at runtime Obviously the former really are constants and cannot be changed While the latter type are relatively commonplace on big systems Microsoft C in 8051 applications the code required to set them up is oft
156. n unsigned int temp unsigned char tmp 2 t t temp pwm_period float pum prescale PWM_Resolution CTRELH t tmp 0 CTRELL t tmp 1 CM1 t temp unsigned int 65536 t temp pwm_duty_ratio 100 KKKKKKKKKK KKK KKK KKK KK KK KK KKK KKK KKK KKK KKK KK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKK Write First Message To Terminal tt Whilst many printf s are used here in a real program they would not in the main program loop due to huge run time void initialise screen void printf s Clear Clear Screen printf s xxx 80C537 Demo Program LineO Print Sign On printf Ss Linel Print Sign On KKKKKKKKKKKKKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKKK Modulate PWM With Analog Inputo KKAAKKKAKKKAKKAKKKAKKKKKKKKKKAKKKKKKAKKKAKKKKKKAKKKAKKKKKKKKKKAKKKKKKKKKKKKKKJ void mod pum void union unsigned int temp unsigned char tmp 2 t t tmp 0 CTRELH t tmpllj CTRELL CMO t temp 65536 t temp 5 analog_data 1 5 BRK K KK RI KR IR e e A RR AA RR IA AA IA AA IA IA A I X N Send Information To Terminal R KKAAKKKAKKKAKKKKKKAKKKAKKKKKKKKKAKKKAKKKAKKKKKKAKKKAKKKKKKAKKKAKKKKKKKKKKKKKKJ void print info void 1 printf sAnalog 0a 8bits 1 2f Volts Line3 analog datalll printf sAnalog 2 8bits 1 2f Volts Line4 analog_data 2
157. n 8051 program to run Like all the classic first programs it prints hello world down the serial port which is assumed to be connected to a dumb terminal A First C51 Program KR IK RR IK KKK KKK KKK e e KKK AA AA RRA AA RA IA I A A I X S Main Program Simplest Version k KKAAKKKAKKKAKKKKKKKKKAKKKAKKKAKKKKKKAKKKAKKKKKKKKKKAKKKKKKAKKKKKKKKKKKKKKKKKKJ This program is entered from the reset vector It simply initialises the serial port and prints hello world repeatedly Declare Memory Model il pragma pragma SMALL Set SMALL model on chip RAM only include C51P INC stdio h Include file contains function prototype for printf Function Prototype void serial0 init TI void Serial port initialisation function Main Loop void main void Enter from reset vector serial0 init TI Initialise serial port 0 timerl baudrate generator Loop Forever while FOREVER printf hello world Send message down 8051 serial port forever BKK HK RR RRR RA I AR AAA RA AA KAR AA A A A KKK He This function initialises Serial Port 0 to run at 4800 Baud using the Timer 1 auto reload mode with a 12MHz XTAL tt To get 9600 baud with timerl requires an 11 059MHz crystal void serial0O_init_T1 void TH1 0x0f3 Timer 1 high byte reload value SMOD 0 F Osc 12 MHz and Timer 1 in mode 2 baudrate of 4800 Baud Timer 1 Interrupt
158. n adapted from generic compilers originally written for more powerful micros such as the 68000 x86 etc eg GNU The approach to the stack problem has largely been through the use of artificial stacks implemented by using 8051 opcodes Typically an area in external RAM is set aside as a stack special library routines manage the new stack every time a function is called While this method works and gives a re entrant capability the price has been very slow runtimes and larger code The net effect is that the processor spends too much time executing the compiler s own code rather than executing your program Besides the inherent inefficiency of generating a new stack the compiled program code is not highly optimised to the peculiarities of the 8051 With this overhead the provision of banked switched expanded memory controlled by IO ports became almost a necessity for some Whilst most compilers and debuggers and ICE can now handle bank switched memory well it is not a route you should really expect to go down Therefore with the 8051 in particular the assembler approach to programming had been the only real alternative for small time critical systems In the last few years Philips Analog Devices and a few others have put FAR pointers in to the 8051 and permitted extended linear memory ie not bank switched out to 8MB but this is the exception not the rule However as far back as 1980 Intel produced a partial solution to the problem of al
159. n e 26 3 3 4 What data goes where E 28 3 4 Setting The Memory Model AANEREN 29 3 5 Local Memory Model Specification ENEE 30 9 9 OVEKVISVV nave tonat r r s ike sna hape shesesh ohh 30 4 Declaring Variables And Constants AANEREN RENE 32 K H eT T ET 32 4 2 Variables cic ides Prod ses Hena dt peshe deeg ede 38 4 2 1 Uninitialised Variables SSES vene nene eee eee meet eee nete ee pene ee nenen pene ne nenen enen eee 38 4 2 2 Initialised Variabl s ci oevssadise sens sesi z sot ser a a ar aaae a is s s n ENER od s se ses dadant ros sis SE 34 4 3 Watchdogs With Large Amounts Of Initialised Data 35 44 CST Variables wien case conde eege e TRR TREE ERa RTE Travan 36 4 4 1 Narlable TY Des vieiciiccscocceccciesancceddudsccee dasagectuuavcecacsededesvashecadesacgeasasdeccdavannasasvessecdeaese 36 4 4 2 Special Function Bits ege ee cetesasececbeleccecosshdetiesevescecarseseasshereccdsssneeduetexescudanstens estate 38 4 4 3 Converting Between Types sss eee esse aaa nenen nene sees neee 39 4 4 4 A Non ISO Approach To Checking Data Type Overilow sese eee eree eee 40 5 Program Structure And Layout EEN 42 5 1 Modular Programming In CBL E 42 5 2 Accessibility Of Variables In Modular Programa A 45 5 3 Building a C51 Modular broogram E 48 5 3 1 The Problema EE 48 5 3 2 Maintainable Inter Module Links 48 5 4 Standard Templates and Version Control 54 5 4 1 Version Control Eeer ENEE SEENEN EE ditaa 54 5 95 Task Scheduling EE 5
160. nces from being established and hence the overlaying process is inhibited KRKKKK KKK KKK SK EAA ALA RAE ARE EEE EAL ARERR IASB AREAL RAE EERE AEE SS lt lt lt lt lt lt lt lt lt lt lt lt lt Recursive Call To Segment Error gt gt gt gt gt gt gt gt gt gt gt gt gt gt ee include lt stdio h gt include lt reg517 h gt void funcl void unsigned char il for il 0 il lt 10 iltt printf THIS IS FUNCTION 1 n String stored in CO MAIN1 segment void func2 void unsigned char i2 for i2 0 i2 lt 10 i2 printf THIS IS FUNCTION 2 n String stored in CO MAIN1 segment code void jump_table funcl func2 Jump table to functions table stored in PCOPZMAINI segment Calling Function main www Phaedsys org page 96 of 194 Version 3 65 jump tablelPl amp 0x01 7 Call function via jump table in CO MAIN1 AAAAAAAAAAAAAAAAAAAAAAA Eng of Module The resulting link output is Note No reference exists between main and funcl 2 so the overlay process cannot occur resulting in wasted RAM OVERLAY MAP OF MODULE MAIN1 MAIN1 SEGMENT BIT GROUP DATA GROUP gt CALLED SEGMENT START LENGTH START LENGTH C_C51STARTUP gt PR MAIN MAIN1 PR MAIN MAIN1 gt CO MAINI t C_LIB_CODE CO MAIN1 gt PR FUNC1 MAIN1 gt PR FUNC2 MAIN1 PR FUNC1 MAIN1 0008H 0001H gt PR P
161. nd up to X OFFFFH 65536 bytes The X prefix implies the external XDATA segment The 8051 s only 16 bit register the DPTR data pointer is used to access the XDATA When using off chip CODE and or XDATA ports 0 and 2 are used to provide the multiplexed address and data lines www Phaedsys org page 19 of 194 Version 3 65 Finally 256 bytes of XDATA can also be addressed in a paged mode This is box 5 in Dol Here an 8 bit register RO is used to access this area termed PDATA When accessing PDATA only port 0 is used You may have noticed the EDATA block on the diagram This is a new 8051 extension used by Philips This is Extra DATA it has also been known as AUX DATA It is 256 bytes and 768 bytes in some parts This block of memory has been included here to illistrate the point that whilst the 8051 core memory DATA SFR IDATA XDATA and CODE are well defined the dozen or so 8051 manufacturers add their own extensions from time to time Siemens now Infineion has some 8051 s with on chip currently The obvious question is How does the 8051 prevent an access to D 00 resulting in data being fetched from C 0000 The answer is in the 8051 hardware When the cpu intends to access D 00 the on chip RAM is enabled by a purely internal READ signal the external RD pin is unchanged The following examples are all in assembler as C hides this addressing process Note the RD and WR pins are shared wirth port 3 pins 6 and 7 These can
162. ns Learned in Software Testing A Context Driven Approach Wiley 2002 ISBN 0 471 08112 4 Kernighan Brian W amp Pike The Practice of Programming Addison Wesley 1999 ISBN 0 201 61586 X Kerzner Harold Project Management A Systems Approach to Planning Scheduling and Controlling 7 ed Wiley 2001 ISBN 0 471 39342 8 Koenig A C Traps and Pitfalls Addison Wesley 1989 K amp R The C programming Language 275 Ed Prentice Hall 1988 Lyons JL Ariane 5 Flight 501 Failure Report by the Enquiry Board Ariane 1996 www Phaedsys org page 188 of 194 Version 3 65 Maric B How to Misuse Code Coverage Reliable Software Technologies 1997 www testing com Maguire Steve Writing Solid Code Microsoft Press 1993 ISBN1 55615 551 4 McConnell Steve Code Complete A handbook of Practical Software Construction Microsoft Press 1993 ISBN 1 55615 484 4 MISRA Guidelines For The Use of The C Language in Vehicle Based Software 1998 From http www misra org uk and http www hitex co uk Morton Stephen Defining a Safe Code Development Process Applied Dynamics International 2001 Murphy Nial Front Panel Designing Software for Embedded User Interfaces R amp D Books 1998 ISBN 0 87930 528 2 Oram amp Talbot Managing Projects with Make 2 Ed O Reilly 1993 ISBN 0 937175 90 0 Parr Andrew Industrial Control Handbook 379 Ed Newnes 1998 ISBNO 7506 3934 2 Pressman Software Engineering A Practitioners Approach
163. ns which are not normally used by C51 For the sake of speed it is sometimes useful to get direct access to these Unlike the normal C51 gt gt functions _cror_ allows direct usage of an 8051 instruction set feature in this case the RR A rotate accumulator This yields a much faster result than would be obtained by writing one using bits and the normal gt gt operator There are also _iror_ and _lror_ intrinsic functions for integer and long data as well The _nop_ function simply adds an in line NOP instruction to generate a short and predictable time delay Another function _testbit_ makes use of the JBC instruction to allow a bit to be tested a branch taken and the bit cleared if set The only extra step necessary is to include intrins h in the C51 source file Here is an example of how the testbit intrinsic function is used to save a CLR instruction include lt intrins h gt unsigned int shift_reg 0 L LA L LA 7 bit test flag LA void main void RSEG PR main T USING 0 main www Phaedsys org page 107 of 194 Version 3 65 SOURCE LINE 12 Use Normal Approach 4 test flag 1 SOURCE LINE 14 SETB test flag S if test_flag 1 SOURCE LINE 16 JNB test flag 2C0001 Z test flag 0 SOURCE LINE 17 CLR test_flag Z Pl Oxff SOURCE LINE 18 MOV Pl 0FFH SOURCE LINE 19 Use Intrinsic Function test flag
164. nterrupt P KKAAKKKAKKKAKKKKKKKAKKKAKKKAKKKAKKKKKKKAKKKAKKKKKKKK KKK KKKAKKKAKKKKKKKKKKKKKKKKKKJ Entered in response to request from CCO interrupt to generate a pulse at a predefined time afterwards b void marker int void interrupt 9 using 2 unsigned int timer_temp EX2 0 Port Pin Low if int marker time CC4 500 gt 0 timer_temp marker_time else timer_temp marker_time time_for_360 cc4 timer temp IEX2 0 P14 1 Turn on at next compare EX2 1 else www Phaedsys org page 137 of 194 Version 3 65 Port Pin High 1 timer_temp CC4 Pulse Nidth cc4 timer_temp IEX2 0 P14 0 Turn off at next compare EX2 1 E KKAKKKKKKKKKKKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKKKK Ss This function initialises the Output Compare Input Capture System on Timer2 e Port 1 to generate a symmetrical PWM on CC4 ki KKAKKKKAKKKAKKKKKKKKKAKKKAKKKAKKKKKKAKKKKKKAKKKAKKKKKKKKKKAKKKKKKKAKKKKKKKKKKKKJ This gives a PWM output where the on time grows from either side of the timer 2 overflow point This is very useful for motor control as the symmetrical nature of the waveform reduces the higher current harmonics circulating in the windings under changing duty ratio conditions SE Downside is that two interrupt services are required per period SC Symmetrical PWM Waveform Asymmetrical
165. nters as per char x y char x_ptr SK char y_ptr SY E p r Kop r 3 st or Xo Sy 28 5 kx ptr y_ptr 25 The most important thing to understand about pointers is that ptr var means set the value of the pointed at address to value var whereas ptr amp var means make ptr point at var by putting the address of amp in ptr but do not move any data out of var itself Thus the rule is to initialise a pointer ptr amp var To access the data indicated by ptr var ptr 7 2 Pointers To Absolute Addresses In embedded C ROM RAM and peripherals are at fixed addresses This immediately raises the question of how to make pointers point at absolute addresses rather than just variables whose address is unknown and largely irrelevant The simplest method is to determine the pointed at address at compile time char abs_ptr Ox8000 Declare pointer and force to 0x8000 immediately However if the address to be pointed at is only known at run time an alternative approach is necessary Simply an uncommitted pointer is declared and then forced to point at the required address thus Unsigned char abs_ptr Declare uncommitted pointer abs_ptr char 0x8000 Initialise pointer to 0x8000 abs_ptr Oxff Write Oxff to Ox8000 abs pL CLL Make pointer point at next location in RAM www Phaedsys org page 66 of 194 Version 3 65 Please see sec
166. o Oxff is IDATA but the bottom 128 bytes is also DATA and the bit it the middle of the DATA is BDATA and the Register banks Having sorted out al that There is a third memory space the CODE segment box 3 in figl This also starts at C zero but this is reserved for the program CODE It typically runs from C 0000 to C OFFFFH 65536 bytes The CODE segment is accessed via the program counter PC for opcode fetches and by DPTR for data both registers being 16 bit registers Obviously normally being ROM FLASH EEPROM etc only constants can be www Phaedsys org page 18 of 194 Version 3 65 stored here However with the advent of FLASH it is possible to change data in the CODE Space Some new parts permit the application to load new blocks of code via an ISP interface The Atmel parts now have boot loaders that will work via the ISP Serial or CAN interface EA 0 In the original 8051 the CODE space on chip and was 4K of either ROM or EPROM In the 8052 the on chip CODE space was 8K ROM Though both of these parts could access additional off chip ROM The 8031 and 8032 had off chip CODE space and no on chip code memory The modern 8051 variants over 600 of them External External have all manner of on chip ROM OTP EPROM EEPROM and FLASH from 2k to 64K In 2000 Philips announced plans for more than 64K of on chip FLASH CODE space and they have produced parts with 256K flash on them There are also many variants that only have off
167. oint during execution pointer point at an intial specific external address is required Thus some method of making a Probably the simplest vvay of setting up such a pointer is to let the C INIT program set the pointer to a location However the initial address must be known at compile time If the pointer is to be altered at run time just equate it without the at run time to the new address Note this automatic initialisation was not supported on earlier versions of C51 Simply do Spaced pointer xdata char xdata a_ptr Ox8000 Generic Pointer xdata char a_ptr 0x028000L Here the pointer is setup to point at xdata address 0x8000 Note that the spaced a_ptr can only point at xdata locations as a result of the second xdata used in its declaration In the generic a_ptr case the 02 tells C51 that an xdata address is intended An example might be 1 d GA k OO JA On 1 1 0000 900000 0003 EO 0004 24F0 0006 FO 0007 900000 000A EO 000B 3400 000D FO en La 000E EO 000F FE 0010 A3 1 EO 2 F582 0014 8E83 6 EO 7 F500 0019 22 R R R xdata char xdata ptr main Ox8000 char x ptr Oxfo MOV DPTR ptr 01H MOVX A DPTR ADD A 0F0H MOVX DPTR A MOV DPTR ptr MOVX A DPTR ADDC A 00H MOVX DPTR A x pty 7 MOVX A DPTR MOV R6 A INC DPTR MOVX A DPTR MOV DPL A MOV DPH R6 MOVX A DPTR MOV x A RET www Phaed
168. on it does not actually have any fixed addresses or local data of its own The characters serve to allow the macro definition to continue to a new line in this case to preserve the function like appearance It is called like a normal function with the parameters to be passed enclosed in However no CALL is used and the necessary code is created in line The end result is that a strcpy is performed but no new RAM or stack is required Please note however the drawback with this very simple example is that the source and destination pointers are modified by the copying process and so is rather suspect A further benefit in this example is that the notional pointers sl and s2 are automatically memory specific and thus very efficient Thus in situations where the same function must operate on pointer data in a variety of memory spaces slow generic pointers are not required define Inline_Strcpy sl s2 while sl s2 NULL char xdata out_buffx Im Zb char xdata Sin buffx Hello char idata in_buffi Hello char idata out_buffi 3 char code in_buffc Hello void main void www Phaedsys org page 109 of 194 Version 3 65 Inline Strepy out buffx in buffx In line functions Inline_Strcpy out buffi in buffi Inline_Strcpy out buffx in buffc Another good example of hovv a macro vvith parameters can be used to aid source readability i
169. on of memory C at processor reset can be defined the absolute start address of IDATA memory is always 0 IDATALEN EQU 80H the length of IDATA memory in bytes XDATASTART EQU OH the absolute start address of XDATA memory XDATALEN EQU OH the length of XDATA memory in bytes PDATASTART EQU OH the absolute start address of PDATA memory PDATALEN EQU OH the length of PDATA memory in bytes Notes The IDATA space overlaps physically the DATA and BIT areas of the 8051 CPU At minimum the memory space occupied from the C51 run time routines must be set to zero Reentrant Stack Initilization The following EQU statements define the stack pointer for reentrant functions and initialized it Stack Space for reentrant functions in the SMALL model IBPSTACK EQU 0 Set to 1 if small reentrant is used IBPSTACKTOP EQU OFFHtl set top of stack to highest locationtl Stack Space for reentrant functions in the LARGE model XBPSTACK EQU 0 Set to 1 if large reentrant is used XBPSTACKTOP EQU OFFFFH 1 set top of stack to highest location l Stack Space for reentrant functions in the COMPACT model PBPSTACK EQU 0 set to 1 if compact reentrant is used PBPSTACKTOP EQU OFFFFHtl set top of stack to highest location l ST rT Page Definition for Using the Compact Model with 64 KByte xdata RAM The following EQU statements define the xdata page used for pdata variables The EQU PPAGE must conform with the PPAGE control used in
170. only have one purpose and may not chagne once their use has been established MOV A 40 Put value held in location 40 into the accumulator This addressing mode direct is very fast and the basis of the SMALL memory model MOV RO 0A0H Put the value held in IDATA location OAOH into MOV A RO the accumulator This addressing mode is used to access the indirectly addressable on chip memory above 80H and as an alternative way to get at the direct memory below this address A variation on DATA is BDATA bit data This is a 16 byte 128 bit area starting at 020H in the direct segment It is useful in that it can be both accessed byte wise bythe normal MOV instructions and addressed by special bit orientated intructions as shown below SETB 20 0 5 CLRB 20 0 The external CODE memory device at C 0000 is not enabled during data RAM access In fact the CODE memory is only enabled when a pin on the 8051 named the PSEN program store enable is pulled low There is an internal equivelent when using on chip CODE memory The XDATA RAM and CODE EPROM do not clash as the XDATA device is only active during a request from the 8051 pins named READ or WRITE To help access the external XDATA RAM special instructions exist conveniently containing an X MOV A 40h Direct internal data move of 0x40 into the A register MOV DPTR 08000H Direct internal data move of Ox08000 into the 16 bit DataPoinTeR MOVX A DPTR Put a value
171. org page 167 of 194 Version 3 65 23 1 6 ISO IEC 9899 1999 TC1 2001 The link leads to a seven page PDF document of 118062 bytes containing ISO IEC 9899 1999 TECHNICAL CORRIGENDUM 1 Published 2001 09 01 http ftp2 ansi org download free_download asp document ISO 2FIEC 98 99 2FCor1 3A2001 The TC is freely available and the link abouve should download the PDF directly 23 2 The Future Back to C Why C is not C The main problem at the moment is that as of November 2001 nothing had changed by Jan 2003 no one has implemented a full C99 compiler for embedded use There are dark mutterings in the embedded world that they may stay with C90 Many people ask for C on small embedded systems What most people do not realize that whilst C was developed from C the two are now separate languages In the early days C was a superset of C This ceased to be true from the mid 1990 s both languages have moved on with slightly diverging paths C is being used on the desktop 64 32 and some 16 bit systems under UNIX MS Windows and a variety of high end embedded RTOS 2000 saw the start of some embedded C for 16 bit systems but that is as far as it will go The use of C on the desktop has declined and the majority use is now in embedded systems often without an RTOS After I wrote this some while ago I have been corrected that many compiler writers and systems writers also use C In late 2000 the ISO C committee was getting more work
172. ork Reinterpreted M amp T Books 1995 ISBN 1 55851 396 5 Whitehead Richard Leading A Software Development Team A Developers Guide to Successfully Leading People and Projects Addison Wesley 2001 ISBN 0 201 67526 9 Wilson Graham Embedded Systems amp Computer Architecture Newnes 2002 ISBN 0 7506 5064 8 Xie amp Engler Using Redundancies to Find Errors Computer Systems Laboratory Stanford University http www stanford edu engler p401 xie pdf www Phaedsys org page 190 of 194 Version 3 65 28 Standarde This is the full set of standards used across the whole QuEST series These are Standards as issued by recognised national or international Standards bodies Note due to the authors position in the Standards Process some of the documents referred to are Committee Drafts or documents that are amendments to standards that may not have been made publicly available by the time this is read ISO 9899 1990 Programming languages C 9899 1999 Programming languages C 9899 1999 TC1 Programming Languages C Technical Corrigendum 1 9945 Portable Operating System Interface POSIX 9945 1 Base Definitions 9945 2 System Interfaces 9945 3 Shell and Utilities 9945 4 Rational 12207 1995 Information Technology Software Life Cycle Processes 14764 1999 Information Technology Software Maintenance 14882 1989 Programming Languages C 15288 2002 Systems Engineering System Lifecycle Processes JTC1 SC7 N2683 Systems Engineer
173. otherwise execute the alternative block if a 1 b 2 executable code Execute if a is equal to 1 or b equal to 2 Increment And Decrement These make direct use of the INC xx opcodes and consequently are very fast Normally they are used as part of larger C expressions where a value needs incrementing or decrementing Increment 8 bits 8 sign 16 bits 16sign 32 bits 32 sign float Cycles 1 1 5 5 59 59 140 Decrement 8 bits 8sign 16 bits 16 sign 32 bits 32 sign float Cycles 1 1 5 5 59 59 140 Examples i Post increment i i Pre increment i i j Post decrement i i j Pre increment i www Phaedsys org page 148 of 194 Version 3 65 for i SQ 2 e Ke e 21 Pl array itt Sequentially write all the XI values in array onto Port 1 i points to next value after after current access I Shifting These allow values to be shifted left or right by a number of bit positions determined either by a constant at compile time or a variable at run time gt gt Right shift 8 bits 8sign l6bits 16 sign 32 bits 32 sign Cycles 7 7 56 56 129 129 7 shifts lt lt Left shift 8 bits 8sign 16 bits 16 sign 32 bits 32 sign float Cycles 7 7 56 56 129 129 7 shifts Examples a lt lt 2 shift a left two bit places a lt lt b shift a left by a number of bit positions determined by the value of b Strings And Arrays These are a number of sequential locations that togethe
174. ow address of any multiple byte object always causes head scratching The _ prefix on the WRITE_EE_PAGE assembler function name is a convention to indicate that registers are used for parameter passing If you are converting from C51 version lt 3 00 please bear this in mind Note that if you pass more parameters than the registers can cope with additional space is taken in the default memory space SMALL data COMPACT pdata LARGE xdata 15 3 Parameter Passing In Registers Parameter passing is now possible via CPU registers RO R7 Coupled with register auto local variables means that function calls can be made very quickly Up to three parameters may be passed this way although when using long and or float parameters only two may be passed due to there being 4 bytes per variable and only 8 registers available To maintain compatibility with 2 5x the NOREGPARMS pragma is provided to force fixed memory locations to be used Those calling assembler coded functions must take note of this Parameter Type Char Int Spaced ptr Long Float Generic Ptr Parameter R7 R6 R7 R4 R7 R1 R2 R3 Parameter R5 R4 R5 R4 R7 R1 R2 R3 Parameter R3 R2 R3 R1 R2 R3 www Phaedsys org page 121 of 194 Version 3 65 www Phaedsys org page 122 of 194 Version 3 65 16 General Things To Be Avvare Of The following rules will allow the compiler to make the best use of the processor s resources Generally approaching C from an assembler programmer s vi
175. p R to ISO C99 A Standard History of C In the beginning in 197 Well it starts in the mists of legend The best social technical description I have seen is the paper The Development of the C Language by Dennis M Ritchie it is as of early 2001 available as a pdf http cm bell labs com cm cs who dmr index html If you have any problems finding it contact chris phaedsys org This dates the beginnings of C as about 1969 to 1973 depending how you measure it C evolved from B and BPCL when modern computing was only about 20 years old and microprocessors had yet to be invented This paper is well worth reading as in my view it gives the best description of how it all came about and why Do not expect to learn C from this paper BTW Unix was so called because it was a Single User OS a parody of Multics the multi user OS that they had No it was not run ona PDP11 first but a PDPT Not a lot of people know that 23 1 1 K amp R OST Edition 1978 1978 saw the publication of The C Programming Language by Kernighan and Ritchie thereafter known as K amp R This was The Bible for all C programmers for over a decade Unfortunately many still cling to the faith despite the language changing a lot in the intervening 25 years Even Dennis Richie said of K amp R 1 Although it did not describe some additions that soon became common this book served as the language reference until a formal standard was adopted more than ten years later
176. packages to do with embedded C and things to help the conversion of mathematical Fortran users to C It was at this point the editor of this work took over as Convener of the UK ISO C committee The next round of work was meant to help the embedded user and will move C further from C Unfortunately the amendments were mainly in the form of DSP math and extensions only of use to 32 bit embedded systems with lots of space There was a lot of discussion in 2003 with some violent disagreements of the direction C should take www Phaedsys org page 168 of 194 Version 3 65 New features in C that might once have been put into C are less likely to happen Partly because there are more embedded people involved and there are fewer desktop people involved The other reason is that some C is not possible in 8 bit systems There are some C compilers for small systems but the are not widely used and have some severe restrictions Their use is dictated more by fashion than engineering reasons In fact even C is being restricted as EC for embedded use For embedded C see http www caravan net ec2plus Where you can get the Embedded C standard as supported by many compiler manufacturers This was an initiative started in Japan that has speard world wide The other major thing the UK standards panel is trying to do is stabilize and iron out the ambiguities of the C99 standard The ambiguities are one of the reasons that two now three yea
177. pdata char xdata ext_ptr I I location I of pointer Memory space pointed into by pointer In this example strings are always copied from the CODE area into an XDATA buffer By customising the library function strcpy to use a CODE source pointer and a XDATA destination pointer the runtime for the string copy was reduced by 50 The new strcpy has been named strcpy_x_c The function prototype is extern char xdata strcpy char xdata char code char xdata _strcpy_x_c strcpy_x_c char xdata Sal Here is the code produced by the spaced pointer strcpy MOV s2210 R4 MOV s2 10 01H R5 j Variable s1 10 assigned to Register R6 R7 unsigned char i 0 Variable i 11 assigned to Register RI CLR A MOV R1 A 2C0004 7 A while sl it s2 0 INC s2 10 01H MOV A sS2 10 01H MOV R4 82 10 JNZ C0008 INC s2210 2C0008 DEC A MOV DPL A MOV DPH RA CLR A MOVC A A DPTR MOV R5 A MOV R4 AR1 INC R1 MOV A R7 ADD A R4 MOV DPL A CLR A ADDC A R6 MOV DPH A MOV A R5 MOVX GDPTR A JNZ C0004 2C0005 pa return s1 U 2C0006 END www Phaedsys org page 78 of 194 char code s2 Version 3 65 Notice that no library functions are used to determine which memory spaces are intended The function prototype tells C51 only to look in code for the string and xdata for the RAM buffer www Phaedsys org page 79 of 194 Version
178. printf SsPWM Fbck 8bit 1 2f Volts Lineb analog datal31 printf sFrequency Sd Hz Line6 unsigned int frequency printf ssTimer d x2 ms Line7 unsigned int real_time_count www Phaedsys org page 140 of 194 Version 3 65 JAKKKKAKKKKKKKKKKKKKAKKKAKKKAKKKA KKK KKKAKKKAKKKKKKKKKAKKKAKKKAKKKKKKKKKKAKKKA x Access Memory Mapped Port x KKAAKKKAKKKAKKKKKKAKKKKKKAKKKAKKKKKKAKKKAKKKKAKKKK k k IA IAA k k k k k k k k k k k k k This function receives a port address and a value to write to it It returns a value at a fixed address include lt absacc h gt Contains definition of XBYTE macro KY and gt mean that the include file will be obtained from the directory indicated by the C51INC DOS environment variable unsigned char get_memory_port unsigned int port_address unsigned char value unsigned char port_value Returned variable unsigned char xdata port_pointer Declare uncommitted pointer into external memory space xdata port_pointer char port_address Make uncommitted pointer point at required address port pointer value Write value to port port value XBYTE 0x8000 Get value from external address 0x8000 return port value JAKKKKAKKKKKKAKKKAKKKKKKAKKKAKKKKKKAKKKAKKKAKKKKKKKKKKAKKKAKKKAKKKKKKAKKKKKKKA H Main Program Full Version a KFE E A E E e E E A E E E A E E A E E e E E A E E E e e e e E E A E E A e
179. put of the latch make up the 16 bits of the address Then Port 0 is the 8 bit data bus Note in this case the CODE is internal as the EA is held high A ADS 1 D6 1 4 A 7 A11 23 74LS373 A12_2 A13 26 A14 1 A15 20 www Phaedsys org page 22 of 194 Version 3 65 3 2 2 External Code The diagram here is for external CODE in EPROM or other write only memory This is very similar to the XDATA but the EA is held low There is no Read or Write but PSEN is used for the chip enable or output The address decoding is exactly the same as the external RAM or XDATA diagram For External CODE and XDATA the tyvo diagrams can be combined e Xll lele lnl nun I fola ujonsjoo I La lo S NIN 3 2 3 VVrite to CODE Space There are cases where you will want to write to CODE space Le when a monitor is used or boot loading of CODE In this case the memory has to be in both CODE and DATA space This requires Von Neumen architecture This is done by ANDing the PSEN and the WR lines A8 24 A10 21 A11 23 A12 2 A13 26 A14 i A15 20 57 www Phaedsys org page 23 of 194 Version 3 65 3 3 Possible Memory Models With a microcontroller like the 8051 the first decision is which memory model to use Whereas the PC programmer with a flat Von Neuman memory chooses between TINY SMALL MEDIUM COMPACT LARGE and HUGE to control how the processor segmentation o
180. quently accessed data requiring the fastest access Interrupt routines whose run time is critical should use DATA usually by declaring the function as SMALL Also background code that is frequently run and has many parameters to pass If you are using re entrant functions the re entrant stacks should be located here as a priority Worst For Any variable arrays and structures of more than a few bytes IDATA 256 Bytes indirectly addressed Idata has a range of 256 bytes an can use instructions such as MOV Ri A where Ri may be RO or R1 Note that the lower 128 bytes of IDATA is the DATA space Best For Fast access data arrays and structures of limited size up to around 32 bytes each but not totalling more than 64 or so bytes As these data types require indirect addressing they are ideally placed in the indirectly addressable area It is also a good place to locate the stack as this is by definition indirectly addressed Worst For Large data arrays fast access words CODE 64K or more with banking Best For Constants and large lookup tables plus opcodes of course Worst For Variables PDATA 256 bytes in paged XDATA COMPACT model default area Best For Medium speed interrupt and fast background char 8 bit variables and moderate sized arrays and structures Also good for variables which need to be viewed in real time using an emulator Worst For www Phaedsys org page 28 of 194 Version 3 65 Very large da
181. r unsigned int n y d else result_y2 unsigned char x unsigned char unsigned int n y d tundef x undef y tundef n undef d y_temp2 y_break_point2 y_break_pointl Prevent Divide By Zero if y_temp2 0 y_temp2 define x result_yl define y result_y2 define n y_value y_break_point1 define d y_temp2 y x if CY result unsigned char x unsigned char unsigned int n y d else result unsigned char x unsigned char unsigned int n y d End of 2D Section else www Phaedsys org page 158 of 194 Version 3 65 1D Interpolation Only map_base map_base x_size x_offset map_xlyl map_base 0 map_x2yl map baselll undef undef undef undef ask x define x map_xlyl define y map x2yl define n x templ define d x_temp2 Se KG if CyY result unsigned char x unsigned char unsigned int n y d else result unsigned char x unsigned char unsigned int n y d End 1D Section return result Here is the test harness used to drive it Sine Conversion Map better d Converts integer angle into sine value 0 255 x_size y_size x_breakpoints y_breakpoints map_data xf const unsigned char sine_table 07 00 00 15 30 45 60 75 90 00 66 127 180 220 246 255 Test Var
182. r between the files Just as important is the need to ensure that no other data leaks between files Some coding standards require that no variable name be used in more than one place in the entire application to ensure that there is no possibility of data leakage Note this is not the same as memory leakage caused by dynamic allocation of memory 5 3 2 Maintainable Inter Module Links The example ATM program is constructed in a modular fashion and we will use it for the example It is modular in that the source is in separate modules However even with this small program a maintenance problem is starting to become apparent The source of the trouble is that to add a new data item or function at least two modules need to be edited Not only the module containing the data declaration but any other module which refers to the changed items With long and meaningful names common in C and complex memory space qualification widespread in C51 much time will be wasted in getting external references to match at the linking stage Simple typographic errors can waste huge amounts of time Function prototypes are one of the more helpful aspects that came in with the ISO C89 This requires that any function unsigned char get_password unsigned char status return pass_status required a function prototype Unlike the older K R style where the parameters were placed after the function name but before the first opening brace the new style
183. r constitute some sort of larger single data object Arrays may be single or multidimensional as is BASIC etc Strings are as in BASIC but because of C s near assembler nature they must be handled with care you must always be aware where they end A true string is always finished with a zero called the null terminator array 4 an array of four elements STARTING at element 0 array 4 2 a two dimensional array of four by 2 elements STARTING at element 0 0 ABCDEF a true string of ascii characters with a zero after the last element Itis the use of doublequotation marks that defines this as a true string Looking at the memory in which this was declared would show 65 66 67 68 69 70 00 A B C D E F g an array of ascii characters with no null terminator Note the and defining the limits of the complete data object Examples char array 4 S Reserve a RAM area of 4 bytes into which 8 bit data will be put at run time www Phaedsys org page 149 of 194 Version 3 65 char array ABCD Fill a RAM area with ABCDO prior to starting the main function The 07 is the null terminator Handling Strings And Characters strcpy destination source 8 element strings Cycles 102 Copy string pointed at by source to another string pointed at by destination The second string is completely overwritten in the process strcat destination source 8
184. r has to keep their style constant Many programmers will complain that they can use their own style and anything else imposed is an infringement of civil liberties Most Project manages have too many other things to worry about As ling as it compiles they are happy The Tile Hill Embedded C Style guide explaines why a Style guide is a good idea if not essential in embedded programming www Phaedsys org page 161 of 194 Version 3 65 www Phaedsys org page 163 of 194 Version 3 65 23 Apendix F A Standard History of C The problem with C is its history I do not propose to re tell The K amp R Story K amp R here However there are some parts pertinent to this paper Irecommend that people read the paper by Dennis Ritchie Ritchie this is available from his web site http cm bell labs com cm cs who dmr index html C was developed initially between 1969 and 1973 to fit into a space of 8K Also C was designed in order to write an portable operating system Unlike today where disks and memory are inexpensive at the time Multics was around operating systems had to take up as little space as possible to leave room for applications on minimal memory systema This makes it ideal for embedded systems C was developed from B and influenced by a group of several other languages Interestingly BCPL from which B was developed used 77 for comments just as C does and now finally c99 One of the problems with C is that now
185. ranged sequentially 11 5 Function Level Optimisation Optimisation levels of 4 and above are essentially function optimisations and as such the whole function must be held in PC memory for processing If there is insufficient memory for this a warning is issued and the additional optimisation abandoned Code execution will still be correct however See p1 8 in the C51 manual 11 6 In Line Functions In C51 One of the fundamentals of C is that code with a well defined input output and job is placed into a function i e a subroutine This involves placing parameters into a passing area whether a stack or a register and then executing a CALL It is unavoidable that the call instruction will use two bytes of stack In most 8051 applications this not a problem as there is generally 256 on chip RAM potentially available as stack Even after allowing for a few registerbanks there is normally sufficient stack space for deeply nested functions However in the case of the 8031 and reduced devices such as the 87C751 every byte of RAM is critical In the latter case there are only 64 bytes A trick which can both save stack and reduce run time is to use macros with parameters to act like in line functions The ability to create macros with replaceable parameters is not commonly used but on limited RAM variants it can be very useful Here a strcpy function created as a macro named Inline_Strcpy whilst it looks like a normal functi
186. res Here is an example A piece of C51 software had to perform a linearisation process on the raw signal from a variety of pressure sensors manufactured by the same company For each sensor to be catered for there is an input signal with a span and offset a temperature coefficient the signal conditioning amplifier a gain and offset The information for each sensor type could be held in normal constants thus unsigned char sensor_typel_gain 0x30 unsigned char sensor_typel_offset 0x50 unsigned char sensor_typel_temp_coeff 0x60 unsigned char sensor_typel_span 0xC4 unsigned char sensor_typel_amp_gain 0x21 unsigned char sensor_type2_gain 0x32 unsigned char sensor_type2_offset 0x56 unsigned char sensor_type2_temp_coeff 0x56 unsigned char sensor_type2_span 0xC5 unsigned char sensor_type2_amp_gain 0x28 unsigned char sensor_type3_gain 0x20 unsigned char sensor_type3_offset 0x43 unsigned char sensor_type3_temp_coeff 0x61 unsigned char sensor_type3_span 0x89 unsigned char sensor_type3_amp_gain 0x29 As can be seen the names conform to an easily identifiable pattern of unsigned char sensor_typeN_gain 0x20 unsigned char sensor_typeN_offset 0x43 unsigned char sensor_typeN_temp_coeff 0x61 unsigned char sensor_typeN_span 0x89 unsigned char sensor_typeN_amp_gain 0x29 Where N is the number of the sensor type A structure is a neat way of condensing this t
187. rs later no one had managed to do a fully implemented C99 Embedded C compiler Actually I don t think there is a full C99 compiler for any use As of the summer of 2002 a couple of compilers had managed it but no mainstream industrial embedded compilers vendors even thought about it Where next for the C standard Judging from history you should expect preparation of the next revision of the C standard to begin around 2004 Most likely we will ask for feedback on an early draft around 2007 In between those times is the best time to provide constructive input but be warned that unsolicited proposals without an active champion participating in the committee are unlikely to get very far If you really want to work on substantial improvements it would be wise to join the committee via your National Body well in advance so you can gain a feel for how the group dynamics work If you want to get involved please email me at chris phaedsys org 23 3 What to read for Embedded C There are thousands of C books out there Few are really good Most are for the desktop MS amp MAC and Unix For a good source of book recommendations try the ACCU at www accu org They have independent reviews of over 2000 C C and SW engineering books And an embedded section at http www accu org bookreviews public reviews 0sb embedded_systems htm They do not sell books so the reviews are completely independent and written by working Engineers There
188. rtain number of modules only GLOBAL would then be available to all modules The new C166 supports this type of task based variable scope Unfortunately C51 does not so a fix is required The linker s OVERLAY command does not help as it only controls the overlaying of local and parameter data One possible solution uses special modules to declare the publics Modulel declares the publics for program task1 Module2 declares the publics for program2 task2 Finally Module3 declares the publics which are available to both sides The trick then is to use the linker to fix the data segments on Module and Module at the same physical address whilst allowing Module3 s variables to be placed automatically by the linker This solution uses three special modules for declaring the publics www Phaedsys org page 100 of 194 Version 3 65 Example of creating two sets of public data in same memory space extern void mainl void extern void main0 void Main module where system splits into two parts void main void bit flag if flag maino Branch 0 else mainl Branch 1 Module that declares publics for branch 2 Publics for branch 2 unsigned char x2 y2 unsigned int z2 char a2 0x30 A variable which is accessible from both branches extern int common AAA AAA AAA AAA AAA AAA AAA End of Module void main0 void 1 unsigned char c0 Local ge
189. run times as short as possible particularly in interrupt routines This means making full use of C51 extensions like memory specific pointers special function bits and local register variables www Phaedsys org page 59 of 194 Version 3 65 6 C Language Extensions For 8051 Programming Whilst there is an ISO standard for C and everyone tries to produce ISO C compliant compilers and tools it is not always very efficient to use pure ISO C in embedded work On the larger 32 and 64 bit systems the vast majority of the embedded interfaceing is hidden by opperating systems Even in 16 bit there is the space to insulate the programmer from the hardware However when one gets to the 8 bit systems and the 8051 in particular there is no room to hide the hardware The programmer must directly interface to the hardware 8051 programming is mainly concerned with accessing real devices at specific locations plus coping with interrupt servicing In the past the interfacing to the hardware would have been done on assembler In some cases it stil is Keil however along with most other 8051 compiler venders has made extensions to the C language to allow near assembler code efficiency when talking to the hardware In many cases this is not just about speed but due tothe architecture of the 8051 For example the BDATA bit addressable area of memory The main points are now covered 6 1 Accessing 8051 On Chip Peripherals In the typical embedded control applica
190. s interrupt arguments are 1 gt generate interrupt vector at address 8 1 3 0x0b 2 gt Switch to register bank two on entry restore original bank on exit void timerO_int void interrupt 1 using 2 Setup Next Interrupt IENO amp Oxfd Clear interrupt flags TRO 0 A Stop timer THO Oxf8 E Reset timer for next interrupt TLO Ox2f 2ms at 12 MHZ TRO 1 C Start timer IENO 0x02 T real time counttt s P6 0x08 Z KKKKKKKKKKKKKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKK KKKKKK s This function sets up the Capture Compare Unit and generates a PWM output on Port 4 0 Pin 1 See p112 of the 517 Manual i gt CTREL 65536 255 for 42 5us period overflow rate at 12MHz Compare timer counts from CTREL to 65535 when Port bit is cleared Port bit set when Compare timer CMO to give asymmetric 8 bit PWM KKAKKKKKKKAKKKAKKKAKKKKKKAKKKKKKAKKKAKKKKKKAKKKAKKKKAKKAKKKAKKKKKKAKKKKKKKKKKKKJ This PWM requires no CPU time and is thus very efficient On 535 an interrupt service would be required to reload the compare register Si void pum init void union unsigned int temp unsigned char tmp 2 t CTCON 0 Basic count time 166ns t temp pwm_period PWM_Resolution 42 5us initial period CTRELH t tmp 0 CTRELL t tmp 1 CM1 t temp unsigned int
191. s struct sensor_desc sensor_database sensor_database gt gain 0x30 sensor_database gt offset 0x50 sensor_database gt temp_coeff 0x60 sensor_database gt span 0xC4 sensor_ database gt amp_gain 0x21 www Phaedsys org page 73 of 194 Version 3 65 test function struct pointer test function struct sensor desc received struct pointer received struct pointer gain 0x20 received struct pointer temp coef 0x40 Advanced Note Using a structure pointer will cause the called function to operate directly on the structure rather than on a copy made during the parameter passing process 7 4 7 Structure Pointers To Absolute Addresses It is sometimes necessary to place a structure at an absolute address This might occur if for example a memory mapped real time clock chip is to be handled as a structure An alternative approach to that given in section 6 4 4 is to address the clock chip via a structure pointer The important difference is that in this case no memory is reserved for the structure only an image of it appears to be at the address The template in this instance might be Define Real Time Clock Structure struct RTC char seconds char mins char hours char days Create A Pointer To Structure struct RTC xdata rtc_ptr xdata tells C51 that this is a memory mapped device void main void rtc_ptr void xdata 0
192. s 1998 ISBN 0 7506 9990 6 Ball Stuart Embedded Microprocessor Systems Real world design 2 Ed Newnes 2000 ISBN 0 7506 7234 X Ball Stuart Analog Interfacing to Embedded Microprocessors Real world design Newnes 2001 ISBN 0 7506 7339 7 Baumgartner J Emulation Techniques Hitex De internal paper may 2001 Barr Michael Programming Embedded Systems in C and C O Rilly 1999 ISBN 1 56592 354 5 Beach M Hitex C51 Primer 30 Ed Hitex UK 1995 Beach M Hitex C51 Primer 3 Ed Hitex UK 1995 http www hitex co uk Draft 3 5 is on http quest phaedsys org Beach M Embedding Software Quality Part 1 Hitex UK Available from www Hitex co uk Berger Arnold Embedded Systems Design Anintroduction to Processes Tools and Techniques CMP Books 2002 ISBN 1 57820 073 3 Black Rex Managing the Testing Process 2 ed Wiley 2002 ISBN 0 471 22398 0 Bramer Brian amp Susan C for Engineers 274 Ed Arnold 1997 ISBN 0 340 67769 4 Bramer Brian amp Susan C for Engineers Arnold 1996 ISBNO 340 64584 9 www Phaedsys org page 185 of 194 Version 3 65 Brooks Fred The Mythical Man Month Essays On Software Engineering Anniversary Edition Addison Wesley 1995 ISBN 0 201 83595 9 Brown John Embedded Systems Programming In C and Assembley VNR 1994 ISBN 0 442 01817 7 Buchner F Embedding Software Quality Part 1 Hitex DE Available from www Hitex co uk Buchner F The Classification Tree Method Interna
193. s is called re entrancy Many 8051 compilers do not do re entrancy or at least require it to be explicitly enabled on a per function basis A serious restriction with the 8051 family is the lack of a proper stack typically with a processor such as the 8086 the stack pointer is 16 bits at least Besides the basic stack pointer there are usually other stack relative pointers such as a base pointer etc The 8051 only has one 8 bit stack pointer register and one 16 bit Data Pointer some derivatives have up to 8 DPTR s but they are not easy to use and their overhead makes it more sensible to think only in terms of 1 DPTR With these extra demands on the stack control system the ability to access data on the stack is crucial As already indicated the 8051 family has a stack system which is really only capable of handling return addresses With a maximum of only 256 8 bit bytes of stack potentially available and typically around 40 bytes in practice it would not take too much function calling and parameter passing to use this up www Phaedsys org page 11 of 194 Version 3 65 This would seem to indicate that implementing a stack intensive language like C on the 8051 would be impossible Well it very nearly has been While there have been 8051 C compilers around for many years now they were not very effective in the early days in fact even now for many of them Most particularly the open source and low end or free compilers have actually bee
194. s best to prototype first and look at what if scenarios You will find that with a little thought a simple priority flag system can be developed It is better to it in the initial stages where timing can be worked out From experience have found that in the case of a simple system that degenerates into bolt ons and quick fixes it is better to re do the scheduler from scratch Do not be tempted to re do the whole program Just the scheduler not the tasks This stops the system overheads becoming the problem www Phaedsys org page 58 of 194 Version 3 65 Frequency However under normal conditions it is a useful way of ensuring that low priority tasks are not executed frequently For example there would be little point in measuring ambient temperature more than once per second In a typical system this measurement might be at level 100 in a switch scheduler To be able to make a judgement about how best to structure the program it is vital to know the run times for each section Where this simple method falls down is when a low priority task has a long run time Even though the interrupt has requested that the loop returns back to the top level to calculate more data there is no way of exiting the task until completed To do so requires a proper time slice mechanism A useful dodge can be to utilize an unused interrupt to guarantee that high priority tasks will be run on time By setting The most important factor overall is to keep
195. s if it was a Single file that was assembled with no library files it did not need linking Whilst modern compiler systems seem very different they do have the same basic system under the IDE It is the advent of modern GUI interfaces that brought about this change Incidentally the modern GUI was Xwindows on Unix that led the way long before MS Windows In fact the current Windows XP has features used on Solaris over a decade before In a modern compiler system such as the Keil C51 the IDE is simply an editor and project control system In the case Of ae u emt the Keil system and many others it also has the simulator debugger and handles a lot more The compiler and linker etc are still called by command line or scripts though this is invisible to the user The compiler is a single pass compiler that outputs object code ready for linking The C51 incorporates the pre processor ccl 2 and 3 in the same program It also normally skips the assembly phase producing object code ready for linking As we will see in later chapters it is still possible to get the compiler to turn out assembler but this is the exception rather than the rule It is at the linker phase that the standard and user libraries are linked in to the program With the modern compiler system it is still easily possible to have both C and assembly modules in the same project A project Build using the Keil uV
196. s in the optimisation feature in Appendix D The interpolation calculation that originally formed a subroutine could easily be redefined as a macro vvith 5 parameters realising a ram and run time saving at the expense of code size Note that r the fifth parameter represents the return value which has to be passed to the macro so that it has somewhere to put the result define interp_sub x y n d r y xj if CY r unsigned char x unsigned char unsigned int n y d else r unsigned char x unsigned char unsigned int Ln y d This is then called by Interpolate 2D Map Values Macro With Parameters Used interp_sub map xlyl map x2yl x templ x temp2 result_yl and later it is reused vith different parameters thus interp sub map xly2 map x2y2 x templ x temp2 result y2 To summarise parameter macros are a good way of telling C51 about a generalised series of operations whose memory spaces or input values change in programs where speed or RAM usage is critical www Phaedsys org page 110 of 194 Version 3 65 12 Some C51 Programming Tricks 12 1 Accessing RO etc directly from C51 A C51 user was using existing assembler routines to perform a specific task For historical reasons the 8 bit return value from the assembler was left in RO of register bank 3 Ordinarily C51 would return chars in R7 and therefore simply equating a variable to the assem
197. s only appeared at link time We will shortly show how this can be avoided and maintenance greatly improved In large programs with many functions and global variables the global area preceding the executable code can get very untidy and cumbersome Though Global variables should be kept to a minimum There is an argument that says it is good to have to have external references at the top of a module when first using a new piece of global data This is because it means that you are always aware of exactly which items are used This is fine in theory but rarely works in practice and ends up with a maintenance nightmare It is preferable to have a single include or header file incorporated as a matter of course in each source file containing an external reference for every global item regardless of whether the host file actually needs them all However this is not the best solution It is an improvement that there is only one version of the definition A solution to this is to have module specific include files Basically for each source module c file a second h include is created This auxiliary file contains both original declarations and function prototypes plus the external references It is therefore similar in concept to the standard library files used in every C compiler Stdio h for example NOTE Many libraries were written a long time ago and may conform to K amp R C not the ISO C89 or current C99 For exampl
198. s possible to declare an array of structures This allows many similar groups of data to have different sets of values struct sensor_desc sensor_database 4 This creates four identical structures in memory each with an internal layout determined by the structure template Accessing this array is performed simply by appending an array index to the structure name Operate On Elements In First Structure Describing Sensor 0 sensor_database sensor_database sensor_database sensor_database O gain 0x30 O offset 0x50 sensor_database 0 temp_coeff 0x60 OJ span 0xC4 O amp_gain 0x21 Operate On Elements In First Structure Describing Sensor 1 sensor databaselll gain 0x32 sensor_database 1 offset 0x56 www Phaedsys org page 71 of 194 Version 3 65 sensor databaselll temp coeff 0x56 sensor databaselll span OxC5 sensor databaselll amp dain 0x28 and soon 7 4 3 Initialised Structures As vvith arrays a structure can be initialised at declaration time struct sensor desc sensor database 0x30 0x50 0x60 OxC4 0x21 so that here the structure is created in memory and pre loaded with values The array case follows a similar form struct sensor_desc sensor_database 4 0x30 0x50 0x60 0xC4 0x21 T 0x32 0x56 0x56 0xC5 0x28 7 4 4 Placing Structures At Absolute Addresses It is sometimes necessary to place a structure at an absolute a
199. s the array index Similarly a variable accessed by a pointer is catered for as the Ri is effectively a pointer This is especially significant now that version 3 xx supports memory space specific pointers The STACK is now simply moved above these new idata objects To summarise with the 8052 if you are hitting the 128 byte ceiling of the directly addressable space the moving of arrays and pointer addressable objects can free up large amounts of valuable directly addressable RAM very easily 9 4 L51 Linker Data RAM Overlaying 9 4 1 Overlaying Principles One of the main tricks used to allow large programs to be generated within an 8051 is the OVERLAY function This is a mechanism whereby different program variables make use of the same RAM location s This possibility arises when automatic local variables are declared These by definition only have significance during the execution of the function within which they were defined Once the function is exited the area of RAM used by them is no longer required Of course static locals must remain intact until the function is next called A similar situation exists for C51 s reserved memory areas used for parameter passing Taken over a complete program each function will have a certain area of memory reserved for its locals and parameters Within the confines of an 8051 the on chip RAM would soon be exhausted The possibility then arises for these individual areas to be combined into a single
200. sed for program addressable so that instructions EIS d gp variables It is directly like MOV A x are usable 4K CODE Bit Addressable BDATA og The problem is that as it is the POATA fasted memory it is also used for other things 2K CODE Fig 1 The 8051 s Memory Spaces www Phaedsys org page 17 of 194 Version 3 65 The bottom 48 bytes of the DATA space are reserved The first 8 bytes are registers RO R7 These are all general purpose 8 bit registers There are 4 identical sets of registers called Banks Bank 0 Bank3 from D 00 to D 1F These are automatically switched by the compiler unless manually over ridden by the user Fig 2 The DATA memory Space There are 16 bytes of bit addressable RAM from D 20 to D 2F This is where 8051 C starts to deviate from the ISO C standard There is no type called BIT in C There BIT are bit fields in variables but no stand addressable alone bit type This is why truly portable ISO C is not efficient for 8051 and Banka _ efficient 8051 code is not portable Bank 2 Above 80H the special function registers Bank 1 are located These run from 80h to FFh P Bank O Sam The SFR s like the DATA block are directly addressable This is the SFR box in fig 1 The SFR s are usually addressed by symbolic names such as SYSCON these names are set up in header or include files Many of the SFR s are defined in the standard 8051 architecture
201. sequent accesses to the register 8 5 Placing Variables At Specific Locations The Linker Method www Phaedsys org page 85 of 194 Version 3 65 A final method of establishing external variables at fixed addresses especially arrays is by using the linker rather than the compiler For example to produce a 10 character array in external memory starting at 8000H the following steps are necessary Module 1 This module contains only data declarations xdata unsigned char array 30 End Module 1 Module 2 This module contains the executable statements extern xdata unsigned char array 10 main unsigned char i i arraylil Now by linking with the invocation L51 modulel obj module2 obj XDATA XD modulel 8000H the linker will make the XDATA segment in Module 1 indicated by XD module1 start at 8000H regardless of other xdata declarations elsewhere Thus the array starts at 8000H and is 10 bytes null terminator long This approach lacks the flexibility of the above methods but has the advantage of making the linker reserve space in the XDATA space Similar control can be exercised over the address of segments in other memory spaces C51 uses the following convention for segment names CODE PR functionname module_name executable code CODE CO functionname module_name lookup tables etc BIT BI functionname module_name DATA DT functionname module_name XDATA
202. series of sequential bytes occupied either by a string or a series of numbers In fact the realms of pointers and arrays overlap with strings by virtue of char test_array HELLO char string_ptr HELLO www Phaedsys org page 67 of 194 Version 3 65 Case 1 creates a sequence of bytes containing the ASCII equivalent of HELLOI Likewise the second case allocates the same sequence of bytes but in addition creates a separate pointer called string_ptr to it Notice that the unsigned char used previously has become char literally an ASCII character The second is really equivalent to char test_array HELLO Then at run time char arr_ptr test_array Array treated as pointer or char arr_ptr amp test_array 0 Put address of first element of array into pointer This again shows the partial interchangeability of pointers and arrays In English the first means transfer address of test_array into art ptr Stating an array name in this context causes the array to be treated as a pointer to the first location of the array Hence no address of amp or to be seen The second case reads as get the address of the first element of the array name and put it into arr ptr No implied pointer conversion is employed just the return of the address of the array base The new pointer arr ptr now exactly corresponds to string ptr except
203. stop L51 locating any variables in a specific area Example Of Excluding Specific Areas From L51 Structure located at base of RTC Chip MAIN C Module extern xdata struct unsigned char seconds unsigned char minutes unsigned char hours H unsigned char days PIF RIGJEHIP y Other XDATA Objects xdata unsigned char time_secs time mins void main void time_secs time_mins RTC_chip seconds RTC_chip minutes ER ER RTCBYTES C Module xdata struct unsigned char seconds unsigned char minutes unsigned char hours unsigned char days RTC_chip Linker Input File To Locate RTC_chip structure over real RTC Registers is 151 main obj rtcbytes obj XDATA XD RICBYTES 0h 8 7 missing ORDER and AT now in C51 Perhaps the most curious omission from C51 was the inability to fix the address of a data object at an absolute address from the source file Whilst there have always been methods of achieving the same effect users have long requested an extension to allow www Phaedsys org page 87 of 194 Version 3 65 the address of an object to be included in the original declaration In C51 v4 xx the new AT Control now exists 8 8 Using The at and ORDER Controls Here the order of the variables must not change as it must match the physical location of the real time clock s registers The pragma ORDER tells C51 to place the data objects at ascending addresses vvith the first item at the
204. sys org page 83 of 194 Version 3 65 8 3 Run Time xdata Pointers The situation often occurs that you need to point at addresses in the xdata space which are only knovvn at run time Here the xdata pointer is setup in the executable code The best vvay to achieve this is to declare an uncommitted pointer at compile time and to then equate it to an address when running char xdata xdata_ptr Uncommitted pointer to xdata memory main xdata_ptr char xdata Ox8000 Point at 0x8000 in xdata An alternative is to declare a pointer to the xdata space and simply equate it to a variable Here is an example char xdata ptr This is a spaced pointer main start_address Ox8000 Variable containing address to be pointed to 0000 750080 R MOV start_address 080H 0003 750000 R MOV start addressto1H 00H ptr start address 000C AEOO R MOV R6 start address 000E AFOO R MOV R7 start_address 01H 0010 8E00 R MOV ptr R6 0012 8F00 R MOV ptr 01H R7 0014 7C 0001 vhile 1 op SADETE 0014 0500 R INC ptrt 01H 0016 E500 R MOV A ptr 01H 0018 AEOO R MOV R6 ptr 001A 7002 JNZ 2C0004 001C 0500 R INC ptr 001E 2C0004 OOlE 14 DEC A 001F FF MOV R7 A 0020 8F82 MOV DPL R7 0022 8E83 MOV DPH R6 0024 EO MOVX A DPTR 0025 FF MOV R7 A 0026 8F00 R MOV x RI 0028 80EA SJMP 2C0001 002A 2C0002 002A 2C0003 002A 22 RET www Phaedsys org page 84 of 194 Version 3 65
205. t baud rate If SMOD 0 then Constant 384 If SMOD 1 then Constant 192 Now the problem is that THI can only hold 8 bit intergers So for example 5Mhz and 2400 with SMOD 0 would give TH1 256 5 000 000 384 2400 This works out to TH1 256 5 425347 THI 250 57466 You would therefore have to use 250 or 251 OxFA or OxFB for TH1 Neither of theses is an exact match The trick is to work the equation back using Baudrate xtal constant 256 TH1 In this case we get Baudrate 5 000 000 384 and Baudrate 5 000 000 384 256 250 256 251 This gives baudrate of 2170 or 2604 Neither is 2400 and is out a fair amount Keil recommend that the rate should be within 2 www Phaedsys org page 175 of 194 Version 3 65 A couple of other useful equations are The maximum baud rate possible for a crystal Baud Crystal constant 256 and the minimum crystal needed for a given baud rate Min Crystal Baudrate constant The constant is 384 for SMOD 1 192 for SMOD 0 There is more on baud rate calculation at http www keil com support docs 689 htm and Keil have an on line calculator at http www keil com c51 baudrate asp The table below shows part of the pattern for THI This shows why not all baud rates are possible at all frequencies baud Rate 110 300 600 1200 2400 4800 9600 19200 38400 56700 115200 Xtal SMOD 1 8432 0 D4 FO F8 FC FE FF 1 8432 l AH EO FO
206. ta arrays and structure above 256 bytes Very frequently used data in interrupts etc Integer and long data XDATA 64K LARGE model default area Best For Large variable arrays and structures over 256 bytes Slovv or infrequently used background variables Also good for variables which need to be viewed in real time using an emulator Worst For Frequently accessed or fast interrupt variables 3 4 Setting The Memory Model Options for Target Target 1 21x Target Output Listing C51 Lan L51 Locate L51 Misc Debug The overall memory type is selected in bles the Keil IDE uVision The memory Xtal MHz 20 0 DA net vete ndara model settings are found by right Code Rom Size Lan 64K program EIS I clicking on the Target in the project Operating system None zl I Use On chip XRAM OxFFOO OxFFFF window and selecting options on the pop up menu Off chip Code memory 0 ff chip Xdata memory Size Start Size n TI BR BS This menu will give you the point and click simplicity for setting the global Start End E deta Banking Start End pak Area JO Thu Banks EZ Bark Area SO ROM and RAM memory models Lok J Gel pose This method is also possible in the older uVision 1 series IDE Before the uVision IDE became common the memory model was set in each file using a pragma This option is still permited for localised setting of the memory models Pra
207. th the background and an interrupt This means that potentially the interrupt may call the function whilst it is still running as a result of a background level call The result could be the over writing of the local data in the background The fact that the offending function is also overlaid vvith other background functions makes the chances of failure very high The simplest solution is to declare the function as REENTRANT so that the compiler will generate a local stack for parameters and variables Thus on each call to the function a new set of parameters and local variables are created without destroying any existing ones from the current call Unfortunately this significantly increases the run time and code produced Another possibility is to make a second and renamed version of the function one for background use and one for interrupt This is somewhat wasteful and presents a maintenance problem as you now have effectively two versions of the same piece of code In many cases the situation is not a problem as the user may have ensured that the reentrant use could never occur but is left with the linker warning However this must be viewed as dangerous particularly if more than one programmer is involved include lt stdio h gt include lt reg517 h gt void funcl void unsigned char il al 15 for il 0 il lt 10 il allill il void func2 void unsigned char i2 a2 15 for i2 0 i2 lt 10 i2tt
208. that the physical HELLO they point at is at a different address 7 3 3 Using Arrays Arrays are typically used like this Copy The String HELLO Into An Empty Array unsigned char source_array HELLO unsigned char dest_array 7 unsigned char array_index unsigned char array_index 0 while array index lt 7 Check for end of array dest arraylarray indexl source arraylarray indexl Move character by character into destination array array_index The variable array_index shows the offset of the character to be fetched and then stored from the starts of the arrays As has been indicated pointers and arrays are closely related Indeed the above program could be re written thus www Phaedsys org page 68 of 194 Version 3 65 Copy The String HELLO Into An Empty Array char string_ptr HELLO unsigned char dest_array 7 unsigned char array_index 5 unsigned char array_index 0 while array index lt 7 Check for end of array dest_array array_index string_ptr array_index Move character by character into destination array array_index The point to note is that by removing the on string_ptr and appending a T pair this pointer has suddenly become an array However in this case there is an alternative way of scanning along the HELLO string using the ptr convention array_index 0 while array index
209. the C file is changed the header is changed to match The new changes are visible identically to all the modules that need it with no more editing Where changes are required to the C file the header file can be relied on to be correct or the home C file would not compile This is where good design comes in to make sure that only minimal changes are required to function prototype parameter lists In most embedded C dialects this can be a major help in program development For example a change in a widely used function s memory model attribute from small to large can easily be propagated through an entire program the change in the intelligent header file belonging to the function s home module Here s how it s done in practice www Phaedsys org page 51 of 194 Version 3 65 Function1 functiont 1 finciude module1 h include module2 h include modulet h include module2 h static function21 Static function 3 static functiony static function22 static function14 static functionz static function32 main Function 1 H function2 function x function 1 m 10 static function21 functionx function 1 static function22 E function1 20 function2 static functionyt static function 23 static function 14 static functionzi www Phaedsys org page 52 of 194 Version 3 65 www Phaedsys org page 53 of 194 Version
210. the linker invocation PPAGEENABLE EQU 0 Set to 1 if pdata object are used PPAGE EQU 0 define PPAGE number 4 3 Watchdogs With Large Amounts Of Initialised Data In large programs the situation may arise that the initialisation takes longer to complete than the watchdog timeout period The result is that the cpu will reset before reaching main where presumably a watchdog refresh action would have been taken To allow for this the INIT A51 assembler file located in the C51p LIB directory should be modified A special empty macro named WATCHDOG is provided which should be altered to contain your normal watchdog refresh procedure Subsequently this is automatically inserted into each of the initialisation loops within the body of INIT A51 WATCHDOG MACRO rInclude any Watchdog refresh code here P6 watchdog_refresh Special application code ENDM U NAME WC INIT C_C51STARTUP SEGMENT CODE C_INITSEG SEGMENT CODE Segment with Initialising Data EXTRN CODE MAIN PUBLIC C_START RSEG C_C51STARTUP INITEND LUMP MAIN www Phaedsys org page 35 of 194 Version 3 65 ZC START MOV DPTR C_INITSEG LOOP WATCHDOG 7 lt lt WATCHDOG REFRESH CODE ADDED HERE CLR A MOV R6 1 MOVC A A DPTR JZ INITEND INC DPTR MOV R7 A Large initialisation loop code DJNZ R7 XLoop DJNZ R6 XLoop SJMP Loop LJMP MAIN 7 C51 Program start RSEG C_INITSEG DB 0 END 4 4 C51 Variables 4 4 1 Variable Types Variables wit
211. this miracle There are many many ways of dong this but operating systems theory is well outside the scope of this publication The simple answer is to use an operating system such as the Keil RTX51 or the CMX Rtos The other more pragmatic approach for most programmers with simple systems is either to use interrupts or to write a simple scheduler Interrupts could be used for the very short things such as servicing 10 but are not really practical for running an application 5 5 2 Simple 8051 multi task Systems The simplest approach is to put each program in to a separate functional block Then call each major sub function in a simple sequential fashion so that after a given time each function has been executed the same number of times This is called a Round Robin This constitutes a background loop In the foreground might be interrupt functions initiated by real time events such as incoming signals or timer overflows The Round Robin is non preemptive That is it runs each task to completion or until the task relinquishes control This is quite simply run as a loop as follows Main The problem here is that it is static in that all the tasks and their initial running order will be known at compile time The foreground interrupts are pre emptive that is that the can preempt or override any task in the Round Robin Interrupts have priorities and may interrupt each other For this reason interrupt routines should
212. tion reading and writing port data setting timer registers and reading input captures etc are commonplace To cope with this without recourse to assembler C51 has the special data types sfr and sbit Typical declarations are sfr PO 0x80 sfr Pl Ox81 sir SCON 0x98 sbit EA OxAF and so on These declarations reside in header files such as reg51 h for the basic 8051 or reg552 h for the 80C552 and so on It is the definition of sfrs in these header files that customises the compiler to the target processor Accessing the sfr data is then a simple matter ADCON 0x08 Write data to register P1 OxFF E Write data to Port io status PO Read data from Port EA 1 Z Set a bit enable all interrupts It is worth noting that control bits in registers which are not part of Intel s original 8051 design generally cannot be bit addressed The rule is usually that addresses that are divisible by 8 are bit addressable Thus for example the serial Port 1 control bits in an 80C537 must be addressed via byte instructions and masking www Phaedsys org page 60 of 194 Version 3 65 Always check the processor s user manual to verify which sfr register bits can be bit addressed 6 2 Interrupts Interrupts play an important part in most 8051 applications There are several factors to be taken into account when servicing an interrupt i The correct vector must be generated so that the routine
213. tions 6 8 and 6 9 for further details on C51 spaced and generic pointers 7 3 Arrays And Pointers Two Sides Of The Same Coin 7 3 1 Uninitialised Arrays The variables declared via unsigned char x unsigned char y are single 8 bit memory locations The declarations unsigned int a unsigned int b yield four memory locations two allocated to a and two to b In other programming languages it is possible to group similar types together in arrays In basic an array is created by DIM a 10 Likewise C incorporates arrays declared by unsigned char a 10 This has the effect of generating ten sequential locations starting at the address of a As there is nothing to the right of the declaration no initial values are inserted into the array It therefore contains zero data and serves only to reserve ten contiguous bytes 7 3 2 Initialised Arrays A more usual instance of arrays would be unsigned char test_array 0x00 0x40 0x80 0xC0 0xFF where the initial values are put in place before the program gets to main Note that the size of this initialised array is not given in the square brackets the compiler works out the size automatically Another common instance of an array is analogous to the BASIC string as per AS HELLO In C this equates to char test_array HELLO In C there is no real distinction between strings and arrays as a C array is just a
214. ts overlaid with cl int other branch x2 0x80 y2 x2 c0 y2 Z2 x2 y2 a2 2 x2 common z2 AKAKAKAAKAKAAKAKAAKAAKAAARKAALKA End of Module Module that declares publics for branch 1 Publics for branch 1 unsigned char xl yl unsigned int zl char al 0x30 A variable which is accessible from both branches extern int common void mainl void char eil www Phaedsys org page 101 of 194 Version 3 65 xl 0x80 yl xl ci yl zi xl yl al 2 x1 common zl AAA AAA AAA AAA AAA AAA AAA End of Module Module that declares variables that both 7 branches can access int common A variable common to both branches 7 Linker Input 151 t obj tl obj t2 obj com obj to t abs DATA DT T1 20H DT T2 20H The choice of 20H for the location places the combined segments just above the register banks The main problem with this approach is that a DATA overlay warning is produced This is not dangerous but is obviously undesirable www Phaedsys org page 102 of 194 Version 3 65 10 Other C51 Extensions 10 1 Special Function Bits A frustration for assembler programmers vvith the old C51 version vvas the need to use bit masks when testing for specific bits with chars and ints despite there being a good set of bit orientated assembler instructions within the 8051 In version 3 however it is possible to force data
215. used in the C program A typical invocation of the linker might be 151 startup obj modulel obj module2 obj module3 obj C51L lib to exec abs Here the three unlocated modules and the startup code in assembler are combined Any calls to library functions in any of these files results in the library C51L lib being searched for the appropriate code The target addresses or offsets for any JMPs or CALLs are calculated and inserted after the relevant opcodes When all five obj files have been combined they are placed into another file called EXEC ABS the ABS implying that this is absolute code that could actually be executed by an 8051 cpu In addition a map file called EXEC M51 is produced which summarises the linking operation This gives the address of every symbol used in the program plus the size of each module In anything other than a very small program the number of modules to be linked can be quite large hence the command line can become huge and unwieldy To overcome this the input list can be a simple ASCII text file thus 151 lt input_file gt where input_file startup obj amp modulel obj amp module2 obj amp module3 obj amp amp C51L 1lib amp amp to exec abs There are controls provided in the linker which determine where the various memory types should be placed For instance if an external RAM chip starts at 4000H and the code memory Eprom is at 8000H the linker must be given
216. vices should be the same There are three basic approaches to this i Use normal variables char ints etc located by the linker ii Use pointers and offsets either via the XBYTE macros or directly with user defined pointers iii Use the _At_ and _ORDER directives In detail these may be implemented as shown in the following sections 8 1 The XBYTE And XWORD Macros To allow memory mapped devices to be accessed from C a method is required to effectively force pointers to point to fixed addresses C51 provides many methods of achieving this the simplest of which are the XBYTE addr16 and XWORD addr16 macros For instance The byte wide PORT8_DDI register of a memory mapped IO device is at 8000H To access it from C it must be declared thus include absacc h Contains macro definitions define port8_ddi XBYTE 0x8000 define port8 data XBYTE 0x8001 To use it then port8_ddi input_val OxFF pa port8 data oil www Phaedsys org page 81 of 194 Version 3 65 To access a word at an even external address define word reg XWORD 0x4000 gives a word variable at 8000H Ignoring the pre defined XWORD macro the equivalent C line is define word_reg_ptr unsigned int 0x24000L creates a pointer to a word int at address 8000H To use this address then word_reg_ptr OxFFFF Note that the address 8000H corresponds to 4000H words hence the 0x24000L Here are some ex
217. void Function to be called indirectly char x5 ob arr5 10 Local variables for x5 0 4 x5 lt 105 x5 4 arr5 x5 x5 return x5 Function which does the calling char execute fptr Receive pointer to function to be used char fptr char tex Local variables for execute function char arrex 10 for tex 0 tex lt 10 text arrex tex fptr www Phaedsys org page 93 of 194 Version 3 65 return tex Declaration of general function pointer char code fp 3 void Main Calling Function void main void char am fp 0 funcl Point array elements at functions fplll func2 fp 2 func3 am fplol Execute functions am fplll am fp 2 if P1 Control which function is called am execute func4 Tell execute function which to run else am execute func5 Tell execute function which to run Resulting Linker Output M51 File for the dangerous condition MS DOS MCS 51 LINKER LOCATER L51 V2 8 INVOKED BY L51 MAIN OBJ TO EXEC ABS OVERLAY MAP OF MODULE EXEC ABS MAIN SEGMENT DATA GROUP gt CALLED SEGMENT START LENGTH C_C51STARTUP gt PR MAIN MAIN PR MAIN MAIN OOOEH 0001H gt PR FUNC1 MAIN gt PR FUNC2 MAIN gt PR FUNC3 MAIN gt PR FUNC4 MAIN gt PR _EXECUTE MAIN gt PR FUNC5 MAIN PR FUNC1 MAIN OOOFH OOOB
218. x8000 Move structure pointer to address of real time clock at 0x8000 in xdata rtc_ptr gt seconds 0 Operate on elements rtc_ptr gt mins 0x01 This general technique can be used in any situation where a pointer addressed structure needs to be placed over a specific IO device However it is the user s responsibility to make sure that the address given is not likely to be allocated by the linker as general variable RAM To summarize the procedure is i Define template ii Declare structure pointer as normal iii At run time force pointer to required absolute address in the normal way www Phaedsys org page 74 of 194 Version 3 65 7 5 Unions A union is similar in concept to a structure except that rather than creating sequential locations to represent each of the items in the template it places each item at the same address Thus a union of 4 bytes only occupies a single byte A union may consist of a combination of longs char and ints all based at the same physical address The the number of bytes of RAM used by a union is simply determined by the size of the largest element so union test char x int y 3 char a 3 Long zj requires 4 bytes this being the size of a long The physical location of each element is addr 0 x byte y high byte alo z highest byte 1 y low byte all z byte 2 a 2 z byte 3 a 3 z lowest byte Non 8051 programmers should see the section on byte or
219. y the pointer to an array should be passed not the array itself Care should be taken with variables to conserve storage space The code below is an example of scope not how to write good code The use of blocks in the function Calculate key below is quite useful if an under used part of C where a large number of temporary variables are required A block may be defined anywhere in c simply by using a pair of NOTE that by default functions are Extern however it is good practice to use the extern or static EREKEK Start of code extern int system_flags defined in another module extern unsigned char get_password unsigned char status function visable in other modules three functions only visable in THIS file static long calculate_key void static long gen_randon_prime long int password_flags variable visable in other files unsigned char get_password unsigned char status varuiables only visable in this fuuction unsigned char pass_status long int key_status key status calculate_key if status gt 0 pass_status key_status else pass_status 0 return pass_status static long int calculate_key void finction only visable in this file www Phaedsys org page 46 of 194 Version 3 65 int temp 1 variables visable in this functiion only 7 static long int temp key 0 74 static variable is only initialsed ONCE at program st
220. yboard_buffer www Phaedsys org page 153 of 194 Version 3 65 www Phaedsys org page 155 of 194 Version 3 65 21 Appendix D A Useful Look up Table Application Please note this is a program from the original C51 Primer In time it will be converted to C51 V7 and MISRA C compliance In a real system getting a true floating point sine would take around lms In a very time critical application this may well be unacceptable If only an approximation is required it is possible to use linear interpolation to get values between the known values in the table To do this a look up table interpolator is required Below is a combine one and two dimensional table interpolator taken from a real project Here the 2 D capability is not used Note The term i Map map is used instead of look up table include lt reg517 h gt KKAKKKKKKKKKKKAKKKKKKKKKKAKKKKKKAKKKAKKKKKKAKKKAKKKKKKAKKKKKKAKKKKKKKKKKKKJ Main Interpolation Routine X KKAKKKKKKKAKKKAKKKKKKAKKKAKKKKAKKAKKKAKKKKKKAKKKKAKKAKKKAKKKKKKAKKKKKKKKKKKKJ L ti This routine has been optimised to run as fast as possible at the expense of code size Further savings could be made by re using temporary RAM S With a 5 x 5 map run time is 490us 735us at 12MHz or 290us 400us with 12MHz Siemens 80C537 ep KAKKKKKKKAKKKAKKKKAKKKAKKKAKKKKKKKAKKKAKKKKKKAKKKAKKKKKKAKKKKKKAKKKKKKKKKKKKJ Input Map Format xy hes JA x_size y_size x_breakpoints
221. ype is related and repeating data In fact the information needed to describe a sensor can be reduced to a generalised unsigned char gain unsigned char offset unsigned char temp_coeff www Phaedsys org page 70 of 194 Version 3 65 unsigned char span unsigned char amp gain The concept of a structure is based on this idea of generalised template for related data In this case a structure template or component list describing any of the manufacturer s sensors vvould be declared struct sensor desc unsigned char gain unsigned char offset unsigned char temp_coeff unsigned char span unsigned char amp_gain This does not physically do anything to memory At this stage it merely creates a template which can now be used to put real data into memory This is achieved by struct sensor_desc sensor_database This reads as use the template sensor_desc to layout an area of memory named sensor_database reflecting the mix of data types stated in the template Thus a group of 5 unsigned chars will be created in the form of a structure The individual elements of the structure can now be accessed as sensor_database gain 0x30 sensor_database offset 0x50 sensor_database temp_coeff 0x60 sensor_database span 0xC4 sensor_database amp_gain 0x21 7 4 2 Arrays Of Structures In the example though information on many sensors is required and as with individual chars and ints it i
Download Pdf Manuals
Related Search
Related Contents
Kristian Spencer Off Shore Master hoses assembling instructions USER MANUAL SPOT-250 DMX MOVING HEAD Massive Wall light 37652/11/10 Toolbox User Manual v1.6 Philips SHL1705WT 外郭にキャラクターが印刷された電気たこ焼き器 TDSHーBA 東芝業務用リモコン 操作器取扱説明書 Attachment Pack 取扱説明書 Copyright © All rights reserved.
Failed to retrieve file