You are on page 1of 184

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925


Intel 80C51 51
8051
8051

C 8051
C ANSI C Intel


8051
C C 8051

C C
C Keil C51
Keil
Keil C Archimedes Avocet
Keil



8051

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

1
8051
PC Motorola 68HC11 8
8051 Intel Philips Siemens
51 I2C
PWM 40M 1.5V
8051

8051
1 8
2 32 I/O 4 8
3 16
4
5 6
6 128 RAM
7 64K
8051 12 12
12

11.059MHz 12 921583
1.085ms

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

2
8051 3 A-1 0

A-1-8051
2.1 CODE
16 64K
EPROM
EPROM EEPROM
8051 EEPROM
EEPROM SRAMs EPROM
EEPROM EEPROM
SRAMs SRAMs EPROM
//

8051
DPTR
DPTR 8051

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

2.2 DATA
8051 128 RAM 8052 128 RAM
DATA DATA
XDATA XDATA
DPTR DATA
DATA
R0 R1 R0 R1
R0 R1


32 PSW RS1 RS0
8051
8051
BDATA 16 128
8051
16

2.3
80H RAM

SFR


EA
EA IE.7
0AFH SFRs /


DATA

SFR A-1
SFR
A-1

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

2.4 IDATA
8051 8052 128 RAM 80H
IDATA IDATA SFRs
IDATA
2.5 XDATA
8051 64K CODE 16
XDATA RAM SRAM
XDATA DPTR R0 DPTR R1 DPTR
R0

R1 XDATA
3 DATA
I/O I/O RAM
XDATA 64K RAM

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

3
8051 BDATA SFRs 128 32 I/O

A-1
22H
MOV
C 22H
23H
ORL
C 23H
24H
MOV
24H C

JBC


P0.0
P0.0 P0.0

A-2
L2
L1

MOV
JB
DJNZ
CLR
RET

timeout #TO_VALUE
P0.0 L1
timeout L2
P0.0

P0.0

P0.0

JBC
A-3

MOV timeout #TO_VALUE


P0.0 L1
P0.0
L2 JBC

DJNZ timeout L2

L1 RET
JBC

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

4
8051
DATA SFR
A-4
03H
MOV A 03H
22H 43H
MOV 43H 22H
C 02H
MOV 02H C
18 42H
MOV 42H #18
09H
MOV 09H SBUF
DPTR PC R0 R1
CODE IDATA XDATA
DATA

CODE DPTR PC

A-5
DATA IDATA
R1 DATA 22H
MOV R1 #22H
R0 IDATA 0A9H
MOV R0 #0A9H
22H
MOV A @R1
A9H
MOV @R0 A
RO AAH
INC R0
R1 23H
INC R1
AAH 34H
MOV 34H @R0
23H
MOV @R1 #67H
XDATA
MOV DPTR #3048H
MOVX A @DPTR
INC DPTR
MOV A #26H
MOVX @DPTR A
MOV R0 #87H
MOVX A @R0

MOV DPTR #TABLE_BASE


MOV A index
MOVC A @A+DPTR

DPTR
3048H

26H A
26H 3049H
R0 87H
87H

DPTR

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

5
PSW BCD
RS0 RS1 0
00H 1 08H 2 10H 3 18H
PSW
CY

AC

CY
AC
F0
RS1
RS0
OV
USR
P

F0

RS1

RS0

OV

USR

6
8051 CHMOS
PCON IDLE
RAM CPU

PDWN
RAM

SMOD 1
SMOD 1 2 3 2
SMOD

SMOD

SMOD
GF1
GF0
PDWN
IDLE

GF1

GF0

PDWN

IDLE



A-3

6
8051 6 /
/

8051/8052 A-4

Tel

020

38730916 38730917 38730976 38730977

8051

0
0
1
1

Fax:38730925

0000H
0003H
000BH
0013H
001BH
0023H
002BH

6.1

IP


A-5 IP
IP
-

PT2
PS
PT1
PX1
PT0
PX0

PT2

PS

PT1

PX1

PT0

PX0

1
1
0
0
A-5

6.2
IE EA
IE IE

IE
EA

EA
ET2
ES
ET1
EX1
ET0
EX0

ET2

ES

ET1

EX1

ET0

EX0

1
1
0
0

6.3
8051

3
3

3
9

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925


3


6 3 3
4
3 IP IE RETI

6.4
8051
0 P3.2 1 P3.3
TCON ITX A-7

12
0

7 /
8051 / 16 /
I/0 TO T1
1/2

TCON timer controller


TR0 TR1 TCON T0
T1
0 1

TCON
TF1

TR1

TF0

TR0

IE1

IT1

IE0

IT0

TF1
TR1
TF0
TR0
IE1

1
1 1 1
0 0
0 0 0
1 P3.3

IT1
1
IE0
1 P3.3

IT0
1
A-7
TMOD TMOD
I/0 TMOD
10

Tel

020

1 0
TMOD-
GATE

C/T
M1
1

GATE

M0

GATE

38730916 38730917 38730976 38730977

Fax:38730925

TMOD

C/T M1
0

M0

GATE TR=1 INT=1 GATE=0


TR
C/T=1 C/T=0

A-8

C/T
M1
M0

C/T C/T=1 I/0


C/T=0

GATE=0 TR
GATE=1 TR=1 INT=1 INT
INT INT

7.1 0 1
0 /
TF0 TF1 1 /
0
7.2 2
2 8 8 TL0 TL1 8 TH0
TH1 TH TL 0
1 2 1
7.3 3
3 0 8 / TH0 TL0 TH0 TMOD
0 TL0 TMOD 1 1

1 /
1 3
7.4 2
51 8052 / 2
T2CON
2
TF2

TF2
EXF2

EXF2

RCLK

TCLK

EXEN2

TR2

C/T2

CP/RL2

2 2 TCLK RCLK 1

2 EXEN2=1 T2EX
2
11

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

RCLK

1 3 2

TCLK
1 3 2

EXEN2
2 EXEN2=1 T2EX
2 EXF2
TR2
2 2

C/T2
C/T2=1 2

CP/RL2
/ EXEN2=1 CP/RL2=1 T2EX
CP/RL2=0 T2EX
T2CON /
0 1 16
EXEN2 EXEN2 T2EX RCAP2H
RCAP2L
EXEN2 EXEN2
16 RCAP2H RCAP2L
EXEN2 T2EX
RCLK TCLK
1 0 1
12
8 UART
8051 SCON
SCON
SCON -
SM0

SM1

SM2

REN

TB8

RB8

TI

SM0
SM1
SM2

RI

0 0 1
2 3 9 1
REN

TB8
2 3 9
RB8
0 1
2 3 9
TI

RI

A-10
UART


8051 10 11 11 8
1 3

12

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

8.1 UART 0
0 UART 8 fosc/12 RXD
TXD 0
8 EEPROM
SBUF TI REN
8 RI
8.2 UART 1
1 10 1 8 1
PC
PCON SMOD 1
TI RI

1 TH1
TH1=256- K*OscFreq / 384*BaudRate
K=1 if SMOD=0
K=2 if SMOD=1
256

9.216M 9600 K=1 9216000
3686400 2.5 K=2 18432000 3686400
5 TH1=251 0FBH
8052 2 RCAP2H RCAP2L

[RCAP2H RCAP2L]=65536-OsFreq/ 32*BaudRate
9.216M 9600
30 65506 FFE2H
8.3 UART 2
2 11 1 8 1
SCON TB8 RB8
1 SCON SM2 SM2
1 SM2 0 11



SM2 SM2
SMOD=O 2 1/64Osc SMOD=1 1/32Osc
2 11.059M 345K 3 2

9
51

13

51

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

9.1 I2C
I2C PHILIPS I2C

8051 I2C P0

9.2 A/D
51 A/D A/D A/D
ADCON ADCON A/D
A/D 40
A/D
9.3
51


51

10
51
51
512 RAM 32K EPROM RAM EPROM
EPROM RAM I/0
I/0 28 51
RAM EPROM SRAM EPROM
51

3.6V

1200 4800 9600 19.2K

20M
EPROM SRAM CMOS
51

11
I/O
RAM RAM
0000H 8000H SRAM
0000H A15 RAM RAM 0E WE RD WR
RAM 32K 32K I/O
I/O

14

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

I/O A-2-8051 I/O


I/O DPTR 8

A-2-8051 I/O

A-6

MOV DPTR #09000H


MOVX A @DPTR
MOV DPH #080H
MOVX @DPTR A
I/O
MOV DPH #090H
12
8051 8051
8051
C

15

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

C 8051

1

8K
C


C
C C
C

C

C
C
C

C
C C

2 C
C C Kernighan Ritchie
C C Keil C51 C
8051 C
C
2.1



unsighed char hour,min,sec;

unsighed int days;


struct time_str{
unsigned char hour,min,sec;
unsigned int days;
}time_of_day;
time_str time_of_day
.
time_of_day.hour=XBYTE[HOURS];
time_of_day.days=XBYTE[DAYS];

16

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

time_of_day.min=time_of_day.sec
curdays=time_of_day.days;


struct time_str oldtime,newtime;
int

oldtime=time_of_day;

oldtime.hour=newtime.hour;
oldtime.days=newtime.days-1;
Keil C C
time_str
Offset
Member Bytes
0
hour
1
5
1
min
1
0-1:
2
sec
1

3
days
2

0-1

2.2

C

union time_type {
unsigned long secs_in_year;
struct time_str time;
}mytime;
time_str


mytime.secs_in_year=JUNEIST;
mytime.time.hour=5;
curdays=mytime.time.days;

Offset
Member
Bytes
0
Secs_in_year
4
0
Mytime
5
0-2
5 5
secs_in_year 5



union status_type{
unsigned char status[4];
17

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

unsigned long status_val;


}io_status;
io_status.status_val=0x12345678;
if(i0_status.status[2]&0x10){

}
2.3

8051 DATA XDATA DPTR

long C

C
unsigned char *my_ptr,*anther_ptr;
unsigned int *int_ptr;
float *float_ptr;
time_str *time_ptr;

My_ptr=&char_val;
Int_ptr=&int_array[10];
Time_str=&oldtime;

1
Time_ptr=(time str *) (0x10000L);
// 0
Time_ptr++;
// 5

time_ptr=oldtime_ptr
//
*int_ptr=0x4500
// 0X4500 int_ptr

time_ptr->days=234;
*time_ptr.hour=12;

struct bst_node{
unsigned char name[20];
//
struct bst_node *left,
, right;
//
};

18

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

2.4
C
time_str
typedef struct time_str{
unsigned char hour,min,sec;
unsigned int days;
}time_type;
time_type
time_type time,*time_ptr,time_array[10];
C
typedef unsigned char UBYTE;
typedef char *strptr;
strptr name;


3 Keil C ANSI C
Keil C ANSI C 8051 C

Keil ANSI C Keil


8051 8051
3.1
Keil C ANSI C 8051
8051


char/unsigned char
8 bit
int/unsigned
char
16
bit
RAM
long/unsigned long
32 bit

float/double
32 bit

generic pointer
24 bit
0-3
3.2
sfr sfr16 16 DPTR
80H
sbit SFR 0-1 8051 Keil

0-1
sfr SCON=0X98;
// SCON
sbit SM0=0X9F;
// SCON
sbit SM1=0X9E;
sbit SM2=0X9D;
sbit REN=0x9C;
sbit TB8=0X9B;

19

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

sbit RB8=0X9A;
sbit TI=0X99;
sbit RI=0X98;
4
Keil

DATA
RAM 128
BDATA
DATA 16
IDATA
RAM 128
PDATA
256 P0
MOVX @Rn,
XDATA
DPTR
CODE
DPTR
4.1 DATA
DATA DATA
DATA DATA
0-2
0-2
unsigned char data system_status=0;
unsigned int data unit_id[2];
char data inp_string[16];
float data outp_value;
mytype data new_var;
DATA DATA
C51 8
8051

4.2 BDATA
DATA

BDATA
0-3
unsigned char bdata status_byte;
unsigned int bdata status_word;
unsigned long bdata status_dword;
sbit stat_flag=status_byte^4;
if(status_word^15){

}
stat_flag=1;
BDATA float double
20

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

float long
0-4
typedef union{
//
unsigned long lvalue;
// 32
float fvalue;
// 32
}bit_float;
//
bit_float bdata myfloat;
// BDATA
sbit float_ld=myfloat^31
//
DATA

DATA BDATA

use_bitnum_status use_byte_status

0-5
1
//
2
unsigned char data byte_status=0x43;
3
4
//
5
unsigned char bdata bit_status=0x43;
6
// bit_status 3
7
sbit status_3=bit_status^3;
8
9
bit use_bit_status(void);
10
11
bit use_bitnum_status(void);
12
13
bit use_byte_status(void);
14
15
void main(void){
16
unsigned char temp=0;
17
if (use_bit_status()){
// 3 temp 1
18
temp++;
19
}
20
if (use_byte_status()){
// 3 temp 1
21
temp++;
22
}
23
if (use_bitnum_status()){
// 3 temp 1
24
temp++;
25
}
26
}
27
28
bit use_bit_status(void){
29
return(bit)(status_3);

21

Tel

020

38730916 38730917 38730976 38730977

30
}
31
32
bit use_bitnum_status(void){
33
return(bit)(bit_status^3);
34
}
35
36
bit use_byte_status(void){
37
return byte _status&0x04;
38
}

; FUNCTION main (BEGIN)


; SOURCE LINE # 15
; SOURCE LINE # 16
0000 E4
0001 F500

0003 120000 R
0006 5002
0008 0500

000A

?C0001:

CLR
MOV

; SOURCE LINE # 17
LCALL use_bit_status
JNC
?C0001
; SOURCE LINE # 18
INC
temp
; SOURCE LINE # 19

000A 120000 R
000D 5002

LCALL
JNC

000F 0500

INC

0011

?C0002:

0011 120000 R
0014 5002
0016 0500

0018
0018 22

A
temp,A

LCALL
JNC
INC

; SOURCE LINE # 20
use_byte_status
?C0002
; SOURCE LINE # 21
temp
; SOURCE LINE # 22
; SOURCE
use_bitnum_status
?C0004
; SOURCE
temp
; SOURCE
; SOURCE

LINE # 23

LINE # 24
LINE # 25
LINE # 26

?C0004:

RET
; FUNCTION main (END)
; FUNCTION use_bit_status (BEGIN)
; SOURCE LINE # 28
; SOURCE LINE # 29
0000 A200 R
MOV C,status_3
; SOURCE LINE # 30

22

Fax:38730925

0002
0002 22

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

?C0005:

RET
; FUNCTION use_bit_status (END)
; FUNCTION use_bitnum_status (BEGIN)
The compiler obtains the desired bit by using the entire byte instead of using
a bit address.
; SOURCE LINE # 32
; SOURCE LINE # 33
0000 E500 R
MOV A,bit_status
0002 6403
XRL A,#03H
0004 24FF
ADD A,#0FFH
; SOURCE LINE # 34
0006
?C0006:
0006 22
RET
; FUNCTION use_bitnum_status (END)
; FUNCTION use_byte_status (BEGIN)
; SOURCE LINE # 36
; SOURCE LINE # 37
0000 E500 R
MOV A,byte_status
0002 A2E2
MOV C,ACC.2
; SOURCE LINE # 38
0004
?C0007:
0004 22
RET
; FUNCTION use_byte_status (END)

4.3 IDATA
IDATA
8

unsigned char idata system_status=0;


unsigned int idata unit_id[2];
char idata inp_string[16];
float idata outp_value;
4.4 PDATA XDATA
PDATA 256 XDATA
65536
unsigned char xdata system_status=0;
unsigned int pdata unit_id[2];
char xdata inp_string[16];
float pdata outp_value;
PDATA XDATA PDATA XDATA
PDATA 8 XDATA 16

23

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

PDATA PDATA XDATA MOVX


0-6
1
#include <reg51.h>
2
3
unisgned char pdata inp_reg1;
4
5
unsigned char xdata inp_reg2;
6
7
void main(void){
8
inp_reg1=P1;
9
inp_reg2=P3;
10 }

; FUNCTION main (BEGIN)


; SOURCE LINE # 7
; SOURCE LINE # 8
'inp_reg1=P1' 4
0000 7800
0002 E590
0004 F2

0005
0008
000A

MOV
MOV
MOVX

R0,#inp_reg1
A,P1
@R0,A
; SOURCE LINE # 9

'inp_reg2=P3'
900000 R
E5B0
F0

5
MOV
DPTR,#inp_reg2
MOV
A,P3
MOVX
@DPTR,A
; SOURCE LINE # 10
000B 22
RET
; FUNCTION main (END)
I/O
C51
char int
0-7
inp_byte=XBYTE[0x8500];
// 8500H
inp_word=XWORD[0x4000];
// 4000H2001H
c=*((char xdata *) 0x0000); // 0000
XBYTE[0x7500]=out_val;
// 7500H
BDATA BIT absacc.h

4.5 CODE
8051

24

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

CODE XDATA

unsigned int code unit_id[2]=1234;
unsigned char
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15
};
5
C51 3
16

DATA IDATA PDATA 8

3
Keil
XDATA
2
CODE
2

IDATA
1

DATA
1

PDATA
1

0-5


378 151
0-8
1
#include <absacc.h>
2
3
char *generic_ptr;
4
5
char data *xd_ptr;
6
7
char mystring[]="Test output";
8
9
main() {
10 1
generic_ptr=mystring;
11 1
while (*generic_ptr) {
12 2
XBYTE[0x0000]=*generic_ptr;
13 2
generic_ptr++;
14 2
}
15 1
16 1
xd_ptr=mystring;
17 1
while (*xd_ptr) {
18 2
XBYTE[0x0000]=*xd_ptr;
19 2
xd_ptr++;
20 2
}
21 1
}

25

Tel

020

38730916 38730917 38730976 38730977

; FUNCTION main (BEGIN)

0000 750004
0003 750000
0006 750000
0009

R
MOV
R
MOV
R
MOV
?C0001:

; SOURCE LINE # 9
; SOURCE LINE # 10
generic_ptr,#04H
generic_ptr+01H,#HIGH mystring
generic_ptr+02H,#LOW mystring
; SOURCE LINE # 11

0009
000B
000D
000F
0012
0013

AB00
AA00
A900
120000
FF
6011

0015 900000
0018 F0
0019
001B
001D
001F
0020
0022

7401
2500
F500
E4
3500
F500

0024 80E3
0026
0026 750000
0029
0029
002B
002C
002D

A800
E6
FF
6008

002F 900000
0032 F0
0033 0500
0035 80F2
0037

R
R
R
E

MOV
MOV
MOV
LCALL
MOV
JZ

