Professional Documents
Culture Documents
Mihajlovi Duan
VIEKANALNI UREAJ ZA AKVIZICIJU ANALOGNIH
SIGNALA
-diplomski rad-
Beograd, 2006
Softver: 50%
Teorija: 10%
Mentor:
Beograd,
16.09.2006.
___________________
Mr. Borislav Hadibabi
IZVOD
U diplomskom radu je opisan viekanalni ureaj za akviziciju analognih signala i
memorisanje rezultata akvizicije na memorijsku karticu. Predvieno je da sistem
bude autonoman to znai da moe samostalno da radi nakon postavljanja u radno
okruenje. Memorisani podaci se mogu prebaciti na raunar radi kasnije analize i
obrade.
ABSTRACT
This work describes multichannel device for analogue signal acquisition and
storing results to the memory card. The system is made with main gold to work as
embedded device after it is placed into the working environment. Stored data can be
transferred to the computer for later analysis and processing.
SADRAJ
1. UVOD..........................................................................................................
2.1 MIKROKONTROLER............................................................................
10
11
12
2.11 TASTATURA.......................................................................................
13
14
16
16
3.2 INICIJALIZACIJA..................................................................................
18
18
19
20
20
21
22
23
25
4. ZAKLJUAK..............................................................................................
27
5. INDEKS POJMOVA...................................................................................
28
6. LITERATURA.............................................................................................
29
7. PRILOG......................................................................................................
30
30
Mihajlovi Duan
1. UVOD
Viekanalni ureaj za akviziciju analognih signala (u daljem tekstu DataLogger)
je ureaj zasnovan na mikrokontroleru iz PIC18 familije mikrokontrolera. Predvieno
je da DataLogger radi kao samostalni (Embedded) ureaj na mestu gde su potrebna
merenja analognih signala i temperature. Svaka fizika veliina se uz odgovarajui
senzor (pretvara) moe konvertovati u analogni napon. Zbog toga je spektar
primena DataLogger-a veoma veliki. Svi izmereni podaci se uvaju na memorijskoj
kartici radi kasnije analize i obrade.
Izrada DataLogger-a zahteva kako projektovanje samog hardvera tako i pisanje
odgovarajueg softvera za ureaj. Hardver se sastoji od sledeih celina logiki
razdvojenih na samoj tampanoj ploi: mikrokontroler, ispravljaki deo, serijska
komunikacija (RS232 i USB), digitalni Ulaz/Izlaz, konektor za programator, 4.096V
naponska referenca, reset kolo, konektori za analogne ulaze, konektori za dodatni
interfejs (za prilagoenje naponskog nivoa signala), DS1820 temperaturni senzor,
grafiki displej (128x64 piksela), tastatura i interfejs za memorijsku karticu. Na
sledeoj slici prikazana je tampana ploa DataLogger-a:
-1-
Mihajlovi Duan
-2-
Mihajlovi Duan
2.1 MIKROKONTROLER
Jedna od najvanijih odluka u procesu projektovanja mikrokontrolerskih ureaja
jeste pravilan izbor mikrokontrolera. Danas je zastupljen veliki broj proizvoaa
mikrokontrolera, ali jedan od najrasprostranjenijih je svakako Microchip sa PIC
mikrokontrolerom.
Karakteristike koje su bitne za pravilan izbor mikrokontrolera su: broj pinova
(zavisi od periferija koje se korise u ureaju), koliina FLASH, RAM i EEPROM
memorije, maksimalna brzina rada i kuite mikrokontrolera.
Odluio sam se za mikrokontroler PIC18F8722 sa 70 U/I pinova, 128KB FLASH
memorije, 3936B RAM memorije, 1024B EEPROM memorije, sa maksimalnom
brzinom od 40MHz i TQFP 80-piskom kuitu.
Ostale karakteristike ovog mikrokontrolera koje su iskoriene u DataLogger-u
su: 10-bitni A/D konvertor (16 kanala), SPI komunikacija (dva modula), EUSART
(RS232) komunikacija (dva modula) i 16-bitni tajmer (tri modula).
Kao to se moe videti na emi, iskorien je kristal kvarca 7.3728MHz.
Mikrokontroler radi u HS-PLL reimu tako da se brzina kristala mnoi sa 4 ime se
konano dobija 29.4912MHz.
PIC18F8722 mikrokontroler se programira preko PGC i PGD linija to e biti
objanjeno u poglavlju Konektor za programator.
-3-
Mihajlovi Duan
MCU-VCC
C3
C4
C5
C6
C7
100nF 100nF 100nF 100nF 100nF
RH2
RH3
RE1
RE0
RG0
RG1
RG2
RG3
MCU-MCLR
RG4
GND
MCU-VCC
RF7
RF6
RF5
RF4
RF3
RF2
RH7
RH6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
RH5
RH4
RF1
RF0
MCU-VCC
GND
RA3
RA2
RA1
RA0
GND
MCU-VCC
RA5
RA4
RC1
RC0
RC6
RC7
RJ4
RJ5
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
RH2/A18
RH1/A17
RH3/A19
RH0/A16
RE1/WR/AD9/P2C
RE2/CS/AD10/P2B
RE0/RD/AD8/P2D
RE3/AD11
RG0/ECCP3/P3A
RE4/AD12
RG1/TX2/CK2
RE5/AD13
RG2/RX2/DT2
RE6/AD14
RG3/CCP4/P3D
RE7/AD15
RG5/MCLR/VPP
RD0/PSP0/AD0
RG4/CCP5/P1D
VCC
GND
GND
VCC
RD1/PSP1/AD1
RF7/SS1
RD2/PSP2/AD2
RF6/AN11
RD3/PSP3/AD3
RF5/AN10/CVREF
RD4/PSP4/AD4/SDO2
RF4/AN9
RD5/PSP5/AD5/SDI2/SDA2
RF3/AN8
RD6/PSP6/AD6/SCK2/SCL2
RF2/AN7/C1OUT
RD7/PSP7/AD7/SS2
RH7/AN15
RJ0/ALE
RH6/AN14
RJ1/OE
RH5/AN13
RH4/AN12
RF1/AN6/C2OUT
RF0/AN5
AVCC
AGND
RA3/AN3/VREF+
RA2/AN2/VREFRA1/AN1
RA0/AN0
GND
VCC
RA5/AN4/HLVDIN
RA4/T0CKI
RC1/T1OSI/CCP2
RC0/T1OSO/T13CKI
RC6/TX1/CK1
RC7/RX1/DT1
RJ4/BA0
RJ5/CE
RJ2/WRL
RJ3/WRH
RB0/INT0
RB1/INT1
RB2/INT2
RB3/INT3
RB4/KBI0
RB5/KBI1/PGM
RB6/KBI2/PGC
GND
OSC2/CLKO/RA6
OSC1/CLKI/RA7
VCC
RB7/KBI3/PGD
RC5/SDO1
RC4/SDI1/SDA1
RC3/SCK1/SCL1
RC2/ECCP1/P1A
RJ7/UB
RJ6/LB
80
79
78
77
76
75
74
73
72
71
70
69
68
67
66
65
64
63
62
61
RH1
RH0
RE2
RE3
RE4
RE5
RE6
RE7
RD0
MCU-VCC
GND
RD1
RD2
RD3
RD4
RD5
RD6
RD7
RJ0
RJ1
60
59
58
57
56
55
54
53
52
51
50
49
48
47
46
45
44
43
42
41
RJ2
RJ3
RB0
RB1
RB2
RB3
RB4
RB5
MCU-RB6
GND
OSC2
OSC1
MCU-VCC
MCU-RB7
RC5
RC4
RC3
RC2
RJ7
RJ6
OSC1
OSC2
X1
7.3728MHz
C9
22pF
C10
22pF
OSCILLATOR
18F8722
MCU
-4-
Mihajlovi Duan
D1
1N4007
DB1
B280C1500
CN1
Vin
Vout
VCC
CON2
E1
470uF
C19
100nF
GND
1
2
REG1
7805
C1
100nF
E2
47uF
R19
2K2
LED dioda LED1 je indikator ukljuenja napona napajanja. Struja LED diode se
proraunava prema formuli:
ID =
VCC U D 5V 0.7V
=
= 4.3mA
R
1K
-5-
CD
DSR
RX
RTS
TX
CTS
DTR
RI
GND
Mihajlovi Duan
1
6
2
7
3
8
4
9
5
CN2
DB9
U1
13
R1 IN
8
R2 IN
11
T1 IN
10
T2 IN
1
E3
1uF
E4
1uF
6
15
MCU-Rx1
RC7
RC0
MCU-CTS1
12
R1 OUT
9
R2 OUT
14
T1 OUT
7
T2 OUT
C1+
C2+
C1 -
C2 -
V-
V+
GND
VCC
MAX232
RS-232 COM.
CONNECTOR
E5
1uF
5
2
E6
1uF
16
VCC
MCU-RTS1
RC1
RC6
MCU-Tx1
VCC
C2
100nF
Mihajlovi Duan
VCC
VCC
E10
10uF
C14
100nF
C15
100nF
U3
MCU-Rx2
MCU-Tx2
MCU-CTS2
MCU-RTS2
RG2
RG1
RG3
RG4
VCC
R12
1K
25
24
23
22
21
20
19
18
TXD
RXD
RTS
CTS
DTR
DSR
DCD
RI
16
TXDEN
15
PWREN
10
SLEEP
LED2
Tx&RxLED
12
TXLED
11
RXLED
VCC
14
R13
330
C13
100nF
PWRCTL
30
AVCC
13
VCCIO
3
VCC
26
VCC
3V3 OUT
USB
CONNECTOR
C16
100nF
CN16
8
USB D7
USB D+
XT IN
C17
27
X2
6MHz
XT OUT
28
TEST
VCC
2
D3
D+
4
GND
R16
27
22pF
C18
22pF
5
RSTOUT
4
RESET
EECS
EESK
EEDATA
R15
27
32
1
2
USB B
R14
1K5
R17
4K7
R18
10K
31
29
AGND
9
GND
17
GND
FT232BM
VCC
-7-
Mihajlovi Duan
JP2
VCC
2
3
3
CON3
RN2
RN3
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
RH0
RH1
RH2
RH3
RH4
RH5
RH6
RH7
RPACK8/9
VCC
RJ0
RJ1
RJ2
RJ3
RJ4
RJ5
RJ6
RJ7
RPACK8/9
CN17
1
3
5
7
9
VCC
CON3
RH0
RH2
RH4
RH6
CN18
RH1
RH3
RH5
RH7
2
4
6
8
10
RJ0
RJ2
RJ4
RJ6
VCC
HEADER 5X2
1
3
5
7
9
2
4
6
8
10
RJ1
RJ3
RJ5
RJ7
HEADER 5X2
CN13
MCU-RB6
MCU-RB7
MCU-MCLR
R20
100K
MCU-VCC
R21
100K
1
3
5
7
9
2
4
6
8
10
RB6
RB7
MCLR
HEADER 5X2
-8-
Mihajlovi Duan
4.096V
= 4mV .
1024
Opseg napona koji se na ovaj nain moe izmeriti je od 0V do 4.092V.
Naponska referenca je vezana za VREF+ pin mikrokontrolera koji je jedan od 16
kanala za A/D konverziju.
AN3/Vref+
RA3
VCC
R3
E7
10uF
REF1
2
VOUT
100
1
VIN
3
GND
MCP1541
-9-
Mihajlovi Duan
CN13
MCU-RB6
MCU-RB7
MCU-MCLR
R20
100K
MCU-VCC
R21
100K
1
3
5
7
9
2
4
6
8
10
RB6
RB7
MCLR
HEADER 5X2
MCLR
RESET
T9
C8
100n
- 10 -
Mihajlovi Duan
1
2
RA0
CON2
CN6
AN1
1
2
RA1
Konektori za dodatni
interfejs
CON2
CN7
AN2
1
2
RA2
CN3
RA0
RA1
RA2
RA5
CON2
CN8
AN4
Konektori za analogne
ulaze
1
2
RA5
VCC
1
3
5
7
9
2
4
6
8
10
HEADER 5X2
CON2
CN9
AN5
1
2
RF0
CN4
RF0
RF1
RF2
RF3
CON2
CN10
AN6
1
2
RF1
VCC
1
3
5
7
9
2
4
6
8
10
HEADER 5X2
CON2
CN11
AN7
1
2
RF2
CON2
CN12
AN8
1
2
RF3
CON2
VCC
TS1
1
VCC
2
DQ
3
GND
DS1820
- 11 -
Mihajlovi Duan
Function
/CSA
/CSB
VSS
GND
VDD
+5V
V0
Constrast adjustment
D/I
R/W
RST
Reset signal
18
VEE
19
20
- 12 -
Mihajlovi Duan
Vo
RE4
RE5
RE6
RD0
RD1
RD2
RD3
RD4
RD5
RD6
RD7
RE7
Kontrolne linije:
RE2-RE7
Linije podataka:
RD0-RD7
R5
10E
VCC
CS1
CS2
GND
VCC
Vo
RS
R/W
E
D0
D1
D2
D3
D4
D5
D6
D7
RST
Vee
LED+
LEDLCD128X64
2.11 TASTATURA
Kod DataLogger-a ugraeno je osam tastera za unos podataka i kontrolu rada
samog sistema. Tasteri su oznaeni sa T1-T8 i vezani su na PORTB mikrokontrolera.
Sobzirom da se PORTB koristi kao ulazni digitalni port neophodno je definisati
osnovno logiko stanje pinova kada tasteri nisu pritisnuti. To se obezbeuje sa pullup otpornikom mreom (RN1) koja osnovno logiko stanje definie kao logiko 1.
Pritiskom na jedan od tastera odgovarajui pin se vezuje na masu to predstavlja
logiku nulu.
- 13 -
Mihajlovi Duan
RB0
RB1
RB2
RB3
RB4
RB5
RB6
RB7
RPACK8/9
T1
T2
T3
T4
T5
T6
T7
T8
VCC
VCC
REG2
3
1
Vin
Vout
MC33269DT-3.3
E8
10uF
VCC3
GND
C11
100nF
E9
10uF
- 14 -
Mihajlovi Duan
MCU-SDI
RC4
MMC-CS#
RC2
MCU-SDO
RC5
MCU-SCK
RC3
VCC3
C12
100nF
VCC3
R6
2K2
R7
2K2
R8
2K2
CN15
1
2
3
4
5
6
7
R9
3K3
R10
3K3
CS
Din
GND
+3.3V
SCK
GND
Dout
MMC CARD
R11
3K3
- 15 -
Mihajlovi Duan
- 16 -
Mihajlovi Duan
START
Inicijalizacija
Citanje
parametara iz
EEPROM-a
Prikaz
"DataLogger" na
displeju
Podesavanje
parametara sistema
(EEPROM)
Citanje rezultata
A/D konverzije
Citanje
temperature
Upis u
memorijsku
karticu
Start A/D
konverzije
Citanje podataka
iz memorijske
kartice
Graficki displej
- 17 -
Mihajlovi Duan
3.2 INICIJALIZACIJA
Prva stvar koja je neophodna prilikom inicijalizacije jeste odreivanje smera
pinova (ulazni/izlazni) i poetnog logikog stanja pina (logiko 0 ili 1). PIC18F8722
ima 70 U/I pinova koji su logiki podeljeni na PORTA, PORTB, PORTC, PORTD,
PORTE, PORTF, PORTG, PORTH i PORTJ.
Sledea je inicijalizacija grafikog displeja i postavljanje osnovnog fonta za ispis
na displej. Linije podataka D0-D7 se nalaze na portu D (RD0-RD7), a kontrolne linije
CS1, CS2, RS, R/W, E i RST se nalaze na portu E (RE2-RE7) respektivno.
Serijska komunkacija EUSART modul 1 se koristi kao standardni RS232 port i
inicijalizuje se na brzinu 115200bit/s. Serijska komunikacija EUSART modul 2 se
koristi sa FT232BM konvertorom na USB komunikaciju tako da se inicijalizuje na
veu brzinu od 921600bit/s. Oba serijska modula koriste hardverski handshaking
tako da je neophodno postaviti aktivan logiki nivo na RTS linijama ovih modula.
Sledee je uitavanje parametara sistema iz EEPROM-a zato to su ti
parametri neophodni za dalju inicijalizaciju ureaja. Preko ovih parametara u toku
inicijalizacije, a i kasnije u toku rada ureaja mogu se menjati karakteristike i
ponaanje sistema: kalibracija 4.096V naponske reference, odreivanje ciklusa upisa
izmerenih podataka u memorijsku karticu i ukljuenje/iskljuenje izvora analognih
napona i DS1820 temperaturnog senzora.
Podeavanje ciklusa upisa u memorijsku karticu direktno utie na inicijalizaciju
Tajmera 0. Timer 1 se koristi za debouncing tastature. Na svakih 50ms vri se
oitavanje stanja tastature i uporeuje sa vrednou prethodnog skeniranja. Ako
postoji razlika znai da je taster pritisnut. Timer 0 i 1 generiu prekide prilikom
dostizanja maksimalne vrednosti i neophodno je obezbediti interapt rutinu koja e
odrediti ta e se desiti ukoliko je nastupio interapt. Tajmeri i interapti su detaljnije
obraeni u sledeem poglavlju.
TCY =
1
1
=
0.1356s
FCY 7.3728MHz
- 18 -
Mihajlovi Duan
vremenski period za upis podataka u memorijsku karticu 50ms (Tajmer 0) dok je taj
vremenski period fiksan za sluaj skeniranja tastature (Tajmer 1).
Da bi mogli da se generiu dui periodi za upis u memorijsku karticu iskoriena
je jo jedna osobina Tajmera 1 a to je Prescaler. Prescaler slui da uspori merenje
vremena od 2 do 256 puta (sa koracima koji su stepen broja 2). Vrednost prescaler-a
se moe menjati podeavanjem parametara u EEPROM-u. Pored ovog podatka u
EEPROM-u se uva i podatak o broju osnovnih vremenskih intervala (50ms) koji je
potrebno da istekne da bi bio generisan interapt. Na ovaj nain period upisa
podataka u memorijsku karticu moe se podeavati od 50ms do priblino 15h.
*****************************************************************
read
...displays current parameter settings,
write -calib ...writes new calibration value for VREF,
write -cycle ...writes new timebase for MMC write,
write -source ...writes new settings for ADC sources selection,
write -ds1820 ...writes new settings for DS1820 temp. sensor!
*****************************************************************
Komanda read prikazuje trenutne parametre sistema. Jedan odziv sistema na
ovu komandu bi mogao da izgleda ovako:
*****************************************************************
calib = 0x8000
cycle = 0xF002
source = 0xFF
ds1820 = 0xFF
*****************************************************************
Komanda write -calib upisuje novu vrednost kalibracione konstante u
EEPROM. Sve konstante se prikazuju i unose u heksadecimalnom brojnom sistemu.
Vrednost kalibracione konstante se rauna prema sledeoj formuli:
- 19 -
Mihajlovi Duan
Cal =
Vizm
32768 .
Vnaz
4.093V
32768 = 32744
4.096V
VCH =
V pret + Vtren
- 20 -
Mihajlovi Duan
TEMPERATURE
+85.0C
+25.0C
+0.5C
0C
-0.5C
-25.0C
-55.0C
DIGITAL OUTPUT
DIGITAL OUTPUT
(Binary)
(Hex)
00AAh
0032h
0001h
0000h
FFFFh
FFCEh
FF92h
- 21 -
Mihajlovi Duan
TAD = 32 TOSC = 32
TCY
0.1356s
= 32
= 1.085s
4
4
T ACQ = 6 T AD = 6 T AD = 6 1.085 s = 6 . 51 s
Ukupno vreme potrebno za A/D konverziju jednog kanala se rauna po formuli:
- 22 -
Mihajlovi Duan
***********************************************************
erase
...erases data from mmc/sd card,
read -mmc
...reads data from mmc/sd card,
read -cid
...reads cid register (card ID),
read -csd
...reads csd register (card specific data)
status
...displays MMC/SD card status (usage etc.)!
***********************************************************
Komanda erase brie sadraj memorijske kartice. Ukoliko kartica nije ubaena
u MMC slot prijavie da kartica nije detektovana.
Komanda read -mmc ita podatke sa MMC kartice. Da bi se podaci sauvali u
tekstualni fajl na PC-u, pre unosa ove komande, potrebno je ukljuiti opciju Capture
Text i upisati ime tekstualne datoteke. Odziv sitema na ovu komandu bi mogao da
izgleda ovako:
***********************************************************
time:
s: val:
***********************************************************
00 00000004 01 08C7
00 00000004 02 078A
00 00000004 04 0A3E
00 00000004 08 0775
00 00000004 10 05E9
00 00000004 20 08A6
00 00000004 40 0B22
00 00000004 80 07CF
- 23 -
Mihajlovi Duan
00 00000004 FF 003C
00 00000006 01 0A3C
00 00000006 02 08CC
00 00000006 04 0BF3
00 00000006 08 08B3
00 00000006 10 06E5
00 00000006 20 0A17
00 00000006 40 0CFD
00 00000006 80 091C
00 00000006 FF 003C
00 00000008 01 0B50
00 00000008 02 09B6
00 00000008 04 0D36
00 00000008 08 099E
00 00000008 10 079D
00 00000008 20 0B26
00 00000008 40 0E5C
00 00000008 80 0A12
00 00000008 FF 003C
***********************************************************
Prva, neoznaena, kolona je neiskorien bajt da bi vrednost podatka jednog
zapisa iznosila osam bajtova. Druga kolona predstavlja referentno vreme kada je
upisan podatak u memorijsku karticu i predstavljan je sa vrednou podeoka od
50ms. Poetak merenja vremena je od prvog upisa u memorijsku karticu. Trea
kolona predstavlja izvor podatka ija je vrednost upisana u koloni broj etiri i
znaenje se moe videti u sledeoj tabeli:
Vrednost
Izvor
0x01
Senzor 0
0x02
Senzor 1
0x04
Senzor 2
0x08
Senzor 3
0x10
Senzor 4
0x20
Senzor 5
0x40
Senzor 6
0x80
Senzor 7
0xFF
DS1820 senzor
- 24 -
Mihajlovi Duan
Komanda read -cid ispisuje na terminalu vrednost CID registra i moe imati
sledei odziv:
***********************************************************
FE 06 00 00 31 32 38 4D 20 20 01 1A CB 62 09 67
***********************************************************
Komanda read -csd ispisuje na terminalu vrednost CSD registra i moe imati
sledei odziv:
***********************************************************
8C 0E 01 2A 0F F9 81 E9 F6 DA 81 E1 8A 40 00 11
***********************************************************
Komanda status ispisuje na ekranu koliko je procenata memorijske kartice
iskorieno i koliki je kapacitet memorijske kartice i moe imati sledei odziv:
- 25 -
Mihajlovi Duan
- 26 -
Mihajlovi Duan
4. ZAKLJUAK
Osnovni zadatak ovog diplomskog rada je akvizicija analognih signala, uvanje
podataka na memorijskoj kartici i njihov prenos na raunar radi kasnije analize i
obrade. Odlueno je da svaki zapis u memorijskoj kartici sadri kako izvor i vrednost
signala tako i referentno vreme kada je signal izmeren. Podaci se na raunar
prenose serijskom komunikacijom i to u tabelarnom obliku tako da je olakana
kasnija analiza. Testiranjem samog ureaja ustanovljeno je da su funkcionalni
zahtevi u potpunosti realizovani.
Ureaj je napravljen tako da moe samostalno da radi nakon smetanja u radno
okruenje. Jedino je neophodno da operater podesi odgovarajue parametre sistema
i da prenese podatke sa ureaja na raunar. Sva kasnija analiza i obrada se moe
obaviti nezavisno od ureaja.
U daljem razvoju bilo bi poeljno da se ostvari beicna komunikacija. Mogao bi
da se iskoristi RF modem za kratka rastojanja ili GPRS modem za prenos preko
interneta. Na taj nain bi operater mogao sa jednog mesta da podeava parametre i
prenese podatke sa desetine ureaja. Ovo bi ureaju dalo jos veu autonomiju.
- 27 -
Mihajlovi Duan
5. INDEKS POJMOVA
A
asembler 2
A/D konvertor 3,10,22
analogni ulaz 1,3,10,11,20,22
akvizicija 1,22,27
B
backlight 13
bafer 6,21
C
C (programski jezik) 2
CTS 6
CID 21,22,23,25
CSD 22,23,25,26
COM port 23
D
debouncing 9,18
E
EEPROM 3,16,18,19,21
EUSART 3,5,7,18
F
FLASH 3
FT232 5,6,7,18,23
G
grafiki displej 1,3,12,13,16,18,25
Grecov most 4
H
HEX (fajl format) 2,8
handshaking 5,6,18,23
I
interfejs 1,3,10,11,14,15,21
inicijalizacija 16,18,22,23
K
kontrast 1,3,12
kompajler 2,16
kristal kvarca 3,18
kalibracija 5,18
N
naponska referenca 1,3,9
O
otpornika mrea 7,13
P
pretvara 1,10
programator 1,2,3,8,9
PIC 3,16
PGC, PGD 3,8
pull-down 7,9
pull-up 7,10,12,13
pojaava 10
piksel 1,3,12
prescaler 19
R
RAM 3
RS232 1,3,5,6,7,18,19,27
regulator 4,14
RTS 6,18
RF modem 27
S
serijska komunikacija
1,3,5,6,18,19,23,27
SPI 3,14,15,21
senzor 1,3,5,10,11,12,18,20,24
smoothing 20
sektor 21,22,26
T
tastatura 1,3,13,14,18,19
temperaturni senzor 1,3,5,11,12,18,20
tajmer 3,18,19
transceiver 5,6
taster 9,10,13,18,25
terminal 19,23,25
L
LED dioda 5
M
MAX232 5
MCLR 8,9,10
- 28 -
Mihajlovi Duan
6. LITERATURA
1. PIC18F8722 Family Datasheet , www.microchip.com
2. FT232 USB UART , www.ftdichips.com
3. SanDisk Secure Digital Card Product Manual , www.sandisk.com
4. MultiMedia Card Specification , www.samsung.com
5. DS1820 Digital Thermometer , www.dalsemi.com
6. PICflash2 Manual , www.mikroe.com
7. MCP1525/41 2.5V and 4.096V Voltage references, www.microchip.com
- 29 -
Mihajlovi Duan
7. PRILOG
7.1 PROGRAMSKI KOD DATALOGGER SISTEMA
U nastavku je dat kompletan programski kod DataLogger sistema. Kod je pisan
za mikroC kompajler firme MikroElektronika i podeljen je po modulima radi
preglednosti.
- 30 -
DataLogger.c
1:
2:
3:
4:
5:
6:
7:
8:
9:
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:
9/19/2006
/*******************************************************************************
* Project name:
DataLogger
* Author:
Mihajlovic Dusan
* Description:
Main program. Oscillator 7.3728*4(HSPLL) = 29.4912 MHz
* NOTES:
None.
*******************************************************************************/
#include
#include
#include
#include
#include
"AsmConstants.h"
"Constants.h"
"Variables.h"
"Declarations.h"
"built_in.h"
void interrupt(void)
{
//ADC interrupt:
if(PIR1.ADIF && PIE1.ADIE)
{
adc_result[ch_num] = (ADRESH << 8) | ADRESL;
//write conversion
result in adc_result for current channel
switch(ch_num)
{
case 0: if(adc_source.F1)
//if next channel is selected start new
conversion and break
{
ADCON0 = 0b00000101; //AN1, IDLE, ON
ch_num = 1;
break;
}
case 1: if(adc_source.F2)
{
ADCON0 = 0b00001001; //AN2, IDLE, ON
ch_num = 2;
break;
}
case 2: if(adc_source.F3)
{
ADCON0 = 0b00010001; //AN4, IDLE, ON
ch_num = 3;
break;
}
case 3: if(adc_source.F4)
{
ADCON0 = 0b00010101; //AN5, IDLE, ON
ch_num = 4;
break;
}
case 4: if(adc_source.F5)
{
ADCON0 = 0b00011001; //AN6, IDLE, ON
ch_num = 5;
break;
}
DataLogger.c
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
9/19/2006
case 5: if(adc_source.F6)
{
ADCON0 = 0b00011101; //An7, IDLE, ON
ch_num = 6;
break;
}
case 6: if(adc_source.F7)
{
ADCON0 = 0b00100001; //AN8, IDLE, ON
ch_num = 7;
break;
}
//if there is no selected channels (or there is no more channels):
default:
{
adc_started = 0;
PIR1.ADIF = 0;
goto ADC_End;
//if there is no more channels to convert
go to ADC_End
}
}
PIR1.ADIF = 0;
ADCON0.GO_DONE = 1; //start conversion
}
ADC_End:
//Timer0 - MMC write:
if(INTCON.TMR0IF && INTCON.TMR0IE)
{
//Reset starting value:
TMR0H = 0x70;
//0x7000 = 28672 (start value)
TMR0L = 0x00;
//65536-28672=36864*Tcy => 5ms
mmc_int++;
//increments every 5ms*prescaler_value
if(mmc_int == 10)
{
mmc_int = 0;
//reset mmc_int
mmc_counter++; //increments every 50ms*prescaler_value
if(mmc_counter >= (mmc_cycle & 0x0FFF))
{
total_time += partial_time; //adds mmc write period (prescaler
included) to total_time
mmc_counter = 0;
//reset mmc_counter
write_mmc = 1;
//set write_mmc flag
}
}
INTCON.TMR0IF = 0;
}
//Timer1 - buttons:
if(PIR1.TMR1IF && PIE1.TMR1IE)
{
//Reset starting value:
TMR1H = 0x70;
//0x7000 = 28672 (start value)
TMR1L = 0x00;
//65536-28672=36864*Tcy => 5ms
buttons_int++;
if(buttons_int == 4)
{
buttons_int = 0;
//reset buttons_int
buttons_new = PORTB;
//Buttons press:
DataLogger.c
113:
9/19/2006
//detects if button
is pressed
114:
115:
116:
117:
118:
119:
{
//set buttons flag (will be overwriten on next button press)
buttons = (buttons_new ^ buttons_old) & buttons_old;
}
//Buttons release:
/*if((buttons_new ^ buttons_old) & buttons_new)
//detects if
button is released
120:
{
121:
//set buttons flag (will be overwriten on next button press)
122:
buttons = (buttons_new ^ buttons_old) & buttons_new;
123:
}*/
124:
buttons_old = buttons_new;
125:
}
126:
PIR1.TMR1IF = 0;
127:
}
128: }
129:
130: main()
131: {
132:
//turn off comparators:
133:
CMCON = 0x07;
//00000111
134:
135:
//disable external memory bus:
136:
MEMCON.EBDIS = 1;
137:
138:
/* PORTA - Analogue inputs and VREF+ as reference (4.096V):
139:
RA5
RA4
RA3
RA2
RA1
RA0
140:
AN4
NC
VREF+ AN2
AN1
AN0
141:
*/
142:
PORTA = 0x00;
//00000000
143:
TRISA = 0xEF;
//11101111
144:
145:
/* PORTB - Buttons (Pulled-Up):
146:
RB7
RB6
RB5
RB4
RB3
RB2
RB1
RB0
147:
#3
#2
#1
ENT RIGHT DOWN LEFT UP
148:
*/
149:
PORTB = 0xFF;
//11111111
150:
TRISB = 0xFF;
//11111111
151:
152:
/* PORTC - RS232-1, SPI ans MMC-CS#:
153:
RC7
RC6
RC5
RC4
RC3
RC2
RC1
RC0
154:
Rx1
Tx1
MOSI MISO SCK MMC-CS# RTS1 CTS1
155:
*/
156:
PORTC = 0x07;
//00000111
157:
TRISC = 0x91;
//10010001
158:
159:
/* PORTD - Graphic LCD data lines:
160:
RD7
RD6
RD5
RD4
RD3
RD2
RD1
RD0
161:
D7
D6
D5
D4
D3
D2
D1
D0
162:
*/
163:
PORTD = 0x00;
//00000000
164:
TRISD = 0x00;
//00000000
165:
166:
/* PORTE - Graphic LCD control lines and DS1820 temp. sensor:
167:
RE7
RE6
RE5
RE4
RE3
RE2
RE1
RE0
168:
RST
E
R/W
RS
CS2# CS1# NC
DS1820
DataLogger.c
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
*/
PORTE = 0x0D;
TRISE = 0x01;
9/19/2006
//00001101
//00000001
RF3
AN8
RF2
AN7
RF1
AN6
RF0
AN5
RG3
CTS2
RG2
Rx2
RG1
Tx2
RG0
NC
//00111000
//00101100
DataLogger.c
227:
228:
229:
9/19/2006
TMR0L = 0x00;
//65536-28672=36864*Tcy => 5ms
T0CON = 0x00;
//Timer0 OFF, 16-bit timer, clear Prescaler settings
T0CON = (T0CON & 0xF0) | (mmc_cycle >> 12); //Load Prescaler settings from
EEPROM
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274: }
275:
AsmConstants.h
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
9/19/2006
/*******************************************************************************
* Project name:
DataLogger
* Author:
Mihajlovic Dusan
* Description:
Assembler constants definitions.
* NOTES:
None.
*******************************************************************************/
#ifndef _ASMCONSTANTS_H_
#define _ASMCONSTANTS_H_
#define
#define
#define
#define
#define
VREF_CAL_ADDR
MMC_CYCLE_ADDR
ADC_SOURCE_ADDR
DS1820_ADDR
CID_ADDR
0
2
4
5
6
#define DIRECT_MAX
#define CYCLE_MAX
writes (in 50ms)
#define
#define
#define
#define
PORTC.F1
PORTC.F0
PORTG.F4
PORTG.F3
//RTS
//CTS
//RTS
//CTS
80
13
6
RTS1
CTS1
RTS2
CTS2
#define ADC_SCALER
glcd graph)
30: #define BAR_WIDTH
31: #define BAR_OFFSET
32:
33: #endif
34:
Usart_console1
Usart_console1
Usart_console2
Usart_console2
Constants.h
1:
2:
3:
4:
5:
6:
7:
8:
9:
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:
9/19/2006
/*******************************************************************************
* Project name:
DataLogger
* Author:
Mihajlovic Dusan
* Description:
Constants definitions.
* NOTES:
None.
*******************************************************************************/
#ifndef _CONSTANTS_H_
#define _CONSTANTS_H_
const char *help1 =
"*****************************************************************\r\n\
\"read\" \t\t...displays current parameter settings,\r\n\
\"write -calib\" \t...writes new calibration value for VREF,\r\n\
\"write -cycle\" \t...writes new timebase for MMC write,\r\n\
\"write -source\" ...writes new settings for ADC sources selection,\r\n\
\"write -ds1820\" ...writes new settings for DS1820 temp. sensor!\r\n\
*****************************************************************\r\n";
const char *read1[5] = {
"*****************************************************************\r\n\
calib = 0x","\t\r\n\
cycle = 0x","\t\r\n\
source = 0x","\t\r\n\
ds1820 = 0x","\t\r\n\
*****************************************************************\r\n"};
const char *value = "Enter value: 0x";
const char *err_value = "Unknown format!\r\nEnter value: 0x";
const char *ok_value = "Parameter is saved in EEPROM!\r\n";
const char *help2 =
"***********************************************************\r\n\
\"erase\" \t...erases data from mmc/sd card,\r\n\
\"read -mmc\" \t...reads data from mmc/sd card,\r\n\
\"read -cid\" \t...reads cid register (card ID),\r\n\
\"read -csd\" \t...reads csd register (card specific data)\r\n\
\"status\" \t...displays MMC/SD card status (usage etc.)!\r\n\
***********************************************************\r\n";
const char *read2[2] = {
"***********************************************************\r\n\
time:
s: val:\r\n\
***********************************************************\r\n",
"***********************************************************\r\n"};
const char *no_card = "MMC/SD card not detected! Please insert card and try
again.\r\n";
const char *abort = "Erase aborted!\r\n";
const char *yes_no = "Are you sure you want to erase data from card? Yes/No? ";
const char *erase_ok = "MMC/SD card erased!\r\n";
const char *err_write = "Error while writing MMC/SD card!\r\n";
const char *err_read = "Error while reading MMC/SD card!\r\n";
const char *full = "MMC/SD card is full!\r\n";
Constants.h
9/19/2006
Variables.h
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
9/19/2006
/*******************************************************************************
* Project name:
DataLogger
* Author:
Mihajlovic Dusan
* Description:
Variables declarations.
* NOTES:
None.
*******************************************************************************/
#ifndef _VARIABLES_H_
#define _VARIABLES_H_
unsigned vref_cal;
unsigned mmc_cycle;
char directive1[DIRECT_MAX+1];
NULL
27:
28: unsigned short count1 = 0;
//count of chars in the
string (console 1)
29: unsigned short write_calib = 0, write_cycle = 0;
//write_calib and
write_cycle flags
30: unsigned short write_source = 0, write_ds1820 = 0; //write_source and
write_ds1820 flags
31:
32: unsigned short write_mmc = 0;
//mmc write enabled (from interrupt)
33: unsigned short mmc_full = 0;
//mmc card full
34: unsigned short mmc_empty = 1;
//mmc card empty
35: unsigned short mmc_err = 0;
//mmc card error
36: unsigned short mmc_int = 0;
//increments on every Timer0 interrupt 5ms*prescaler_value
37: unsigned mmc_counter = 0;
//increments on every 10th Timer0 interrupt 50ms*prescaler_value
38: unsigned short mmc_backup = 0; //mmc_backup flag
39:
40: unsigned short buttons = 0x00, buttons_old = 0xFF, buttons_new = 0xFF;
//buttons state
41: unsigned short buttons_int = 0; //increments on every Timer1 interrupt - 5ms
42:
43: unsigned long total_time = 0;
//total time in 50ms
44: unsigned long partial_time = 0; //mmc_cycle in 50ms (with prescaler included)
45: unsigned short data[512];
//buffer for MMC sector reading/writing
46: unsigned short data_sec[512];
//secondary buffer for MMC sector
reading/writing
47: unsigned data_counter = 0;
//counts how many bytes are writen into buffer
48: unsigned short CID_old[16];
//buffer for last CID
49: unsigned short CID_new[16];
//buffer for new CID
50: unsigned short CSD[16];
//buffer for CSD
Variables.h
9/19/2006
Declarations.h
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
9/19/2006
/*******************************************************************************
* Project name:
DataLogger
* Author:
Mihajlovic Dusan
* Description:
Subroutines declarations.
* NOTES:
None.
*******************************************************************************/
#ifndef _DECLARATIONS_H_
#define _DECLARATIONS_H_
void
void
void
void
void
Eeprom_startup();
Usart_InitHS1();
Usart_InitHS2();
Usart_console1();
Usart_console2();
26:
27: void WriteStr1(const char *s);
//writes string on Usart1
28: void WriteStr2(const char *s);
//writes string on Usart2
29: unsigned short isStrX(char *s);
//all digits in string are Hex digits? 1 Yes, 0 - No
30:
31: void Read_ADC();
//read ADC result and do calibration
32: void MMC_write();
//writes ADC and DS1820 result into MMC when
mmc_write flag is set
33: void Backup();
//writes buffer to mmc without effecting
data_counter or sector address
34: void Start_ADC();
//start A/D conversion
35: void Read_ds1820();
//read ds1820 temperature
36: unsigned short GetBit(unsigned short *array, unsigned short bit); //gets bit 0255 from array (max 32-byte)
37:
38: //Send command to MMC:
39: unsigned char Mmc_Send_Command_Cust(char partial_cmm, unsigned long address,
char crc);
40: //Read CSD Register:
41: unsigned char Mmc_Read_Csd_Cust(char * data_for_registers);
42: unsigned short strcmp_cust(char *str1, char *str2);
43: void ADCtoStr(unsigned number, char *output);
//converts ADC_result to string
44: void ds1820toStr(int number, char *output);
//converts ds1820_result to
string
45: void GLCD_main();
//manage display modes depending on button presses
46: void GLCD_graph();
//draw graph on glcd depending on analogue input and
temperature
Declarations.h
9/19/2006
EEPROM.c
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
9/19/2006
/*******************************************************************************
* Project name:
DataLogger
* Author:
Mihajlovic Dusan
* Description:
EEPROM subroutines definitions.
* NOTES:
None.
*******************************************************************************/
#include "AsmConstants.h"
#include "Declarations.h"
#include "built_in.h"
EEPROM.c
49:
50:
51:
9/19/2006
52:
53:
54:
55:
//Reads ADC sources (1-byte):
56:
adc_source = Eeprom_Read(ADC_SOURCE_ADDR);
57:
58:
//Reads DS1820 On/Off (1-byte):
59:
ds1820 = Eeprom_Read(DS1820_ADDR);
60:
61:
//Reads last CID (16-bytes):
62:
for(i=0; i<16; i++)
63:
{
64:
CID_old[i] = Eeprom_Read(CID_ADDR+i);
65:
}
66: }
67:
68: void Usart_console1()
//Console for EEPROM parameters setup
69: {
70:
char ch, temp[8];
//received
character and temporary string
71:
unsigned short string_done = 0;
//flag for string
completion
72:
unsigned i, j;
//counters
73:
extern unsigned short count1;
//count of chars
in the string
74:
extern unsigned short write_calib, write_cycle;
//write_calib and
write_cycle flags
75:
extern unsigned short write_source, write_ds1820;
//write_source and
write_ds1820 flags
76:
extern const char *help1, *read1[5], *value, *err_value, *ok_value;
//help1, read1, value, err_value, ok_value strings
77:
extern char directive1[DIRECT_MAX+1];
//buffer for
received string
78:
79:
if(Usart_Data_Ready1())
80:
{
81:
ch = Usart_Read1();
82:
//If there is no more space in string and last recaived char is not
83:
//CR do nothing - return
84:
if(count1 == DIRECT_MAX && ch != 13) return;
85:
Usart_Write1(ch);
//writes back received char so we
can see what we type
86:
directive1[count1++] = tolower(ch);
87:
if(ch == 13)
88:
{
89:
directive1[count1-1] = 0;
90:
count1 = 0;
91:
string_done = 1;
//string completion flag
92:
Usart_Write1(13);
//CR
93:
Usart_Write1(10);
//LF
94:
}
95:
if(string_done)
EEPROM.c
96:
97:
98:
99:
100:
101:
9/19/2006
{
if(write_calib == 1)
//stores new vref_calib value into EEPROM
{
if(!isStrX(directive1))
{
WriteStr1(err_value);
//displays "Unknown format!" on
the terminal
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
return;
}
write_calib = 0;
vref_cal = atowHEX(directive1);
//Writes NEW 4.096V reference calibration value (2-bytes):
Eeprom_Write(VREF_CAL_ADDR,Lo(vref_cal));
Eeprom_Write(VREF_CAL_ADDR+1,Hi(vref_cal));
WriteStr1(ok_value);
//displays "Parameter is saved in
EEPROM!" on the terminal
return;
}
if(write_cycle == 1)
//stores new mmc_cycle value into EEPROM
{
if(!isStrX(directive1))
{
WriteStr1(err_value);
//displays "Unknown format!" on
the terminal
return;
}
write_cycle = 0;
mmc_cycle = atowHEX(directive1);
//Writes NEW timebase for MMC write cycle (2-bytes):
Eeprom_Write(MMC_CYCLE_ADDR,Lo(mmc_cycle));
Eeprom_Write(MMC_CYCLE_ADDR+1,Hi(mmc_cycle));
WriteStr1(ok_value);
//displays "Parameter is saved in
EEPROM!" on the terminal
//Loads NEW Prescaler settings into Timer0:
T0CON = (T0CON & 0xF0) | (mmc_cycle >> 12);
if(T0CON.F3 == 1)
//if Prescaler is not assigned mmc write
period equals mmc_cycle (bits 0 - 11)
{
partial_time = (unsigned long)(mmc_cycle & 0x0FFF);
}
else
//if Prescaler is assigned mmc write period
equals mmc_cycle*prescaler_value
{
switch(T0CON & 0x07)
{
case 0b00000111: partial_time = (unsigned long)(mmc_cycle &
0x0FFF) << 8; break;
case 0b00000110: partial_time = (unsigned long)(mmc_cycle &
0x0FFF) << 7; break;
case 0b00000101: partial_time = (unsigned long)(mmc_cycle &
0x0FFF) << 6; break;
case 0b00000100: partial_time = (unsigned long)(mmc_cycle &
0x0FFF) << 5; break;
case 0b00000011: partial_time = (unsigned long)(mmc_cycle &
0x0FFF) << 4; break;
case 0b00000010: partial_time = (unsigned long)(mmc_cycle &
0x0FFF) << 3; break;
case 0b00000001: partial_time = (unsigned long)(mmc_cycle &
0x0FFF) << 2; break;
EEPROM.c
142:
9/19/2006
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
}
}
if(partial_time > CYCLE_MAX && data_counter != 0)
//if mmc
write period is more then CYCLE_MAX*50ms
{
//and
buffer have min 1 record do mmc write
mmc_backup = 1; //set mmc_backup flag
}
return;
}
if(write_source == 1)
//stores new ADC_source value into EEPROM
{
if(!isStrX(directive1))
{
WriteStr1(err_value);
//displays "Unknown format!" on
the terminal
return;
}
write_source = 0;
adc_source = atobHEX(directive1);
//Writes NEW ADC sources (1-byte):
Eeprom_Write(ADC_SOURCE_ADDR,adc_source);
WriteStr1(ok_value);
//displays "Parameter is saved in
EEPROM!" on the terminal
return;
}
if(write_ds1820 == 1)
//stores new DS1820 On/Off value into EEPROM
{
if(!isStrX(directive1))
{
WriteStr1(err_value);
//displays "Unknown format!" on
the terminal
return;
}
write_ds1820 = 0;
ds1820 = atobHEX(directive1);
//Writes NEW DS1820 On/Off (1-byte):
Eeprom_Write(DS1820_ADDR,ds1820);
WriteStr1(ok_value);
//displays "Parameter is saved in
EEPROM!" on the terminal
return;
}
if(0 == strcmp_cust(directive1,"help")) //displays "help" on the
terminal
{
WriteStr1(help1);
return;
}
if(0 == strcmp_cust(directive1,"read")) //displays EEPROM
parameters on the terminal
{
for(i = 0; i<5; i++)
{
WriteStr1(read1[i]);
switch (i)
{
EEPROM.c
191:
192:
193:
194:
9/19/2006
case 0:
{
WordToStrHEX(vref_cal,temp);
for(j = 0; j<4; j++)
//displays 4 digit HEX value on
the terminal
195:
196:
197:
198:
199:
200:
201:
202:
203:
{
Usart_Write1(temp[j]);
}
break;
}
case 1:
{
WordToStrHEX(mmc_cycle,temp);
for(j = 0; j<4; j++)
//displays 4 digit HEX value on
the terminal
204:
205:
206:
207:
208:
209:
{
Usart_Write1(temp[j]);
}
break;
}
case 2:
decimal format)
210:
211:
212:
{
ByteToStrHEX(adc_source,temp);
for(j = 0; j<2; j++)
//displays 2 digit HEX value on
the terminal
213:
214:
215:
216:
217:
218:
{
Usart_Write1(temp[j]);
}
break;
}
case 3:
decimal format)
219:
220:
221:
{
ByteToStrHEX(ds1820,temp);
for(j = 0; j<2; j++)
//displays 2 digit HEX value on
the terminal
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
{
Usart_Write1(temp[j]);
}
break;
}
}
}
return;
}
if(0 == strcmp_cust(directive1,"write -calib"))
{
WriteStr1(value);
//displays "Enter value" on the terminal
and sets write_calib flag
234:
write_calib = 1;
235:
return;
236:
}
237:
if(0 == strcmp_cust(directive1,"write -cycle"))
238:
{
239:
WriteStr1(value);
//displays "Enter value" on the terminal
and sets write_cycle flag
240:
write_cycle = 1;
EEPROM.c
9/19/2006
241:
242:
243:
244:
245:
return;
}
if(0 == strcmp_cust(directive1,"write -source"))
{
WriteStr1(value);
//displays "Enter value" on the terminal
and sets write_cycle flag
246:
write_source = 1;
247:
return;
248:
}
249:
if(0 == strcmp_cust(directive1,"write -ds1820"))
250:
{
251:
WriteStr1(value);
//displays "Enter value" on the terminal
and sets write_cycle flag
252:
write_ds1820 = 1;
253:
return;
254:
}
255:
}
256:
}
257: }
258:
ADC.c
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
9/19/2006
/*******************************************************************************
* Project name:
DataLogger
* Author:
Mihajlovic Dusan
* Description:
ADC subroutines definitions.
* NOTES:
None.
*******************************************************************************/
#include "AsmConstants.h"
extern unsigned vref_cal;
//calibration value for 4.096V reference
/* ADC sources (1 - Enabled, 0 - Disabled):
AN8, AN7, AN6, AN5, AN4, AN2, AN1, AN0
*/
extern unsigned short adc_source;
extern unsigned short adc_started; //adc started flag
extern unsigned short ch_num;
//channel number
extern unsigned adc_result[8];
//adc result buffer
extern unsigned adc_result_cal[8]; //adc result buffer (calibrated)
extern unsigned graph_new[9];
//new results for GLCD (0-7 - ADC channels,
8 - ds1820)
24:
25: void Read_ADC()
//read ADC result and do calibration
26: {
27:
float cal_value = (float)vref_cal/32768;
28:
PIE1.ADIE = 0; //disable A/D conversion interrupt
29:
if(adc_source.F0)
//if channel is selected...
30:
{
31:
//smoothing adc_result:
32:
adc_result_cal[0] = (adc_result_cal[0] + (unsigned)((adc_result[0] <<
2)*cal_value)) >> 1;
33:
//adc_result_cal[0] = (unsigned)((adc_result[0] << 2)*cal_value);
34:
graph_new[0] = adc_result_cal[0]/ADC_SCALER;
//write scaled value
for glcd displaying
35:
}
36:
else graph_new[0] = 0xFF;
37:
if(adc_source.F1)
38:
{
39:
adc_result_cal[1] = (adc_result_cal[1] + (unsigned)((adc_result[1] <<
2)*cal_value)) >> 1;
40:
//adc_result_cal[1] = (unsigned)((adc_result[1] << 2)*cal_value);
41:
graph_new[1] = adc_result_cal[1]/ADC_SCALER;
42:
}
43:
else graph_new[1] = 0xFF;
44:
if(adc_source.F2)
45:
{
46:
adc_result_cal[2] = (adc_result_cal[2] + (unsigned)((adc_result[2] <<
2)*cal_value)) >> 1;
47:
//adc_result_cal[2] = (unsigned)((adc_result[2] << 2)*cal_value);
48:
graph_new[2] = adc_result_cal[2]/ADC_SCALER;
49:
}
50:
else graph_new[2] = 0xFF;
51:
if(adc_source.F3)
52:
{
53:
adc_result_cal[3] = (adc_result_cal[3] + (unsigned)((adc_result[3] <<
2)*cal_value)) >> 1;
ADC.c
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
9/19/2006
<<
<<
<<
<<
82:
83:
84:
85:
86:
87:
88:
89: void Start_ADC()
//start A/D conversion
90: {
91:
if(adc_started == 0)
//if adc is not in progress
92:
{
93:
if(adc_source)
94:
{
95:
if(adc_source.F0)
//if channel is selected...
96:
{
97:
ADCON0 = 0b00000001; //AN0, IDLE, ON
98:
ch_num = 0;
99:
}
100:
else if(adc_source.F1)
101:
{
102:
ADCON0 = 0b00000101; //AN1, IDLE, ON
103:
ch_num = 1;
104:
}
105:
else if(adc_source.F2)
106:
{
107:
ADCON0 = 0b00001001; //AN2, IDLE, ON
ADC.c
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139: }
140:
9/19/2006
ch_num = 2;
}
else if(adc_source.F3)
{
ADCON0 = 0b00010001; //AN4, IDLE, ON
ch_num = 3;
}
else if(adc_source.F4)
{
ADCON0 = 0b00010101; //AN5, IDLE, ON
ch_num = 4;
}
else if(adc_source.F5)
{
ADCON0 = 0b00011001; //AN6, IDLE, ON
ch_num = 5;
}
else if(adc_source.F6)
{
ADCON0 = 0b00011101; //An7, IDLE, ON
ch_num = 6;
}
else if(adc_source.F7)
{
ADCON0 = 0b00100001; //AN8, IDLE, ON
ch_num = 7;
}
ADCON0.GO_DONE = 1; //start conversion
adc_started = 1;
//set adc_started flag
}
}
MMC.c
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
9/19/2006
/*******************************************************************************
* Project name:
DataLogger
* Author:
Mihajlovic Dusan
* Description:
MMC subroutines definitions.
* NOTES:
None.
*******************************************************************************/
#include "AsmConstants.h"
#include "Declarations.h"
#include "built_in.h"
extern unsigned short mmc_refresh;
extern unsigned graph_old[9];
channels, 8 - ds1820)
18:
19: extern unsigned short CID_new[16];
//buffer for new CID
20: extern unsigned short CSD[16];
//buffer for CSD
21: extern unsigned data_counter;
//counts how many bytes are writen
into buffer
22: extern unsigned short data[512];
//buffer for MMC sector
reading/writing
23: extern unsigned short data_sec[512];
//secondary buffer for MMC sector
reading/writing
24: extern unsigned long sector, max_sector;
//first free sector, number of
sectors
25: extern unsigned long partial_time;
//time period for mmc write in 50ms
26: extern unsigned long total_time;
//total time in 50ms
27: extern unsigned short mmc_err;
//mmc card error
28: extern unsigned short mmc_full;
//mmc card full
29: extern unsigned short mmc_empty;
//mmc card empty
30:
31: extern unsigned card_size;
//card size in MB
32: extern char *sometext;
33: extern unsigned short glcd_refresh;
//refresh glcd flag
34: extern unsigned short mmc_refresh;
//refresh glcd screen on mmc event
35: extern unsigned short adc_refresh;
//refresh glcd screen when entering
text mode
36:
37: extern const unsigned short downloading_data_bmp[1024]; //picture: downloading
data
38: extern const unsigned short terminal_error_bmp[1024];
//picture: terminal
error
39:
40: void MMC_write()
//writes ADC and DS1820 result into MMC when write_mmc flag
is set
41: {
42:
unsigned i, j;
//counters
43:
extern unsigned short adc_source;
//ADC sources On/Off
44:
extern unsigned mmc_cycle;
//timebase for MMC write cycle
45:
extern unsigned short ds1820;
//DS1820 On/Off (1 - Enabled, 0 Disabled)
46:
extern int ds1820_result;
//ds1820 temp. sensor result
47:
extern unsigned short write_mmc;
//mmc write enabled (from interrupt)
48:
extern unsigned short mmc_backup;
//mmc_backup flag
MMC.c
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
9/19/2006
95:
96:
{
for(j=0; j<16; j++)
EEPROM
97:
98:
99:
100:
101:
{
CID_old[j] = CID_new[j];
Eeprom_Write(CID_ADDR+j,CID_new[j]);
}
//writes total_time (init value 0) into boot sector (sector
0)
MMC.c
9/19/2006
102:
103:
104:
105:
106:
data_sec[0] = 0;
data_sec[1] = 0;
data_sec[2] = 0;
data_sec[3] = 0;
//writes data_counter (init value 0) into boot sector
(sector 0)
107:
108:
109:
data_sec[4] = 0;
data_sec[5] = 0;
//write address of first free sector (sector 1) into boot
sector (sector 0)
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
data_sec[6] = 0;
data_sec[7] = 0;
data_sec[8] = 0;
data_sec[9] = 1;
if(Mmc_Write_Sector(0,data_sec))
//writes boot record
{
mmc_err = 2;
//error No. 2: WRITE_SECTOR
return;
}
break;
}
}
if(Mmc_Read_Sector(0,data_sec)) //reads boot record
{
mmc_err = 1; //error No. 1: READ_SECTOR
return;
}
//read total_time:
Highest(total_time) = data_sec[0];
Higher(total_time) = data_sec[1];
Hi(total_time) = data_sec[2];
Lo(total_time) = data_sec[3];
//read data_counter:
Hi(data_counter) = data_sec[4];
Lo(data_counter) = data_sec[5];
//read first free sector (sector 1 if card is different than last
one):
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
Highest(sector) = data_sec[6];
Higher(sector) = data_sec[7];
Hi(sector) = data_sec[8];
Lo(sector) = data_sec[9];
if(sector >= max_sector)
//if card is full
{
mmc_full = 1;
//set mmc_full flag
return;
}
if(sector != 1 || data_counter != 0)
{
mmc_empty = 0; //if there is data writen to mmc clear
mmc_empty flag
}
mmc_full = 0;
//clear mmc_full flag
card_verified = 1; //set card_verified flag
if(data_counter != 0) //if there is partially filled sector
{
//read it in buffer (first free sector)...
if(Mmc_Read_Sector(sector,data))
//...in order to completely
fill the sector
{
MMC.c
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
9/19/2006
}
if(write_mmc)
//if write_mmc flag is set (by interrupt)
{
INTCON.GIE = 0; //Disable Global interrupt
for(i=0; i<8; i++)
{
temp = 0b00000001 << i;
if(adc_source & temp)
//if adc_source.i bit is set...
{
data[data_counter++] = 0;
//not used
data[data_counter++] = Highest(total_time);
//writes
time in 50ms
data[data_counter++] = Higher(total_time);
//...
data[data_counter++] = Hi(total_time);
//...
data[data_counter++] = Lo(total_time);
//...
data[data_counter++] = temp;
//writes
source ID
data[data_counter++] = Hi(adc_result_cal[i]);
//writes 2bytes into buffer
data[data_counter++] = Lo(adc_result_cal[i]);
//...
if(data_counter == 512) //if buffer is full
{
if(Mmc_Write_Sector(sector++,data)) //write to first
free sector
{
mmc_err = 2;
//error No. 2: WRITE_SECTOR
return;
}
mmc_empty = 0;
//clear mmc_empty
flag
data_counter = 0;
//reset data_counter
data_sec[0] = Highest(total_time); //writes total_time
into sector 0
data_sec[1] = Higher(total_time);
//...
data_sec[2] = Hi(total_time);
//...
data_sec[3] = Lo(total_time);
//...
data_sec[4] = 0;
//writes
data_counter (value 0) into sector 0
data_sec[5] = 0;
data_sec[6] = Highest(sector);
//writes first free
sector address into sector 0
data_sec[7] = Higher(sector);
//...
data_sec[8] = Hi(sector);
//...
data_sec[9] = Lo(sector);
//...
if(Mmc_Write_Sector(0,data_sec))
//writes boot sector
{
mmc_err = 2;
//error No. 2: WRITE_SECTOR
return;
}
if(sector >= max_sector) //if first free sector address
is equal (or higher) then max. return
{
MMC.c
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
9/19/2006
mmc_full = 1;
card_verified = 0;
return;
}
}
}
}
if(ds1820 == 0xFF) //is ds1820 is ON
{
data[data_counter++] = 0;
data[data_counter++] = Highest(total_time);
data[data_counter++] = Higher(total_time);
data[data_counter++] = Hi(total_time);
data[data_counter++] = Lo(total_time);
data[data_counter++] = ds1820;
data[data_counter++] = Hi(ds1820_result);
data[data_counter++] = Lo(ds1820_result);
if(data_counter == 512)
{
if(Mmc_Write_Sector(sector++,data))
{
mmc_err = 2;
//error No. 2: WRITE_SECTOR
return;
}
mmc_empty = 0;
data_counter = 0;
data_sec[0] = Highest(total_time); //writes total_time
into sector 0
data_sec[1] = Higher(total_time);
//...
data_sec[2] = Hi(total_time);
//...
data_sec[3] = Lo(total_time);
//...
data_sec[4] = 0;
//writes data_counter
(value 0) into sector 0
data_sec[5] = 0;
data_sec[6] = Highest(sector);
//writes first free
sector address into sector 0
data_sec[7] = Higher(sector);
//...
data_sec[8] = Hi(sector);
//...
data_sec[9] = Lo(sector);
//...
if(Mmc_Write_Sector(0,data_sec))
{
mmc_err = 2;
//error No. 2: WRITE_SECTOR
return;
}
if(sector >= max_sector) //if first free sector address is
equal (or higher) then max. return
{
mmc_full = 1;
//set mmc_full flag
card_verified = 0; //clear card_verified flag
return;
}
}
}
if(partial_time > CYCLE_MAX && data_counter != 0)
//if mmc write
period is more then CYCLE_MAX*50ms
{
//and buffer
have min 1 record do mmc write
mmc_backup = 1; //set mmc_backup flag
MMC.c
256:
257:
258:
259:
260:
261:
262:
9/19/2006
}
write_mmc = 0; //clear mmc_write flag
INTCON.GIE = 1; //Enable Global interrupt
}
if(mmc_backup) //if mmc_backup flag is set
{
if(Mmc_Write_Sector(sector,data))
//writes buffer to first free
sector
263:
264:
265:
266:
267:
268:
269:
{
mmc_err = 2;
return;
}
mmc_empty = 0;
//clear mmc_empty flag
//writes boot sector
data_sec[0] = Highest(total_time);
//writes total_time into
sector 0
270:
271:
272:
273:
data_sec[1]
data_sec[2]
data_sec[3]
data_sec[4]
=
=
=
=
Higher(total_time);
Hi(total_time);
Lo(total_time);
Hi(data_counter);
//...
//...
//...
//writes data_counter into
sector 0
274:
275:
data_sec[5] = Lo(data_counter);
data_sec[6] = Highest(sector);
//writes first free sector
address into sector 0
276:
data_sec[7] = Higher(sector);
//...
277:
data_sec[8] = Hi(sector);
//...
278:
data_sec[9] = Lo(sector);
//...
279:
if(Mmc_Write_Sector(0,data_sec))
280:
{
281:
mmc_err = 2;
//error No. 2: WRITE_SECTOR
282:
return;
283:
}
284:
mmc_backup = 0; //reset mmc_backup flag
285:
}
286:
}
287:
else
//if mmc is not detected and initialized
288:
{
289:
if(card_verified == 1) //if card was verified
290:
{
291:
mmc_refresh = 1;
//set mmc_refresh flag
292:
card_verified = 0;
//clear card_verified flag
293:
}
294:
T0CON.TMR0ON = 0;
//Timer0 OFF (will be switched on when mmc
verified)
295:
//when card not verified clear all parameters:
296:
c_size_mult = 0;
297:
read_bl_len = 0;
298:
c_size = 0;
299:
max_sector = 0;
300:
card_size = 0;
301:
302:
mmc_full = 0;
//clear mmc card full flag
303:
mmc_empty = 1;
//set mmc card empty flag (init value)
304:
}
305: }
306:
307: void Usart_console2()
//Console for MMC read and erase
308: {
MMC.c
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
9/19/2006
MMC.c
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
9/19/2006
data_sec[6] = 0;
data_sec[7] = 0;
data_sec[8] = 0;
data_sec[9] = 1;
if(Mmc_Write_Sector(0,data_sec))
//writes boot sector
{
mmc_err = 2;
//error No. 2: WRITE_SECTOR
WriteStr2(err_write);
return;
}
total_time = 0;
//reset total_time counter
data_counter = 0;
//clear data_counter
sector = 1;
//card initial sector
mmc_empty = 1;
//set mmc_empty flag
mmc_full = 0;
//clear mmc_full flag
WriteStr2(erase_ok);
}
else
{
WriteStr2(no_card);
}
}
else if(0 == strcmp_cust(directive2,"no"))
{
WriteStr2(abort);
}
erase = 0;
//reset erase flag
return;
}
if(0 == strcmp_cust(directive2,"help"))
terminal
387:
388:
389:
390:
391:
{
WriteStr2(help2);
return;
}
if(0 == strcmp_cust(directive2,"erase")) //erases data from mmc/sd
card
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
{
if(Mmc_Init(&PORTC,2))
{
WriteStr2(yes_no);
erase = 1;
}
else
{
WriteStr2(no_card);
}
return;
}
if(0 == strcmp_cust(directive2,"read -mmc")) //reads mmc/sd card
{
if(Mmc_Init(&PORTC,2)) //if card is detected
{
if(mmc_empty)
//if card is empty
{
WriteStr2(empty);
return;
}
MMC.c
413:
414:
415:
416:
417:
418:
419:
420:
9/19/2006
Glcd_Image(downloading_data_bmp);
WriteStr2(read2[0]);
for(j=1; j<sector; j++) //from initial to last writen sector
{
timeout = 0;
//clear timeout value
while(CTS2 == 1 && ++timeout < 0xFFFF); //waits for
terminal to be ready
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
if(timeout == 0xFFFF)
{
terminal_err = 1;
Glcd_Image(terminal_error_bmp);
Delay_1sec();
Delay_1sec();
Delay_1sec();
Glcd_Fill(0x00);
glcd_refresh = 1;
adc_refresh = 1;
mmc_refresh = 1;
for(i=0; i<9; i++) graph_old[i] = 0;
return;
}
if(Mmc_Read_Sector(j,data_sec))
{
mmc_err = 1; //error No. 1: READ_SECTOR
WriteStr2(err_read);
return;
}
for(k=0; k<512; k++)
//writes data in HEX table
{
i = k%8;
ByteToStrHEX(data_sec[k],temp);
Usart_Write2(temp[0]);
Usart_Write2(temp[1]);
if(i == 0 || i == 4 || i == 5) Usart_Write2(' ');
if(i == 7)
{
Usart_Write2(13);
Usart_Write2(10);
}
}
}
if(partial_time > CYCLE_MAX && data_counter != 0)
//if
mmc write period is more then CYCLE_MAX*50ms = 10s
{
//and
sector have min 1 record do mmc read
if(Mmc_Read_Sector(sector,data_sec))
{
mmc_err = 1; //error No. 1: READ_SECTOR
WriteStr2(err_read);
return;
}
for(k=0; k<data_counter; k++)
//reads data from
partially filled sector
{
MMC.c
467:
468:
469:
470:
471:
472:
473:
474:
475:
476:
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
9/19/2006
i = k%8;
ByteToStrHEX(data_sec[k],temp);
Usart_Write2(temp[0]);
Usart_Write2(temp[1]);
if(i == 0 || i == 4 || i == 5) Usart_Write2(' ');
if(i == 7)
{
Usart_Write2(13);
Usart_Write2(10);
}
}
}
WriteStr2(read2[1]);
Glcd_Fill(0x00);
glcd_refresh = 1;
adc_refresh = 1;
mmc_refresh = 1;
for(i=0; i<9; i++) graph_old[i] = 0;
}
else
{
WriteStr2(no_card);
}
return;
}
if(0 == strcmp_cust(directive2,"read -cid")) //reads cid register
(card ID)
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
{
if(Mmc_Init(&PORTC,2))
{
WriteStr2(read2[1]);
for(i=0; i<16; i++)
{
ByteToStrHEX(CID_new[i],temp);
Usart_Write2(temp[0]);
Usart_Write2(temp[1]);
if(i == 15)
{
Usart_Write2(13);
Usart_Write2(10);
break;
}
Usart_Write2(' ');
}
WriteStr2(read2[1]);
}
else
{
WriteStr2(no_card);
}
return;
}
if(0 == strcmp_cust(directive2,"read -csd")) //reads csd register
(card specific data)
520:
{
521:
if(Mmc_Init(&PORTC,2))
522:
{
MMC.c
9/19/2006
523:
524:
525:
526:
527:
528:
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
539:
540:
541:
542:
543:
544:
545:
WriteStr2(read2[1]);
for(i=0; i<16; i++)
{
ByteToStrHEX(CSD[i],temp);
Usart_Write2(temp[0]);
Usart_Write2(temp[1]);
if(i == 15)
{
Usart_Write2(13);
Usart_Write2(10);
break;
}
Usart_Write2(' ');
}
WriteStr2(read2[1]);
}
else
{
WriteStr2(no_card);
}
return;
}
if(0 == strcmp_cust(directive2,"status")) //displays card status
(usage)
546:
547:
548:
549:
550:
551:
552:
553:
554:
555:
556:
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
{
if(Mmc_Init(&PORTC,2))
{
if(mmc_full) WriteStr2(full);
else if(sector == 1)
{
WriteStr2(empty);
}
else
{
WriteStr2(usage[0]);
ByteToStr((sector*100)/max_sector,temp);
Usart_Write2(temp[0]);
Usart_Write2(temp[1]);
Usart_Write2(temp[2]);
WriteStr2(usage[1]);
WordToStr(card_size,temp);
Usart_Write2(temp[0]);
Usart_Write2(temp[1]);
Usart_Write2(temp[2]);
Usart_Write2(temp[3]);
Usart_Write2(temp[4]);
WriteStr2(usage[2]);
}
}
else
{
WriteStr2(no_card);
}
return;
}
}
}
MMC.c
9/19/2006
580: }
581:
GLCD.c
1:
2:
3:
4:
5:
6:
7:
8:
9:
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:
9/19/2006
/*******************************************************************************
* Project name:
DataLogger
* Author:
Mihajlovic Dusan
* Description:
GLCD subroutines definitions.
* NOTES:
None.
*******************************************************************************/
#include "AsmConstants.h"
#include "Declarations.h"
#include "built_in.h"
extern unsigned graph_new[9];
ADC channels, 8 - ds1820)
extern unsigned graph_old[9];
ADC channels, 8 - ds1820)
extern unsigned short glcd_refresh;
extern unsigned short mmc_refresh;
event
extern unsigned short adc_refresh;
entering text mode
extern const unsigned short graph_bmp[1024];
elements
extern const unsigned short noMMC_bmp[1024];
extern const unsigned short mmc_full_bmp[1024];
//new results for GLCD (0-7 //old results for GLCD (0-7 //refresh glcd flag
//refresh glcd screen on mmc
//refresh glcd screen when
//picture: glcd graph static
//picture: MMC not Detected!
//picture: MMC FULL!!!
GLCD.c
52: {
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
9/19/2006
unsigned short i = 0;
switch(buttons)
{
case 0b00100000:
//#1 graph mode (default mode)
{
buttons = 0;
graph_mode = 1;
text_mode = 0;
couloring = 0;
glcd_refresh = 1;
Glcd_Fill(0);
for(i=0; i<9; i++) graph_old[i] = 0;
break;
}
case 0b01000000:
//#2 text mode
{
buttons = 0;
graph_mode = 0;
text_mode = 1;
position = 0;
adc_refresh = 1;
Glcd_Fill(0);
break;
}
case 0b00000010:
//left
{
buttons = 0;
if(graph_mode == 1)
{
if(couloring > 0)
{
couloring--;
Glcd_Fill(0);
glcd_refresh = 1;
for(i=0; i<9; i++) graph_old[i] = 0;
}
}
else
{
if(position > 0)
{
position--;
Glcd_Fill(0);
}
}
break;
}
case 0b00001000:
//right
{
buttons = 0;
if(graph_mode == 1)
{
if(couloring < 3)
{
couloring++;
Glcd_Fill(0);
glcd_refresh = 1;
GLCD.c
9/19/2006
110:
for(i=0; i<9; i++) graph_old[i] = 0;
111:
}
112:
}
113:
else
114:
{
115:
if(position < 2)
116:
{
117:
position++;
118:
Glcd_Fill(0);
119:
}
120:
}
121:
break;
122:
}
123:
default: break;
124:
}
125:
126:
if(graph_mode)
127:
{
128:
GLCD_graph();
129:
}
130:
131:
if(text_mode)
132:
{
133:
GLCD_text();
134:
}
135: }
136:
137: void GLCD_graph()
//draw graph on glcd depending on analogue input and
temperature
138: {
139:
unsigned short i;
140:
Glcd_Set_Font(System3x6,3,6,32);
141:
if(glcd_refresh == 1)
//if refresh glcd flag is set draw static elements
142:
{
143:
Glcd_Image(graph_bmp);
144:
glcd_refresh = 0;
145:
}
146:
for(i=0; i<9; i++) //check if there is difference between old and new
value for display
147:
{
148:
if(graph_new[i] != graph_old[i])
149:
{
150:
Refresh(i);
151:
}
152:
}
153:
Glcd_Set_Font(FontSystem5x8,5,8,32);
154: }
155:
156: void Refresh(unsigned short source) //refresh glcd graph
157: {
158:
unsigned short i;
159:
unsigned short x_offset = BAR_OFFSET+BAR_WIDTH*source; //starting point
for each channel
160:
if(graph_new[source] == 0xFF)
//if channel (ds1820) is OFF
161:
{
162:
for(i=13; i<64; i++)
//delete old bar
163:
{
164:
Glcd_H_Line(x_offset,x_offset+11,i,0);
GLCD.c
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
9/19/2006
}
Glcd_Write_Char('O',x_offset+1,7,1);
Glcd_Write_Char('F',x_offset+5,7,1);
Glcd_Write_Char('F',x_offset+9,7,1);
}
else
{
//write '"OFF"
if(graph_old[source] == 0xFF)
//if old value was OFF
{
for(i=57; i<64; i++)
//delete "OFF"
{
Glcd_H_Line(x_offset,x_offset+11,i,0);
}
graph_old[source] = 0; //this is for drawing from zero
}
//Writes white or black bar depending on couloring scheme or parity (in
mixed mode):
181:
if(source.F0 == couloring || couloring == 2)
//if white-black or
white mode
182:
{
183:
if(graph_new[source] > graph_old[source])
//add white part
184:
{
185:
if(graph_old[source] > 0)
186:
{
187:
Glcd_H_Line(x_offset+1,x_offset+10,64-graph_old[source],0);
188:
}
189:
Glcd_V_Line(64-graph_new[source],63-graph_old[source],x_offset,
1);
190:
Glcd_V_Line(64-graph_new[source],63-graph_old[source],
x_offset+11,1);
191:
Glcd_H_Line(x_offset+1,x_offset+10,64-graph_new[source],1);
192:
}
193:
else
//remove white part
194:
{
195:
for(i=64-graph_old[source]; i<64-graph_new[source]; i++)
196:
{
197:
Glcd_H_Line(x_offset,x_offset+11,i,0);
198:
}
199:
if(graph_new[source] > 0)
200:
{
201:
Glcd_H_Line(x_offset,x_offset+11,64-graph_new[source],1);
202:
}
203:
}
204:
}
205:
else
//if black-white or black mode
206:
{
207:
if(graph_new[source] > graph_old[source])
//add black part
208:
{
209:
for(i=64-graph_new[source]; i<64-graph_old[source]; i++)
210:
{
211:
Glcd_H_Line(x_offset,x_offset+11,i,1);
212:
}
213:
}
214:
else
//remove black part
215:
{
216:
for(i=64-graph_old[source]; i<64-graph_new[source]; i++)
217:
{
218:
Glcd_H_Line(x_offset,x_offset+11,i,0);
GLCD.c
9/19/2006
219:
}
220:
}
221:
}
222:
}
223:
graph_old[source] = graph_new[source]; //current value becomes old value
224: }
225:
226: void GLCD_text()
//writes data on glcd depending on analogue input and
temperature
227: {
228:
char *hex = "0x";
229:
if(position == 0)
//display ADC
230:
{
231:
mmc_refresh = 1;
//set mmc_refresh flag (for redrawing mmc screen)
232:
if(adc_refresh == 1)
//if adc_refresh flag is set (drawes static
infos)
233:
{
234:
sometext = "Sensor 0:";
235:
Glcd_Write_Text(sometext,0,0,1);
236:
sometext = "Sensor 1:";
237:
Glcd_Write_Text(sometext,0,1,1);
238:
sometext = "Sensor 2:";
239:
Glcd_Write_Text(sometext,0,2,1);
240:
sometext = "Sensor 3:";
241:
Glcd_Write_Text(sometext,0,3,1);
242:
sometext = "Sensor 4:";
243:
Glcd_Write_Text(sometext,0,4,1);
244:
sometext = "Sensor 5:";
245:
Glcd_Write_Text(sometext,0,5,1);
246:
sometext = "Sensor 6:";
247:
Glcd_Write_Text(sometext,0,6,1);
248:
sometext = "Sensor 7:";
249:
Glcd_Write_Text(sometext,0,7,1);
250:
adc_refresh = 0;
251:
}
252:
253:
if(adc_source.F0 == 0) //if channel is disabled
254:
{
255:
sometext = "OFF
";
256:
Glcd_Write_Text(sometext,80,0,1);
257:
}
258:
else
//if channel is enabled
259:
{
260:
ADCtoStr(adc_result_cal[0],text);
261:
Glcd_Write_Text(text,80,0,1);
262:
}
263:
264:
if(adc_source.F1 == 0)
265:
{
266:
sometext = "OFF
";
267:
Glcd_Write_Text(sometext,80,1,1);
268:
}
269:
else
270:
{
271:
ADCtoStr(adc_result_cal[1],text);
272:
Glcd_Write_Text(text,80,1,1);
273:
}
274:
GLCD.c
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
9/19/2006
if(adc_source.F2 == 0)
{
sometext = "OFF
";
Glcd_Write_Text(sometext,80,2,1);
}
else
{
ADCtoStr(adc_result_cal[2],text);
Glcd_Write_Text(text,80,2,1);
}
if(adc_source.F3 == 0)
{
sometext = "OFF
";
Glcd_Write_Text(sometext,80,3,1);
}
else
{
ADCtoStr(adc_result_cal[3],text);
Glcd_Write_Text(text,80,3,1);
}
if(adc_source.F4 == 0)
{
sometext = "OFF
";
Glcd_Write_Text(sometext,80,4,1);
}
else
{
ADCtoStr(adc_result_cal[4],text);
Glcd_Write_Text(text,80,4,1);
}
if(adc_source.F5 == 0)
{
sometext = "OFF
";
Glcd_Write_Text(sometext,80,5,1);
}
else
{
ADCtoStr(adc_result_cal[5],text);
Glcd_Write_Text(text,80,5,1);
}
if(adc_source.F6 == 0)
{
sometext = "OFF
";
Glcd_Write_Text(sometext,80,6,1);
}
else
{
ADCtoStr(adc_result_cal[6],text);
Glcd_Write_Text(text,80,6,1);
}
if(adc_source.F7 == 0)
{
sometext = "OFF
";
GLCD.c
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
9/19/2006
Glcd_Write_Text(sometext,80,7,1);
}
else
{
ADCtoStr(adc_result_cal[7],text);
Glcd_Write_Text(text,80,7,1);
}
}
if(position == 1)
//display temperature
{
adc_refresh = 1;
//set adc refresh flag (for redrawing adc screen)
mmc_refresh = 1;
//set mmc_refresh flag (for redrawing mmc screen)
sometext = "TEMPERATURE:";
Glcd_Write_Text(sometext,0,0,1);
if(ds1820 == 0x00) //if ds1820 is OFF
{
sometext = "OFF
";
Glcd_Write_Text(sometext,80,0,1);
}
else
//if ds1820 is ON
{
ds1820toStr(ds1820_result,text);
Glcd_Write_Text(text,80,0,1);
}
}
if(position == 2)
//display mmc
{
adc_refresh = 1;
//set adc refresh flag (for redrawing adc
screen)
if(mmc_refresh == 1)
//if mmc_refresh flag is set clear screen
(white or black)
{
Glcd_Fill(0x00);
mmc_refresh = 0;
//clear mmc_refresh flag
}
if(card_verified == 0) //if mmc is not verified
{
if(mmc_full == 1)
//if mmc is FULL
{
Glcd_Image(mmc_full_bmp);
}
else
//if mmc is not detected
{
Glcd_Image(noMMC_bmp);
}
}
else
//if mmc is detected
{
sometext = "CSIZE:";
Glcd_Write_Text(sometext,0,0,1);
Glcd_Write_Text(hex,80,0,1);
WordToStrHEX(c_size,text);
Glcd_Write_Text(text,92,0,1);
sometext = "CSIZE MULT:";
Glcd_Write_Text(sometext,0,1,1);
Glcd_Write_Text(hex,80,1,1);
ByteToStrHEX(c_size_mult,text);
GLCD.c
9/19/2006
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
Glcd_Write_Text(text,92,1,1);
sometext = "BLOCK LEN:";
Glcd_Write_Text(sometext,0,2,1);
Glcd_Write_Text(hex,80,2,1);
ByteToStrHEX(read_bl_len,text);
Glcd_Write_Text(text,92,2,1);
sometext = "SECTORS:";
Glcd_Write_Text(sometext,0,4,1);
LongToStr(max_sector,text);
RemoveSpace(text, text_sec);
//removes space at begining of
string
401:
402:
403:
404:
405:
406:
string
407:
408:
409:
410:
411:
412:
}
413: }
414:
Glcd_Write_Text(text_sec,80,4,1);
sometext = "MBYTES:";
Glcd_Write_Text(sometext,0,5,1);
WordToStr(card_size,text);
RemoveSpace(text, text_sec);
//removes space at begining of
Glcd_Write_Text(text_sec,80,5,1);
sometext = "WRITING TO MMC...";
Glcd_Write_Text(sometext,0,7,1);
}
Subroutines.c
1:
2:
3:
4:
5:
6:
7:
8:
9:
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:
9/19/2006
/*******************************************************************************
* Project name:
DataLogger
* Author:
Mihajlovic Dusan
* Description:
General subroutines definitions.
* NOTES:
None.
*******************************************************************************/
#include "built_in.h"
void Usart_InitHS1()
{
TXSTA1.TXEN = 1;
RCSTA1.CREN = 1;
TXSTA1.BRGH = 1;
BAUDCON1.BRG16 = 1;
SPBRGH1 = 0x00;
SPBRG1 = 0x3F;
RCSTA1.SPEN = 1;
}
void Usart_InitHS2()
{
TXSTA2.TXEN = 1;
RCSTA2.CREN = 1;
TXSTA2.BRGH = 1;
BAUDCON2.BRG16 = 1;
SPBRGH2 = 0x00;
SPBRG2 = 0x07;
RCSTA2.SPEN = 1;
}
Subroutines.c
9/19/2006
59:
if(isdigit(s[i])) result += s[i] - '0';
60:
else
61:
{
62:
if(islower(s[i])) result += 10 + s[i] - 'a';
63:
else result += 10 + s[i] - 'A';
64:
}
65:
if(i < 3) result <<= 4;
66:
}
67:
return result;
68: }
69:
70: void ByteToStrHEX(unsigned short number, char *output) //converts byte to
string (HEX)
71: {
72:
unsigned short i, digit;
73:
for(i = 0; i<2; i++)
74:
{
75:
if(i == 0)
76:
{
77:
digit = (number & 0xF0)>>4;
78:
}
79:
if(i == 1)
80:
{
81:
digit = number & 0x0F;
82:
}
83:
if(digit < 10) output[i] = digit + '0';
84:
else output[i] = digit - 10 + 'A';
85:
}
86:
output[i] = 0;
87: }
88:
89: void WordToStrHEX(unsigned number, char *output)
//converts word to
string (HEX)
90: {
91:
unsigned short i, digit;
92:
for(i = 0; i<4; i++)
93:
{
94:
if(i == 0)
95:
{
96:
digit = (number & 0xF000)>>12;
97:
}
98:
if(i == 1)
99:
{
100:
digit = (number & 0x0F00)>>8;
101:
}
102:
if(i == 2)
103:
{
104:
digit = (number & 0x00F0)>>4;
105:
}
106:
if(i == 3)
107:
{
108:
digit = number & 0x000F;
109:
}
110:
if(digit < 10) output[i] = digit + '0';
111:
else output[i] = digit - 10 + 'A';
112:
}
113:
output[i] = 0;
114: }
Subroutines.c
9/19/2006
115:
116: void LongToStrHEX(unsigned long number, char *output)
//converts long to
string (HEX)
117: {
118:
unsigned short i, digit;
119:
for(i = 0; i<8; i++)
120:
{
121:
if(i == 0)
122:
{
123:
digit = (number & 0xF0000000)>>28;
124:
}
125:
if(i == 1)
126:
{
127:
digit = (number & 0x0F000000)>>24;
128:
}
129:
if(i == 2)
130:
{
131:
digit = (number & 0x00F00000)>>20;
132:
}
133:
if(i == 3)
134:
{
135:
digit = (number & 0x000F0000)>>16;
136:
}
137:
if(i == 4)
138:
{
139:
digit = (number & 0x0000F000)>>12;
140:
}
141:
if(i == 5)
142:
{
143:
digit = (number & 0x00000F00)>>8;
144:
}
145:
if(i == 6)
146:
{
147:
digit = (number & 0x000000F0)>>4;
148:
}
149:
if(i == 7)
150:
{
151:
digit = number & 0x0000000F;
152:
}
153:
if(digit < 10) output[i] = digit + '0';
154:
else output[i] = digit - 10 + 'A';
155:
}
156:
output[i] = 0;
157: }
158:
159: void WriteStr1(const char *s)
//writes string on Usart1
160: {
161:
unsigned i = 0;
162:
while(1)
163:
{
164:
if(s[i] == 0) break;
165:
Usart_Write1(s[i++]);
166:
}
167: }
168:
169: void WriteStr2(const char *s)
//writes string on Usart2
170: {
171:
unsigned i = 0;
Subroutines.c
9/19/2006
172:
while(1)
173:
{
174:
if(s[i] == 0) break;
175:
Usart_Write2(s[i++]);
176:
}
177: }
178:
179: unsigned short isStrX(char *s)
//all digits in string are Hex digits? 1 Yes, 0 - No
180: {
181:
unsigned short i = 0;
182:
while(1)
183:
{
184:
if(s[i] == 0) return 1;
185:
if(!isxdigit(s[i])) return 0;
186:
i++;
187:
}
188: }
189:
190: void Read_ds1820()
//read ds1820 temperature
191: {
192:
extern unsigned short ds1820;
//DS1820 On/Off (1 - Enabled, 0 Disabled)
193:
extern int ds1820_result;
//ds1820 temp. sensor result
194:
extern unsigned graph_new[9];
//new results for GLCD (0-7 - ADC channels,
8 - ds1820)
195:
if(ds1820 == 0xFF) //if ds1820 is enabled
196:
{
197:
Ow_Reset(&PORTE,0);
// Onewire reset signal
198:
Ow_Write(&PORTE,0,0xCC);
// Issue command SKIP_ROM
199:
Ow_Write(&PORTE,0,0x44);
// Issue command CONVERT_T
200:
201:
if(Ow_Reset(&PORTE,0) == 0)
//if sensor is detected get temperature
value
202:
{
203:
Ow_Write(&PORTE,0,0xCC);
// Issue command SKIP_ROM
204:
Ow_Write(&PORTE,0,0xBE);
// Issue command
READ_SCRATCHPAD
205:
206:
Lo(ds1820_result) = Ow_Read(&PORTE,0);
207:
Hi(ds1820_result) = Ow_Read(&PORTE,0);
208:
if(ds1820_result >= 0)
209:
{
210:
graph_new[8] = ds1820_result >> 1;
211:
if(graph_new[8] > 50) graph_new[8] = 50;
//max 50 degerees C
212:
}
213:
else graph_new[8] = 0; //min 0 degrees C
214:
}
215:
else
//if sensor is not detected result is zero
216:
{
217:
ds1820_result = 0;
218:
graph_new[8] = 0;
219:
}
220:
}
221:
else graph_new[8] = 0xFF;
222: }
223:
224: unsigned short GetBit(unsigned short *array, unsigned short bit) //gets bit 0255 from array (max 32-byte)
Subroutines.c
225:
226:
227:
228:
229:
230:
231:
9/19/2006
{
unsigned short byte = bit/8;
return (array[byte] >> bit%8) & 0x01;
}
Subroutines.c
9/19/2006
282:
283:
return result;
284: }
285:
286: void ADCtoStr(unsigned number, char *output)
string
287: {
288:
unsigned temp = number;
289:
temp /= 1000;
290:
output[0] = '0' + temp;
291:
output[1] = '.';
292:
temp = number%1000;
293:
temp /= 100;
294:
output[2] = '0' + temp;
295:
temp = number%100;
296:
temp /= 10;
297:
output[3] = '0' + temp;
298:
temp = number%10;
299:
output[4] = '0' + temp;
300:
output[5] = ' ';
301:
output[6] = 'V';
302:
output[7] = 0;
303: }
304:
305: void ds1820toStr(int number, char *output)
string
306: {
307:
int temp = number;
308:
if(number >= 0) output[0] = '+';
309:
else output[0] = '-';
310:
temp /= 20;
311:
output[1] = '0' + abs(temp);
312:
temp = number%20;
313:
temp /= 2;
314:
output[2] = '0' + temp;
315:
output[3] = '.';
316:
if( number%2 ) output[4] = '5';
317:
else output[4] = '0';
318:
output[5] = ' ';
319:
output[6] = 'C';
320:
output[7] = 0;
321: }
322:
323: void RemoveSpace(char *input, char *output)
string
324: {
325:
unsigned short i=0, j=0;
326:
while(1)
327:
{
328:
if(input[i] != ' ')
329:
{
330:
output[j++] = input[i];
331:
}
332:
if(input[i] == 0) break;
333:
i++;
334:
}
335: }
336:
//converts ADC_result to
//converts ds1820_result to
Pictures.c
1:
2:
3:
4:
5:
6:
7:
8:
9:
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:
9/19/2006
/*******************************************************************************
* Project name:
DataLogger
* Author:
Mihajlovic Dusan
* Description:
Bitmap pictures definition.
* NOTES:
None.
*******************************************************************************/
//
//
//
//
21,
17,
0,
0,
21,
0,
7,
20,
0,
0,
0,
0,
0,
0,
0,
31,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
9,
31,
0,
0,
21,
31,
0,
28,
0,
0,
0,
0,
0,
0,
0,
64,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
4,
0,
0,
16,
0,
18,
9,
21,
0,
0,
0,
0,
0,
0,
0,
0,
0,
70,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
4,
0,
Pictures.c
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
16, 16, 16, 16, 16,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
4, 4, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
9/19/2006
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 16, 16, 16, 16, 16,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 64, 64, 64, 66, 66,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 8, 8
};
//
//
//
//
Pictures.c
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
9/19/2006
Pictures.c
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
9/19/2006
255,255,255,255,255,255,255,255,255,255,255,255,127,127,255,255,
255,127,127,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255, 0, 0,254,254,254,254,254,252, 0,
0, 3,255,255, 31, 7,227,243,243,243,227, 7, 31,255,243,131,
3, 31,255, 63, 7,131,131, 7, 63,255, 31, 3,131,243,255, 3,
3,243,243,243,243,243, 7, 7,255,255,255, 0, 0,255,255, 31,
7,227,243,243,243,227, 7, 31,255,255,115, 51, 51, 51, 51, 51,
51, 3, 15,255,255, 15, 7,227,243,243,243,243, 0, 0,255,255,
255, 2, 2,255,255, 3, 3,243,243,243,243,243, 7, 7,255,255,
15, 7,227,243,243,243,243, 3, 3,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,240,240,243,243,243,243,243,241,248,
248,254,255,255,254,248,241,243,243,243,241,248,254,255,255,255,
252,240,241,240,252,255,255,252,240,241,240,252,255,255,255,240,
240,255,255,255,255,255,240,240,255,255,255,240,240,255,255,254,
248,241,243,243,243,241,248,254,255,255,248,240,243,243,243,243,
243,240,240,255,255,252,248,241,243,243,243,243,240,240,255,255,
255,240,240,255,255,240,240,255,255,255,255,255,240,240,255,255,
252,152,145,147,147,147,147,128,192,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255, 31, 31,159,159,159,159,159, 31, 63, 63,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 31,
31,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255, 0, 0,255,255,255,255,255,127, 0, 0,
128,255,255, 28, 12,204,204,204,204,204, 0, 3,255,252,252, 0,
0,252,252,252,255, 28, 12,204,204,204,204,204, 0, 3,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,252,252,252,252,252,252,252,252,254,254,
255,255,255,254,252,252,252,252,252,252,252,252,255,255,255,254,
252,252,252,252,255,254,252,252,252,252,252,252,252,252,255,255,
252,252,255,255,252,252,255,255,252,252,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
};
//
//
//
//
Pictures.c
9/19/2006
Pictures.c
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
9/19/2006
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
};
//
//
//
//
Pictures.c
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
9/19/2006
Pictures.c
9/19/2006
407: 243,243,243,243,243,243,255,255,255,255,255,255,255,255,255,255,
408: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
409: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
410: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
411: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
412: 255,255,127, 31,159,207,207,207,207,207,207,207,255,255, 15, 15,
413: 255,255,255,255,255,255,255, 15, 15,255,255, 15, 15,255,255,255,
414: 255,255,255,255,255, 15, 15,255,255,255,255,255,255,255,255,255,
415:
15, 15,255,255,255,255, 15, 15,255,255,255,255, 15, 15,255,255,
416: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
417: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
418: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
419: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
420: 255,255, 0, 0,243,243,243,243,243,243,243,243,255,255,128, 0,
421:
63,127,127,127,127,127, 63, 0,128,255,255,128, 0, 63,127,127,
422: 127,127,127,127,255,128, 0, 63,127,127,127,127,127,127,255,255,
423:
64, 64,255,255,255,255, 64, 64,255,255,255,255, 64, 64,255,255,
424: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
425: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
426: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
427: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
428: 255,255,254,254,255,255,255,255,255,255,255,255,255,255,255,255,
429: 254,254,254,254,254,254,254,255,255,255,255,255,255,254,254,254,
430: 254,254,254,254,255,255,255,254,254,254,254,254,254,254,255,255,
431: 254,254,255,255,255,255,254,254,255,255,255,255,254,254,255,255,
432: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
433: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
434: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
435: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
436: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
437: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
438: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
439: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
440: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
441: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
442: };
443: