Professional Documents
Culture Documents
C51user1
C51user1
020
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
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
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
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
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
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
DJNZ timeout L2
L1 RET
JBC
Tel
020
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
DPTR
3048H
26H A
26H 3049H
R0 87H
87H
DPTR
Tel
020
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
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
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
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
Fax:38730925
TMOD
C/T M1
0
M0
A-8
C/T
M1
M0
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
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
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
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
Fax:38730925
A-2-8051 I/O
A-6
15
Tel
020
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;
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
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
Fax:38730925
}
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
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
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
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
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
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
}
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
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
23
Tel
020
Fax:38730925
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
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
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
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
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
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
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
Tel
020
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
}
29
Tel
020
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
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
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
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
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
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
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
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
020
//
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
Fax:38730925
//
38
Tel
020
Fax:38730925
1
8051
2x16 LCD
15
,,.
RAM RAM 128
0-1
2
SRAM RAM 128
RAM
RAM
L51
39
Tel
020
Fax:38730925
0-2
RAM RAM
printf
printf
0-1
40
Tel
020
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
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
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
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
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
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
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
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
48
Tel
020
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
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;
//
//
curtime;
timeholder;
//
//
//
//
//
//
50
Fax:38730925
Tel
020
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
};
//
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
//
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
/*******************************************************
: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
:
:
:
****************************************************/
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
55
Fax:38730925
Tel
020
/***************************************************
;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
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
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
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
Fax:38730925
60
Tel
020
;
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
CLRXDATA:
IF XDATALEN <> 0
MOV
DPTR,#XDATASTART
61
Fax:38730925
Tel
020
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
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
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
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
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
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
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
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
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
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
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
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
Fax:38730925
73
Tel
020
Fax:38730925
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
Fax:38730925
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
Fax:38730925
;
;
;
;
;
IE
1 0
RETI
C
IE
;
;
;
;
;
IE
1 0
RETI
C
IE
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
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
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
;
;
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
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
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
Fax:38730925
82
Tel
020
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
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
Fax:38730925
1
2
1/10
CPU
DPTR
10000
10Hz I/O
10Hz
INT0INT1 8051
3
8051
85
Tel
020
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
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
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
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
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
Fax:38730925
7
ISR
UART
SBUF
ISR
ISR
20ms
8051
ISR
A/D
10ms
ISR
ISR ISR
8
8051.
8051
8051
91
Tel
020
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
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
Fax:38730925
0-2
0-3
0-4
0-5
0-6
0-7
(FSA) FSA
FSA
94
Tel
020
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
95
unsigned char
recv_state=FSA_INIT,
recv_timer=0,
recv_chksum,
recv_ctr,
recv_buf[35];
Tel
//
//
//
//
//
020
Fax:38730925
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
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;
}
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
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
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
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,
};
//
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
.
.
*****************************************************************/
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
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
*****************************************************************/
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
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
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
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
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
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
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
Tel
020
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
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
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
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
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
} 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
}
}
/*****************************************************************
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
118
Fax:38730925
Tel
020
Fax:38730925
RETI
FAST_ISR: JBC
CHK_XMIT: JBC
RETI
RI, RECV_INT
TI, XMIT_INT
;
;
;
;
;
;
CHK_XMIT3: POP
POP
CHK_XMIT2: POP
CHK_XMIT1: POP
MOV
JMP
DPL
DPH
00H
ACC
SCON, uart_mode
CHK_XMIT
;
;
;
;
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
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
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
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
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
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
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
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
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
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
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
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
; 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]) {
130
Fax:38730925
Tel
020
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
Fax:38730925
132
Tel
020
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
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
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
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
/*****************************************************************
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
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
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
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
Fax:38730925
// 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
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
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
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
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
//
145
Tel
020
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
5 64K RAM
8051 64KRAM I/O
I/ORAM 1
RAM
146
Tel
020
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
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
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
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
?_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
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
;
;
;
;
;
Fax:38730925
idata
xdata
pdata
data or bdata
code
; pdata,
; 00
MOV DPTR, #?_page_memcpy?BYTE+5
JMP L2
153
Tel
020
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
SEL_TABLE2:
AJMP
AJMP
AJMP
AJMP
AJMP
; idata
; xdata
; pdata
; data or bdata
; code
SEL_PDATA2:
SEL_XDATA2:
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:
155
Fax:38730925
Tel
020
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
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
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
158
Tel
020
Fax:38730925
7
Keil
RAMROM
159
Tel
020
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
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
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
Fax:38730925
5
20
DISTANCE FAR NEAR CLOSE VCLOSE(very close) VCLOSE
AND
0-3
VFASTFAR MEDIUM
0-4
163
VELOCITYVSLOW
Tel
020
Fax:38730925
0-5 VELOCITY
DISTANCEBRAKE
0-6 DISTANCE
0-7 BRAKE
6
8
8
8
ANDOR 8
164
Tel
020
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
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
//
//
//
//
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
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
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
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
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
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
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
Fax:38730925
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
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
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
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
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
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
Tel
020
};
//***************************************************************
// 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
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
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
}
defuzzify();
Fax:38730925
//
//
}
8
PC
183
Tel
020
Fax:38730925
8051 8051
C C
C8051
184