R3,generic_ptr
R2,generic_ptr+01H
R1,generic_ptr+02H
?C_CLDPTR
R7,A
?C0002
; SOURCE LINE # 12
MOV DPTR,#00H
MOVX @DPTR,A
; SOURCE LINE # 13
MOV A,#01H
R
ADD A,generic_ptr+02H
R
MOV generic_ptr+02H,A
CLR A
R
ADDC A,generic_ptr+01H
R
MOV generic_ptr+01H,A
; SOURCE LINE # 14
SJMP ?C0001
?C0002:
; SOURCE LINE # 16
R
MOV xd_ptr,#LOW mystring
?C0003:
; SOURCE LINE # 17
R
MOV R0,xd_ptr
MOV A,@R0
MOV R7,A
JZ
?C0005
; SOURCE LINE # 18
MOV DPTR,#00H
MOVX @DPTR,A
; SOURCE LINE # 19
R
INC xd_ptr
; SOURCE LINE # 20
SJMP ?C0003
; SOURCE LINE # 21
?C0005:

26

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0037 22

RET
; FUNCTION main (END)

6
8051 ,C51 C (
) interrupt (0 31).
IE IE
0 0 0 0 0-6

IE

C
0
0

1
0

2
1
B
3
1

4


5
2

0-6
C51 5 8051/8052
0 4 8051 27
0-9
1
#include <reg51.h>
2
#include <stdio.h>
3
4
#define RELOADVALH 0x3C
5
#define RELOADVALL 0xB0
6
7
extern unsigned int tick_count;
8
9
void timer0(void) interrupt 1 {
10 1
TR0=0;
// 0
11 1
TH0=RELOADVALH;
// 50ms
12 1
TL0=RELOADVALL;
13 1
TR0=1;
// T0
14 1
tick_count++;
// 1
15 1
printf("tick_count=%05u\n", tick_count);
16 1 }

0000
0002
0004
0006

; FUNCTION timer0 (BEGIN)


C0E0
PUSH ACC
C0F0
PUSH B
C083
PUSH DPH
C082
PUSH DPL

27

0008
000A
000C
000E
0010
0012
0014
0016
0018

C0D0
C000
C001
C002
C003
C004
C005
C006
C007

PUSH
PUSH
PUSH
PUSH
PUSH
PUSH
PUSH
PUSH
PUSH

Tel

020

38730916 38730917 38730976 38730977

PSW
AR0
AR1
AR2
AR3
AR4
AR5
AR6
AR7
; SOURCE LINE # 9
; SOURCE LINE # 10

001A C28C

CLR TR0
; SOURCE LINE # 11

001C 758C3C

MOV TH0,#03CH
; SOURCE LINE # 12

001F 758AB0

MOV TL0,#0B0H
; SOURCE LINE # 13

0022 D28C

SETB TR0
; SOURCE LINE # 14

0024
0027
0028
0029
002A
002C
002F
0030
0031
0032

900000 E
E0
04
F0
7006
900000 E
E0
04
F0
?C0002:

MOV DPTR,#tick_count+01H
MOVX A,@DPTR
INC A
MOVX @DPTR,A
JNZ ?C0002
MOV DPTR,#tick_count
MOVX A,@DPTR
INC A
MOVX @DPTR,A
; SOURCE LINE # 15

0032
0034
0036
0038
003B
003C
003D
003E
003F
0042
0043
0044
0045
0046

7B05
MOV R3,#05H
7A00 R MOV R2,#HIGH ?SC_0
7900 R MOV R1,#LOW ?SC_0
900000 E MOV DPTR,#tick_count
E0
MOVX A,@DPTR
FF
MOV R7,A
A3
INC DPTR
E0
MOVX A,@DPTR
900000 E MOV DPTR,#?_printf?BYTE+03H
CF
XCH A,R7
F0
MOVX @DPTR,A
A3
INC DPTR
EF
MOV A,R7
F0
MOVX @DPTR,A

28

Fax:38730925

0047 120000 E LCALL

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

_printf
; SOURCE LINE # 16

004A
004C
004E
0050
0052
0054
0056
0058
005A
005C
005E
0060
0062
0064

D007
POP
AR7
D006
POP
AR6
D005
POP
AR5
D004
POP
AR4
D003
POP
AR3
D002
POP
AR2
D001
POP
AR1
D000
POP
AR0
D0D0
POP
PSW
D082
POP
DPL
D083
POP
DPH
D0F0
POP
B
D0E0
POP
ACC
32
RETI
; FUNCTION timer0 (END)
printf
printf C

0-10
1
#include <reg51.h>
2
3
#define RELOADVALH 0x3C
4
#define RELOADVALL 0xB0
5
6
extern unsigned int tick_count;
7
8
void timer0(void) interrupt 1 using 0 {
9 1
TR0=0;
// 0
10 1
TH0=RELOADVALH;
// 50ms
11 1
TL0=RELOADVALL;
12 1
TR0=1;
// T0
13 1
tick_count++;
// 1
14 1
}

; FUNCTION timer0 (BEGIN)


0000 C0E0
PUSH
ACC
Push and pop of register bank 0 and the B register is eliminated because printf was
usingthe registers for parameters and using B internally.
0002 C083
PUSH
DPH
0004 C082
PUSH
DPL

29

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

; SOURCE LINE # 8
; SOURCE LINE # 9
0006 C28C

CLR

TR0
; SOURCE LINE # 10

0008 758C3C

MOV

TH0,#03CH
; SOURCE LINE # 11

000B 758AB0

MOV

TL0,#0B0H
; SOURCE LINE # 12

000E D28C
0010
0013
0014
0015
0016
0018
001B
001C
001D
001E

SETB

900000 E MOV
E0
MOVX
04
INC
F0
MOVX
7006
JNZ
900000 E MOV
E0
MOVX
04
INC
F0
MOVX
?C0002:

TR0
; SOURCE LINE # 13
DPTR,#tick_count+01H
A,@DPTR
A
@DPTR,A
?C0002
DPTR,#tick_count
A,@DPTR
A
@DPTR,A
; SOURCE LINE # 14

001E
0020
0022
0024

D082
D083
D0E0
32

POP
DPL
POP
DPH
POP
ACC
RETI
; FUNCTION timer0 (END)

6.1

using 0 3 4
32 2

0
0
0-11
1
#include <reg51.h>
2
#include <stdio.h>
3
4
#define RELOADVALH 0x3C
5
#define RELOADVALL 0xB0
6
7
extern unsigned int tick_count;
8
9
void timer0(void) interrupt 1 using 0 {

30

10
11
12
13
14
15
16

1
1
1
1
1
1
1

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

TR0=0;
// 0
TH0=RELOADVALH;
// 50ms
TL0=RELOADVALL;
TR0=1;
// T0
tick_count++;
// 1
printf("tick_count=%05u\n", tick_count);
}

0000
0002
Push
that
0004
0006
0008
000A

000D
000F
0012
0015
0017
001A
001B
001C
001D
001F
0022
0023
0024
0025
0025
0027
0029
002B

; FUNCTION timer0 (BEGIN)


C0E0
PUSH
ACC
C0F0
PUSH
B
and pop of register bank 0 has been eliminated because the compiler assumes
thisISR 'owns' RB0.
C083
PUSH
DPH
C082
PUSH
DPL
C0D0
PUSH
PSW
75D000
MOV
PSW,#00H
; SOURCE LINE # 9
; SOURCE LINE # 10
C28C
CLR
TR0
; SOURCE LINE # 11
758C3C
MOV
TH0,#03CH
; SOURCE LINE # 12
758AB0
MOV
TL0,#0B0H
; SOURCE LINE # 13
D28C
SETB
TR0
; SOURCE LINE # 14
900000 E
MOV
DPTR,#tick_count+01H
E0
MOVX
A,@DPTR
04
INC
A
F0
MOVX
@DPTR,A
7006
JNZ
?C0002
900000 E
MOV
DPTR,#tick_count
E0
MOVX
A,@DPTR
04
INC
A
F0
MOVX
@DPTR,A
?C0002:
; SOURCE LINE # 15
7B05
MOV
R3,#05H
7A00 R
MOV
R2,#HIGH ?SC_0
7900 R
MOV
R1,#LOW ?SC_0
900000 E
MOV
DPTR,#tick_count

31

002E
002F
0030
0031
0032
0035
0036
0037
0038
0039
003A

E0
FF
A3
E0
900000 E
CF
F0
A3
EF
F0
120000 E

003D
003F
0041
0043
0045
0047

D0D0
D082
D083
D0F0
D0E0
32

MOVX
MOV
INC
MOVX
MOV
XCH
MOVX
INC
MOV
MOVX
LCALL

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

A,@DPTR
R7,A
DPTR
A,@DPTR
DPTR,#?_printf?BYTE+03H
A,R7
@DPTR,A
DPTR
A,R7
@DPTR,A
_printf
; SOURCE LINE # 16
PSW
DPL
DPH
B
ACC

POP
POP
POP
POP
POP
RETI
; FUNCTION timer0 (END)

7
8051 C51 C
C51



C51


bit
8 Keil C
Keil C

8.1
C
int 8

unsigned char
8.2
8051

32

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925


8.3
8 32

ints longs doubles floats

80517 80320



fpsave
fprestore sin()
,
0-12
#include <math.h>
void timer0_isr(void) interrupt 1 {
struct FPBUF fpstate;
...
//
//
fpsave(&fpstate);
//
...
// ,
//
fprestore(&fpstate);
//
//
...
//
//
}
float my_sin(float arg) {
float retval;
bit old_ea;
old_ea=EA;
//
EA=0;
//
retval=sin(arg);
//
EA=old_ea;
//
return retval;
}


8.4

unsigned char

33

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

7 RAM
8.5




8.6
,
RAM ,,,,

DATA IDATA PDATA XDATA
8.7
XDATA
CODE

8.8

ANSI

RL A RR A _crol_ _cror_(
) int long
int _irol_,_iror_ , long _lrol_,_lror_
C JBC _testbit_ 1
0 C
JBC
0-13
#include <instrins.h>
void serial_intr(void) interrupt 4 {
if (!_testbit_(TI)) {
//
P0=1;
// P0.0
_nop_();
//
P0=0;
...
}
if (!_testbit_(RI)) {
test=_cror_(SBUF, 1); // SBUF
//
...
}
}

34

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

8.8


0-14
#define led_on() {\
led_state=LED_ON; \
XBYTE[LED_CNTRL] = 0x01;}
#define led_off() {\
led_state=LED_OFF; \
XBYTE[LED_CNTRL] = 0x00;}
#define checkvalue(val) \
( (val < MINVAL || val > MAXVAL) ? 0 : 1 )


9
C51 3

RAM
DATA
DATA RAM
120 128
8
256 RAM
PDATA RAM
XDATA RAM
PDATA R0 R1 DPTR

XDATA Keil C

XDATA XDATA

10
Keil

RAM RAM



XDATA

35

Tel

020

38730916 38730917 38730976 38730977

11





0-7

gets
printf
sprinf
scanf
sscanf
memccpy
strcat
strncat
strncmp
strncpy
strspn
strcspn
strpbrk
strrpbrk

atof
atol
atoi
exp
log
log10
sqrt
srand
cos
sin
tan
acos
asin
atan
0-7

Fax:38730925

atan2
cosh
sinh
tanh
calloc
free
Init_mempool
malloc
realloc
ceil
floor
modf
pow

12
C malloc free
Keil C


Keil C


XDATA
DATA DATA
XDATA
init_mempool ,

malloc( unsigned int ,),calloc(
unsigned int ,),realloc(
unsigned int ,
),free(,)
NULL
0-15
#include <stdio.h>
#include <stdlib.h>
//
typedef struct entry_str {
struct entry_str xdata *next;
char text[33];
} entry;

//
//
//

void init_queue(void);
void insert_queue(entry xdata *);
void display_queue(entry xdata *);
void free_queue(void);
entry xdata *pop_queue(void);

36

Tel

entry xdata *root=NULL;

020

38730916 38730917 38730976 38730977

//

void main(void) {
entry xdata *newptr;
init_queue();
//
...
newptr=malloc(sizeof(entry));
//
sprintf(newptr->text, "entry number one");
insert_queue(newptr);
//
...
newptr=malloc(sizeof(entry));
sprintf(newptr->text, "entry number two");
insert_queue(newptr);
//
...
display_queue(root);
...
newptr=pop_queue();
printf("%s\n", newptr->text);
free(newptr);
...
free_queue();

//
//
//
//

}
void init_queue(void) {
static unsigned char memblk[1000];
//
init_mempool(memblk, sizeof(memblk)); //
}
void insert_queue(entry xdata *ptr) {
entry xdata *fptr, *tptr;
if (root==NULL){
root=ptr;
} else {
fptr=tptr=root;
while (fptr!=NULL) {
tptr=fptr;
fptr=fptr->next;
}
tptr->next=ptr;
}
ptr->next=NULL;
}

//

37

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

void display_queue(entry xdata *ptr) {//


entry xdata *fptr;
fptr=ptr;
while (fptr!=NULL) {
printf("%s\n", fptr->text);
fptr=fptr->next;
}
}
void free_queue(void) {
entry xdata *temp;
while (root!=NULL) {
temp=root;
root=root->next;
free(temp);
}
}

//

entry xdata *pop_queue(void) {


//
entry xdata *temp;
if (root==NULL) {
return NULL;
}
temp=root;
root=root->next;
temp->next=NULL;
return temp;
}
ANSI C
13
C

38

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925


1

8051
2x16 LCD
15

,,.

RAM RAM 128

RAM RAM 0-1


EPROM 8051 EPROM 74373
0 2
0-2

LCD


SRAM

0-1
2
SRAM RAM 128

RAM
RAM
L51


39

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0-2
RAM RAM
printf
printf

0-1

40

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

3
GMD16202 2x16 0-1


40ms 1.64ms
3.1 LCD
,, 8
P1
8051 XBYTE[]

8051 LCD

EPROM


LCD

3



0-3 0-4


I/0

0-1
void disp_write(unsigned char value) {
DISPDATA=value; //
REGSEL=1;
//
RDWR=0;
//
ENABLE=1;
// LCD
ENABLE=0;
}
disp_write LCD LCD

0-2
void disp_cmd(unsigned char cmd) {

41

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

DISPDATA=cmd;
//
REGSEL=0;
//
RDWR=0;
//
ENABLE=1;
// LCD
ENABLE=0;
TH1=0;
// 85ms
TL1=0;
TF1=0;
TR1=1;
while (!TF1 && disp_read() & DISP_BUSY);//
//
TR1=0;
}
disp_cmd disp_write LCD

0-3
unsigned char disp_read(void) {
unsigned char value;
DISPDATA=0xFF;
//
REGSEL=0;
//
RDWR=1;
//
ENABLE=1;
// LCD
value=DISPDATA;
//
ENABLE=0;
// LCD
return(value);
}
disp_read
P1


4

,
. putchar LCD

255 putchar

0-4
char putchar(char c) {
static unsigned char flag=0;
if (!flag || c==255) {
//

42

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

disp_cmd(DISP_HOME);
flag=0;
if (c==255) {
return c;
}
}
if (flag==16) {
disp_cmd(DISP_POS | DISP_LINE2);
}
disp_write(c);
while (disp_read() & DISP_BUSY);
flag++; // increment the line flag
if (flag>=32) { flag=0; }
return(c);

//
//
//
//
//

}
I/O

4.1 printf
C51 printf
PC 8051
printf putchar
putchar printf
putchar printf

0-5
void disp_time(void) {
//
//
//
printf("\xFFTIME OF DAY IS: %B02u:%B02u:%B02u ",
timeholder.hour, timeholder.min, timeholder.sec);
disp_update=0;
//
}
5



NOP DJNZ



idle

43

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

ISR
C


50ms
3ms


50ms
12MHz 1MHz, 1us

50000 50ms 65536 50000
15536 3CB0
0 1
0-6
#define RELOAD_HIGH 0x3C
#define RELOAD_LOW 0xB0
void system_tick(void) interrupt 1 {
TR0=0;
//
TH0=RELOAD_HIGH; //
TL0=RELOAD_LOW;
TR0=1;
//
//
}




0
LED 2
if (led_timer) {
// 0
led_timer--;
//
if (!led_timer) {
// ...
LED=OFF; // turn off the LED
}
}


1
0
50ms

44

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

second_cnt--;
//
if (!second_cnt) {
// ...
...
//
second_cnt=20;
// 1
}
50ms

6



1 0

50ms 0.2
8051 I/O
1 0

cur_field set_cursor

printf
pirntf

0-7
void system_tick(void) interrupt 1 {
static unsigned char second_cnt=20;
// 1
TR0=0;
//
TH0=RELOAD_HIGH;
//
TL0=RELOAD_LOW;
TR0=1;
//
if (switch_debounce)
switch_debounce--;
}
if (!switch_debounce) {
if (!SET) {
// ...
switch_debounce=DB_VAL;
if (!set_mode && !disp_update) {
//
set_mode=1;
//

45

Tel

020

38730916 38730917 38730976 38730977

set_mode_to=TIMEOUT;
cur_field=HOUR;
set_cursor(ON, HOUR);
}else {
cur_field++;
if (cur_field>SEC) {

Fax:38730925

//
//
//
//
//
//
//

set_mode=0;
set_mode_to=0;
set_cursor(OFF, HOME);
//
}else {
set_cursor(ON, cur_field); //
set_mode_to=TIMEOUT;
}
}
}
if (set_mode && !SELECT) {
set_mode_to=TIMEOUT;
incr_field();
disp_time();
}

//
//
//

}
if (!set_mode) {
second_cnt--;
if (!second_cnt) {
second_cnt=20;
second_tick();
}
}

//
//
//
//


1
1...

}
7

C51
2
DIV MUL 3


0-8
; FUNCTION system_tick (BEGIN)
0000 C0E0
PUSH ACC
2, 2
0002 C0F0
PUSH B
2, 4
0004 C083
PUSH DPH
2, 6
0006 C082
PUSH DPL
2, 8

46

0008
000A
000C
000E
0010
0012
0014
0016
0018

C0D0
C000
C001
C002
C003
C004
C005
C006
C007

PUSH
PUSH
PUSH
PUSH
PUSH
PUSH
PUSH
PUSH
PUSH

Tel

020

38730916 38730917 38730976 38730977

PSW
AR0
AR1
AR2
AR3
AR4
AR5
AR6
AR7

Fax:38730925

2, 10
2, 12
2, 14
2, 16
2, 18
2, 20
2, 22
2, 24
2, 26
; SOURCE LINE # 332
; SOURCE LINE # 335
001A C28C
CLR TR0
1, 27
; SOURCE LINE # 336
001C 758C3C
MOV TH0,#03CH
2, 29
; SOURCE LINE # 337
001F 758AAF
MOV TL0,#0AFH
2, 31
; SOURCE LINE # 338
0022 D28C
SETB TR0
1, 32
; SOURCE LINE # 340
34 32+2
52

printf
6039 printf putchar
6039 6.093ms
23 59 59 00 00 00

207
.207ms,.076ms
50ms 6.246ms
43.754ms
printf

printf

printf

2000
BCD ASCII
76
disp_time printf 3
putchar
120 1951 1189
printf 811 disp_time 105 disp_time

47

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0-9
void disp_time(void) {
//
//
//
static char time_str[32]="TIME OF DAY IS: XX:XX:XX ";
unsigned char I;
time_str[T_HOURT]=bcdmap[timeholder.hour][0];
time_str[T_HOUR]=bcdmap[timeholder.hour][1];
time_str[T_MINT]=bcdmap[timeholder.min][0];
time_str[T_MIN]=bcdmap[timeholder.min][1];
time_str[T_SECT]=bcdmap[timeholder.sec][0];
time_str[T_SEC]=bcdmap[timeholder.sec][1];
putchar(0xFF);
for (i=0; i<32; i++) {
putchar(time_str[i]);
}
disp_update=0;
//
}
disp_time 2238 12MHz 2.238ms
1.64ms 32 1.28ms 2.92ms
6.866ms 76x19 (
19 ) 207 2238
2.92ms
8 RAM
RAM M51

TYPE BASE LENGTH RELOCATION SEGMENT NAME


----------------------------------------------------* * * * * * * D A T A M E M O R Y * * * * * * *
REG
0000H
0008H ABSOLUTE
"REG BANK 0"
DATA
0008H
0002H UNIT
"DATA_GROUP"
000AH
0016H
*** GAP ***
BIT
0020H.0 0000H.2 UNIT
?BI?CH4CLOCK
BIT
0020H.2 0000H.1 UNIT
"BIT_GROUP"
0020H.3 0000H.5
*** GAP ***
DATA
0021H
002BH UNIT
?DT?CH4CLOCK
IDATA 004CH
0001H UNIT
?STACK
, 0AH 20H 22
CH4CLOCK

ch4clock.c

48

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925


tab

DT ch4clock





22
9
TYPE BASE LENGTH RELOCATION SEGMENT NAME
----------------------------------------------------* * * * * * * D A T A M E M O R Y * * * * * * *
REG 0000H 0008H ABSOLUTE "REG BANK 0"
DATA 0008H 0022H UNIT
?DT?CH4NEW
BIT 002AH.0 0000H.2 UNIT
?BI?CH4NEW
BIT 002AH.2 0000H.1 UNIT
_BIT_GROUP_
002AH.3 0000H.5
*** GAP ***
DATA 002BH 0009H UNIT
?DT?VARS
DATA 0034H 0004H UNIT
_DATA_GROUP_
IDATA 0038H 0001H UNIT
?STACK
72 80H-28H
72
disp_time 13 PC 2 2 disp_time
putchar, putchar disp_cmd disp_cmd disp_read 4
25 47
9
,
0-10
#include<reg51.h>
#include<stdio.h>
// 0
#define RELOAD_HIGH 0x3C
#define RELOAD_LOW
0xD2
//
#define DB_VAL
//
#define TIMEOUT
200
//
#define HOME

49

Tel

#define HOUR
#define MIN
#define SEC

38730916 38730917 38730976 38730977

1
2
3

//
#define OFF
#define ON

0
1

//
#define DISP_BUSY
#define DISP_FUNC
#define DISP_ENTRY
#define DISP_CNTL
#define DISP_ON
#define DISP_CURSOR
#define DISP_CLEAR
#define DISP_HOME
#define DISP_POS
#define DISP_LINE2

0x80
0x38
0x06
0x08
0x04
0x02
0x01
0x02
0x80
0x40

sbit
sbit
sbit
sbit
sbit

020

SET=P3^4;
SELECT=P3^5;
ENABLE=P3^1;
REGSEL=P3^7;
RDWR=P3^6;

sfr DISPDATA=0x90;

//
//
//
//
//
// 8

typedef struct {
//
unsigned char hour,min,sec;
}timestruct;
bit set_mode=0;
disp_updata=0;

//
//

unsigned char set_mode_to=0;


switch_debounce=0;
cur_field=HOME;
timestruct

curtime;
timeholder;

//
//
//
//
//

unsigned char code fieldpos[3]={

//

50

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

DISP_LINE2|0x01;
DISP_LINE2|0x04;
DISP_LINE2|0x07;
};
#define
#define
#define
#define
#define
#define

T_HOURT
T_HOUR
T_MINT
T_MIN
T_SECT
T_SEC

16
17
19
20
22
23

char code bcdmap[60][2]={


00,01,02,03,04,05,06,07,08,09,
10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,
30,31,32,33,34,35,36,37,38,39,
40,41,42,43,44,45,46,47,48,49,
50,51,52,53,54,55,56,57,58,59,

};
//
void disp_cmd(unsigned char);
void disp_init(void);
unsigned char disp_read(void);
void disp_time(void);
void disp_write(unsigned char);
void incr_field(void);
void second_tick(void);
void set_cursor(bit,unsigned char);
/*****************************************************
:
:, 8051,,



*****************************************************/
void main(void){
disp_init();
//
TMOD=0x11;
//
TCON=0x15;
IE=0x82;
For(;;)
{

51

if (disp_updata){
disp_time( );

Tel

020

38730916 38730917 38730976 38730977

//

PCON=0x01;
}
}
/**************************************************
disp_cmd
lcd


*************************************************/
void disp_cmd(unsigned char cmd){
DISPDATA=cmd;
//
REGSEL=0;
//
RDWR=0;
//
ENABLE=1;
ENABLE=0;
TH1=0;
// 85ms
TL1=0;
TF1=0;
TR1=1;
while(!TF1&&disp_read()&DISP_BUSY); //
TR1=0;
}

/****************************************************
:disp_init
:
:
:
****************************************************/
void disp_init(void){
TH1=0;
TL1=0;
TF1=0;
TR1=1;
while (!TF1&&disp_read()&DISP_BUSY);
TR1=0;
disp_cmd(DISP_FUNC);
//
disp_cmd(DISP_ENTRY);
//, 1
disp_cmd(DISP_CNTL|DISP_ON);
//,
disp_cmd(DISP_CLEAR);
//

52

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

/*******************************************************
:disp_read
:
:
:
*********************************************************/
unsigned char disp_read(void){
unsigned char value;
DISPDATA=0XFF;
REGSEL=0;
//
RDWR=1;
//
ENABLE=1;
// LCD
value=DISPDATA;
//
ENABLE=0;
retrun(value);
}
/**********************************************************
:disp_time
:
:
:
******************************************************/
void disp_time(void){
static char time_str[32]= TIME OF DAY IS:XX:XX:XX
;
unsigned char I;
time_str[T_HOURT]=bcdmap[timeholder.hour][0];
time_str[T_HOUR]=bcdmap[timeholder.hour][1];
time_str[T_MINT]=bcdmap[timeholder.min][0];
time_str[T_MIN]=bcdmap[timeholder.min][1];
time_str[T_SECT]=bcdmap[timeholder.sec][0];
time_str[T_SEC]=bcdmap[timeholder.sec][1];
putchar(0xFF);
for(i=0;i<32;i++){
putchar(time_str[i]);
}
disp_updata=0;
}
/***************************************************
:disp_write

53

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

:
:
:
****************************************************/
void disp_write(unsigned char value){
DISPDATA=value;
REGSEL=1;
RDWR=0;
ENABLE=1;
ENABLE=0;
}
/*************************************************
:incr_field
:
:
:
**********************************************/
void incr_field(void){
if (cur_field= =SEC){
curtime.sec++;
if(curtime.sec>59){
curtime.sec=0;
}
}
if (cur_field= =MIN){
curtime.min++;
if(curtime.min>59){
curtime.min=0;
}
}
if (cur_field= =HOUR){
curtime.hour++;
if(curtime.hour>23){
curtime.hour=0;
}
}
}
/***********************************************************
:putchar
: putchar ,
:
:
************************************************************/

54

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

char putchar(char c){


static unsigned char flag=0;
if(!flag||c= =255){
disp_cmd(DISP_HOME);
flag=0;
if(c= =255){
return c;
}
}
if(flag= =16){
disp_cmd(DISP_POS|DISP_LINE2);
}
disp_write(c);
while(disp_read( )&DISP_BUSY);
flag++;
if (flag>=32){flag=0};
return(c);
}
/*************************************************************
:second_tick
:,
:
:
*************************************************************/
void second_tick(void){
curtime.sec++;
// 1
if (curtime.sec>59){
//
curtime.sec=0;
crutime.min++;
// 1
if (curtime.min>59){
//
curtime.min=0;
curtime.hour++;
// 1
if(curtime.hour>23){
//
curtime.hour=0;
}
}
}
if(!disp_updata){
// timeholder
timeholder=curtime;
//
disp_updata=1;
//
}
}

55

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

/***************************************************
;set_cursor
:,
:new_mode ,
field

:
***************************************************/
void set_cursor(bit new_mode,unsigned char field){
unsigned char mask;
mask=DISP_CNTL|DISP_ON;
if(new_mode){
mask|=DISP_CURSOR;
}
disp_cmd(mask);
if (field= =HOME){
mask=DISP_HOME;
}else{
mask=DISP_POS|fieldpos[field-1];
}
disp_cmd(mask);
}
/*******************************************************
: system_tick
: 0 , 50ms
:
:
*******************************************************/
void system_tick(void) interrupt1{
static unsigned char second_cnt=20;
TR0=0;
TH0=RELOAD_HIGH;
//
TL0=RELOAD_LOW;
TR0=1;
//
if(switch_debounce){
//
switch_debounce--;
}
if (!switch_debounce){
if(!SET){
//
switch_debounce=DB_VAL;
//
if(!set_mode&&!disp_updata){ //
set_mode=1;
//
set_mode_to=TIMEOUT;
//
cur_field=HOUR;
//

56

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

set_cursor(ON,HOUR);
//
}else{
cur_field++;
//
if(cur_field>SEC){
//
set_mode=0;
//
set_mode_to=0;
set_cursor(OFF,HOME);
//
}else{
set_cursor(ON,cur_field); //
set_mode_to=TIMEOUT;
}
}
}
if(set_mode&&!SELECT){
//
set_mode_to=TIMEOUT;
incr_field( );
//
disp_time( );
//
}
}
if(!set_mode){
//
second_cnt- -;
// 1
if(!second_cnt){
// 1
second_cnt=20;
//
second_tick( );
}
}
}
10
,

I/O
bug




Pilips80C550
void wd_init(unsigned prescale){
WDL=0xFF;
//
WDCON=(prescale&0xE0)|0x05;
//
wd_reload();
}
void wd_reload(void){

57

Tel

020

38730916 38730917 38730976 38730977

EA=0;
WPEED1=0xA5
WFEED2=0x5A
EA=1

Fax:38730925

//
//
//
//

0-12
void main(void){
//

for(;;){
//

wd_reload( );
//
PCON=0x80;
//
}
}
void my_ISR(void)interrupt 0{
static unsigned char int_count=0; //
int_count++;
if(int_count>MAXINTS){
//
int_count=0;
wd_reload( );
//
}

}

RAM

12


8051 RAM



00 FF
AA CC RAM
startup.a51 RAM
RAM startup.a51
startup.a51 RAM 0 RAM

58

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

RAM RAM 0

0-13
unsigned char xdata bootflag;
void main(void){

if (bootflag!=0xAA){
//
init_lcd();
//
init_rtc();
//
init_hw();
// I/O
reset_queue();
//
bootflag=0xAA;
//
}else{
clear_lcd();
//
}

}
RAM startup.a51
startup.a51
0-14
;----------------------------------------------------------------; This file is part of the C-51 Compiler package
; Copyright (c) KEIL ELEKTRONIK GmbH and Keil Software, Inc.,
; 1990-1992
;-----------------------------------------------------------------; STARTUP.A51:
This code is executed after processor reset.
;
; To translate this file use A51 with the following invocation:
;
; A51 STARTUP.A51
;
; To link the modified STARTUP.OBJ file to your application use
; the following L51 invocation:
;
; L51 <your object file list>, STARTUP.OBJ <controls>
;
;----------------------------------------------------------------;
; User-defined Power-On Initialization of Memory
;
; With the following EQU statements the initialization of memory
; at processor reset can be defined:
;

59

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

EXTRN DATA (bootflag)


;
; the absolute start-address of IDATA memory is always 0
IDATALEN
EQU
80H
; the length of IDATA memory in bytes.
;
XDATASTART EQU
0H
; the absolute start-address of XDATA
; memory
XDATALEN
EQU
0H
; the length of XDATA memory in bytes.
;
PDATASTART EQU
0H
; the absolute start-address of PDATA
; memory
PDATALEN
EQU
0H
; 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 C-51 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
0FFH+1
; set top of stack to highest location+1.
;
; Stack Space for reentrant functions in the LARGE model.
XBPSTACK
EQU
0
; set to 1 if large reentrant is used.
XBPSTACKTOP EQU
0FFFFH+1 ; set top of stack to highest location+1.
;
; Stack Space for reentrant functions in the COMPACT model.
PBPSTACK
EQU
0
; set to 1 if compact reentrant is used.
PBPSTACKTOP EQU
0FFFFH+1 ; set top of stack to highest location+1.
;
;----------------------------------------------------------------;
; 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 the linker invocation.

60

Tel

020

38730916 38730917 38730976 38730977

;
PPAGEENABLE
EQU 0
; set to 1 if pdata object are used.
PPAGE
EQU 0
; define PPAGE number.
;
;----------------------------------------------------------------NAME
?C_STARTUP
?C_C51STARTUP SEGMENT
CODE
?STACK
SEGMENT
IDATA
RSEG ?STACK
DS 1

?C_STARTUP:

EXTRN
PUBLIC
CSEG
LJMP

CODE (?C_START)
?C_STARTUP
AT 0
STARTUP1

RSEG

?C_C51STARTUP

MOV
CJNE
SJMP

A, bootflag
;
A, #0AAH, CLRMEM
CLRCOMP
;
;
;
;

STARTUP1:

CLRMEM:
IF IDATALEN <> 0
MOV
CLR
IDATALOOP:
MOV
DJNZ
JMP
ENDIF

R0,#IDATALEN - 1
A
@R0,A
R0,IDATALOOP
CLRXDATA

CLRCOMP:

CLR

L1:

MOV
MOV
MOV
INC
CJNE

20H, A
R0, #3EH
@R0, A
R0
R0, #76H, L1

RAM is good, clear only


compiler owned locations
RAM was not good,
zero it all

; zero out compiler owned


; areas

CLRXDATA:
IF XDATALEN <> 0
MOV

check if RAM is good

DPTR,#XDATASTART

61

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

MOV
R7,#LOW (XDATALEN)
IF (LOW (XDATALEN)) <> 0
MOV
R6,#(HIGH XDATALEN) +1
ELSE
MOV
R6,#HIGH (XDATALEN)
ENDIF

XDATALOOP:

CLR
MOVX
INC
DJNZ
DJNZ

A
@DPTR,A
DPTR
R7,XDATALOOP
R6,XDATALOOP

ENDIF
IF PDATALEN <> 0
MOV
MOV
CLR
PDATALOOP:
MOVX
INC
DJNZ
ENDIF
IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)
MOV
ENDIF
IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)
MOV
MOV
ENDIF
IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
MOV
ENDIF
IF PPAGEENABLE <> 0
MOV
ENDIF
MOV

R0,#PDATASTART
R7,LOW (PDATALEN)
A
@R0,A
R0
R7,PDATALOOP

?C_IBP,#LOW IBPSTACKTOP

?C_XBP,#HIGH XBPSTACKTOP
?C_XBP+1,#LOW XBPSTACKTOP

?C_PBP,#LOW PBPSTACKTOP

P2,#PPAGE

SP,#?STACK-1

62

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

LJMP
?C_START
END
,

20H 3EH 75H
startup.a51
TYPE BASE LENGTH RELOCATION SEGMENT NAME
----------------------------------------------------* * * * * * * D A T A M E M O R Y * * * * * * *
REG 0000H 0008H ABSOLUTE "REG BANK 0"
DATA 0008H 0012H UNIT
?DT?VARS
DATA 001AH 0001H UNIT
?DT?PUTCHAR
001BH 0005H
*** GAP ***
DATA 0020H 0001H BIT_ADDR ?C_LIB_DBIT
BIT 0021H.0 0000H.5 UNIT
?BI?COINOP
BIT 0021H.5 0001H.2 UNIT
"BIT_GROUP"
0022H.7 0000H.1
*** GAP ***
DATA 0023H 001BH UNIT
?DT?COINOP
DATA 003EH 000FH UNIT
?C_LIB_DATA
DATA 004DH 0029H UNIT
"DATA_GROUP"
IDATA 0076H 001EH UNIT
?ID?COINOP
IDATA 0094H 0001H UNIT
?STACK

RAM RAM EEPROM flash
RAM RAM EEPROM
RAM
SRAM EEPROM
,



13


63

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

8051 C
1

C C
C
2
C C C


C
C51
C C


DATA XDATA
DATA CODE
DATA

0-1
; declare the code segment for the function
?PR?IDCNTL?IDCNTL SEGMENT CODE
; declare the data segment for local storage
; this segment is overlayable for linker optimization
; of memory usage
?DT?IDCNTL?IDCNTL SEGMENT DATA OVERLAYABLE
PUBLIC idcntl
PUBLIC ?idcntl?BYTE
; define the layout of the local data segment
RSEG ?DT?IDCNTL?IDCNTL
?idcntl?BYTE:
TEMP:
DS
1
COUTNT:
DS
1
VAL1:
DS
2
VAL2:
DS
2

idcntl:

RSEG ?PR?IDCNTL?IDCNTL
... ; function code begins here

RET
DATA,
?idcntl?BYTE
C

64

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

3
SRAM 8051
8051
8051
Keil C
0x4050 C

_at_
type [memory_space] variable_name _at_ constant;
,
DATA
unsigned char data byteval _at_ 0x32;
_at_I/O
XDATA0x4500

unsigned char xdata inpreg _at_ 0x4500;


inpreg Keil
C 0-2


256 0-3

0-2
void myfunc(void) {
unsigned char inpval;
inpval=inpreg;
//
inpval=XBYTE[0x4500];
...
if (inpreg & 0x40) {
...
}
}
0-3
;
MOV DPH, #HIGH mytable
MOV DPL, index
CLR A
MOVC A, @A+DPTR
;

8000H DATA

0-4

65

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

;
CSEG AT 8000H
mytable: DB 1, 2, 3, 4, 5, 6, 7, 8
... ;
DSEG AT 70H
cur_field: DS 1
...
END ;
, Cextern
C


C
,
0-5
CSEG AT 023H
LJMP serial_intr

0-6
;
RSEG ?PR?serial_intr?SERIAL
USING 0
serial_intr: PUSH ACC
...
RETI

; 0
;

4 C
C BCD
C C

C
C
C
C
0-7
;
?PR?clrmem?LOWLVL SEGMENT CODE
;
PUBLIC clrmem
;
RSEG ?PR?clrmem?LOWLVL
;*****************************************************************
; Function: CLRMEM

66

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

; Description: RAM
; Parameters:
; Returns: .
; Side Effects: .
;*****************************************************************
clrmem:
MOV R0,#7FH
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
RET
END

PR C51 0-1
RSEG



Keil CRAM
0-1
3

0-2

C
RAM
3

0-8
C code
// C
bit devwait(unsigned char ticks, unsigned char xdata *buf);
// invocation of assembly function
if (devwait(5, &outbuf)) {
bytes_out++;
0-9

;
?PR?_devwait?LOWLVL SEGMENT CODE

67

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

;
PUBLIC _devwait
;
RSEG
?PR?_devwait?LOWLVL
;*****************************************************************
; Function: _devwait
; Description: 0 P1
;
XDATA
; Parameters: R7
; R4|R5 XDATA
; Returns: 1,0
; Side Effects: none.
;*****************************************************************
_devwait: CLR TR0
;0
CLR TF0
MOV TH0, #00
MOV TL0, #00
SETB TR0
JBC TF0, L1
;
JB T1, L2
;
L1:
DJNZ R7, _devwait ; 1
CLR C
CLR TR0
; 0
RET
L2:
MOV DPH, R4
; DPTR
MOV DPL, R5
PUSH ACC
MOV A, P1
;
MOVX @DPTR, A
POP ACC
CLR TR0
; 0
SETB C
;
RET
END

0 1
C51

0-3


0-3

R4R74

68

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925


5
,,
,
asmC
0-10
#include <reg51.h>
extern unsigned char code newval[256];
void func1(unsigned char param) {
unsigned char temp;
temp=newval[param];
temp*=2;
temp/=3;
#pragma asm
MOV P1, R7 ; temp
NOP
;
NOP
NOP
MOV P1, #0
#pragma endasm
}
src,asmendasmSRC
src asmendasm
.src
.obj .src
0-11
; ASMEXAM.SRC generated from: ASMEXAM.C
$NOMOD51
NAME ASMEXAM
P0
P1
P2
P3
T0
AC
T1
EA
IE
RD
ES

DATA
DATA
DATA
DATA
BIT
BIT
BIT
BIT
DATA
BIT
BIT

080H
090H
0A0H
0B0H
0B0H.4
0D0H.6
0B0H.5
0A8H.7
0A8H
0B0H.7
0A8H.4

69

IP
RI
INT0
CY
TI
INT1
PS
SP
OV
WR
SBUF
PCON
SCON
TMOD
TCON
IE0
IE1
B
ACC
ET0
ET1
TF0
TF1
RB8
TH0
EX0
IT0
TH1
TB8
EX1
IT1
P
SM0
TL0
SM1
TL1
SM2
PT0
PT1
RS0
TR0
RS1
TR1
PX0

DATA
BIT
BIT
BIT
BIT
BIT
BIT
DATA
BIT
BIT
DATA
DATA
DATA
DATA
DATA
BIT
BIT
DATA
DATA
BIT
BIT
BIT
BIT
BIT
DATA
BIT
BIT
DATA
BIT
BIT
BIT
BIT
BIT
DATA
BIT
DATA
BIT
BIT
BIT
BIT
BIT
BIT
BIT
BIT

Tel

020

38730916 38730917 38730976 38730977

0B8H
098H.0
0B0H.2
0D0H.7
098H.1
0B0H.3
0B8H.4
081H
0D0H.2
0B0H.6
099H
087H
098H
089H
088H
088H.1
088H.3
0F0H
0E0H
0A8H.1
0A8H.3
088H.5
088H.7
098H.2
08CH
0A8H.0
088H.0
08DH
098H.3
0A8H.2
088H.2
0D0H.0
098H.7
08AH
098H.6
08BH
098H.5
0B8H.1
0B8H.3
0D0H.3
088H.4
0D0H.4
088H.6
0B8H.0

70

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

PX1 BIT
0B8H.2
DPH DATA 083H
DPL DATA 082H
REN BIT
098H.4
RXD BIT
0B0H.0
TXD BIT
0B0H.1
F0
BIT
0D0H.5
PSW DATA 0D0H
?PR?_func1?ASMEXAM SEGMENT CODE
EXTRN CODE (newval)
PUBLIC _func1
;
; #include <reg51.h>
;
; extern unsigned char code newval[256];
;
; void func1(unsigned char param) {
RSEG ?PR?_func1?ASMEXAM
USING 0
_func1:
;---- Variable 'param?00' assigned to Register 'R7' ---; SOURCE LINE # 6
; unsigned char temp;
;
; temp=newval[param];
; SOURCE LINE # 9
MOV A,R7
MOV DPTR,#newval
MOVC A,@A+DPTR
MOV R7,A
;---- Variable 'temp?01' assigned to Register 'R7' ---; temp*=2;
; SOURCE LINE # 10
ADD A,ACC
MOV R7,A
; temp/=3;
; SOURCE LINE # 11
MOV B,#03H
DIV AB
MOV R7,A
;
; #pragma asm
MOV P1, R7 ; write the value of temp out
NOP ; allow for hardware delay

71

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

NOP
NOP
MOV P1, #0 ; clear P1
; #pragma endasm
; }
; SOURCE LINE # 20
RET
; END OF _func1
END
asmendasmSRC

6


C
C

C Keil C
A51




DPTR
0-12
char code bcdmap[60][2]={
"00", "01", "02", "03", "04", "05", "06", "07", "08", "09",
"10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
"20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
"30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
"40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
"50", "51", "52", "53", "54", "55", "56", "57", "58", "59"
};
void disp_time(void) {
static char time_str[32]="TIME OF DAY IS: XX:XX:XX ";
unsigned char i;
time_str[T_HOURT]=bcdmap[timeholder.hour][0];
time_str[T_HOUR]=bcdmap[timeholder.hour][1];
time_str[T_MINT]=bcdmap[timeholder.min][0];
time_str[T_MIN]=bcdmap[timeholder.min][1];
time_str[T_SECT]=bcdmap[timeholder.sec][0];
time_str[T_SEC]=bcdmap[timeholder.sec][1];
putchar(0xFF);

72

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

for (i=0; i<32; i++) {


putchar(time_str[i]);
}
disp_update=0; //
}
bcdmap120
256

0-13
; time_str[T_HOURT]=bcdmap[timeholder.hour][0];
; SOURCE LINE # 214
MOV A,timeholder
ADD A,ACC
ADD A,#LOW bcdmap
MOV DPL,A
CLR A
ADDC A,#HIGH bcdmap
MOV DPH,A
CLR A
MOVC A,@A+DPTR
MOV time_str?42+010H,A
6 bcdmap
DPTR

C C
0-14
Cbcdmap
0-14
CSEG AT 0400H
bcdmap: DB '0' ,'0'
DB '0' ,'1'
DB '0' ,'2'
...
DB '5' ,'7'
DB '5' ,'8'
DB '5' ,'9'
END
0-15
0-15
; time_str[T_HOURT]=bcdmap[timeholder.hour][0];
; SOURCE LINE # 214
MOV A,timeholder
ADD A,ACC
MOV DPL,A

73

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

MOV DPH,#HIGH bcdmap


MOVC A,@A+DPTR
MOV time_str?42+010H,A
11,17
812
6
6 0-16
0-16
getbcd:
ADD A,ACC
MOV DPL,A
MOV DPH,#HIGH bcdmap
MOVC A,@A+DPTR
RET
; time_str[T_HOURT]=bcdmap[timeholder.hour][0];
; SOURCE LINE # 214
MOV A,timeholder
LCALL getbcd
MOV time_str?42+010H,A
getbcddisp_time disp_time

typedef struct
unsigned char hour, min, sec;
} timestruct;
3
0-17
; timeholder=curtime;
; SOURCE LINE # 327
MOV R0,#LOW timeholder
MOV R4,#HIGH timeholder
MOV R5,#04H
MOV R3,#04H
MOV R2,#HIGH curtime
MOV R1,#LOW curtime
MOV R6,#00H
MOV R7,#03H
LCALL ?C_COPY
1611 C_COPY70
3

0-18
; timeholder=curtime;

74

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

; SOURCE LINE # 327


MOV timeholder, curtime
MOV timeholder+1, curtime+1
MOV timeholder+2, curtime+2
66
C

7
,
Intel 8051
3
1
1
0-19
PUSH IE
; IE
MOV IE, #LVL2INTS ; 2
CALL DUMMY_LBL
; RETI
...
;
POP IE
; IE
RET
DUMMY_LBL: RETI
IE IE 2
RETI
PICs(programmable interrupt controllers)
ISR
10


0-4 5

ISRIE
0-4

10 0 0

00
1 13
0-20
EX1_MASK EQU 99H ; 1 0
SER_MASK EQU 89H ; 1 0
T1_MASK EQU 81H ; 0
,
0-21
?PR?EXT1?LOWLVL SEGMENT CODE

75

Tel

EXT1:

PUSH IE
MOV IE, #EX1_MASK
CALL DUMMY_EX1
LCALL ex1_isr
POP IE
RET
DUMMY_EX1: RETI

020

38730916 38730917 38730976 38730977

Fax:38730925

;
;
;
;
;

IE
1 0
RETI
C
IE

;
;
;
;
;

IE
1 0
RETI
C
IE

?PR?SINTR?LOWLVL SEGMENT CODE


SINTR:

PUSH IE
MOV IE, #SER_MASK
CALL DUMMY_SER
LCALL ser_isr
POP IE
RET
DUMMY_SER: RETI
?PR?TMR1?LOWLVL SEGMENT CODE
TMR1:

PUSH IE
; IE
MOV IE, #T1_MASK ; 0
CALL DUMMY_T1
; RETI
LCALL tmr1_isr
; C
POP IE
; IE
RET
DUMMY_T1: RETI
C

8
,



T1 100KHz
2us 3us T1
0-1

76

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0-1
12MHz 1us C
0-22
0-22
;
; void sendbyte(unsigned char);
?PR?_sendbyte?SYS_IO
?DT?_sendbyte?SYS_IO

SEGMENT CODE
SEGMENT DATA OVERLAYABLE

PUBLIC _sendbyte
PUBLIC ?_sendbyte?BYTE
RSEG ?DT?_sendbyte?SYS_IO
?_sendbyte?BYTE:
BITCNT: DS 1
RSEG ?PR?_sendbyte?SYS_IO
_sendbyte: PUSH ACC
;
MOV BITCNT, #8 ; 8
MOV A, R7
;
RLC A
LOOPSTRT:

JC
SETB
CLR
RLC
NOP
NOP
NOP
DJNZ

SETHIGH:

SETB
CLR
SETB
RLC
NOP
CLR
DJNZ
POP

SETHIGH
T1
T1
A

; 2, 9
; 1, 0
; 1, 1
; 1, 2
; 1, 4
; 1, 5
; 1, 6
BITCNT, LOOPSTRT; 2, 7
T1
T1
T1
A

; 1, 0
; 1, 1
; 1, 2 1
; 1, 3
; 1, 4
T1
; 1, 5
BITCNT, LOOPSTRT; 2, 7
ACC
;
77

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

RET
END

101 09


NOP

T1 100KHz


0-23
?PR?_sendbyte?SYS_IO SEGMENT CODE
?DT?_sendbyte?SYS_IO SEGMENT DATA OVERLAYABLE
?BI?_sendbyte?SYS_IO SEGMENT BIT OVERLAYABLE
PUBLIC _sendbyte
PUBLIC ?_sendbyte?BYTE
PUBLIC ?_sendbyte?BIT
RSEG
?_sendbyte?BYTE:
BITCNT:
DS 1
DELVAL:
DS 1

?DT?_sendbyte?SYS_IO

RSEG
?_sendbyte?BIT:
ODD:
DBIT

?BI?_sendbyte?SYS_IO
1

RSEG
?PR?_sendbyte?SYS_IO
_sendbyte: PUSH ACC
;
MOV BITCNT, #8
; 8
CLR C
MOV A, R5
;
CLR ODD
;
JNB ACC.0, P_EVEN
SETB ODD
;
DEC ACC
;
P_EVEN:

SUBB A, #4
RR A
MOV DELVAL, A
MOV R5, A

; 4
; 2 DJNZs

78

Tel

020

38730916 38730917 38730976 38730977

JNB ODD, SEND_EVEN


SEND_ODD: MOV A, R7
RLC A

;
;

LOOP_ODD: JC SETHIGH_O
;
SETB T1
;
CLR T1
;
RLC A
;
NOP
;
NOP
;
MOV R5, DELVAL
;
DJNZ R5, $
;
NOP
;
DJNZ BITCNT, LOOP_ODD

2, 9
1, 0
1, 1
1, 2
1, 3
1, 4
2, 6
2, 8
1, 9
; 2, 11

SETHIGH_O: SETB T1
;
CLR T1
;
SETB T1
;
RLC A
;
NOP
;
MOV R5, DELVAL
;
DJNZ R5, $
;
CLR T1
;
DJNZ BITCNT, LOOP_ODD
POP ACC
;
RET

1, 0
1, 1
1, 2
1, 3
1, 4
2, 6
2, 8
1, 9
; 2, 11

SEND_EVEN: MOV A, R7
RLC A

;
;

LOOP_EVEN: JC SETHIGH_E
; 2,
SETB T1
; 1,
CLR T1
; 1,
RLC A
; 1,
MOV R5, DELVAL
; 2,
DJNZ R5, $
; 2,
NOP
; 1,
NOP
; 1,
DJNZ BITCNT, LOOP_EVEN ;
SETHIGH_E: SETB T1
CLR T1
SETB T1

9
0
1
2
4
6
7
8
2, 10

; 1, 0
; 1, 1
; 1, 2

79

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

RLC A
; 1, 3
MOV R5, DELVAL
; 2, 5
DJNZ R5, $
; 2, 7
CLR T1
; 1, 8
DJNZ BITCNT, LOOP_EVEN ; 2, 10
POP ACC
;
RET
END
DJNZ
2DJNZ
4 5
DJNZ 6
C
9

C

80

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925


1

PC

ICE

2

I/O


RAM
I/O
PCB
PCB
ICE

ICE


I/O
3
ICE

8051


10PC

0-1
#include <reg51.h>
#include <intrins.h>
#ifndef NULL

81

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

#define NULL ((void *) 0L)


#endif
#define DB_MAXSIZE 0x20
unsigned char db_head, db_tail, db_buffer[DB_MAXSIZE];
/*****************************************************************
Function: debug_init
Description: 0
Parameters:
Returns:
*****************************************************************/
void debug_init(void) {
SCON=0x90; 2
db_head=db_tail=0;
ES=1;
}
/*****************************************************************
Function: debug_insert
Description:
Parameters: base
size
Returns:
*****************************************************************/
void debug_insert(unsigned char data *base, unsigned char size) {
bit sendit=0; //
unsigned char i=0;
if (!size || base==NULL) { return; }//
if (db_tail==db_head)
sendit=1;
}
while (db_tail!=db_head && i<size) {//
//
db_buffer[db_tail]=base[i];
//
i++;
db_tail++;
//
if (db_tail==DB_MAXSIZE) {
//
db_tail=0;
}
}
if (sendit) {
//
SBUF=db_buffer[db_head];
}

82

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

}
/*****************************************************************
Function: debug_output
Description:

Parameters:
Returns:
*****************************************************************/
void debug_output(void) interrupt 4 {
RI=0;
if (_testbit_(TI))
db_head++;
if (db_head==DB_MAXSIZE) { //
db_head=0;
}
if (db_head!=db_tail)
SBUF=db_buffer[db_head]; //
}
}
}
,
,
RAM
4RAM RAM

4 Monitor-51

8051
EPROM
Keil C51
Monitor-51
PC PC
MON51.EXE PC
SFRs


SRAM
Monitor-51
2816256XDATA
Monitor-51 install.a51 11.059MHz
9600 8000H
install.a51 PC

83

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

5 I/0
I/O I/0

8 LED








6 ICE
8051

debug
C objectextend

C
ICE


baud




16K
128K

7


EEPROM

84

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925


1



2




1/10




CPU





DPTR

10000



10Hz I/O
10Hz


INT0INT1 8051

3
8051

85

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

3.1

10 1
RETI


3.2



50%













4
3

INT1

P1.0P1.1
,
, INT1
P1.1P1.0
P1.1P1.0

86

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0-1 INT1
0-1

0-1
sbit SLAVE1 = P1^0;
//
sbit SLAVE2 = P1^1;
void int1_isr(void) interrupt 2 {
if (!SLAVE1) {
// slave1
slave1_service();
}
if (!SLAVE2)
slave2_service();
}
}
dowhile

87

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0-2
8000H

0-2
#define INTREG 0x8000
unsigned char bdata intmask; //
sbit signal0 = intmask^0;
//
sbit signal1 = intmask^1;
sbit signal2 = intmask^2;
sbit signal3 = intmask^3;
sbit signal4 = intmask^4;
sbit signal5 = intmask^5;
sbit signal6 = intmask^6;
sbit signal7 = intmask^7;
void int1_isr(void) interrupt 2 {
intmask=XBYTE[INTREG]; //
//
if (signal0) {
//
signal0_isr();
}
...
if (signal7) {
signal7_isr();
}
88

reset_int();

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

//

}







3

8051INT0INT1



6
Intel8051
5 /




T0T1
FFH

0-3
#include <reg51.h>
void main(void) {
...
TMOD=0x66; // /8
TH1=0xFF; //
TH0=0xFF;
TL0=0xFF;
TL1=0xFF;
TCON=0x50; //
IE=0x9F; //
...
}
/*****************************************************************
0
*****************************************************************/
void timer0_int(void) interrupt 1 {

89

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

...
}
/*****************************************************************
1
*****************************************************************/
void timer1_int(void) interrupt 3 {
while (!T1) {
//
...
}
}

T0T1

1
80528051


RXD
2 8
RI UARTISR

0-4
#include <reg51.h>
void main(void) {
...
SCON=0x90; // 2
IE=0x9F; //
...
}
void serial_int(void) interrupt 4 {
if (!_testbit_(RI)) {
...
}
}

5/8
8UART
9 UART RXD

UART

90

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

7








ISR
UART
SBUF
ISR

ISR
20ms

8051
ISR
A/D
10ms

ISR
ISR ISR

8
8051.
8051
8051

91

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

7
1
8051 8051
UART

2 PC
PC
RS-2328051
8051RS-232
PC PCRS-232
PC12V5V

0-1 PC



SBUF SCON



SBUF


SBUF

300K

92

Tel

020

38730916 38730917 38730976 38730977

4
0-2

Fax:38730925

PC

0-2/
RS-232PC 0-3

0-3
PC 0 32


43H

0-1
PC 4
(,,,).:

93

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0-2

0-3

0-4

0-5

0-6

0-7

(FSA) FSA
FSA
94

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925


FSA
CISR
FSA
unsigned char

C

0-4 FSA
9600 1.042ms
11.059MHz 1.085us 960
FSA ISR
0-1
// FSA
#define FSA_INIT
0
#define FSA_ADDRESS 1
#define FSA_COMMAND 2
#define FSA_DATASIZE 3
#define FSA_DATA
4
#define FSA_CHKSUM 5
//
#define SYNC 0x33
#define CLOCK_ADDR 0x43
//
#define CMD_RESET
#define CMD_TIMESYNC
#define CMD_TIMEREQ
#define CMD_DISPLAY
#define CMD_ACK

0x01
0x02
0x03
0x04
0xFF

#define RECV_TIMEOUT 10

/* define the interbyte timeout */

95

unsigned char
recv_state=FSA_INIT,
recv_timer=0,
recv_chksum,
recv_ctr,
recv_buf[35];

Tel

//
//
//
//
//

020

38730916 38730917 38730976 38730977

Fax:38730925

unsigned char code valid_cmd[256]={ //


//
//
0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};

0, 0, 0, // 00 - 0F
0, 0, 0, // 10 - 1F
0, 0, 0, // 20 - 2F
0, 0, 0, // 30 - 3F
0, 0, 0, // 40 - 4F
0, 0, 0, // 50 - 5F
0, 0, 0, // 60 - 6F
0, 0, 0, // 70 - 7F
0, 0, 0, // 80 - 8F
0, 0, 0, // 90 - 9F
0, 0, 0, // A0 - AF
0, 0, 0, // B0 - BF
0, 0, 0, // C0 - CF
0, 0, 0, // D0 - DF
0, 0, 0, // E0 - EF
0, 0, 0, // F0 - FF

/*****************************************************************
: serial_int
: FSAs.
: none.
: nothing.
: none.
*****************************************************************/
void serial_int(void) interrupt 4 {
unsigned char data c;
if (_testbit_(TI)) {
//
}
if (_testbit_(RI)) {
c=SBUF;
switch (recv_state) {
case FSA_INIT:
//

96

Tel

020

38730916 38730917 38730976 38730977

if (c==SYNC) {
//
recv_state=FSA_ADDRESS; //
recv_timer=RECV_TIMEOUT; //
recv_chksum=SYNC;
//
}
break;
case FSA_ADDRESS:
//
if (c==CLOCK_ADDR) {
//
recv_state=FSA_COMMAND; //
recv_timer=RECV_TIMEOUT; //
recv_chksum+=c;
//
} else {
//
recv_state=FSA_INIT;
//
recv_timer=0;
//
}
break;
case FSA_COMMAND:
//
if (!valid_cmd[c]) {
//
recv_state=FSA_INIT;
// FSA
recv_timer=0;
} else {
recv_state=FSA_DATASIZE;
//
recv_chksum+=c;
//
recv_buf[0]=c;
//
recv_timer=RECV_TIMEOUT;
//
}
break;
case FSA_DATASIZE:
//
recv_chksum+=c;
//
recv_buf[1]=c;
//
if (c) {
//
recv_ctr=2;
//
recv_state=FSA_DATA;
//
} else {
recv_state=FSA_CHKSUM;
}
recv_timer=RECV_TIMEOUT;
break;
case FSA_DATA:
//
recv_chksum+=c;
//
recv_buf[recv_ctr]=c;
//
recv_ctr++;
//
if ((recv_ctr-2)==recv_buf[1]) { //
// datasize

97

Fax:38730925

Tel

020

recv_state=FSA_CHECKSUM;
}
recv_timer=RECV_TIMEOUT;
break;
case FSA_CHECKSUM:
if (recv_chksum==c) {
c=1;
switch (recv_buf[0]) {
case CMD_RESET:
break;
case CMD_TIMESYNC:
break;
case CMD_TIMEREQ:
break;
case CMD_DISPLAY:
break;
}
if (c) {
//
}
}
default:
recv_timer=0;
recv_state=FSA_INIT;
break;
}

38730916 38730917 38730976 38730977

Fax:38730925

//
//
//
//
//
//
//

//
//
// ASCII

// FSA

}
}
0-4

PC ,PC


SBUF SBUF

0-2
//
#define SYNC
0x33
#define CLOCK_ADDR 0x43
unsigned char
trans_buf[7],
trans_ctr,

//
//

98

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

trans_size,
//
trans_chksum;
//
/*****************************************************************
: serial_int
FSAs
: .
: .
: .
*****************************************************************/
void serial_int(void) interrupt 4 {
unsigned char data c;
if (_testbit_(TI)) {
//
trans_ctr++;
//
if (trans_ctr<trans_size) { //
if (trans_ctr==(trans_size-1)) { //
SBUF=trans_chksum;
} else {
SBUF=trans_buf[trans_ctr];
//
trans_chksum+=trans_buf[trans_ctr]; //
}
}
}
if (_testbit_(RI)) {
c=SBUF;
switch (recv_state) {
// FSAs
case FSA_CHECKSUM:
//
if (recv_chksum==c) {
//
c=1;
// c
switch (recv_buf[0]) {
//
case CMD_RESET:
//
break;
case CMD_TIMESYNC:
//
break;
case CMD_TIMEREQ:
//
c=0;
break;
case CMD_DISPLAY:
// ASCII
break;
}
if (c) {
//
trans_buf[0]=SYNC;
//
trans_buf[1]=CLOCK_ADDR;
trans_buf[2]=CMD_ACK;

99

Tel

020

38730916 38730917 38730976 38730977

trans_buf[3]=1;
trans_buf[4]=recv_buf[1];//
trans_ctr=0;
//
trans_size=6;
//
SBUF=SYNC;
//
trans_chksum=SYNC;
//
}

Fax:38730925

}
default:
recv_timer=0;
recv_state=FSA_INIT;
break;
}
}
}
ISR

ISR



PCLCD

PC




ISR
0-3
//
#define FSA_INIT
0
#define FSA_ADDRESS
1
#define FSA_COMMAND
2
#define FSA_DATASIZE
3
#define FSA_DATA
4
#define FSA_CHKSUM
5
//
#define SYNC 0x33
#define CLOCK_ADDR 0x43
//

100

#define
#define
#define
#define
#define
#define

CMD_RESET
CMD_TIMESYNC
CMD_TIMEREQ
CMD_DISPLAY
CMD_ACK
RECV_TIMEOUT

Tel

020

38730916 38730917 38730976 38730977

0x01
0x02
0x03
0x04
0xFF
10 /* */

unsigned char
recv_state=FSA_INIT,
recv_timer=0,
recv_chksum,
recv_size,
recv_ctr
recv_buf[35];

//
//
//
//
//
//

unsigned char
trans_buf[7],
trans_ctr,
trans_size,
trans_chksum;

//
//
//
//

unsigned
0, 1, 1,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
};

char code valid_cmd[256]={


1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,

//
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,

1
0, 0, 0, // 00 - 0F
0, 0, 0, // 10 - 1F
0, 0, 0, // 20 - 2F
0, 0, 0, // 30 - 3F
0, 0, 0, // 40 - 4F
0, 0, 0, // 50 - 5F
0, 0, 0, // 60 - 6F
0, 0, 0, // 70 - 7F
0, 0, 0, // 80 - 8F
0, 0, 0, // 90 - 9F
0, 0, 0, // A0 - AF
0, 0, 0, // B0 - BF
0, 0, 0, // C0 - CF
0, 0, 0, // D0 - DF
0, 0, 0, // E0 - EF
0, 0, 0, // F0 - FF

/*****************************************************************
: serial_int
: FSAs.
: .

101

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

.
.
*****************************************************************/
void serial_int(void) interrupt 4 {
unsigned char data c;
if (_testbit_(TI)) {
//
trans_ctr++;
// 1
if (trans_ctr<trans_size) { //
if (trans_ctr==(trans_size-1)) { //
SBUF=trans_chksum;
} else {
SBUF=trans_buf[trans_ctr]; //
trans_chksum+=trans_buf[trans_ctr]; // u
}
}
}
if (_testbit_(RI)) {
c=SBUF;
switch (recv_state) {
case FSA_INIT:
if (c==SYNC) {
//
recv_state=FSA_ADDRESS; //
recv_timer=RECV_TIMEOUT;
recv_chksum=SYNC;
}
break;
case FSA_ADDRESS:
if (c==CLOCK_ADDR) { //
recv_state=FSA_COMMAND;
recv_timer=RECV_TIMEOUT;
recv_chksum+=c;
} else { //
recv_state=FSA_INIT; //
recv_timer=0;
}
break;
case FSA_COMMAND:
if (!valid_cmd[c]) { //
recv_state=FSA_INIT; /
recv_timer=0;
} else {
recv_state=FSA_DATASIZE;
recv_chksum+=c;
recv_buf[0]=c;
// s

102

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

recv_timer=RECV_TIMEOUT;
}
break;
case FSA_DATASIZE:
//
recv_chksum+=c;
recv_buf[1]=c;
if (c) {
//
recv_ctr=2;
recv_state=FSA_DATA;
} else {
recv_state=FSA_CHKSUM;
}
recv_timer=RECV_TIMEOUT;
break;
case FSA_DATA: //
recv_chksum+=c;
recv_buf[recv_ctr]=c; //
recv_ctr++;
if ((recv_ctr-2)==recv_buf[1]) { //
recv_state=FSA_CHECKSUM;
}
recv_timer=RECV_TIMEOUT;
break;
case FSA_CHECKSUM: // reading in checksum
if (recv_chksum==c) { //
memcpy(msg_buf, recv_buf, recv_buf[1]+2);
msg_buf_valid=1;
}
default: //
recv_timer=0;
recv_state=FSA_INIT;
break;
}
}
}
ISR

0-4
/*****************************************************************
Function: execute_cmd
Description:
Parameters: .
Returns: .
Side Effects: .

103

Tel

020

38730916 38730917 38730976 38730977

*****************************************************************/
void execute_cmd(void) {
bit need_ack=1;
switch (recv_buf[0])
case CMD_RESET:
//
EA=0; //
curtime.sec=curtime.min=curtime.hour=0;
timeholder=curtime;
EA=1; //
break;
case CMD_TIMESYNC: //
EA=0;
curtime.hour=recv_buf[3];
curtime.min=recv_buf[4];
curtime.sec=recv_buf[5];
timeholder=curtime;
EA=1;
break;
case CMD_TIMEREQ: //
trans_buf[0]=SYNC;
trans_buf[1]=CLOCK_ADDR;
trans_buf[2]=CMD_TIMEREQ; //
trans_buf[3]=3;
EA=0;
trans_buf[4]=curtime.hour;
trans_buf[5]=curtime.min;
trans_buf[6]=curtime.sec;
EA=1;
trans_ctr=0;
trans_size=8; // 8
need_ack=0;
break;
case CMD_DISPLAY: // ASCII
recv_buf[34]=0; //
printf("\xFF%s", &recv_buf[2]); //
display_time=100;
break;
}
if (need_ack) { //
trans_buf[0]=SYNC;
trans_buf[1]=CLOCK_ADDR;
trans_buf[2]=CMD_ACK;
trans_buf[3]=1;
trans_buf[4]=recv_buf[0];

104

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

trans_ctr=0; //
trans_size=6;
}
SBUF=SYNC; //
trans_chksum=SYNC; //
/*****************************************************************
Function:
Description: 8051

Parameters: .
Returns: .
*****************************************************************/
void main(void) {
disp_init();
//
TMOD=0x21;
// 016 1
//
TCON=0x55;
//
TH1=0xFD;
// 19600
SCON=0x50;
// 1
IE=0x92;
// 0
for (;;) {
if (_testbit_(msg_buf_valid)) { //
execute_cmd();
//
}
if (disp_update) {
disp_time();
//
}
PCON=0x01;
//
}
}

PC

3 I/O
PC
PC
8051 PC

105

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0-5
11.059MHz
PC

0-6 8051
8051 UART2 345593.75baud
9600
31.829us 30
1.04ms
80512 8


1


0

0-5
//
#define SYNC
0x33
#define CLOCK_ADDR 0x43

106

//
#define CMD_RESET
#define CMD_TIMESYNC
#define CMD_TIMEREQ
#define CMD_DISPLAY
#define CMD_ACK

Tel

020

38730916 38730917 38730976 38730977

0x01
0x02
0x03
0x04
0xFF

// 128
#define TO_VAL
0x80
unsigned char data recv_chksum,
//
recv_buf[35];
//
unsigned char trans_buf[7],
//
trans_ctr,
//
trans_size,
//
trans_chksum;
//
unsigned char code
0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00 - 0F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10 - 1F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 - 2F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 30 - 3F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40 - 4F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 50 - 5F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60 - 6F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 70 - 7F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80 - 8F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90 - 9F
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A0 - AF
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B0 - BF
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C0 CF
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D0 - DF
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E0 - EF
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F0 - FF
};
/*****************************************************************
Function: ser_xmit
Description: .
Parameters: none.
Returns: nothing.
Side Effects: none.
*****************************************************************/
void ser_xmit(void) {
trans_ctr++;
//

107

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

if (trans_ctr<trans_size) {
//
if (trans_ctr==(trans_size-1)) { //
SBUF=trans_chksum;
} else {
SBUF=trans_buf[trans_ctr];
//
trans_chksum+=trans_buf[trans_ctr]; //
}
}
}
/*****************************************************************
Function: push_msg
Description:
Parameters: none.
Returns: nothing.
Side Effects: none.
*****************************************************************/
void push_msg(void) {
memcpy(msg_buf, recv_buf, recv_buf[1]+2);
msg_buf_valid=1;
//
recv_chksum=SYNC+CLOCK_ADDR;
}
/*****************************************************************
Function: execute_cmd
Description:
Parameters: none.
Returns: nothing.
Side Effects: none.
*****************************************************************/
void execute_cmd(void) {
bit need_ack=1;
switch (recv_buf[1])
case CMD_RESET:
//
EA=0;
//
curtime.sec=curtime.min=curtime.hour=0;
timeholder=curtime;
EA=1;
break;
case CMD_TIMESYNC:
//
EA=0;
curtime.hour=recv_buf[3];
curtime.min=recv_buf[4];
curtime.sec=recv_buf[5];
timeholder=curtime;
EA=1;

108

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

break;
case CMD_TIMEREQ:
//
trans_buf[0]=SYNC;
trans_buf[1]=CLOCK_ADDR;
trans_buf[2]=CMD_TIMEREQ;
trans_buf[3]=3;
EA=0;
trans_buf[4]=curtime.hour;
trans_buf[5]=curtime.min;
trans_buf[6]=curtime.sec;
EA=1;
trans_ctr=0;
trans_size=8;
// 8
need_ack=0;
break;
case CMD_DISPLAY:
// ASCII
recv_buf[34]=0;
printf("\xFF%s", &recv_buf[2]); //
display_time=100;
// 5
break;
}
if (need_ack) {
//
trans_buf[0]=SYNC;
trans_buf[1]=CLOCK_ADDR;
trans_buf[2]=CMD_ACK;
trans_buf[3]=1;
trans_buf[4]=recv_buf[1];
trans_ctr=0;
trans_size=6;
// 6
}
SBUF=SYNC;
//
trans_chksum=SYNC;
//
}
/****************************************************************
Function: main
Description: 8051

Parameters: None.
Returns: Nothing.
****************************************************************/
void main(void) {
disp_init();
//
TH1=TO_VAL;
//

109

Fax:38730925

TMOD=0x21;

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

// 18
// 016

TCON=0x15;
SCON=0xB0;
// UART2
IE=0x92;
//
for (;;) {
if (_testbit_(msg_buf_valid))
execute_cmd();
}
if (disp_update) {
disp_time(); //
}
PCON=0x01;
//
}
}

0-7 FSA

push_message ISR

TI Cser_xmit

ISR 0
FSA 0-7

UART2
SBUF30
30

0-6
EXTRN DATA (recv_chksum) ;
EXTRN DATA (recv_buf)
;
EXTRN CODE (ser_xmit)
;
EXTRN CODE (valid_cmd) ;

110

EXTRN CODE (push_msg)

Tel

020

38730916 38730917 38730976 38730977

SYNC
EQU
33H
CLK_ADDR EQU
43H
CSEG
AT
23H
ORG
23H
LJMP SER_INTR ;
PUBLIC
SER_INTR
?PR?SER_INTR?SER_INTR SEGMENT CODE
RSEG ?PR?SER_INTR?SER_INTR
;*****************************************************************
; Function: readnext
; Description:
; Parameters: none.
; Returns: R0
; Side Effects: none.
;*****************************************************************
readnext:
CLR C
;
MOV TL1, TH1
; T1
SETB TR1
RN_WAIT:
JBC RI, RN_EXIT
; RI ,
JBC TF1, RN_TO
;
RN_TO:
SETB C
;
CLR TR1
RET
RN_EXIT:
MOV A, SBUF
CLR TR1
RET
;*****************************************************************
; Function: SER_INTR
; Description: 8051
; Parameters: none.
; Returns: nothing.
; Side Effects: none.
;*****************************************************************
SER_INTR: JBC RI, RECV_INT ;
CHK_XMIT: JBC TI, XMIT_INT ;
RETI
XMIT_INT: LCALL ser_xmit
RETI
;
;
;

111

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

CHK_XMIT3: POP
POP
CHK_XMIT2: POP
CHK_XMIT1: POP
SETB
JMP
RECV_INT: PUSH
MOV
CJNE

DPL
DPH
00H
ACC
SM2
CHK_XMIT
;
ACC
A, SBUF
;
A, #SYNC, CHK_XMIT1 ;
;
CLR SM2
;
PUSH 00H
MOV R0, #recv_buf
; R0
CALL readnext
;
JC CHK_XMIT2
;
CJNE A, #CLK_ADDR, CHK_XMIT2 ;
CALL readnext
JC CHK_XMIT2
PUSH DPH
PUSH DPL
MOV DPTR, #valid_cmd
;
MOVC A, @A+DPTR
;
JZ CHK_XMIT3
; 1
;
MOV @R0, A
;
ADD A, recv_chksum
;
MOV recv_chksum, A
INC R0
;
CALL readnext
;
JC CHK_XMIT3
MOV @R0, A
;
ADD A, recv_chksum
MOV recv_chksum, A
MOV A, @R0
; 0
;
JZ RECV_CHK
MOV DPL, A
;
RECV_DATA: INC R0
;
CALL readnext
JC CHK_XMIT3
ADD A, recv_chksum
MOV recv_chksum, A
DJNZ DPL, RECV_DATA
;
RECV_CHK: CALL readnext

112

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

JC CHK_XMIT3
CJNE A, recv_chksum, CHK_XMIT3 ;
CALL push_msg
;
JMP CHK_XMIT3
END

_readnext

readnext




4
8051 8051PC PC
RS-232
National Semiconductor
UART

113

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

8051
1
8
PC PC
PC PC
PC
PCRS-232
PC960010

RS-232UART
8051UART
PC
UART 12V


PC
PC
PC
PC
PC
0-1

0-1
PC
9600 8 PC
8
8
9600

114

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

9600 C
300K
30
9600

