Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
la scritta rotante
Bonfanti Alice
Rottigni Stefano e Ruggeri Alessandro
16 Giugno 2006
2
Ringraziamenti
Vorremmo ringraziare i professori dell’area tecnica:
• Ghilardi Sergio
• Capelli Rodolfo
• Cornacchia Andrea
• Martin Massimiliano
• Alba Antonio
• Pisano Ignazio
• Cortinovis Barbara
• Bombardieri Carla
• Mucciolo Michele
• Pezzotta Lucia
• Zenoni Serena
• Quistini Franco
Bonfanti Alice
Rottigni Stefano
Ruggeri Alessandro
Indice
3 Parte Meccanica 15
3.1 Motore in corrente continua . . . . . . . . . . . . . . . . . . . 15
3.2 Braccio rotante . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.3 Contatti striscianti . . . . . . . . . . . . . . . . . . . . . . . . 15
4 Parte Hardware 17
4.1 Scheda Led . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.2 Scheda Microcontrollore . . . . . . . . . . . . . . . . . . . . . 17
4.2.1 Il sensore di Posizione . . . . . . . . . . . . . . . . . . 17
4.2.2 Il sensore di temperatura . . . . . . . . . . . . . . . . 21
4.2.3 L’NVRAM . . . . . . . . . . . . . . . . . . . . . . . . 22
4.2.4 Il microcontrollore . . . . . . . . . . . . . . . . . . . . 23
4.3 L’Alimentatore . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4.3.1 Controllo motore . . . . . . . . . . . . . . . . . . . . . 24
4.3.2 Il regolatore lineare . . . . . . . . . . . . . . . . . . . . 25
4.3.3 Alimentatore Switching . . . . . . . . . . . . . . . . . 25
5 Parte Software 27
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
5.2 The main function . . . . . . . . . . . . . . . . . . . . . . . . 28
5.2.1 ConfHard function . . . . . . . . . . . . . . . . . . . . 28
5.2.2 Automation call . . . . . . . . . . . . . . . . . . . . . 31
5.3 The Interrupt Service Routines . . . . . . . . . . . . . . . . . 31
5.3.1 INT0 Interrupt . . . . . . . . . . . . . . . . . . . . . . 32
5.3.2 serial Interrupt . . . . . . . . . . . . . . . . . . . . . . 34
5.3.3 T1 Interrupt . . . . . . . . . . . . . . . . . . . . . . . 34
5.4 The other functions . . . . . . . . . . . . . . . . . . . . . . . 35
5.4.1 Serial function.c . . . . . . . . . . . . . . . . . . . . . 35
5.4.2 Symbols.c . . . . . . . . . . . . . . . . . . . . . . . . . 38
4 INDICE
A Schemi Elettrici 41
B Layout 49
D Datasheet 73
Capitolo 1
Il Lessicottero è stato concepito dopo una visita al BIAS1 del 2004, la quale
ci ha fornito l’idea del progetto.
La prima realizzazione risale alla fine del 2004 ed era un prototipo
del progetto finale che avevamo idealizzato; costituito solo da otto led e
un microcontrollore PIC, la scritta era limitata e fissa. L’assemblaggio del
manufatto era molto precario poichè costituito da materiali di recupero.
1
Biennale Internazionale dell’Automazione e Strumentazione
10 La storia del Lessicottero
Parte Meccanica
un’apposita sede ricavata da una struttura d’alluminio che è stata poi isolata
dal sostegno del motore attraverso l’apposizione di due supporti isolanti.
Capitolo 4
Parte Hardware
Io = 18000/Rset (4.1)
Ogni integrato può pilotare 16 LED e quindi, date le nostre esigenze,
sono stati impiegati due driver connessi in cascata. L’alimentazione della
scheda è di 5V e con tutti i LED accesi assorbe circa 2A.
• una porta logica NOT con Trigger di Schmitt configurata come oscil-
latore astabile che oscilla ad una frequenza di circa 150kHz.
D2 D3 D4
1 2 1 2 1 2
+Vcc +15V
1N4148 1N4148 1N4148
C12 C13
U2E 100nF U2F 100nF
C14
11 10 13 12 22uF
74HC14 74HC14
R8 33k
C15
100pF
4.2.3 L’NVRAM
Sulla scheda microcontrollore è montata una DS1742, che è una RAM non
volatile da 8kByte. Essa consiste in una normale RAM CMOS a basso
consumo con integrata nel package stesso una batteria al litio ricaricabile.
Questo significa che i dati contenuti nella RAM sono mantenuti anche se l’al-
imentazione viene a mancare. Inoltre nelle ultime locazioni della RAM è con-
tenuto un datario autoaggiornato con doppio latch. Questo ci ha permesso
di visualizzare la data e l’ora sul Lessicottero.
Il datario è incrementato utilizzando un quarzo interno da 32kHz e la
precisione è di ±2min al mese (35ppm). Il datario include i registri di Se-
colo, Anno, Mese, Giorno, Giorno della settimana, Ora, Minuti, Secondo e
4.2 Scheda Microcontrollore 23
4.2.4 Il microcontrollore
Il microcontrollore utilizzato è l’AT89C51ED2 della Atmel e le sue carat-
teristiche sono ampiamente discusse nel capitolo dedicato al software e nel
datasheet allegato. Una nota particolare va alla presenza di un bus esterno
nonostante si tratti di un microcontrollore. Attraverso questa caratteristica
abbiamo potuto interfacciare il convertitore A/D e la RAM esterna con un
bus parallelo, derivato dai pin del micro (Port 0, 2 e alcuni del 3) e dal
latch 74HC573 usato per demultiplexare il bus dati e la parte bassa degli
indirizzi, multiplexati appunto sul Port 0. L’acquisizione della parte bassa
24 Parte Hardware
4.3 L’Alimentatore
L’alimentatore fornisce 3 diverse tensione d’alimentazione:
• 12V per le ventole di raffreddamento
• 8V per la logica della scheda micro e la scheda LED
• alimentazione variabile 0V-30V e circa 20A max per il motore
In ingresso c’è un trasformatore con più primari e più secondari; i pri-
mari disponibili sono 380V, 270V, 220V mentre in uscita 12V e 24V. Noi
utilizziamo la combinazione 270V - 12V e 270V - 24V. L’uscita 0 - 24V for-
nisce una tensione alternata che tramite un ponte diodi e una batteria di
condensatori viene portata ad una tensione lineare, usata per l’alimentazione
della scheda di controllo della velocità del motore. L’uscita 0 - 12V entra
in un secondo ponte diodi che raddirizza la tensione e poi in un regolatore √
lineare che ha il compito di portare la tensione da circa 18Volt (12V · 2)
a 8V per poi poter essere ulteriormente abbassata a 5V attraverso un altro
regolatore lineare che fornirà il giusto valore di tensione d’alimentazione per
le 2 schede. Per quanto riguarda le ventole di raffreddamento vengono ali-
mentate a 12V forniti da un alimentate switching che preleva la tensione in
uscita dalla batteria di condensatori e ne genera una in uscita di 12V. Sono
stati previsiti come sistema di sicurezza un fusibile da 2,5A sull’ingresso e
un pulsante di arresto del motore.
Parte Software
5.1 Introduction
The heart of Lessicottero main board is an embedded Atmelr microcon-
troller, the AT89C51ED2. It’s main features are:
- 80C52 Core:
- SPI Interface
The AT89C51ED2 core needs only 6 clock periods per machine cycle.
This feature is called X2. In order to keep the original C51 compatibility, a
divider by 2 is inserted between the XTAL1 signal and the main clock input
of the core. The X2 bit in the CKCON0 register (table 5.1) allows a switch
from 12 clock periods per instruction to 6 clock periods and vice versa. The
others bits switch the peripherals3 from standard speed to fast speed. These
bits are active only during X2 mode.
1
Power On Reset
2
Power Fail Detect
3
Timer0, Timer1, Timer2, Uart, PCA, and Watchdog
5.2 The main function 29
//XRAM=1792;ALE=ON;EXTRAM
AUXR=0x11; //0x11;
1. The Lower 128 bytes of RAM (addresses 00h to 7Fh) are directly and
indirectly addressable.
2. The Upper 128 bytes of RAM (addresses 80h to FFh) are indirectly
addressable only.
The internal 1792bytes RAM can be enabled using XRSn bits in AUXR
Register (table 5.2). These sets the size of internal XRAM. The M0 bit allows
to stretch the XRAM timings; if M0 is set, the read and write pulses are
extended from 6 to 30 clock periods. This is useful to access external slow
peripherals. The ALE signal is used to demultiplex address and data buses
on port 0 when used with external program or data memory. Nevertheless,
during internal code execution, ALE signal is still generated. In order to
reduce EMI, ALE signal can be disabled by setting AO bit.
//setup serial port & Timer2
PCON |= 0x80; // SMOD=1
RCAP2L and RCAP2H are the two Timer 2 reload registers. Timer
2 is configured to Serial Baud Rate Generator so their content determine
the Baud Rate of the Serial Port. The preprocessor directives #if, #else,
#endif evaluate the expression debug for a conditional compilation. When
debug=1 the serial port shift out data at 28800bps6 , else at 1200bps.
5
Internal Baud Rate Generator
6
Bits Per Seconds
5.3 The Interrupt Service Routines 31
The program is an endless while loop. Every times the program loop, the
automations are called.
Serial Automation
The Serial Automation analyze the incoming serial message and replay it.
The analysis begin when f analisi rx is set7 .
void automa_seriale(void){
unsigned char k;
if(f_analisi_rx){
switch(v_rx[0]){
case ’S’: //Set
switch(v_rx[1]){
case ’t’: //set time
...
A switch structure identify the incoming message, parsing the string charac-
ter by character. Then the command is send back to the serial port followed
by an equal sign and by the output message.
Finally the program erase the incoming serial buffer and clear the f analisi rx
flag.
...
break;
}
break;
}
//clear buffer
for(k=0;k<LEN_VRX;k++){
v_rx[k]=0;
}
f_analisi_rx=false;
}
}
TH1=0;
TL1=0;
TR1=1;
//calc. vel
vel=(int)(1/(Tcounter*tmpTim1.ul)*60);
This ISR is call when the hall-effect sensor cross the reference point. The
software clears the pointer of the display matrix, restart the Timer 0, stop
the Timer 1 counter and read it. Timer 1 is used, with the T1OF variable, to
measure the time that the Lessicottero use to cover a turn. In fact when the
result is copy and the timer re-enabled, the time of a revolution is calculate
and store in vel global variable. This is done using the tmpTim1 structure:
when the variables are inserted it is an array of four char that became an
unsigned long in the calculation. The speed of rotation is obtained doing
the reciprocal of Tcounter (this is the time which the counter employ to
34 Parte Software
5.3.3 T1 Interrupt
/*------------------------------------------------
TIMER 1 OVERFLOW
------------------------------------------------*/
void T1_IT(void) interrupt 3{
T1OF++;
//Rotate?
if(T1OF>50){ //2 sec
fermo=true;
8
Revolution Per Second
9
Revolution Per Minute
5.4 The other functions 35
//Beep
if(k_beep>5){
BUZ=0;
}else{
//beep
BUZ=1;
k_beep++;
}
}
start pack
void start_pack(void){
EOT=false;
p_tx=0;
//add sync chars
v_tx[p_tx++]=0x55;
v_tx[p_tx++]=0xFF;
//add start byte
v_tx[p_tx++]=’:’;
//2 byte void
p_tx+=2;
}
Start pack function wait until the last character of the precedent packet, if
present, is sent. Then reset the pointer of transmitter (p tx ) and add to the
transmitter buffer (v tx[] ) the two sync chars (0x55 and 0xFF). Finally it
add the start character and increment the pointer of two to insert the packet
length when it is know.
send functions
void send_num8(unsigned char Numero){
v_tx[p_tx++]=((Numero/100)%10)+48;
v_tx[p_tx++]=((Numero/10)%10)+48;
v_tx[p_tx++]=(Numero%10)+48;
}
There are five function used to add data at the packet. In particular:
• send num8 add an unsigned 8bit number
5.4 The other functions 37
sPut function call cPut function many times as len. This is the length
of the string which we would send. This function accept the pointer of the
string. cPut copy only the value of the ASCII code of character to the buffer.
send pack
void send_pack(void){
xdata unsigned char tmpCHK=0;
xdata unsigned int k;
//space
p_tx++;
//add 10 & 13
v_tx[p_tx++]=13;
v_tx[p_tx++]=10;
//lenght
v_tx[3]=(((p_tx-10)/10)%10)+48;
v_tx[4]=((p_tx-10)%10)+48;
//chk
for(sj=10;sj<p_tx-3;sj++){
tmpCHK+=v_tx[sj];
}
v_tx[p_tx-3]=tmpCHK;
//copy string len
l_tx=p_tx-1;
p_tx=0;
//enable transmitter
enTX=0;
enRX=1;
//wait ~10ms
for(k=0;k<1000;k++);
//send first char
SBUF=v_tx[0];
}
Send pack function complete the packet. In fact it add another space (for
the checksum) and add the CR and The LF. Then calculate the length of
the data and concatenate in the buffer. The checksum is calculated doing
the sum of all characters and masking with 25512 . Completed the buffer, the
12
This is implicit: when the int value tmpCHK is copied into emphv tx[p tx-3] is
automatically casted
38 Parte Software
transmitter is enabled and after a small pause (10ms) to ensure its properly
start, the first character is send on the serial port.
5.4.2 Symbols.c
Symbols.c contains some functions which are used to display a word on
the Lessicottero. It is based on a non volatile13 Character Generator Array
(Sy[93][120] ). This contains a piece of ASCII alphabet and its correspondent
in sequence of lighting or quenching of LEDs. Furthermore another array
(dimSy[93] )indicates how many LEDs is width the character. In fact the
font choose14 is a multiwidth font. This means that the character ’M’ is
more width than ’i’.
clrDisplay
void clrDisplay(void){
if(nDisplay==1){
for(ptDisplay=0;ptDisplay<8000;ptDisplay++){
nvDisplayA[ptDisplay]=0;
}
}else{
for(ptDisplay=0;ptDisplay<8000;ptDisplay++){
nvDisplayB[ptDisplay]=0;
}
}
ptDisplay=0;
}
clrDisplay is used to clear the nvRam of the selected display. This is doing
by a for cycle which clear each cell of the ram.
add functions
void addDigit(unsigned char Symbol){
chLen=dimSy[Symbol+NUMOFS];
currChar=Symbol+NUMOFS;
if(nDisplay==1){
for(k=0;k<chLen;k++){
nvDisplayA[ptDisplay++]=Sy[currChar][k];
13
Memorized in the microcontroller Flash
14
Comics MS Sans
5.4 The other functions 39
}
}else{
for(k=0;k<chLen;k++){
nvDisplayB[ptDisplay++]=Sy[currChar][k];
}
}
}
These three functions are used to add content in display. The first add a
digit15 , the second add a char and the third call the second many times as
the string length. The principally difference between these function is the
additional constant that is added to the passed value. For the numerical
function NUMOFS is equal to 0x10 and it is added, while for the character
function CHROFS is equal to 0x20 and it is subtracted. This because the
different value passed to the function. for the numerical function is a digit
[0..9], while for the character function is the ASCII code of the character. We
haven’t used the standard ASCII code. Our alphabet is similar but shifted
back by 32 positions (0x20 in hexadecimal). All these functions write many
ram cells as chLen tells. In fact for a specific character there is a specific
length.
15
To add a full number we have to call this function repeatedly
40 Parte Software
Appendice A
Schemi Elettrici
A B C D E
42
4 4
J1 T1
PLUG AC MALE 380V 24V
S1 F1 D8
270V
3 PWM MOTORE PWM MOTORE 3
2,5 A T 220V 12V - +
+Vm
SW DPST
C11 C12
0V 0V BRIDGE 25A 22000uF 22000uF
S2
TRASFORMATORE 400VA -Vm V+motore
+Vl
-Vl
V-motore
C13 C14
22000uF 22000uF
Fungo blocco motore
ALIM SW
Vin Vout
GND GND
ALIM SW
2 D9 2
lineare
- +
Vin Vout
C15
BRIDGE 6A 4700uF
GND GND
JP11
9
8
7
6
5
4
3
2
1
Connettore Militare
1 1
Schemi Elettrici
Title
Cablaggio scheda alimentatore
4 4
R1
1 2
1
4k7
JP1
1
R2 Jumper3
2 1 2
2
1k5
3
2
R3
3
Vin JP2 1 3
1 15k
D1
1
3 2 3
4
JP3 U1
HEADER 2 L1
Vout
2
adj
4 - + 2 1 2 1 2
1 in out
BRIDGE lm2576 150uH
on/off
1
gnd
IN
1
R4
3
3
5
R5 1k
2
1k JP4
D2
2
1
1
1
1
C1 C2 1
2
1N5822 C3 C4 2
100uF 50V 100nF 1000uF 25V 100nF
2
2
1
2
2
1
1
OUT
D3 D4
LED LED
2
2
2 GND 2
GND
Title
Alimentatore Switching
4 4
3 3
Vin
JP9 BD242
3 2
1
2
Q2
1
Vout
Power IN
GND
Power OUT
3
GND
2 2
C9 C10
220nF 100nF
Title
Regolatore lineare
U2A
1 2 +Vl
4 40106 4
U2B JP5
VCC VDD
1
3 4 VSS
2
Vlogica
40106
-Vl
D5 +Vm V+motore
R6 +Vm
1 2 2 1 R7
JP6
1
100K
1K JP7
+Vm 1
3 1N4148 3
2 1
2
3 2
4 3
1
Vmotore V+motore
1
R8 D6 C5
3
1 2 1 2 100nF D7
2
-Vm
1K RURG8060
1N4148 V-motore
2
U2C U2D JP8
1
5 6 9 8
2
3
40106 40106 V-motore
1
C6
2
1nF U2E
2
R9 Q1
2 11 10 1 2 1 IRPF150N 2
3
VCC 10E
40106
U2F
1
1
2
2
40106
1 1
45
Title
Regolatore velocità motore in CC PWM
A B C D E
A B C D E
+Vcc
46
Memory map
JP1 U1C
JP2 0000
1 LEN ScratchPad RAM
5 6
9
2 nOE 1 TxD
SCK RxD (256b)
3 2 R1 00FF
C
4 MOSI 3 enTX 0100
enRX 74HC14
Scheda Braccio 4 4k7
U1B
TrasmWireless
R1
R2
R3
R4
R5
R6
R7
R8
3 4 INT XRAM
(1792b)
1
2
3
4
5
6
7
8
74HC14 07FF
4 0800
4
AD0
S1 AD1
AD2
T0
AD3
S2 AD4
U1A BZ1 AD5
T1
AD6 +Vcc
S3 1 2 1 +Vcc AD7 C1
T2 1FFF
2 +Vcc +Vcc
S4 74HC14 BUZZER +Vcc C2 C3 100nF 2000
T3
U2
100nF 100nF A0 10 11 AD0 DisplayA
A0 D0 AD1
A1 9 12
8 A1 D1 13 AD2
U3 U4 A2
C4 A2 D2 AD3
31 39 2 19 A0 A3 7 15
10uF EA P0.0/AD0 D1 Q1 A3 D3 AD4 2FA0
38 3 18 A1 A4 6 16
P0.1/AD1 D2 Q2 A4 D4 AD5 2FA1
9 37 4 17 A2 A5 5 17
RESET P0.2/AD2 D3 Q3 A5 D5 AD6
36 5 16 A3 A6 4 18
12 P0.3/AD3 35 6 D4 Q4 15 3 A6 D6 19 AD7
nINT0 A4 A7
P3.2/INT0 P0.4/AD4 D5 Q5 A7 D7 DisplayB
LEN 13 34 7 14 A5 A8 25
P3.3/INT1 P0.5/AD5 D6 Q6 A8
enRX 14 33 8 13 A6 A9 24
P3.4/T0 P0.6/AD6 D7 Q7 A9
enTX 15 32 9 12 A7 A10 21
P3.5/T1 P0.7/AD7 D8 Q8 A10
nPSEN 29 A11 23
+Vcc PSEN 30 11 2 A11 3FF7
A12
+Vcc ALE/PROG C A12 3FF8
T0 1 1 A13 26
3 P1.0/T2 OC A13 DS1743 3
T1 2 A14 1
3 P1.1/T2EX/SS 21 A14
T2 74HC573 A8 CLOCK REGISTER
C5 +Vcc P1.2/ECI P2.0/A8 3FFF
T3 4 22 A9 nRD 22
C6 C7 P1.3/CEX0 P2.1/A9 OE 4000
nOE 5 23 A10 nWR 27
1uF 6 P1.4/CEX1 P2.2/A10 24 A15 20 WE
A11
10uF P1.5/CEX2/MISO P2.3/A11 CE
SCK 7 25 A12
100nF 8 P1.6/CEX3/SCK P2.4/A12 26 DS1743
A13
2
MOSI P1.7/CEX4/MOSI P2.5/A13
U5 27 A14
P2.6/A14 A15 ADC
1 4 28
C1+ C2+ P2.7/A15
V+
CONVERTER
C8 C9 P1
1uF 3 5 1uF 5 18 17
C1- C2- XTAL1 P3.7/RD nRD
9 16 nWR
P3.6/WR
4 Y1 11 TxD
P3.1/TxD
TxD 11 14 8 19 10 RxD
T1in T1out XTAL2 P3.0/RxD FFFF
10 7 3
T2in T2out 20MHz AT89C51ED2
7
12 13 2 C11 C12
RxD R1out R1in 33pF 33pF
9 8 6
V-
R2out R2in
1
MAX232
6
RS232 PC
+Vcc
C10
+Vcc
C14
100nF
1uF C13
1
U6 R2 10K
2 AD0 18 19 1 2 1 2 R3 2
AD1 DB0 CLKR 3K3
17
AD2 16 DB1 4 150pF
AD3 DB2 CLK
15
2
AD4 DB3
14 R4
+Vcc A15 AD5 13 DB4 6 1 2
AD6 DB5 VI+
12
AD7 DB6 U7
U1D 11
1
2
1 1 nRD RD
C16 C17 3
2 10uF 100nF 2 nWR WR
74HC14 5
1
+Vcc D1 D2 D3 R6
1
1 2 1 2 1 2 5K R5
+Vcc +12V
5K
1N4148 1N4148 1N4148 2 2
R7
5k6 C18 C19
U1E 100nF U1F 100nF
1
C20
3
+12V 11 10 13 12 22uF
nINT0
JP5
3
1 1
1 R8
2 Q1 74HC14 74HC14 R10
2 BC107C JP6
Schemi Elettrici
3 47k
1
nPSEN
Sensore
R11 R9 33k JUMPER
10k 2k2 Title
C21 Lessicottero MainBoard
100pF
Size Document Number Rev
A3 ADP 2005-2006 - Bonfanti Alice, Rottigni Stefano, Ruggeri Alessandro 01
VCC
VCC VCC D1
2 1
1
1
D2
C1 C2 2 LED 1
100nF 100nF
2
2
D3
2 LED 1
4 D4 4
2 LED 1
VCC
D5
2 LED 1
1
JP1
U1
C3 3 5 D6
4.7uF 1 CLK U0
2 6 2 LED 1
2
2 DIN U1
21 7
3 OE U2
4 8 D7
4 LATCH U3 9 2 LED 1
R1 U4
10
HEADER 4 U5
1 2 23 11 D8
SET U6
22 12 2 LED 1
360E DOUT U7
13
U8
14 D9
U9
15 2 LED 1
U10
16
U11
17 D10
U12 18 2 LED 1
U13 19
U14
20 D11
U15
2 LED 1
1 D13
2 LED 1
3 2 3
D14
HEADER 2 2 LED 1
D15
2 LED 1
D16
2 LED 1
LED
VCC
D17
2 1
D18
2 LED 1
D19
2 LED 1
D20
2 LED 1
2 2
MAX6969 D28
2 LED 1
D29
2 LED 1
1 D30 1
2 LED 1
D31
47
2 LED 1
D32
2 LED 1
Title
Scheda LED
LED
Size Document Number Rev
A3 Bonfanti - Rottigni - Ruggeri 5°AEN 1.0
Date: Thursday, May 11, 2006 Sheet 1 of 1
A B C D E
48 Schemi Elettrici
Appendice B
Layout
50 Layout
C.1 STARTUP.A51
$NOMOD51
;------------------------------------------------------------------------------
; This file is part of the C51 Compiler package ; Copyright (c)
1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
;------------------------------------------------------------------------------
; 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 ; BL51 invocation: ; ; BL51 <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: ; ; ; the absolute
start-address of IDATA memory is always 0 IDATALEN EQU
80H ; the length of IDATA memory in bytes. ; XDATASTART EQU
0H ; the absolute start-address of XDATA memory XDATALEN
EQU 0H ; the length of XDATA memory in bytes. ; PDATASTART
EQU 0H ; the absolute start-address of PDATA memory
PDATALEN EQU 0H ; the length of PDATA memory in
bytes. ; ; Notes: The IDATA space overlaps physically the DATA and
BIT areas of the ; 8051 CPU. At minimum the memory space
occupied from the C51 ; run-time routines must be set to
zero.
;------------------------------------------------------------------------------
; ; Reentrant Stack Initilization ; ; The following EQU statements
define the stack pointer for reentrant ; functions and initialized
it: ; ; Stack Space for reentrant functions in the SMALL model.
IBPSTACK EQU 0 ; set to 1 if small reentrant is
used. IBPSTACKTOP EQU 0FFH+1 ; set top of stack to highest
location+1. ; ; Stack Space for reentrant functions in the LARGE
model. XBPSTACK EQU 0 ; set to 1 if large reentrant
is used. XBPSTACKTOP EQU 0FFFFH+1; set top of stack to
highest location+1. ; ; Stack Space for reentrant functions in the
COMPACT model. PBPSTACK EQU 0 ; set to 1 if compact
reentrant is used. PBPSTACKTOP EQU 0FFFFH+1; set top of
stack to highest location+1. ;
;------------------------------------------------------------------------------
; ; Page Definition for Using the Compact Model with 64 KByte xdata
RAM ; ; The following EQU statements define the xdata page used for
pdata ; variables. The EQU PPAGE must conform with the PPAGE
54 8051 Source Code
NAME ?C_STARTUP
RSEG ?STACK
DS 1
CSEG AT 0
?C_STARTUP: LJMP STARTUP1
RSEG ?C_C51STARTUP
STARTUP1:
IF IDATALEN <> 0
MOV R0,#IDATALEN - 1
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
ENDIF
IF XDATALEN <> 0
MOV DPTR,#XDATASTART
MOV R7,#LOW (XDATALEN)
IF (LOW (XDATALEN)) <> 0
MOV R6,#(HIGH (XDATALEN)) +1
ELSE
MOV R6,#HIGH (XDATALEN)
ENDIF
CLR A
XDATALOOP: MOVX @DPTR,A
INC DPTR
DJNZ R7,XDATALOOP
DJNZ R6,XDATALOOP
ENDIF
IF PPAGEENABLE <> 0
MOV PPAGE_SFR,#PPAGE
ENDIF
IF PDATALEN <> 0
MOV R0,#LOW (PDATASTART)
MOV R7,#LOW (PDATALEN)
CLR A
PDATALOOP: MOVX @R0,A
INC R0
DJNZ R7,PDATALOOP
ENDIF
C.2 main.c 55
MOV SP,#?STACK-1
; This code is required if you use L51_BANK.A51 with Banking Mode 4
; EXTRN CODE (?B_SWITCH0) ; CALL ?B_SWITCH0 ;
init bank mechanism to code bank 0
LJMP ?C_START
END
C.2 main.c
/*------------------------------------------------------------------------------
Lessicottero main.c by Ale Ruggeri
------------------------------------------------------------------------------*/
#include <REG_AT89C51.H> /* special function register
declarations */
/* for the Atmel AT89C51ED2 */
/*------------------------------------------------
MAIN FUNCTION
------------------------------------------------*/
void main (void){
ConfHard();
#if debug
ISDwait ();
#endif
nvControl=NVNORMAL;
fill_ram();
OE=0;
while (1){
automa_seriale();
if(fermo){
read_key();
}else{
56 8051 Source Code
automa_processo();
}
};
}
/*------------------------------------------------
CONF HARD
------------------------------------------------*/
void ConfHard(void){
//clock
CKCON0=0x01;
//XRAM=1792;ALE=ON;EXTRAM
AUXR=0x11; //0x11;
#if debug//28800
RCAP2L=0xEA; //0xF5; //0xBF;
RCAP2H=0xFF; //0xFF; //0xFF
#else//1200 //115200
RCAP2L=0xBF; //0xF5; //0xBF;
RCAP2H=0xFF; //0xFF; //0xFF
#endif
SCON=0X50; // serial port mode 1 (8 bit data, 1 start bit, 1 stop bit)
//setup timer0&1
TCON=0x5A;
TMOD=0x11;
TH0=0x20;
TL0=0x00;
/*//setup PCA
CMOD=0x02; // Fclk/2
CCON=0x40; // Run
//setup CCR
CCAPM1=0x42; // PWM
CCAP1H=0x00; // Always on */
//SPI
SPCON=0x73;
//Interrupt
ES=1; // Enable serial interrupt
// EC=0; // Enable the PCA interrupt
EA=1; // Enable global interrupt
ET0=1; // Enable timer 0 interrupt
ET1=1; // Enable timer 1 interrupt
EX0=1; // Enable external interrupt
IT0=1; // Interrupt active on front
ET2=0; // Enable timer 2 interrupt
//enable transmitter
enTX=0;
enRX=1;
v_rx[p_rx]=0;
}
p_rx=0;
}
/*------------------------------------------------
Read Keypad
------------------------------------------------*/
void read_key(void){
if(!K0){ //Time
k_beep=0;
if(!f_strings){
stato=0;
rel_stato=10;
}else{
f_strings=false;
p_strings=0;
}
}else if(!K1){ //Speed
k_beep=0;
if(!f_strings){
stato=0;
rel_stato=20;
}else{
f_strings=false;
p_strings=1;
}
}else if(!K2){ //Temperature
k_beep=0;
if(!f_strings){
stato=0;
rel_stato=30;
}else{
f_strings=false;
p_strings=2;
}
}else if(!K3){ //Strings
f_strings=true;
k_beep=0;
if(!f_strings){
stato=40;
rel_stato=0;
}else{
f_strings=false;
p_strings=3;
}
}
}
/*------------------------------------------------
TIMER 0 OVERFLOW
------------------------------------------------*/
void T0_IT(void) interrupt 1 using 2 {
unsigned char a;
unsigned char b;
//shift out data
if(nDisplay==0){
SPDAT=nvDisplayA[pDisplay++];
b=nvDisplayA[pDisplay++];
}else{
SPDAT=nvDisplayB[pDisplay++];
58 8051 Source Code
b=nvDisplayB[pDisplay++];
}
while((SPSTA&0x80)!=0x80);a=SPDAT;
SPDAT=b;
if(nDisplay==0){
b=nvDisplayA[pDisplay++];
}else{
b=nvDisplayB[pDisplay++];
}
while((SPSTA&0x80)!=0x80);a=SPDAT;
SPDAT=b;
if(nDisplay==0){
b=nvDisplayA[pDisplay];
}else{
b=nvDisplayB[pDisplay];
}
while((SPSTA&0x80)!=0x80);a=SPDAT;
SPDAT=b;
while((SPSTA&0x80)!=0x80);a=SPDAT;
//stobe data
LEN=1;
//increment pointer
if(pDisplay<LENDISPLAY){
pDisplay++;
}
TH0=HIGH(T0Rel);
TL0=LOW(T0Rel);
LEN=0;
}
/*------------------------------------------------
INT 0 INTERRUPT
Hall-Effect Sensor
------------------------------------------------*/
void INT0_IT(void) interrupt 0 using 1{
//clear pointer
pDisplay=0;
//T0 OF
TF0=1;
TH0=0;
TL0=0;
//read and clear T1
TR1=0;
tmpTim1.c[3]=TL1;
tmpTim1.c[2]=TH1;
tmpTim1.c[1]=T1OF;
T1OF=0;
TH1=0;
TL1=0;
TR1=1;
//calc. vel
vel=(int)(1/(Tcounter*tmpTim1.ul)*60);
T0Rel=65535-(tmpTim1.ul/1000);
}
/*------------------------------------------------
TIMER 1 OVERFLOW
------------------------------------------------*/
void T1_IT(void) interrupt 3{ //0.04 sec
T1OF++;
C.3 AutomaSeriale.c 59
//Rotate?
if(T1OF>50){ //2 sec
fermo=true;
OE=1; //led off
if(T1OF>250)T1OF=250; //block counter
}else{
fermo=false;
OE=0; //led on
}
//Beep
if(k_beep>5){
BUZ=0;
}else{
//beep
BUZ=1;
k_beep++;
}
}
/*------------------------------------------------
TIMER 2 OVERFLOW
------------------------------------------------*/
void T2_IT(void) interrupt 5{
/*------------------------------------------------
SERIAL INTERRUPT
------------------------------------------------*/
void serial_IT(void) interrupt 4 using 3{
char copy_buffer;
if (RI){
RI=0; //ACK
copy_buffer=SBUF;
if(copy_buffer==13){
//ricevuto CR
f_analisi_rx=true;
p_rx=0;
}else{
v_rx[p_rx]=copy_buffer;
if(p_rx<LEN_VRX)p_rx++;
}
}else if(TI){
TI=0; //ACK
if(p_tx<l_tx){
//send another char
SBUF=v_tx[++p_tx];
}else{
//set flag EOT
EOT=true;
}
}
}
C.3 AutomaSeriale.c
/*------------------------------------------------------------------------------
Automa Seriale.c
60 8051 Source Code
void automa_seriale(void){
unsigned char k;
if(f_analisi_rx){
switch(v_rx[0]){
case ’D’: //debug
break;
case ’S’: //Set
switch(v_rx[1]){
case ’t’: //set time
nvControl=NVWRITE;
nvHour=((v_rx[3]-0x30)<<4)+(v_rx[4])-0x30;
nvMinutes=((v_rx[6]-0x30)<<4)+(v_rx[7])-0x30;
nvSeconds=((v_rx[9]-0x30)<<4)+(v_rx[10])-0x30;
nvControl=NVNORMAL;
break;
case ’d’: //set date
nvControl=NVWRITE;
nvDate=((v_rx[3]-0x30)<<4)+(v_rx[4])-0x30;
nvMonth=((v_rx[6]-0x30)<<4)+(v_rx[7])-0x30;
nvYear=((v_rx[9]-0x30)<<4)+(v_rx[10])-0x30;
nvControl=NVNORMAL;
break;
case ’b’: //set brightness
//CCAP1H=255-((v_rx[3]-0x30)*100+(v_rx[4]-0x30)*10+(v_rx[5]-0x30));
break;
case ’s’: //set strings
nvStringsL[v_rx[2]-0x30]=((v_rx[4]-0x30)<<4)+(v_rx[5])-0x30;
for(k=0; k<nvStringsL[v_rx[2]-0x30]; k++){
nvStrings[v_rx[2]-0x30][k]=v_rx[k+6];
}
}
break;
case ’R’: //Read
switch(v_rx[1]){
case ’s’: //read speed
start_pack();
sPut("Rs=", 3);
send_num16(vel);
send_pack();
break;
case ’t’: //read time
start_pack();
sPut("Rt=",3);
nvControl=NVREAD;
send_numBCD(nvHour);
cPut(’:’);
send_numBCD(nvMinutes);
C.4 AutomaProcesso.c 61
cPut(’:’);
send_numBCD(nvSeconds);
nvControl=NVNORMAL;
send_pack();
break;
case ’d’: //read date
start_pack();
sPut("Rd=",3);
nvControl=NVREAD;
send_numBCD(nvDate);
cPut(’/’);
send_numBCD(nvMonth);
cPut(’/’);
send_numBCD(nvYear);
nvControl=NVNORMAL;
send_pack();
break;
case ’b’: //read brightness
start_pack();
sPut("Rb=", 3);
send_num8(255-CCAP1H);
send_pack();
break;
case ’v’: //read version
start_pack();
sPut("Rv=",3);
send_num8(VER_HIGH);
cPut(’.’);
send_num8(VER_LOW);
send_pack();
break;
}
break;
}
//clear buffer
for(k=0;k<LEN_VRX;k++){
v_rx[k]=0;
}
f_analisi_rx=false;
}
}
C.4 AutomaProcesso.c
/*------------------------------------------------------------------------------
automaProcesso.c
switch(stato){
case 0:
//Wait state
if(nvSeconds!=tmpSeconds){
stato=rel_stato;
tmpSeconds=nvSeconds;
}
break;
case 10:
//Make the time mask
nvControl=NVREAD;
clrDisplay();
addString("Data= ",6);
addDigit(HIGHNIBBLE(nvDate));
addDigit(LOWNIBBLE(nvDate));
addChar(’/’);
addDigit(HIGHNIBBLE(nvMonth));
addDigit(LOWNIBBLE(nvMonth));
addChar(’/’);
addDigit(HIGHNIBBLE(nvYear));
addDigit(LOWNIBBLE(nvYear));
addChar(’ ’);
addDigit(HIGHNIBBLE(nvHour));
addDigit(LOWNIBBLE(nvHour));
addChar(’:’);
addDigit(HIGHNIBBLE(nvMinutes));
addDigit(LOWNIBBLE(nvMinutes));
addChar(’:’);
addDigit(HIGHNIBBLE(nvSeconds));
addDigit(LOWNIBBLE(nvSeconds));
nDisplay=!nDisplay;
nvControl=NVNORMAL;
stato=10;
break;
case 20:
//Read Speed
start_pack();
temp=((ADC*40)-2515);
send_num16(temp);
send_pack();
ADC=0;
clrDisplay();
addString("Vel = ",6);
addDigit(((vel/1000)%10));
addDigit(((vel/100)%10));
//addChar(’.’);
addDigit(((vel/10)%10));
addDigit((vel%10));
addString(" [rpm]", 6);
nDisplay=!nDisplay;
stato=0;
break;
case 30:
//Read Temperature
arrTemp[pTemp++]=((ADC*40)-2515);
if(pTemp>=10)pTemp=0;
C.5 serial function.c 63
ADC=0;
clrDisplay();
temp=(arrTemp[0]+arrTemp[1]+arrTemp[2]+arrTemp[3]+arrTemp[4]+
arrTemp[5]+arrTemp[6]+arrTemp[7]+arrTemp[8]+arrTemp[9])/10;
addString("temp = ",7);
addDigit(((temp/1000)%10));
addDigit(((temp/100)%10));
addChar(’.’);
addDigit(((temp/10)%10));
addDigit((temp%10));
nDisplay=!nDisplay;
stato=0;
break;
case 40:
clrDisplay();
addString(nvStrings[p_strings],nvStringsL[p_strings]);
nDisplay=!nDisplay;
stato=0;
break;
case 100:
if(nvSeconds!=tmpSeconds){
tmpSeconds=nvSeconds;
if(c_sec>5){
c_sec=0;
stato=rel_stato;
}else{
c_sec++;
}
}
break;
case 110:
clrDisplay();
addString("Il Lessicottero:",16);
nDisplay=!nDisplay;
rel_stato=120;
stato=100;
break;
case 120:
clrDisplay();
addString("Area di Progetto",16);
nDisplay=!nDisplay;
rel_stato=130;
stato=100;
break;
case 130:
clrDisplay();
addString("Classe 5AEn 2005 - 2006",23);
nDisplay=!nDisplay;
rel_stato=110;
stato=100;
break;
};
//Fine macchina a stati
}
void start_pack(void){
EOT=false;
p_tx=0;
//add sync chars
v_tx[p_tx++]=0x55;
v_tx[p_tx++]=0xFF;
//add start byte
v_tx[p_tx++]=’:’;
//???address???
//v_tx[p_tx++]=1;
//v_tx[p_tx++]=5;
//2 byte void
p_tx+=2;
//???command???
}
void send_pack(void){
xdata unsigned char tmpCHK=0;
xdata unsigned int k;
//space
p_tx++;
//add 10 & 13
v_tx[p_tx++]=13;
v_tx[p_tx++]=10;
//lenght
v_tx[3]=(((p_tx-10)/10)%10)+48;
v_tx[4]=((p_tx-10)%10)+48;
//chk
for(sj=10;sj<p_tx-3;sj++){
tmpCHK+=v_tx[sj];
}
v_tx[p_tx-3]=tmpCHK;
//copy string len
l_tx=p_tx-1;
p_tx=0;
//enable transmitter
enTX=0;
enRX=1;
//wait ~10ms
for(k=0;k<1000;k++);
//send first char
SBUF=v_tx[0];
}
C.6 NVram.c
/*------------------------------------------------------------------------------
NVRAM.c
void fill_ram(void){
unsigned int k;
for(k=0;k<LENDISPLAY;k++){
nvDisplayA[k]=DisplayK[k];
}
}
C.7 Symbols.c
/*------------------------------------------------------------------------------
Symbols.c
//Sy[number of code][x+y]
code unsigned char Sy[93][120]= { ...
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0B, 0x7F,
0xFE, 0xF0, 0x1B, 0xFF, 0xFE, 0xF0, 0x1B, 0xFF, 0xFE, 0x90, 0x03,
0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00}, //!
...};
66 8051 Source Code
void clrDisplay(void){
if(nDisplay==1){
for(ptDisplay=0;ptDisplay<8000;ptDisplay++){
nvDisplayA[ptDisplay]=0;
}
}else{
for(ptDisplay=0;ptDisplay<8000;ptDisplay++){
nvDisplayB[ptDisplay]=0;
}
}
ptDisplay=0;
}
Sbit (P0_7 , 0x80, 7); Sbit (P0_6 , 0x80, 6); Sbit (P0_5 , 0x80, 5);
Sbit (P0_4 , 0x80, 4); Sbit (P0_3 , 0x80, 3); Sbit (P0_2 , 0x80, 2);
Sbit (P0_1 , 0x80, 1); Sbit (P0_0 , 0x80, 0);
Sbit (P1_7 , 0x90, 7); Sbit (P1_6 , 0x90, 6); Sbit (P1_5 , 0x90, 5);
Sbit (P1_4 , 0x90, 4); Sbit (P1_3 , 0x90, 3); Sbit (P1_2 , 0x90, 2);
Sbit (P1_1 , 0x90, 1); Sbit (P1_0 , 0x90, 0);
Sfr (P2 , 0xA0); Sbit (P2_7 , 0xA0, 7); Sbit (P2_6 , 0xA0, 6); Sbit
(P2_5 , 0xA0, 5); Sbit (P2_4 , 0xA0, 4); Sbit (P2_3 , 0xA0, 3); Sbit
(P2_2 , 0xA0, 2); Sbit (P2_1 , 0xA0, 1); Sbit (P2_0 , 0xA0, 0);
Sbit (P3_7 , 0xB0, 7); Sbit (P3_6 , 0xB0, 6); Sbit (P3_5 , 0xB0, 5);
Sbit (P3_4 , 0xB0, 4); Sbit (P3_3 , 0xB0, 3); Sbit (P3_2 , 0xB0, 2);
Sbit (P3_1 , 0xB0, 1); Sbit (P3_0 , 0xB0, 0);
Sbit (RD , 0xB0, 7); Sbit (WR , 0xB0, 6); Sbit (T1 , 0xB0, 5); Sbit
(T0 , 0xB0, 4); Sbit (INT1 , 0xB0, 3); Sbit (INT0 , 0xB0, 2); Sbit
(TXD , 0xB0, 1); Sbit (RXD , 0xB0, 0);
Sfr (P4 , 0xC0); Sbit (P4_7 , 0xC0, 7); Sbit (P4_6 , 0xC0, 6); Sbit
(P4_5 , 0xC0, 5); Sbit (P4_4 , 0xC0, 4); Sbit (P4_3 , 0xC0, 3); Sbit
(P4_2 , 0xC0, 2); Sbit (P4_1 , 0xC0, 1); Sbit (P4_0 , 0xC0, 0);
Sfr (P5 , 0xE8); Sbit (P5_7 , 0xE8, 7); Sbit (P5_6 , 0xE8, 6); Sbit
(P5_5 , 0xE8, 5); Sbit (P5_4 , 0xE8, 4); Sbit (P5_3 , 0xE8, 3); Sbit
(P5_2 , 0xE8, 2); Sbit (P5_1 , 0xE8, 1); Sbit (P5_0 , 0xE8, 0);
Sbit (CY , 0xD0 , 7); Sbit (AC , 0xD0 , 6); Sbit (F0 , 0xD0 ,
5); Sbit (RS1 , 0xD0 , 4); Sbit (RS0 , 0xD0 , 3); Sbit (OV , 0xD0
, 2); Sbit (UD , 0xD0 , 1); Sbit (P , 0xD0 , 0);
Sfr (ACC , 0xE0); Sfr (B , 0xF0); Sfr (SP , 0x81); Sfr (DPL , 0x82);
Sfr (DPH , 0x83);
0x88, 2); Sbit (IE0 , 0x88, 1); Sbit (IT0 , 0x88, 0);
Sfr (T2CON , 0xC8); Sbit (TF2 , 0xC8, 7); Sbit (EXF2 , 0xC8, 6);
Sbit (RCLK , 0xC8, 5); Sbit (TCLK , 0xC8, 4); Sbit (EXEN2 , 0xC8,
3); Sbit (TR2 , 0xC8, 2); Sbit (C_T2 , 0xC8, 1); Sbit (CP_RL2,
0xC8, 0);
Sfr (T2MOD , 0xC9); Sfr (TL0 , 0x8A); Sfr (TL1 , 0x8B); Sfr (TL2 ,
0xCC); Sfr (TH0 , 0x8C); Sfr (TH1 , 0x8D); Sfr (TH2 , 0xCD); Sfr
(RCAP2L , 0xCA); Sfr (RCAP2H , 0xCB); Sfr (WDTRST , 0xA6); Sfr
(WDTPRG , 0xA7);
/* IEN0 */ Sbit (EA , 0xA8, 7); Sbit (EC , 0xA8, 6); Sbit (ET2
, 0xA8, 5); Sbit (ES , 0xA8, 4); Sbit (ET1 , 0xA8, 3); Sbit (EX1
, 0xA8, 2); Sbit (ET0 , 0xA8, 1); Sbit (EX0 , 0xA8, 0);
Sbit (CCF4 , 0xD8, 4); Sbit (CCF3 , 0xD8, 3); Sbit (CCF2 , 0xD8,
2); Sbit (CCF1 , 0xD8, 1); Sbit (CCF0 , 0xD8, 0);
/*------------------ T W I registers
------------------------------*/ Sfr ( SSCON , 0x93); Sfr ( SSCS ,
0x94); Sfr ( SSDAT , 0x95); Sfr ( SSADR , 0x96); Sfr ( PI2 ,
0xF8); Sbit (PI2_1 , 0xF8, 1); Sbit (PI2_0 , 0xF8, 0);
#endif
C.9 Const.h
/*------------------------------------------------
CONST.H
------------------------------------------------*/
#define LOW(x) ((unsigned char)(x)) #define HIGH(x)
((unsigned char)((x)>>8)) #define HIGHNIBBLE(x) (((x) & 0xF0)>>4)
#define LOWNIBBLE(x) ((x) & 0x0F)
//versione
#define VER_HIGH 0 #define VER_LOW 1
//seriale
#define LEN_VRX 20 #define LEN_VTX 40 #define NEWLINE 10 #define
enRX P3_4 #define enTX P3_5
//RAM
#define MAX_XRAM 1790/2
//int eeprom
#define eeCONTACCH 0 #define eeCONTACCL 1
//NVRAM
#define NVREAD 0x40 #define NVWRITE 0x80 #define NVNORMAL
0x00 #define LENDISPLAY 4000
C.10 var.h
/*------------------------------------------------
VAR.H
------------------------------------------------*/
//e2prom
//xdata unsigned char mappa_eeprom[100] _at_ 0x0000;
//myTypes
70 8051 Source Code
union f {
float f; // Floating-point value
unsigned long ul; // Unsigned long value
unsigned char c[4]; // Array of unsigned char
};
union l{
unsigned long ul; // Unsigned long value
unsigned char c[4]; // Array of unsigned char
};
union i{
unsigned int ui; // Unsigned int value
unsigned char c[2]; // Array of unsigned char
};
//Vars
unsigned int pDisplay=0;unsigned int ptDisplay=0; bit nDisplay=0;
bit flag=false; unsigned char T1OF=0; unsigned int T0Rel=0; bit
inviaSer=false; code float Tcounter=600e-9; struct l tmpTim1;
unsigned int vel=0; bit fermo=false; char k_beep=-20; unsigned int
arrTemp[10]; unsigned char pTemp=0; unsigned char c_sec=0; bit
f_strings=false; unsigned char p_strings=0;
//Serial port
bit f_analisi_rx=false; bit EOT=false; xdata char v_rx[LEN_VRX];
xdata unsigned char p_rx=0; xdata char v_tx[LEN_VTX]; xdata unsigned
char p_tx=0; xdata unsigned char sj=0; xdata unsigned char l_tx=0;
//nvram
xdata unsigned char nvDisplayA[LENDISPLAY] _at_ 0x2000; xdata
unsigned char nvDisplayB[LENDISPLAY] _at_ (0x2000+LENDISPLAY+1);
xdata unsigned char nvStringsL[4] _at_ 0x3F41; xdata
unsigned char nvStrings[4][LENSTR] _at_ 0x3F45;
//myTypes
union f {
C.12 prot.h 71
union l{
unsigned long ul;
unsigned char c[4];
};
union i{
unsigned int ui;
unsigned char c[2];
};
//Vars
extern unsigned int vel; extern unsigned int ptDisplay; extern bit
nDisplay; extern unsigned int arrTemp[10]; extern unsigned char
pTemp; extern unsigned char c_sec; extern unsigned char p_strings;
//Serial port
extern bit f_analisi_rx; extern bit EOT; extern xdata char
v_rx[LEN_VRX]; extern xdata unsigned char p_rx; extern xdata char
v_tx[LEN_VTX]; extern xdata unsigned char p_tx; extern xdata
unsigned char sj; extern xdata unsigned char l_tx;
//nvram
extern xdata unsigned char nvDisplayA[LENDISPLAY]; extern xdata
unsigned char nvDisplayB[LENDISPLAY]; extern xdata unsigned char
nvStringsL[4]; extern xdata unsigned char nvStrings[4][LENSTR];
extern xdata volatile unsigned char nvControl; extern xdata volatile
unsigned char nvSeconds; extern xdata volatile unsigned char
nvMinutes; extern xdata volatile unsigned char nvHour; extern xdata
volatile unsigned char nvDay; extern xdata volatile unsigned char
nvDate; extern xdata volatile unsigned char nvMonth; extern xdata
volatile unsigned char nvYear;
C.12 prot.h
/*------------------------------------------------
PROT.H
------------------------------------------------*/
//Main
void ConfHard(void); void read_key(void);
//Serial Functions
void start_pack(void); void send_pack(void); void send_num8(unsigned
char Numero); void send_numBCD(unsigned char Numero); void
send_num16(unsigned int Numero); void send_num16bin(unsigned int
Numero); void cPut(char carattere); void sPut(char *carattere,
unsigned char len);
//Other
void automa_seriale(void);
void automa_processo(void);
//NVRAM
72 8051 Source Code
void fill_ram(void);
//Symbols
void clrDisplay(void); void addDigit(unsigned char Symbol); void
addChar(char Symbol); void addString(char *Symbol, unsigned char
len);
C.13 INTRINS.H
/*--------------------------------------------------------------------------
INTRINS.H
#endif
Appendice D
Datasheet
74 Datasheet
Bibliografia