0-1
/*****************************************************************
Function: ser_9600
Description: 9600
Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
void ser_9600(void) {
if (_testbit_(TI)) {
//
ser_xmit();
}
if (_testbit_(RI)) {
//
ser_recv();
}
}
/*****************************************************************
Function: ser_recv
Description: 9600
Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
void ser_recv(void) {
unsigned char c, temp;
c=SBUF;
switch (recv_state) {
case FSA_INIT:
//
if (c==SYNC) {
//
recv_state=FSA_ADDRESS;
//
recv_timeout=RECV_TIMEOUT; //
recv_chksum=SYNC;
//
}
break;
case FSA_ADDRESS:
//
if (c==SM_ADDR) {
//
recv_state=FSA_COMMAND;
//
recv_timeout=RECV_TIMEOUT; //
recv_chksum+=c;
//

115

Tel

020

38730916 38730917 38730976 38730977

} else {
//
recv_state=FSA_INIT;
//
recv_timeout=0;
}
break;
case FSA_COMMAND:
//
if (!valid_cmd[c]) {
//
recv_state=FSA_INIT;
//
recv_timeout=0;
} else {
recv_state=FSA_DATASIZE;
//
recv_chksum+=c;
//
recv_buf[0]=c;
//
recv_timeout=RECV_TIMEOUT; //
}
break;
case FSA_DATASIZE:
//
recv_chksum+=c;
recv_buf[1]=c;
//
if (c) {
//
recv_ctr=2;
//
recv_state=FSA_DATA; //
}else {
recv_state=FSA_CHKSUM; //
}
recv_timeout=RECV_TIMEOUT;
break;
case FSA_DATA:
//
recv_chksum+=c;
recv_buf[recv_ctr]=c;
// save data byte
recv_ctr++;
//
if ((recv_ctr-2)==recv_buf[1]) { //
recv_state=FSA_CHKSUM;
}
recv_timeout=RECV_TIMEOUT;
break;
case FSA_CHKSUM:
if (recv_chksum==c)
push_msg();
}
default:
recv_timeout=0;
recv_state=FSA_INIT;
break;

116

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

}
}
/*****************************************************************
Function: ser_xmit
Description:
Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
void ser_xmit(void) {
trans_ctr++;
// 1
//
if (trans_ctr < ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head].size) {
//
if (trans_ctr == (ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head]
.size-1)) {
SBUF=trans_chksum;
} else {
//
SBUF=ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head].buf[trans_ctr];
//
trans_chksum+=ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head]
.buf[trans_ctr];
}
} else {
//
//
//
if (!ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head].retries) {
if (queue_pop(XMIT_QUEUE)) {
//
check_stat();
}
} else {
xmit_timeout=XMIT_TIMEOUT;
//
}
}
}

0-2
; : SERINTR.A51

117

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

EXTRN DATA (uart_mode)


; SCON
EXTRN BIT (baud_9600)
; 9600
EXTRN DATA (recv_chksum)
;
EXTRN DATA (recv_buf)
;
EXTRN CODE (ser_xmit)
;
EXTRN CODE (valid_cmd)
;
EXTRN CODE (push_msg)
;
EXTRN CODE (ser_9600)
;
SYNC EQU
33H
;
SM_ADDR EQU 40H
;
CSEG
AT
23H
ORG
23H
LJMP
SER_INTR
PUBLIC SER_INTR
?PR?SER_INTR?SER_INTR SEGMENT CODE
RSEG
?PR?SER_INTR?SER_INTR
;*****************************************************************
; Function: readnext
; Description:
; returns.
; Parameters: .
; Returns: R0
; Side Effects: .
;*****************************************************************
readnext: CLR C ; clear the return flag
MOV TL1, TH1
; T1
SETB TR1
;
RN_WAIT: JBC RI, RN_EXIT ;
JBC TF1, RN_TO
;
RN_TO:
SETB C
;
CLR TR1
;
RET
RN_EXIT: MOV A, SBUF
CLR TR1
RET
;*****************************************************************
; Function: SER_INTR
; Description: 8051
; Parameters: .
; Returns: .
; Side Effects: .
;*****************************************************************
SER_INTR: JNB baud_9600, FAST_ISR ;
LCALL ser_9600

118

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

RETI
FAST_ISR: JBC
CHK_XMIT: JBC
RETI

RI, RECV_INT
TI, XMIT_INT

XMIT_INT: LCALL ser_xmit


RETI

;
;

;
;
;
;

CHK_XMIT3: POP
POP
CHK_XMIT2: POP
CHK_XMIT1: POP
MOV
JMP

DPL
DPH
00H
ACC
SCON, uart_mode
CHK_XMIT

RECV_INT: PUSH ACC


MOV A, SBUF
CJNE A, #SYNC, CHK_XMIT1

;
;
;
;
PUSH 00H
; R0
MOV R0, #recv_buf
; R0
CALL readnext
;
CJNE A, #SM_ADDR, CHK_XMIT2 ;
CLR SM2
;
CALL readnext
;
PUSH DPH
; DPTR
PUSH DPL
MOV DPTR, #valid_cmd
;
MOVC A, @A+DPTR
JZ CHK_XMIT3
; 0
;
MOV @R0, A
;
ADD A, recv_chksum
;
MOV recv_chksum, A
INC R0
;
CALL readnext
;
MOV @R0, A
;
ADD A, recv_chksum
;
MOV recv_chksum, A
MOV A, @R0
; 0
;

119

Tel

020

38730916 38730917 38730976 38730977

JZ RECV_CHK
MOV DPL, A
RECV_DATA: INC R0
CALL readnext
ADD A, recv_chksum
MOV recv_chksum, A
DJNZ DPL, RECV_DATA
RECV_CHK: CALL readnext
CJNE A, recv_chksum, CHK_XMIT3
LCALL push_msg

Fax:38730925

;
; 1

;
;
;
;
;

JMP CHK_XMIT3
END



0-3
/****************************************************************
Function: system_tick
Description: 0 50ms

Parameters: .
Returns: .
*****************************************************************/
void system_tick(void) interrupt 1 {
TR0=0;
//
TH0=RELOAD_HIGH; //
TL0=RELOAD_LOW;
TR0=1;
//
if (poll_time) { //
poll_time--;
if (!poll_time) {
poll_time=POLL_RATE;
start_poll(); //
}
}
if (xmit_timeout) { //
//
xmit_timeout--;
if(!xmit_timeout) { //
ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head].retries--;
if (ser_queue[XMIT_QUEUE]

120

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

.entry[ser_queue[XMIT_QUEUE].head].retries) {
//
SCON=uart_mode=ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head]
.uart_mode;
ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head]
.status=STAT_SENDING;
SBUF=ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head].buf[0];
trans_ctr=0;
//
//
trans_size=ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head].size;
//
trans_chksum=ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head]
.buf[0];
} else {
// 0
//
if (queue_pop(XMIT_QUEUE)) { //
//
//
// UART
// UART
// UART
check_stat();
//
} else {
// UART
// PC
TH1=TO9600_VAL;
TR1=0;
TL1=TH1;
// UART
//
TF1=0;
TR1=1;
baud_9600=1;
P1=0x09;
// PC I/O
}
}
}
}
if (recv_timeout) {
recv_timeout--;
if (!recv_timeout) {

//
// ...

121

recv_state=FSA_INIT;
check_stat();

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

// FSA

}
}
}
/*****************************************************************
Function: start_poll
Description:
Parameters: .
Returns: .
*****************************************************************/
void start_poll(void) {
unsigned char i, temp;
//
for (i=0; i<NUM_SLAVES; i++) {
temp=queue_push(XMIT_QUEUE);
//
if (temp!=0xFF) {
//
//
memcpy(ser_queue[XMIT_QUEUE].entry[temp].buf,
slave_buf[i],
slave_buf[i][3]+4);
//
ser_queue[XMIT_QUEUE].entry[temp].size=slave_buf[i][3]+5;
// 3
ser_queue[XMIT_QUEUE].entry[temp].retries=3;
//
ser_queue[XMIT_QUEUE].entry[temp].uart_mode=BAUD_300K;
//
ser_queue[XMIT_QUEUE].entry[temp].status=STAT_WAITING;
}
}
check_stat();
//
// UART
}
1 9600 1
0 300K
1 1
1
9600 TH11
9600

122

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925


UART
0-4
Listing 0-4
/*****************************************************************
Function: check_stat
Description:

Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
void check_stat(void) {
if (ser_queue[XMIT_QUEUE].head!=UNUSED) {//
// ...
//
if (ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head]
.status == STAT_WAITING) {
//
//
if (recv_state==FSA_INIT ||
(uart_mode == ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head]
.uart_mode)) {
//
SCON=uart_mode=ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head]
.uart_mode;
if (uart_mode==BAUD_300K) {
// 1
//
TH1=TO300K_VAL;
baud_9600=0;
P1=0x06;
// I/O
} else {
TH1=TO9600_VAL;
TR1=0;
TL1=TH1;
// UART
//
TF1=0;
TR1=1;
baud_9600=1;

123

Tel

020

38730916 38730917 38730976 38730977

P1=0x09;

Fax:38730925

// PC I/O

}
ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head]
.status=STAT_SENDING;
SBUF=ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head].buf[0];
trans_ctr=0;
//
trans_size=ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head].size;
trans_chksum=ser_queue[XMIT_QUEUE]
.entry[ser_queue[XMIT_QUEUE].head].buf[0];
}
}
}
}

, PC
PC
PC

0-5
Listing 0-5
/*****************************************************************
Function: push_msg
Description: 9600,
T1
Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
void push_msg() {
unsigned char temp;
temp=queue_push(RECV_QUEUE);
//
if (temp!=0xFF) {
//
//
memcpy(ser_queue[RECV_QUEUE].entry[temp].buf, recv_buf,
recv_buf[1]+2);
//
ser_queue[RECV_QUEUE].entry[temp].size=recv_buf[1]+2;
//
ser_queue[RECV_QUEUE].entry[temp].status=STAT_IDLE;
// 0
ser_queue[RECV_QUEUE].entry[temp].retries=0;

124

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

//
ser_queue[RECV_QUEUE].entry[temp].uart_mode=uart_mode;
}
recv_chksum=SYNC+SM_ADDR;
recv_state=FSA_INIT;
check_stat();

//
//
//

}
/*****************************************************************
Function: ser_exec
Description: .
Parameters: .
Returns: .
*****************************************************************/
void ser_exec() {
#ifdef USEEXEC
do {
switch (ser_queue[RECV_QUEUE].entry[head].buf[1]) {
...
}
} while (ser_queue(RECV_QUEUE)); //
#endif
check_stat();
//

}
2
entries
entry
UART UART
UART

0-6
typedef struct {
//
unsigned char buf[MSG_SIZE]; //
unsigned char size,
//
retries,
//
uart_mode,
// UART
status;
//
} entry_type;
typedef struct {
//
unsigned char head,
//
tail;
//
entry_type
entry[QUEUE_SIZE]; // entry

125

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

} queue_type;
extern queue_type ser_queue[2];//
Keil


0-7
/*****************************************************************
Function: queue_push
Description: entry
Parameters: queue - unsigned char. .
Returns: 0xFF
Side Effects: none.
*****************************************************************/
unsigned char queue_push(unsigned char queue) {
unsigned char temp;
if (ser_queue[queue].head==UNUSED) { //
// 0
ser_queue[queue].head=ser_queue[queue].tail=0;
return 0;
}
temp=ser_queue[queue].tail;
//
// 1
ser_queue[queue].tail=(ser_queue[queue].tail+1) % QUEUE_SIZE;
//
if (ser_queue[queue].head == ser_queue[queue].tail) {
ser_queue[queue].tail=temp;
//
return 0xFF;
}
return ser_queue[queue].tail;
//
}
/*****************************************************************
Function: queue_pop
Description:
Parameters: queue - unsigned char.
Returns: 0 1
Side Effects: .
*****************************************************************/
bit queue_pop(unsigned char queue) {
// 1
ser_queue[queue].head=(ser_queue[queue].head+1) % QUEUE_SIZE;
//

126

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

//
if (((ser_queue[queue].head-ser_queue[queue].tail)==1) ||
(!ser_queue[queue].head &&
(ser_queue[queue].tail==QUEUE_SIZE-1))) {
ser_queue[queue].head=ser_queue[queue].tail=UNUSED;
return 0;
}
return 1;
}

PC
PC

3 TDMA


0-2
PC
PC 9600

1 2n 1

TDMA Time Divion-Multiple Access


50ms
51
TDMA

127

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

TDMA 8DIPP1
TDMA
50ms
12
12 22
2
2
12

5 50ms
3

0-8
/*****************************************************************
Function: main
Description: .8051,

Parameters: .
Returns: .
*****************************************************************/
void main(void) {
slotnum=P1 & 0x0F;
//
slottot=P1 / 16;
//
TH1=TO9600_VAL;
// 1
TH0=RELHI_50MS;
// 0
TL0=RELLO_50MS;
TMOD=0x21;
// 016
// 8
TCON=0x55;
//
//
SCON=BAUD_9600;
// UART 2
IE=0x92;
// 0
//
init_queue();
//
for (;;) {
if (tick_flag) {
//
system_tick();
}
if (rcv_queue.head!=UNUSED) { //
ser_exec();
//
}
PCON=0x01;
//

128

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

}
}
0 system_tick
0 ISR

0-9
EXTRN BIT
(tick_flag)
;
EXTRN CODE (start_xmitt) ; ...
EXTRN XDATA (curslot)
;
; 11.059MHz50ms
; 9
REL_HI EQU
04CH
REL_LOW EQU
007H
SEG

AT
ORG
LJMP

0BH
0BH
T0_INTR

PUBLIC T0_INTR
?PR?T0_INTR?T0INT
SEGMENT CODE
RSEG ?PR?T0_INTR?T0INT
;*****************************************************************
; Function: T0_INTR
; Description: 0 50ms
;
; Parameters: .
; Returns: .
; Side Effects: .
;*****************************************************************
T0_INTR:
CLR TR0
; 1, 3 0
MOV TH0, #REL_HI
; 2, 5
MOV TL0, #REL_LOW
; 2, 7
CLR TF0
; 1, 8
SETB TR0
; 1, 9
SETB tickflag
;
LCALL check_slot
;
PUSH
PUSH
PUSH
PUSH

ACC
B
DPH
DPL

MOV DPTR, #curslot

129

Tel

MOVX A, @DPTR
INC A
MOV B, A
MOV A, P1
SWAP A
ANL A, #00FH
XCH A, B
CLR C
SUBB A, B
JC L1
CLR A
MOVX @DPTR, A
L1:

L2:

MOVX A, @DPTR
MOV B, A
MOV A, P1
ANL A, #00FH
CLR C
SUBB A, B
JNZ L2
LCALL start_xmit
POP DPL
POP DPH
POP B
POP ACC
RETI

020

38730916 38730917 38730976 38730977

; 1
;

;
; >=
; curslot

;
;

; curslot==slotnum
;
; curslot==slotnum,

END
C
0-10
/*****************************************************************
Function: system_tick
Description: .

Parameters: .
Returns: .
*****************************************************************/
void system_tick(void) {
unsigned char i;
tick_flag=0;
//
for (i=0; i<MAX_MSG; i++)
if (xmit_timeout[i][0]) {

// see if the msg timed out

130

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

xmit_timeout[i][0]--;
if (!xmit_timeout[i][0]) {
// if so, check retries
check_msg(xmit_timeout[i][1]);
}
}
}
if (recv_timeout) {
recv_timeout--;
if (!recv_timeout) {
recv_state=FSA_INIT;
check_stat();
}

//
//
// ...

}
}


0





0-11
/*****************************************************************
Function: start_xmit
Description:
Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
void start_xmit(void) {
unsigned char maxbytes=45,
//
msgnum=0,
//
i;
if (tq_head == UNUSED) {
//
return;
}
while (maxbytes) {
//
if (maxbytes>=tq[temp].size) {
//
//

131

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

for (i=0, chksum=0, trans_size=0;


i<tq[temp].size;
i++, trans_size++) {
trans_buf[trans_size]=tq[temp].buf[i];
chksum+=tq[temp].buf[i];
}
trans_buf[trans_size]=chksum;
//
xmit_timeout[msgnum][0]=MSG_TIMEOUT; //
xmit_timeout[msgnum][1]=tq[temp].retries;
msgnum++;
// 1
maxbytes-=tq[temp].size+1;
// reduce amount remaining by
// amount used
temp=tq[temp].next;
} else {
maxbytes=0;
//
}
}
}
/*****************************************************************
Function: ser_xmit
Description:
Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
void ser_xmit(void) {
trans_ctr++;
// 1
//
if (trans_ctr < trans_size) {
//
if (trans_ctr==trans_size-1)) {
SBUF=trans_chksum;
} else {
//
SBUF=trans_buf[trans_ctr];
//
trans_chksum+=trans_buf[trans_ctr];
}
}
}

3 23
123

132

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

entry
entris


0-12
0-12
/*****************************************************************
Function: tq_init
Description:
Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
void tq_init(void) {
tq_head=tq_tail=UNUSED;
//
tq_free=0;
//
for (i=0; i<QUEUE_SIZE; i++) {
tq[i].next=i+1;
}
tq[QUEUE_SIZE-1].next=UNUSED;
//
}
/*****************************************************************
Function: tq_push
Description:
Parameters: .
Returns: 0xFF
Side Effects: .
*****************************************************************/
unsigned char tq_push(void) {
unsigned char temp;
if (tq_free==UNUSED) {
// ...
return UNUSED;
//
}
temp=tq_free;
//
tq_free=tq[tq_free].next;
//
tq[temp].next=UNUSED;
//
//
tq[tq_tail].next=temp;
//
//
tq_tail=temp;
return temp;
//
}

133

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

/*****************************************************************
Function: tq_pop
Description: .
Parameters: entry - unsigned char.
Returns: 0 , 1
Side Effects: .
*****************************************************************/
bit tq_pop(unsigned char entry) {
unsigned char temp, trail;
if (tq_head==UNUSED || entry>(QUEUE_SIZE-1)) {
//
//
return (tq_head==UNUSED) ? 0 : 1;
}
if (entry==tq_head) {

//
//

temp=tq_head;
tq_head=tq[tq_head].next;
//
tq[temp].next=tq_free;
//
tq_free=temp;
} else {
temp=trail=tq_head;
//
while (temp!=entry && temp!=UNUSED) { //
//
trail=temp;
temp=tq[temp].next;
}
if (temp!=UNUSED) {
// ...
tq[trail].next=tq[temp].next;
//
tq[temp].next=tq_free;
//
tq_free=temp;
if (temp==tq_tail) {
tq_tail=trail;
}
}
}
return (tq_head==UNUSED) ? 0 : 1;
}
3
TDMA


PC

134

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0
8051INT0 ISR0
PC
0
0-13
/*****************************************************************
Function: start_tdma
Description:
0
Parameters: .
Returns: .
*****************************************************************/
void start_tdma(void) interrupt 0 {
TH0=RELHI_50MS;
// 0
TL0=RELLO_50MS;
TF0=0;
TR0=1;
curslot=0xFF;
// 0
}

PC 0
PC
PC
PC
PC
TDMA
PC
4 CSMA
TDMA

TDMA

TDMA



CSMA Carrier Sense-Multiple Access CSMA

8051CSMA 8051
8052
TDMA0
2 0 RI

135

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0 0


0CSMA

0
0

0-14
0-14
/****************************************************************
Function: network_timer
Description:0

Parameters: none.
Returns: .
Side Effects: .
*****************************************************************/
void network_timer(void) interrupt 1 {
TR0=0;
//
if (delay_wait) {
//
delay_wait=0;
//
trans_restart();
//
}
network_busy=0;
//
check_status();
//
}
/*****************************************************************
Function: trans_restart
Description:

Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
void trans_restart(void) {
SBUF=trans_buf[0];
//
last_out=trans_buf[0];
//
trans_ctr=0;
//
trans_chksum=trans_buf[0]; //
}
SBUF
SBUF

0-15

136

Tel

020

38730916 38730917 38730976 38730977

/*****************************************************************
Function: ser_xmit
Description: .
Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
void ser_xmit(void) {
trans_ctr++;
// 1
//
if (trans_ctr < trans_size) {
//
if (trans_ctr==trans_size-1)) {
SBUF=trans_chksum;
last_out=trans_chksum;
} else {
//
SBUF=trans_buf[trans_ctr];
last_out=trans_buf[trans_ctr];
//
trans_chksum+=trans_buf[trans_ctr];
}
}
}
/*****************************************************************
Function: ser_recv
Description: 9600 .
Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
void ser_recv(void) {
unsigned char c, temp;
c=SBUF;
if (TH0 > NET_DELAY_HI)
TR0=0;
//
TH0=NET_DELAY_HI;
TL0=NET_DELAY_LO;
TR0=1;
}
if (transmitting) {

//
// ...

137

Fax:38730925

if (c!=last_out) {
trans_hold();
}
} else {
switch (recv_state) {
...
}
}

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

// SBUF
//

//

//

}
/*****************************************************************
Function: trans_hold
Description: 2.0ms11.76ms
Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
void trans_hold(void) {
unsigned int holdoff;
trans_chksum=trans_ctr=0;
//
holdoff=(unsigned int) rand(); //
holdoff/=3;
//
holdoff+=TWO_MS;
// 2ms
holdoff=(0xFFFF-holdoff)+1;
//
TR0=0;
//
TL0=(unsigned char) (holdoff & 0x00FF);
TH0=(unsigned char) (holdoff / 256);
delay_wait=1;
//
//
TR0=1;
}
last_out
SBUF

CSMA

5
8051

138

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925


1 CKeil C
8051 8051
Keil C 8051Keil C
CKeil C C51
CANSI ANSI C51

8051
8051

80518
8
bdata







8051 C51
80x86
8051
C51
reentrant

01ISR


C

C51 CBYTE CWORD XBYTE XWORD DBYTE
DWORD POBYTE PWORD absacc.h
char,int,long
MOVX
ArchimedesAvocet
Keil bdata,variables,reentrant
Keil
ArchimedesC51 CODEXDATA
C51

139

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

2 Keil
Keil Keil
Keil C C
C
Keil Avocet
PCON Avocet
8051 PCON
3 using
80514 8 32DATA
PSW SFRRS0RS1
03
0 0 RS0RS1
usingusing
using

32

0 00
12
NOAREGS
ISR
0-1
void main(void) {
IP=0x11;
// 0
//
IE=0x97;
// ,1
// 00
init_system();
...
for (;;) {
PCON=0x81;
//
}
}
void serial_intr(void) interrupt 4 using 2 {
//
// 2
if (_testbit_(RI)) {
recv_fsa();
}
if (_testbit_(TI)) {
xmit_fsa();
}
}

140

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

void recv_fsa(void) using 2 { // recv_fsa


//
//
...
}
void xmit_fsa(void) using 2 { // xmit_fsa
//
//
...
}
void intr_0(void) interrupt 0 using 2 {
//
// 2
handle_io();
...
}
void handle_io(void) using 2 {

// RB2
// RB2

...
}
void timer_0(void) interrupt 1 using 1 {
//
// 1
...
}
void intr_1(void) interrupt 2 using 1 {
//
// 1
...
}
ISRISR
C510

141

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0-1


0-2
void main(void) {
IP=0x11;
// 0
//
IE=0x97;
// ,1
// 00
init_system();
...
display();
//
//
for (;;) {
PCON=0x81;
//
}
}
void serial_intr(void) interrupt 4 using 2{
//
// 2
if (_testbit_(RI)) {
recv_fsa();
}
if (_testbit_(TI)) {
xmit_fsa();
}
}
void recv_fsa(void) using 2 { //
//
//
...
display();
//
//

recv_fsa

142

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

}
void xmit_fsa(void) using 2 { // xmit_fsa
//
//
...
}
void intr_0(void) interrupt 0 using 2 {
// -
// 2
handle_io();
...
}
void handle_io(void) using 2 { // RB2
// RB2
...
}
void timer_0(void) interrupt 1 using 1 {
//
// 1
...
display();

//
//

}
void intr_1(void) interrupt 2 using 1 {
//
// 1
...
}
void display(void) {
...
}
display8051 displaydisplay

0display
ROR7
00007
display 0
display

143

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

display

0 displayNOAREGS
R0R7
display NOAREGS
AREGS C51
#pragma NOAREGS
void display(void) {
...
}
#pragma AREGS

0-2
display C51

8051
80x86680x0

0display
recv_fsa display display


display

Keil C51display

display
#pragma NOAREGS
void display(void) reentrant {
144

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

...
}
#pragma AREGS


C51

XDATA0FFFFH
.M51
4


0-3
void main(void) {
IP=0x00;
init_system();
...
display(0);
IE=0x8A;
for (;;) {
PCON=0x81;
}
}

C51

//

// 00
//

void timer_0(void) interrupt 1 using 1 {


//
// 1
...
display(1);
}
void intr_1(void) interrupt 2 using 1 {
//
// 1
...
display(2);
}
void display(unsigned char x) {
...
}
display 01

*** WARNING 15: MULTIPLE CALL TO SEGMENT

145

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

SEGMENT: ?PR?_DISPLAY?INTEXAM
CALLER1: ?PR?TIMER_0?INTEXAM
CALLER2: ?PR?INTR_1?INTEXAM
*** WARNING 15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?_DISPLAY?INTEXAM
CALLER1: ?PR?INTR_1?INTEXAM
CALLER2: ?C_C51STARTUP
display display
01display
1
display
01
display
display






DATA

L51
L51 example.obj
L51 enable variable overlaying


displaymain,timer_0,intr_1

1 0 0
L51 Additonal

L51 example.obj overlay(main ~ _display, intr_1 ~ _display)



5 64K RAM
8051 64KRAM I/O
I/ORAM 1
RAM

146

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0-3 RAMI/O
RAM P0.1 8051 P0.1
RAM I/O P1.0RAM

RAM I/O
RAM RAM RAM
I/O0-4 RAM
RAM
0-4
#include <reg51.h>
#include <absacc.h>
sbit SRAM_ON = P1^0;
/*****************************************************************
: output
: XDATA
: - unsigned int.
- unsigned char.
:
: RAM
*****************************************************************/
void output(unsigned int address, unsigned char value) {
EA=0;
//
SRAM_ON=0;
// RAM
XBYTE[address]=value;
//
SRAM_ON=1;
// RAM

147

EA=1;

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

//

}
/*****************************************************************
: input
: XDATA
: - unsigned int.
: .
: RAM
*****************************************************************/
unsigned char input(unsigned int address) {
unsigned char data value;
EA=0;
//
SRAM_ON=0;
// RAM
value=XBYTE[address]; //
SRAM_ON=1;
// RAM
EA=1;
//
return value;
}
RAM RAM64K 64K RAM
8051
RAM64K RAMP174HC373
RAM 0 I/0
RAM0 RAM
0-4
P1.1P1.2256K RAM

0-4 RAM

148

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

I/O
P1.0 RAM P1.1P1.2RAM0
0 XDATA
startup.a51P1.1P1.2
RAM RAM
RAM
RAM0-5
0-5
#include <reg51.h>
#include <absacc.h>
sbit SRAM_ON = P1^0;
unsigned char data xfer_buf[32];
/*****************************************************************
: page_out
: XDATA
: - unsigned int.
- unsigned char. RAM
- unsigned char.
:
:RAM

*****************************************************************/
void page_out(unsigned int address, unsigned char page,
unsigned char num) {
unsigned char data i;
unsigned int data mem_ptr; //
mem_ptr=address;
num&=0x1F;
// 32
page&=0x03;
// 0..3
page<<=1;
page|=0x01;
// RAM
EA=0;
//
P1=page;
//
for (i=0; i<num; i++) {
XBYTE[mem_ptr]=xfer_buf[i]; //
mem_ptr++;
}
P1=1;
// 0
EA=1;
//
}

149

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

/*****************************************************************
: page_in
: RAM
: - unsigned int.
- unsigned char.
- unsigned char.
:
: RAM

*****************************************************************/
void page_input(unsigned int address, unsigned char page,
unsigned char num) {
unsigned char data i;
unsigned int data mem_ptr; //
mem_ptr=address;
num&=0x1F;
// 32
page&=0x03;
// 0..3
page<<=1;
page|=0x01;
// RAM
EA=0;
//
P1=page;
//
for (i=0; i<num; i++) {
xfer_buf[i]=XBYTE[mem_ptr]; //
mem_ptr++;
}
P1=1;
// 0
EA=1;
//
}
mem_ptr for1
XDATA XDATA DATA

C51
memcpy RAM
Keil C3
15
XDATA
RAM mempcy
page_mempcy
void *page_memcpy(void *dest,void *source,int num);

0-6
?PR?PAGE_MEMCPY?PAGE_IO
?XD?PAGE_MEMCPY?PAGE_IO

SEGMENT CODE
SEGMENT XDATA OVERLAYABLE

150

PUBLIC

_page_memcpy,

Tel

020

38730916 38730917 38730976 38730977

?_page_memcpy?BYTE

RSEG
?XD?PAGE_MEMCPY?PAGE_IO
?_page_memcpy?BYTE:
dest:
DS
3
src:
DS
3
num:
DS
2
;*****************************************************************
; : _page_memcpy
; :
;
xdataRAM
; : RAM R1..R3
;

;
- RAM
;
- unsigned integer.
; :
; :
;*****************************************************************
RSEG
?PR?PAGE_MEMCPY?PAGE_IO
_page_memcpy: PUSH 07
;
PUSH 06
PUSH 02
PUSH 01
PUSH 00
PUSH ACC
PUSH B
MOV DPTR, #?_page_memcpy?BYTE+6
MOVX A, @DPTR
;
MOV 06, A
INC DPTR
MOVX A, @DPTR
MOV 07, A
ORL A, 06
JZ

GTFO

; if (!num) { return }

MOV
MOV
MOVX
INC
MOV
MOVX

DPTR, #?_page_memcpy?BYTE
A, 03
;
@DPTR, A
DPTR
A, 02
@DPTR, A

151

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

INC DPTR
MOV A, 01
MOVX @DPTR, A
L1:

GTFO:

LCALL GETSRC
LCALL PUTDEST

;
;

MOV
CLR
SUBB
MOV
MOV
SUBB
MOV
ORL

; num--

JZ
JMP
POP
POP
POP
POP
POP
POP
POP
RET

A, 07
C
A, #1
07, A
A, 06
A, #0
06, A
A, 07

GTFO
L1
B
ACC
00
01
02
06
07

; if (!num) { return }
;

;*****************************************************************
; : GETSRC
; : ,1
;

; :
; : A
; :
;*****************************************************************
GETSRC:
MOV DPTR, #?_page_memcpy?BYTE+3
MOVX A, @DPTR
;
MOV B, A
;
DEC A
; scale selector to 0..4
ANL A, #00FH
; RAM
MOV DPTR, #SEL_TABLE1
RL A
JMP @A+DPTR
;

152

Fax:38730925

SEL_TABLE1: AJMP
AJMP
AJMP
AJMP
AJMP

SEL_IDATA1
SEL_XDATA1
SEL_PDATA1
SEL_DATA1
SEL_CODE1

Tel

020

38730916 38730917 38730976 38730977

;
;
;
;
;

Fax:38730925

idata
xdata
pdata
data or bdata
code

SEL_PDATA1: MOV 00, #00

; pdata,
; 00
MOV DPTR, #?_page_memcpy?BYTE+5
JMP L2

SEL_XDATA1: MOV DPTR, #?_page_memcpy?BYTE+4


MOVX A, @DPTR
;
MOV 00, A
INC DPTR
L2:
MOVX A, @DPTR
MOV DPH, 00
; set DPTR to XDATA address
MOV DPL, A
MOV A, B
; RAM
ANL A, #0F0H
SWAP A
RL A
ORL A, #01H
MOV P1, A
; RAM
MOVX A, @DPTR
;
MOV 01, A
;
MOV P1, #01H
; RAM page
INC DPTR
MOV 00, DPL
MOV A, DPH
;
MOV DPTR, #?_page_memcpy?BYTE+4
MOVX @DPTR, A
INC DPTR
MOV A, 00
MOVX @DPTR, A
MOV A, 01
; A
RET
SEL_CODE1: MOV DPTR, #?_page_memcpy?BYTE+4
MOVX A, @DPTR
;
MOV 00, A
INC DPTR
MOVX A, @DPTR

153

Tel

020

38730916 38730917 38730976 38730977

MOV DPH, 00
; DPTR
MOV DPL, A
CLR A
MOVC A, @A+DPTR
;
MOV 01, A
INC DPTR
; 1
MOV 00, DPL
MOV A, DPH
MOV DPTR, #?_page_memcpy?BYTE+4
MOVX @DPTR, A
;
INC DPTR
MOV A, 00
MOVX @DPTR, A
MOV A, 01
;
RET
SEL_IDATA1:
SEL_DATA1: MOV DPTR, #?_page_memcpy?BYTE+5
MOVX A, @DPTR
;
MOV 00, A
MOV A, @R0
INC R0
; 1
XCH A, 00
MOVX @DPTR, A
;
XCH A, 00
;
RET
;*****************************************************************
; : PUTDEST
; : A
;
1
; : .
; : .
; :.
;*****************************************************************
PUTDEST:
MOV 02, A
;
MOV DPTR, #?_page_memcpy?BYTE
MOVX A, @DPTR
;
MOV B, A
;
DEC A
ANL A, #00FH
MOV DPTR, #SEL_TABLE2
RL A
JMP @A+DPTR
;

154

Fax:38730925

Tel

SEL_IDATA2
SEL_XDATA2
SEL_PDATA2
SEL_DATA2
SEL_CODE2

020

38730916 38730917 38730976 38730977

SEL_TABLE2:

AJMP
AJMP
AJMP
AJMP
AJMP

; idata
; xdata
; pdata
; data or bdata
; code

SEL_PDATA2:

MOV 00, #00

SEL_XDATA2:

MOV DPTR, #?_page_memcpy?BYTE+1


MOVX A, @DPTR
;
MOV 00, A
INC DPTR

L4:

MOVX A, @DPTR
MOV DPH, 00
MOV DPL, A
MOV A, B
ANL A, #0F0H
SWAP A
RL A
ORL A, #01H
MOV P1, A
MOV A, 02
MOVX @DPTR, A
MOV 01, A
MOV P1, #01H
INC DPTR
MOV 00, DPL
MOV A, DPH

; pdata
; 0
MOV DPTR, #?_page_memcpy?BYTE+2
JMP L4

; DPTR
; RAM

; RAM
;
;
; RAM
; 1

;
MOV DPTR, #?_page_memcpy?BYTE+1
MOVX @DPTR, A
INC DPTR
MOV A, 00
MOVX @DPTR, A
RET
SEL_CODE2:

RET

; CODE

SEL_IDATA2:
SEL_DATA2:

MOV DPTR, #?_page_memcpy?BYTE+2

155

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

MOVX A, @DPTR
;
MOV 00, A
MOV @R0, 02
INC R0
;1
XCH A, 00
MOVX @DPTR, A
;
RET
END
,

Fax:38730925

6 64K
8051,
64K




----
EPROM
64K 805164K Keil
80511MB
KeilBL51 RAM EPROM


EPROM
C51
EPROM

156

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0-5 EPROM
20K 44K
32KEPROM 32K
EPROMP1 RAM
0-5 864KEPROM 512KEPROM
EPROM

CODE







L51_BANK.A51
0-7
0-7
$NOCOND DEBUGPUBLICS
;-----------------------------------------------------------------------; This file is part of the BL51 Banked Linker/Locater package
; Copyright (c) KEIL ELEKTRONIK and Keil Software GmbH 1989-1994
; Version 1.2
;-----------------------------------------------------------------------;********************** Configuration Section ***************************
157

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

change one - ensure that the proper number of code banks is set
?B_NBANKS
EQU 8
; Define max. Number of Banks
*
;
*
?B_MODE
EQU 0
; 0 for Bank-Switching via 8051 Port
*
;
; 1 for Bank-Switching via XDATA Port
*
;
*
IF ?B_MODE = 0;
*
;-----------------------------------------------------------------------*
; if ?BANK?MODE is 0 define the following values
*
; For Bank-Switching via 8051 Port define Port Address / Bits
*
?B_PORT
EQU P1
; default is P1
*
change two - set the bank switching LSB
?B_FIRSTBIT EQU
0
; default is Bit 3
*
;-----------------------------------------------------------------------*
ENDIF;
L51_BANK.A51
L51 BL51 BL51Keil

BL51L51

BL51 BL51 BL51


BANKAREA,BANKAREABL51 0000HFFFFH COMMON
COMMONBL51 BANKx
BL51
BL51 COMMON{C_ROOT.OBJ}, &
BANK0{BANK0.OBJ}, &
BANK1{BANK1.OBJ}, &
BANK2{BANK2.OBJ}, &
BANK3{BANK3A.OBJ,BANK3B.OBJ}, &
BANK4{BANK4.OBJ}, &
BANK5{?PR?MYFUNC?MISC, BANK5.OBJ}, &
BANK6{TABLES.OBJ,BANK6.OBJ}, &
BANK7{BANK7.OBJ,MISC.OBJ} &
BANKAREA(0000H,0FFFFH)


BANKx

158

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

7
Keil
RAMROM

159

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

8051
1





8051

2
510

1 0
0-1
01 .25 .5 .75
90 0-1
90

cold,chilly,mild,warm,hot

0-1
90 warm,hot , 0
0 90warm0.25
hot1.00

160

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0-2
singletoncrisp u=0 u=1
trapezoidal
u u
singleton crisp triangular
trapezoidal triangular crispsingleton




if then if,then
AND OR NOT
0-2



1

0-2

1 1 01
15
60

0-3

0-3

161

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925


u u0


90
u
u1.00 90
1.00 0 1
1

ulow = 0.00
umedium = 0.57
uhigh = 1.00
high

0-4

n Vi Ui

4





162

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

5









20




DISTANCE FAR NEAR CLOSE VCLOSE(very close) VCLOSE

VELOCITY VSLOW FAST


MEDIUM SLOW VSLOW VSLOW0
BRAKE NONE LIGHT MEDIUM VHARD


AND

0-3

VFASTFAR MEDIUM

0-4

163

VELOCITYVSLOW

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

DISTANCEVCLOSE BRAKE LIGHT VELOCITY VSLOW DISTANCE


VELOCITYVSLOW BRAKE
VCLOSE BRAKENONE
NONE

VELOCITY 0MPH25MPH
VELOCITY

0-5 VELOCITY

DISTANCEBRAKE

0-6 DISTANCE

0-7 BRAKE

6
8

8
8
ANDOR 8



164

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0-5
70 20 64
3u
71 20 3

0
1 0 0n n
5 5 VELOCITY
IS VFAST VEL_VFAST 0-1
0-1
//
#define VEL_VSLOW 0x00
#define VEL_SLOW 0x10
#define VEL_MEDIUM 0x20
#define VEL_FAST 0x30
#define VEL_VFAST 0x40
//
#define DIST_VCLOSE 0x01
#define DIST_CLOSE 0x11
#define DIST_NEAR 0x21
#define DIST_FAR 0x31
//
#define BRAKE_NONE 0x80
#define BRAKE_LIGHT 0x90
#define BRAKE_MEDIUM 0xA0
#define BRAKE_HARD 0xB0
#define BRAKE_VHARD 0xC0

x1y1x2y2 x3y3
ANDOR velocityvfastvelocityslowfar
none
VEL_FAST, VEL_SLOW | 0x08, DIST_FAR, BRAKE_NONE

0-2
unsigned char code rules[RULE_TOT]={ //
//
if...
and...
then...
VEL_VSLOW, DIST_VCLOSE, BRAKE_LIGHT,
VEL_VSLOW, DIST_CLOSE, BRAKE_NONE,
VEL_VSLOW, DIST_NEAR, BRAKE_NONE,

165

Tel

VEL_VSLOW,
VEL_SLOW,
VEL_SLOW,
VEL_SLOW,
VEL_SLOW,
VEL_MEDIUM,
VEL_MEDIUM,
VEL_MEDIUM,
VEL_MEDIUM,
VEL_FAST,
VEL_FAST,
VEL_FAST,
VEL_FAST,
VEL_VFAST,
VEL_VFAST,
VEL_VFAST,
VEL_VFAST,

BRAKE_NONE,
BRAKE_MEDIUM,
BRAKE_LIGHT,
BRAKE_NONE,
BRAKE_NONE,
BRAKE_HARD,
BRAKE_HARD,
BRAKE_MEDIUM,
BRAKE_LIGHT,
BRAKE_VHARD,
BRAKE_VHARD,
BRAKE_HARD,
BRAKE_MEDIUM,
BRAKE_VHARD,
BRAKE_VHARD,
BRAKE_HARD,
BRAKE_MEDIUM

DIST_FAR,
DIST_VCLOSE,
DIST_CLOSE,
DIST_NEAR,
DIST_FAR,
DIST_VCLOSE,
DIST_CLOSE,
DIST_NEAR,
DIST_FAR,
DIST_VCLOSE,
DIST_CLOSE,
DIST_NEAR,
DIST_FAR,
DIST_VCLOSE,
DIST_CLOSE,
DIST_NEAR,
DIST_FAR,

020

38730916 38730917 38730976 38730977

Fax:38730925

};



4
0-8

0-8
13 12 4 u u
FFH OOH u
00HFFH 3 0-3
0-3
unsigned char code input_memf[INPUT_TOT][MF_TOT][4]={
// .
//
//
{
{ 0x00, 0x00, 0x1E, 0x09 },
// VSLOW
{ 0x1E, 0x0D, 0x50, 0x09 },
// SLOW
{ 0x50, 0x0D, 0x96, 0x0D },
// MEDIUM
{ 0x8C, 0x06, 0xC8, 0x09 },
// FAST
{ 0xC8, 0x0D, 0xFF, 0x00 }
// VFAST
},

166

//
{
{ 0x00, 0x00,
{ 0x33, 0x08,
{ 0x6E, 0x07,
{ 0xC7, 0x0A,
}

0x2B,
0x80,
0xC7,
0xFF,

Tel

0x0A
0x0A
0x08
0x00

},
},
},
}

020

//
//
//
//

38730916 38730917 38730976 38730977

Fax:38730925

VCLOSE
CLOSE
NEAR
FAR

};

4 416
0FF

0-4
#include <stdio.h>
void main(void) {
unsigned char val[4], output[4], ans, flag;
do {
printf("\n\nenter 4 hex points: ");
scanf(" %x %x %x %x", &val[0], &val[1], &val[2], &val[3]);
output[0]=val[0];
output[2]=val[2];
if (val[1]-val[0]) {
output[1]=(0xFF+((val[1]-val[0])/2))/(val[1]-val[0]);
} else {
output[1]=0;
}
if (val[3]-val[2]) {
output[3]=(0xFF+((val[3]-val[2])/2))/(val[3]-val[2]);
} else {
output[3]=0x00;
}
printf("\nThe point-slope values are: %02X %02X %02X
%02X\n\n",output[0], output[1], output[2], output[3]);
do {
flag=1;
printf("run another set of numbers? ");
while (!kbhit());
ans=getch();
if (ans!='y' && ans!='Y' && ans!='n' && ans!='N') {
flag=0;
printf("\nhuh?\n");
}
} while (!flag);
} while (ans=='y' || ans=='Y');

167

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

printf("\nlater, hosehead!\n");
}

0-9

0-5
unsigned char code output_memf[OUTPUT_TOT][MF_TOT]={
//
// ,
{ 15, 67, 165, 220, 255, 0, 0, 0 } // braking force singletons:
// NONE, LIGHT, MEDIUM, HARD,
// VHARD
};
u
if_val ,if_val
u if_val if_val
if_val
0-6

0-6
/*****************************************************************
Function: fuzzy_engine
Description:
Parameters:
Returns: .
Side Effects:
*****************************************************************/
unsigned char bdata clause_val;
//
//
sbit operator = clause_val^3;
//
sbit clause_type = clause_val^7;
//
//
void fuzzy_engine(void) {
bit then;
//
//
unsigned char if_val,
//
168

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

//
clause,
//
mu,
//
inp_num,
//
label;
//
then=0;
//
if_val=MU_MAX;
// max out mu for the first rule
for (clause=0; clause<RULE_TOT; clause++) { //
clause_val=rules[clause];
//
if (!clause_type) {
//
if (then) {
// ...
then=0;
if_val=MU_MAX;
// mu
}
inp_num=clause_val & IO_NUM; //
label=(clause_val & LABEL_NUM) / 16; //
mu=compute_memval(inp_num, label); //
if (operator) {
// OR
// ...
if (mu > if_val) {
//
if_val=mu;
}
} else {
// AND
if (mu < if_val) {
//
if_val=mu;
}
}
} else {
//
then=1;
//
// mu,
if (outputs[clause_val & IO_NUM]
[(clause_val & LABEL_NUM) / 16] < if_val) {
outputs[clause_val & IO_NUM]
[(clause_val & LABEL_NUM) / 16]=if_val;
}
}
}
defuzzify();
// COG
//
}
compute_memvalu

0-7
/*****************************************************************

169

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

Function: compute_memval
Description: mu,
Parameters: inp_num - unsigned char.
label - unsigned char.
Returns:
unsigned char. mu
Side Effects:
*****************************************************************/
unsigned char compute_memval(unsigned char inp_num,
unsigned char label) {
int data temp;
if (input[inp_num] < input_memf[inp_num][label][0]) {
//
// u0
return 0;
} else {
if (input[inp_num] < input_memf[inp_num][label][2]) {
temp=input[inp_num];
// mu
temp-=input_memf[inp_num][label][0];
if (!input_memf[inp_num][label][1]) {
temp=MU_MAX;
} else {
temp*=input_memf[inp_num][label][1];
}
if (temp < 0x100) {
// 1
return temp;
//
} else {
return MU_MAX;
// mu
}
} else {
//
temp=input[inp_num];
//
// mu
temp-=input_memf[inp_num][label][2];
temp*=input_memf[inp_num][label][3];
temp=MU_MAX-temp;
if (temp < 0) {
// 0
return 0;
} else {
return temp;
// mu
}
}
}
return 0;
}
outputs

170

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

defuzzifyCOG

0-8
/*****************************************************************
Function: defuzzify
Description:

Parameters: .
Returns: .
Side Effects: outputs[][] .
*****************************************************************/
void defuzzify(void) {
unsigned long numerator, denominator;
unsigned char i, j;
for (i=0; i<OUTPUT_TOT; i++) {
// ...
numerator=0;
//
denominator=0;
for (j=0; j<MF_TOT; j++) {
//
numerator+=(outputs[i][j]*output_memf[i][j]);
denominator+=outputs[i][j];
outputs[i][j]=0;
//
}
if (denominator) {
// 0
fuzzy_out[i]=numerator/denominator; // COG
} else {
fuzzy_out[i]=DEFAULT_VALUE;
//
}
}
normalize();
//
}
7

3RAM 80RAM1290 380

171

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

256
2304EPROM

u
compute_memval
mu=input_memf[inp_num][label][input[inp_num]];

4 7500
33000

1RAM 8RAM3010
EPROM 2625

OR
u0
RAM 8RAM3031EPROM 2625

0-9

0-9
#define OUTPUT_TOT 1
#define MF_TOT 5
#define INPUT_TOT 2
#define MU_MAX 0xFF
#define IO_NUM 0x07
#define LABEL_NUM 0x70
#define DEFAULT_VALUE 0x80
unsigned char outputs[MF_TOT],
// mu
fuzzy_out;
//
unsigned char input[INPUT_TOT] ={ //
0, 0
};
unsigned char code input_memf[INPUT_TOT][MF_TOT][256]={
//
{
{ // velocity: VSLOW
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xF6,
0xED, 0xE4, 0xDB, 0xD2, 0xC9, 0xC0, 0xB7, 0xAE, 0xA5, 0x9C, 0x93, 0x8A, 0x81, 0x78,

172

0x6F, 0x66,
0x5D, 0x54, 0x4B, 0x42,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00
},
{ // velocity: SLOW
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x0D,
0x1A, 0x27, 0x34, 0x41,
0xD0, 0xDD,
0xEA, 0xF7, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xF6, 0xED, 0xE4,
0x81, 0x78,
0x6F, 0x66, 0x5D, 0x54,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0x39, 0x30, 0x27, 0x1E, 0x15, 0x0C, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x4E, 0x5B, 0x68, 0x75, 0x82, 0x8F, 0x9C, 0xA9, 0xB6, 0xC3,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xDB, 0xD2, 0xC9, 0xC0, 0xB7, 0xAE, 0xA5, 0x9C, 0x93, 0x8A,
0x4B, 0x42, 0x39, 0x30, 0x27, 0x1E, 0x15, 0x0C, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

173

Tel

0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00
},
{ // velocity: MEDIUM
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x0D, 0x1A, 0x27, 0x34,
0xB6, 0xC3,
0xD0, 0xDD, 0xEA, 0xF7, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x97, 0x8A,
0x7D, 0x70, 0x63, 0x56, 0x49,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,

020

38730916 38730917 38730976 38730977

Fax:38730925

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,


0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,


0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x41, 0x4E, 0x5B, 0x68, 0x75, 0x82, 0x8F, 0x9C, 0xA9,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xF2, 0xE5, 0xD8, 0xCB, 0xBE, 0xB1, 0xA4,
0x3C, 0x2F, 0x22, 0x15, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

174

0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00
},
{ // velocity: FAST
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x0C, 0x12,
0x18, 0x1E, 0x24, 0x2A,
0x6C, 0x72,
0x78, 0x7E, 0x84, 0x8A,
0xCC, 0xD2,
0xD8, 0xDE, 0xE4, 0xEA,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xC9, 0xC0,
0xB7, 0xAE, 0xA5, 0x9C,
0x39, 0x30,
0x27, 0x1E, 0x15, 0x0C,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00
},
{ // velocity: VFAST
0x00, 0x00, 0x00, 0x00,

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
0x30, 0x36, 0x3C, 0x42, 0x48, 0x4E, 0x54, 0x5A, 0x60, 0x66,
0x90, 0x96, 0x9C, 0xA2, 0xA8, 0xAE, 0xB4, 0xBA, 0xC0, 0xC6,
0xF0, 0xF6, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0xED, 0xE4, 0xDB, 0xD2,
0x93, 0x8A, 0x81, 0x78, 0x6F, 0x66, 0x5D, 0x54, 0x4B, 0x42,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

175

0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x4E, 0x5B,
0x68, 0x75, 0x82, 0x8F,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF
}
},
{
{ // distance: VCLOSE
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xE1, 0xD7,
0xCD, 0xC3, 0xB9, 0xAF,
0x41, 0x37,
0x2D, 0x23, 0x19, 0x0F,

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x1A, 0x27, 0x34, 0x41,
0x9C, 0xA9, 0xB6, 0xC3, 0xD0, 0xDD, 0xEA, 0xF7, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,

0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xEB,
0xA5, 0x9B, 0x91, 0x87, 0x7D, 0x73, 0x69, 0x5F, 0x55, 0x4B,
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

176

0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00
},
{ // distance: CLOSE
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x58, 0x60,
0x68, 0x70, 0x78, 0x80,
0xD8, 0xE0,
0xE8, 0xF0, 0xF8, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xF5, 0xEB, 0xE1,
0x73, 0x69,
0x5F, 0x55, 0x4B, 0x41,

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x40, 0x48, 0x50,
0x88, 0x90, 0x98, 0xA0, 0xA8, 0xB0, 0xB8, 0xC0, 0xC8, 0xD0,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xD7, 0xCD, 0xC3, 0xB9, 0xAF, 0xA5, 0x9B, 0x91, 0x87, 0x7D,
0x37, 0x2D, 0x23, 0x19, 0x0F, 0x05, 0x00, 0x00, 0x00, 0x00,

177

0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00
},
{ // distance: NEAR
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x07,
0x0E, 0x15, 0x1C, 0x23,
0x70, 0x77,
0x7E, 0x85, 0x8C, 0x93,
0xE0, 0xE7,
0xEE, 0xF5, 0xFC, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,
0xC7, 0xBF,
0xB7, 0xAF, 0xA7, 0x9F,
0x47, 0x3F,
0x37, 0x2F, 0x27, 0x1F,

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2A, 0x31, 0x38, 0x3F, 0x46, 0x4D, 0x54, 0x5B, 0x62, 0x69,
0x9A, 0xA1, 0xA8, 0xAF, 0xB6, 0xBD, 0xC4, 0xCB, 0xD2, 0xD9,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xEF, 0xE7, 0xDF, 0xD7, 0xCF,
0x97, 0x8F, 0x87, 0x7F, 0x77, 0x6F, 0x67, 0x5F, 0x57, 0x4F,
0x17, 0x0F, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

178

Tel

020

38730916 38730917 38730976 38730977

0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00
},
{ // distance: FAR
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x14,
0x46, 0x50,
0x5A, 0x64, 0x6E, 0x78, 0x82, 0x8C, 0x96, 0xA0, 0xAA, 0xB4,
0xE6, 0xF0,
0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF
}
}
};
unsigned char code output_memf[MF_TOT]={
15, 67, 165, 220, 255
// braking force singletons:
// NONE, LIGHT, MEDIUM, HARD,
// VHARD

179

Fax:38730925

0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00,


0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x1E, 0x28, 0x32, 0x3C,
0xBE, 0xC8, 0xD2, 0xDC,
0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF,

Tel

020

38730916 38730917 38730976 38730977

};
//***************************************************************
// 70
// 64 3
// 0AND 1OR 20
//
//****************************************************************
// define constants for the velocity input
#define VEL_VSLOW 0x00
#define VEL_SLOW 0x10
#define VEL_MEDIUM 0x20
#define VEL_FAST 0x30
#define VEL_VFAST 0x40
// define constants for the distance input
#define DIST_VCLOSE 0x01
#define DIST_CLOSE 0x11
#define DIST_NEAR 0x21
#define DIST_FAR
0x31
// define constants for the brake output
#define BRAKE_NONE 0x80
#define BRAKE_LIGHT 0x81
#define BRAKE_MEDIUM 0x82
#define BRAKE_HARD 0x83
#define BRAKE_VHARD 0x84
#define RULE_TOT 60
unsigned char code rules[RULE_TOT]={ //
// if...
and...
then...
VEL_VSLOW, DIST_VCLOSE, BRAKE_LIGHT,
VEL_VSLOW, DIST_CLOSE,
BRAKE_NONE,
VEL_VSLOW, DIST_NEAR,
BRAKE_NONE,
VEL_VSLOW, DIST_FAR,
BRAKE_NONE,
VEL_SLOW, DIST_VCLOSE, BRAKE_MEDIUM,
VEL_SLOW, DIST_CLOSE,
BRAKE_LIGHT,
VEL_SLOW, DIST_NEAR,
BRAKE_NONE,
VEL_SLOW, DIST_FAR,
BRAKE_NONE,
VEL_MEDIUM, DIST_VCLOSE, BRAKE_HARD,
VEL_MEDIUM, DIST_CLOSE,
BRAKE_HARD,
VEL_MEDIUM, DIST_NEAR,
BRAKE_MEDIUM,
VEL_MEDIUM, DIST_FAR,
BRAKE_LIGHT,
VEL_FAST, DIST_VCLOSE, BRAKE_VHARD,
VEL_FAST, DIST_CLOSE,
BRAKE_VHARD,
VEL_FAST, DIST_NEAR,
BRAKE_HARD,
VEL_FAST, DIST_FAR,
BRAKE_MEDIUM,

180

Fax:38730925

VEL_VFAST,
VEL_VFAST,
VEL_VFAST,
VEL_VFAST,
};

DIST_VCLOSE,
DIST_CLOSE,
DIST_NEAR,
DIST_FAR,

Tel

020

38730916 38730917 38730976 38730977

BRAKE_VHARD,
BRAKE_VHARD,
BRAKE_HARD,
BRAKE_MEDIUM

/*****************************************************************
Function: defuzzify
Description:
Parameters:
Returns: .
Side Effects: outputs[]
*****************************************************************/
void defuzzify() {
unsigned long numerator, denominator;
unsigned char j;
numerator=0;
//
denominator=0;
for (j=0; j<MF_TOT; j++) {
//
numerator+=(outputs[j]*output_memf[j]);
denominator+=outputs[j];
outputs[j]=0;
//
}
if (denominator) {
// 0
fuzzy_out=numerator/denominator; //
} else {
fuzzy_out=DEFAULT_VALUE;
//
//
}
normalize();
//
//
}
/*****************************************************************
Function: fuzzy_engine
Description:
Parameters: .
Returns: .
Side Effects: .
*****************************************************************/
unsigned char bdata clause_val;
//
sbit operator = clause_val^3;
//
sbit clause_type = clause_val^7;
//
//

181

Fax:38730925

Tel

020

38730916 38730917 38730976 38730977

void fuzzy_engine() {
bit then;
unsigned char if_val,
clause,
mu,
inp_num,
label;

Fax:38730925

//
// u
//
// mu
//
//
//
then=0;
//
if_val=MU_MAX;
//
for (clause=0; clause<RULE_TOT; clause++) { //
clause_val=rules[clause];
//
// bdata
if (!clause_type) {
// ...
if (then)
then=0;
if_val=MU_MAX;
}
inp_num=clause_val & IO_NUM;
//
label=(clause_val & LABEL_NUM) / 16;
//
mu=input_memf[inp_num][label][input[inp_num]];//
if (!mu) {
//
do {
//
clause++;
} while (clause<RULE_TOT && !(rules[clause]&0x80));
//
while (clause+1<RULE_TOT && (rules[clause+1]&0x80)) {
clause++;
}
if_val=MU_MAX;
//
} else {
if (mu < if_val) {
//
if_val=mu;
}
}
} else {
//
then=1;
//
// 1
// mu,
//
if (outputs[clause_val & 0x07] < if_val) {
outputs[clause_val & 0x07]=if_val;
}
}

182

Tel

020

38730916 38730917 38730976 38730977

}
defuzzify();

Fax:38730925

//
//

}
8


PC

183

Tel

020

38730916 38730917 38730976 38730977

Fax:38730925

8051 8051
C C

C8051

184

You might also like