You are on page 1of 89

VIA ELEKTROTEHNICKA KOLA

Mihajlovi Duan
VIEKANALNI UREAJ ZA AKVIZICIJU ANALOGNIH
SIGNALA
-diplomski rad-

Beograd, 2006

Kandidat: Mihajlovi Duan


Broj indeksa: 75/04
Smer: Raunarska tehnika
Tema: VIEKANALNI UREAJ ZA AKVIZICIJU ANALOGNIH
SIGNALA
Osnovni zadaci:
1. Analiza problema
2. Projekat i realizacija
3. Ispitivanje
Hardver: 40%

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. OPIS HARDVERA DATALOGGER SISTEMA...........................................

2.1 MIKROKONTROLER............................................................................

2.2 ISPRAVLJAKI DEO............................................................................

2.3 SERIJSKA KOMUNIKACIJA.................................................................

2.3.1 RS232 komunikacija......................................................................

2.3.2 USB komunikacija..........................................................................

2.4 DIGITALNI ULAZ/IZLAZ.......................................................................

2.5 KONEKTOR ZA PROGRAMATOR.......................................................

2.6 4.096V NAPONSKA REFERENCA......................................................

2.7 RESET KOLO.......................................................................................

2.8 KONEKTORI ZA ANALOGNE ULAZE I DODATNI INTERFEJS..........

10

2.9 DS1820 TEMPERATURNI SENZOR....................................................

11

2.10 GRAFIKI DISPLEJ...........................................................................

12

2.11 TASTATURA.......................................................................................

13

2.12 INTERFEJS ZA MEMORIJSKU KARTICU.........................................

14

3. OPIS SOFTVERA DATALOGGER SISTEMA...........................................

16

3.1 OPTI ALGORITAM.............................................................................

16

3.2 INICIJALIZACIJA..................................................................................

18

3.3 TAJMERI I INTERAPTI.........................................................................

18

3.4 PODEAVANJE PARAMETARA SISTEMA (EEPROM)......................

19

3.5 ITANJE REZULTATA A/D KONVERZIJE..........................................

20

3.6 ITANJE TEMPERATURE...................................................................

20

3.7 UPIS U MEMORIJSKU KARTICU........................................................

21

3.8 START A/D KONVERZIJE....................................................................

22

3.9 ITANJE PODATAKA IZ MEMORIJSKE KARTICE.............................

23

3.10 GRAFIKI DISPLEJ...........................................................................

25

4. ZAKLJUAK..............................................................................................

27

5. INDEKS POJMOVA...................................................................................

28

6. LITERATURA.............................................................................................

29

7. PRILOG......................................................................................................

30

7.1 PROGRAMSKI KOD DATALOGGER SISTEMA..................................

30

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

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:

Slika 1. DataLogger sistem

-1-

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

Pisanje softvera za mikrokontroler je podjednako vano koliko i projektovanje


samog hardvera. Softver je taj koji daje inteligenciju ureaju i koji odreuje njegovu
konanu funkcionalnost. Softver se moe pisati u asembleru ili nekom od viih
programskih jezika (C, Pascal, Basic) i neophodno ga je prevesti u HEX format da bi
ga mikrokontroler razumeo. Prevoenje se radi u kompajleru i upisuje u
mikronontroler uz pomo programatora. Izabran je mikroC kompajler firme
MikroElektronika zato to nudi veliki broj funkcija za rad sa PIC mikrokontrolerima i
PICflash2 programator (softver i hardver), takoe firme MikroElektronika, za upis
HEX fajla u mikrokontroler.

-2-

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

2. OPIS HARDVERA DATALOGGER SISTEMA


Kao to je ve napomenuto DataLogger se sastoji od sledeih celina logiki
razdvojenih na 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) i potenciometar za kontrast, tastatura i interfejs za
memorijsku karticu. Svaki od delova DataLogger-a e biti naknadno objanjen.

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.

Slika 2. Mikrokontroler i kristal kvarca

-3-

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala


U2

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

Slika 3. ema mikrokontrolera i oscilatora

2.2 ISPRAVLJAKI DEO


Ispravljaki deo se sastoji od konektora (CN1), Grecovog mosta (DB1),
naponskog regulatora (stabilizatora) 7805 (REG1), ulaznih i izlaznih kondenzatora i
indikatora napajanja. Ulazni napon moe biti kako naizmenian tako i jednosmeran
bilo kog polariteta. Vrednost ulaznog napona je odreena ulaznim karakteristikama
regulatora 7805 i kree se u granicama od 8V do 16V. Naponski regulator 7805 slui
da obezbedi stabilan napon od 5V za napajanje ureaja. Elektrolitski kondenzator E1
na ulazu regulatora slui da stabilizuje naizmenini ulazni napon dok elektrolitski
kondenzator E2 na izlazu regulatora slui za odravanje naponskog nivoa od 5V.
Kondenzatori C19 i C1 na ulazu i izlazu regulatora slue da smanje um na naponu
napajanja i da odravaju stabilan rad regulatora (da ne doe do oscilacija).
Dioda D1 je dioda za zatitu stabilizatora. Kada je prilikom iskljuenja izvora
napajanja napon na kondenzatoru E2 vii nego napon na kondenzatoru E1 dioda D1
lui da bi se kondenzator E2 ispraznio.

-4-

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala


VCC
R1
1K
LED1
POWER

D1
1N4007
DB1
B280C1500

CN1

Vin

Vout

VCC

CON2
E1
470uF

C19
100nF

GND

1
2

REG1
7805

C1
100nF

E2
47uF

R19
2K2

Slika 4. ema ispravljakog dela

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

2.3 SERIJSKA KOMUNIKACIJA


2.3.1 RS232 KOMUNIKACIJA
RS232 je standardna serijska komunikacija koja slui za prenos podataka
izmeu dva ureaja. Za prenos se koriste dve linije Rx (prijemna linija) i Tx (predajna
linija). RS232 standard zahteva da naponski nivo logicke nule bude +12V, a naponski
nivo logike jedinice -12V. Sobzirom da su naponski nivoi logike nule i jedinice kod
PIC18F8722 mikrokontrolera 0V i 5V respektivno, potreban je transceiver za
prilagoenje naponskog nivoa. Tu funkciju obavlja integrisano kolo MAX232. Kod
DataLogger-a RS232 komunikacija je iskoriena za upis i itanje parametara
sistema preko PC-a: kalibracija naponske reference, podeavanje ciklusa upisa u
memorijsku karticu, ukljuenje izvora analognog napona i ukljuenje DS1820
temperaturnog senzora.
Maksimalna brzina koja se moe postii RS232 komunikacijom je 115200b/s.
Zbog sigurnosti prenosa podataka iskoriena je mogunost hardverskog
handshaking-a koja slui za indikaciju spremnosti komuniciranja kako na strani
ureaja (DataLogger-a) tako i na strani raunara. Standardni RS232 port je vezan na
EUSART modul 1 mikrokontrolera.

-5-

Viekanalni ureaj za akviziciju analognih signala

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

Slika 5. RS232 konektor

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

Slika 6. ema RS232 transceiver-a

2.3.2 USB KOMUNIKACIJA


PIC18F8722 mikrokontroler nema USB kontroler. Zbog ogranienja brzine
prenosa podataka standardnom RS232 komunikacijom i velike koliine podataka
koja treba da se prenese sa memorijske kartice na PC uveden je konvertor
standardne serijske komunikacije na USB komunikaciju. Integrisano kolo koje je
iskorieno za ovu konverziju je FT232BM (FTDI chips). Kao i kod standardne
RS232 komunikacije i ovde je iskorien hardverski handshaking. Zapravo, u ovom
sluaju je hardverski handshaking jo potrebniji zato to su brzine prenosa
podataka do 8 puta vee nego kod RS232 komunikacije. Maksimalna brzina prenosa
podataka na ovaj nain je 921600b/s.
Problemi koji se mogu javiti pri ovim brzinama prenosa podataka jesu
prepunjenje prijemnog bafera. Naime, ukoliko raunar ne stigne dovoljno brzo da
proita i sauva podatke iz prijemnog bafera moe se desiti da ti podaci budu
prepisani novim podacima. Nain da se ovo izbegne je upravo hardverski
handshaking. Kada se na strani PC-a napuni prijemni bafer raunar postavlja liniju
RTS (request to send) na neaktivni logiki nivo (logika jedinica). RTS linija sa PC-a
je povezana na CTS (clear to send) liniju mikrokontrolera koji itanjem ove linije
saznaje da PC nije spreman za dalju komunikaciju. Mikrokontroler eka da RTS linija
dostigne aktivni logiki nivo (logika nula) i tada nastavlja sa slanjem podataka.
Identino se deava i prilikom slanja podataka sa PC-a na mikrokontroler.
-6-

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala


VCC

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

Slika 7. ema FT232BM konvertora

ema RS232-USB konvertora je standardna ema preporuena od strane


proizvoaa integrisanog kola. Postoje dva naina napajanja FT232BM ipa.
Napajanje od strane ureaja na kome se nalazi (eksterno napajanje) i napajanje od
strane USB konekcije. Izbor izmeu ove dve vrste napajanja se vri hardverski i
odreuje se logikim stanjem na PWRCTL pinu FT232BM ipa (pin 14). Ukoliko je
ovaj pin na 0V tada se ip napaja sa USB konektora u suprotnom, ukoliko je pin
povezan na 5V, napajanje ipa se vri od strane ureaja na kome je ip ugraen.
Ovaj drugi nain je iskorien kod DataLogger-a.
Pinovi TxLED i RxLED slue za indikaciju protoka podataka. TxLED slui za
indikaciju prilikom slanja podataka, a RxLED za indikaciju prijema podataka. Kod
DataLogger-a je iskoriena konfiguracija sa jednom LED diodom koja vri indikaciju
i slanja i prijema podataka.
FT232BM konvertor je povezan na EUSART modul 2 mikrokontrolera.

2.4 DIGITALNI ULAZ/IZLAZ


Radi naknadne nadogradnje i unapreenja DataLogger-a na tampanoj ploi su
izvedena i dva digitalna porta; PORTH i PORTJ. Ovi portovi su izvedeni na dva
IDC10 konektora i povezani na pull-up/pull-down otpornike mree. Ove otpornike
mree slue da odrede napon neaktivnog logikog stanja kada se pin koristi kao
ulazni. Kada su damperi (kratkospojnici) JP1 i JP2 u gorjem poloaju napon ulazne
linije pri neaktivnom stanju +5V, a kada su damperi u donjem poloaju tada je
napon ulazne linije pri neaktivnom stanju 0V.

-7-

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala


JP1

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

Slika 8. ema konektora za digitalne U/I

2.5 KONEKTOR ZA PROGRAMATOR


Kao to je ranije napomenuto mikrokontroler PIC18F8722 se programira preko
PGC (program clock) i PGD (program data) linija. Programiranje se vri u high
voltage programming modu (programiranje visokim naponom) to znai da je na
MCLR (master clear) liniju mikrokontrolera prilikom programiranja potrebno dovesti
13V.
Programator koji je iskorien za upis HEX fajla u mikrokontroler je PICflash2
programator firme MikroElektronika i konektor je povezan prema specifikaciji
proizvoaa. Sa desne strane konektora nalaze se veze pinova RB6 i RB7 prema
periferijama i MCLR pin koji je vezan na reset kolo. Sa druge, leve, strane konektora
nalaze se veze pinova RB6, RB7 (PGC i PGD pinovi) i MCLR ka mikrokontroleru.
Prema specifikaciji proizvoaa PICflash2 programatora napajanje mikrokontrolera
MCU-VCC i napajanja ostatka uredjaja VCC su odvojeni. Ovo je neophodno za
programiranje nekih ipova iz PIC16F serije mikrokontrolera.
VCC
VCC
R4
100K

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

Slika 9. ema konektora za programiranje mikrokontrolera

-8-

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

Kada programator nije prikljuen na DataLogger neophodno je staviti dampere


na mesto programatora da bi se uspostavila veza izmeu RB6, RB7 i MCLR pinova
mikrokontrolera i periferija tj. reset kola. Takoe samo na taj nain je mogue
povezati napajanje ureaja VCC na napajanje mikrokontrolera MCU-VCC. U sluaju
da se ne stave damperi RB6 i RB7 pinovi mikrokontrolera nee biti povezani sa
periferijama, ali na ovim linijama se nalaze dva pull-down otpornika (R20 i R21) od
100K koji definiu stanje ova dva pina (logika nula) kada se koriste kao ulazni
pinovi.

2.6 4.096V NAPONSKA REFERENCA


Integrisano kolo iskorieno kao izvor naponske reference od 4.096V je
Microchip-ov MCP1541. Ova naponska referenca se koristi prilikom A/D konverzije i
predstavlja maksimalnu vrednost koja moe biti izmerena prilikom konverzije. Razlog
zato se koristi 4.096V referenca umesto 5V je taj to je 4096 stepen od broja 2
( 4096 = 210 ) pa je stoga ta vrednost laka za prikaz u digitalnom obliku.
PIC18F8722 mikrokontroler ima 10-bitni A/D (Analogno/Digitalni) konvertor sa
16 kanala. To znaci da moe da izmeri 210 = 1024 razliitih vrednosti. Sa naponskom
referencom od 4.096V preciznost merenja je:

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

Slika 10. ema 4.096V naponske reference

2.7 RESET KOLO


Kod DataLogger-a iskorieno je standardno reset kolo. Paralelno reset tasteru
(T9) vezan je kondenzator (C8) vrednosti 100nF koji slui za debouncing tj. za
neutralisanje oscilacija u tasteru. Zbog mehanikih karakteristika i nesavrenosti
tastera prilikom pritiskanja i otputanja desava se da se nekoliko puta uspostavi i
raskine kontakt. Kondenzator C8 spreava nagle promene napona na krajevima
tastera i samim tim neutralie ovu pojavu.

-9-

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala


VCC
VCC
R4
100K

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

Slika 11. Reset taster

C8
100n

Slika 12. ema reset kola

Reset taster je preko konektora za programiranje vezan na MCLR (Master


Clear) pin mikrokontrolera. Na ovaj pin je vezan pull-up otpornik (R4) od 100K ime
je logiko stanje ovog pina definisano kao logiko jedan (neaktivno stanje nema
reseta). Aktivno stanje MCLR pina je logika nula tako da do reseta mikrokontrolera
dolazi kada se pritisne reset taster.

2.8 KONEKTORI ZA ANALOGNE ULAZE I DODATNI INTERFEJS


Kao to je ve reeno PIC18F8722 mikrokontroler ima 10-bitni A/D konvertor sa
16 kanala. U DataLogger-u je iskorieno prvih 8 kanala za A/D konverziju koji su
oznaeni sa AN0, AN1, AN2, AN4, AN5, AN6, AN7 i AN8. Kanal AN3 je VREF+ pin
koji je iskorien za 4.096V naponsku referencu.
Svi kanali su vezani na konektore (CN5-CN12) tako da se na DataLogger moe
vezati 8 razliitih izvora napona. Svaka fizika veliina se uz odgovarajui senzor
(pretvara) moe konvertovati u analogni napon. Ukoliko senzor daje napon koji se
ne nalazi u opsegu od 0V do 4.096V predvieni su konektori (CN3 i CN4) za dodatni
interfejs (Daughter Board Interface) na kojima se moe nalaziti pojaava
(prilagoavac) naponskog nivoa tako da odgovara DataLogger sistemu.

Slika 13. Konektori za analogne ulaze

- 10 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala


CN5
AN0

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

Slika 14. ema konektora za analogne ulaze i dodatni interfejs

Konektori za analogne ulaze i konektori za dodatni interfejs su vezani paralelno


tako da u sluaju da se koristi dodatni interfejs moraju se obezbediti posebni
konektori za analogne ulaze (konektori za analogne ulaze na DataLogger sistemu se
u tom sluaju ne mogu koristiti).

2.9 DS1820 TEMPERATURNI SENZOR


DS1820 temperaturni senzor firme Dallas je poznat kao one-wire senzor. Ima
tri pina od toga su dva za napajanje VCC i GND i trei pin za prenos podataka DQ.
Napon napajanja moe biti u opsegu od 3V do 5.5V. Raspon temperatura koje se
mogu izmeriti ovim senzorom su od -55C do +125C. U opsegu od -10C do +85C
ima tanost 0.5C. Rezolucija rezultata merenja temperature je 9 bitova. Najvii bit
(bit 9) nosi znak temperature; 0 je pozitivna temperatura, a 1 je negativna
temperatura. Nizih 8 bitova nose vrednost izmerene temperature.
VCC
R2
10K
RE0

VCC

TS1
1
VCC
2
DQ
3
GND
DS1820

Slika 15. ema veza DS1820 temperaturnog senzora

- 11 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

DQ pin DS1820 temperaturnog senzora je vezan za RE0 pin mikrokontrolera.


Neophodno je vezati pull-up otpornik (R2) na liniju DQ zato to je ona tipa otvorenog
drejna (open-drain). Na ovaj nain se definie osnovno logiko stanje DQ linije
(logicko 1) .

2.10 GRAFIKI DISPLEJ


Grafiki displej koji je iskorien kod DataLogger sistema je GDM12864B firme
Xiamen Ocular sa rezolucijom 128x64 piksela. Kontroler koji ima ovaj displej je
S6B0108.
GDM12864B displej ima 20 pinova, iji su raspored i uloga dati u sledeoj
tabeli:
PIN NO Symbol

Function

/CSA

Chip select for IC1

/CSB

Chip select for IC2

VSS

GND

VDD

+5V

V0

Constrast adjustment

D/I

H/L Register select signal

R/W

H/L Read/Write signal

H/L Enable signal

9 to 16 DB0 to DB7 H/L Data bus line


17

RST

Reset signal

18

VEE

Negative voltage output

19

Power supply for BKL(4.2V)

20

Power supply for BKL(GND)

Tabela 1. Raspored i uloga pinova GDM12864B displeja

Data linije D0-D7 su vezane na PORTD mikrokontrolera (RD0-RD7), a


kontrolne linije CS1, CS2, RS, R/W, E i RST su vezane na pinove RE2-RE7
respektivno. Vo pin je pin za podeavanje kontrasta grafikog displeja. Da bi se
obezbedio odgovarajui kontrast neophodno je na ovaj pin dovesti negativan napon
od 9.5V. GDM12864B ima interni generator negativnog napona iji se izlaz nalazi na
pinu Vee. Da bi postojala mogucnost podeavanja kontrasta negativni napon (Vee) je
vezan na Vo pin preko trimer potenciometra P1.

- 12 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala


CN14
RE2
RE3
GND
VCC
P1
10K

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

Slika 16. ema grafikog displeja GDM12864B

LED+ i LED- pinovi grafikog displeja slue da obezbede pozadinsko


osvetljenje (backlight) displeja. Pad napona na pozadinskom osvetljenju je
V F = 4.2V , a struja pri maksimalnom osvetljenju I F = 360mA .
Struja pozadinskog osvetljenja kod DataLogger-a iznosi:
ID =

VCC VF 5V 4.2V 0.8V


=
=
= 80mA .
10
10
R5

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

Viekanalni ureaj za akviziciju analognih signala


VCC
RN1
1
2
3
4
5
6
7
8
9

RB0
RB1
RB2
RB3
RB4
RB5
RB6
RB7

RPACK8/9
T1

T2

T3

T4

T5

T6

T7

T8

Slika 17. ema tastature

2.12 INTERFEJS ZA MEMORIJSKU KARTICU


Jedan od osnovnih zadataka DataLogger sistema je upis izmerenih analognih
napona i temperature u MMC/SD memorijsku karticu. Radni napon
MMC
(MultiMediaCard) kartice je 3.3V zbog ega je bilo neophodno ugraditi 3.3V naponski
regulator. Za to je iskorieno kolo MC33269DT-3.3 firme Motorola. Osnovne
karakteristike ovog regulatora su maksimalna izlazna struja od 800mA, zatita od
pregrevanja i zatita od kratkog spoja.
VCC

VCC

VCC
REG2
3
1

Vin

Vout

MC33269DT-3.3
E8
10uF

VCC3

GND

C11
100nF

E9
10uF

Slika 18. ema 3.3V regulatora

MMC memorijska kartica komunicira sa mikrokontrolerom preko SPI (Serial


Peripheral Interface) komunikacije. Ova komunkacija zahteva tri linije SCK (Serial
Clock), SDI (Serial Data Input) i SDO (Serial Data Output). SCK linija je zajednika
za mikrokontroler i memorijsku karticu, dok se SDI linija mikrokontrolera vezuje na
SDO liniju memorijeske kartice i obratno. Neophodna je jo jedna, kontrolna, linija za
hardversko selektovanje memorijske kartice, ona je oznaena sa CS (Chip Select).

- 14 -

Mihajlovi Duan
MCU-SDI

RC4

MMC-CS#

RC2

MCU-SDO

RC5

MCU-SCK

RC3

Viekanalni ureaj za akviziciju analognih signala

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

Slika 19. ema interfejsa za MMC/SD karticu

Kako je naponski nivo logike jedinice na izlazu mikrokontrolera 5V, a


maksimalni napon na ulazu memorijske kartice 3.6V neophodno je izvriti
prilagoenje naponskog nivoa. Na izlazne linije SPI komunikacije iz mikrokontrolera
(SCK, SDO i CS) vezuju se tri razdelnika napona (R6-R11) koji obezbeuju da napon
logike jedinice na ulaznim pinovima memorijske kartice bude 3.3V.
Napon logike jedinice izlazne linije iz memorijske kartice (SDO) je 3.3V. Ova
linija se moe bez problema vezati direktno na ulazni pin (SDI) mikrokontrolera zato
to je opseg napona koje mikrokontroler prepoznaje kao logiku jedinicu od 2.5V do
5V.

Slika 20. Interfejs za MMC/SD karticu

- 15 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

3. OPIS SOFTVERA DATALOGGER SISTEMA


Pisanje softvera za mikrokontrolere je karakteristino i razlikuje se od pisanja
softvera za PC. Programer mikrokontrolera mora imati vee poznavanje hardvera od
programera softvera za PC. Neophodno je veoma paljivo inicijalizovati
mikrokontrolerski sistem da bi on pravilno radio. Da bi se napisao kvalitetan softver
programer mora biti upoznat sa samom arhitekturom mikrokontrolera i nainom rada
perifernih ureaja integrisanih u njemu. To znai da je uz programiranje potrebna
konstantna konsultacija sa uputstvom proizviaa odgovarajueg mikrokontrolera.
U ovom poglavlju bie opisan kako opti algoritam softvera DataLogger
sistema, tako i njegovi specifini delovi. Posebna panja bie posveena inicijalizaciji
i prenosu podataka izmeu PIC18F8722 mikrokontrolera i periferija.
U razvoju softvera korien je mikroC kompajler firme MikroElektronika koji u
mnogome olakava razvoj jer sadri veliki broj gotovih funkcija za rad sa PIC
mikrokontrolerima.

3.1 OPTI ALGORITAM


Na slici 21 je prikazan opti algoritam DataLogger sistema. Na samom startu,
nakon ukljuenja izvora napajanja ili reseta ureaja, neophodno je inicijalizovati
periferije. Nakon inicijalizacije uitavaju se parametri sistema iz EEPROM-a i na
grafikom displeju sistema se ispisuje poruka DataLogger to je znak da je ureaj
pravilno inicijalizovan i program nastavlja dalje sa izvravanjem.
Nakon toga program ulazi u beskonanu petlju u kojoj ce se zadrati sve dok se
ne iskljui napon napajanja ili ne resetuje sistem. U ovoj beskonanoj petlji e se
izvravati sve funkcije DataLogger sistema. Te funkcije su logiki podeljene i bie
detaljno objanjene.

- 16 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

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

Slika 21. Opti algoritam DataLogger sistema

- 17 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

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.

3.3 TAJMERI I INTERAPTI


DataLogger sistem koristi kristal kvarca od 7.3728MHz. Mikrokontroler radi u
HS-PLL reimu tako da se brzina kristala mnoi sa 4 ime se konano dobija
29.4912MHz. PIC18F8722 mikrokontroler ima podeljen takt izvravanja instrukcija na
etiri dela tako da je realna brzina izvravanja instrukcija 7.3728MHz. To znai da je
osnovni period izvravanja instrukcija:

TCY =

1
1
=
0.1356s
FCY 7.3728MHz

Upisivanjem vrednosti 28672 kao poetne vrednosti u Tajmer 0 i 1 dobija se


generisanje interapta na svakih:
T = (65536 28672) TCY = 36864 TCY = 36864 0.1356s = 5ms
Poetna vrednost je oduzeta od 65536 zato to tajmeri rade u 16-bitnom reimu
pa je maksimalna vrednost koju tajmer 0 i 1 mogu izbrojati 216 = 65536 . Ovaj osnovni
period od 5ms se u samoj interapt rutini mnoi sa deset tako da je minimalni

- 18 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

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.

3.4 PODEAVANJE PARAMETARA SISTEMA (EEPROM)


Parametri sistema se podeavaju serijskom komunikacijom ostvarenom preko
standardne RS232 komunikacije i slui za upis i itanje parametara iz EEPROM-a
mikrokontrolera PIC18F8722. Radi na brzini od 115200bit/s i koristi hardverski
handsaking za kontrolu prenosa podataka. Nakon povezivanja PC-a i DataLogger-a
na strani PC-a je neophodno pokrenuti neki od terminala (preporuuje se
HyperTerminal koji ima svaki Windows operativni sistem) i podesiti brzinu i
karakteristike prenosa podataka.
Ukoliko se otkuca komanda help (bez navodnika) i pritisne enter na ekranu
terminala dobie se spisak komandi:

*****************************************************************
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 =

Viekanalni ureaj za akviziciju analognih signala

Vizm
32768 .
Vnaz

Kada su izmerena i nazivna vrednost reference jednake tada se za kalibracionu


konstantu dobija 32768 (0x8000) to predstavlja odnos Vizm : Vnaz = 1 : 1 . U sluaju da
je izmerena vrednost jednaka 4.093V kalibraciona konstanta e biti:
Cal =

4.093V
32768 = 32744
4.096V

to predstavlja 0x7FE8 u heksadecimalnom sistemu.


Komanda write -cycle upisuje novu vrednost ciklusa za upis u memorijsku
karticu. Potrebno je uneti broj veliine dva bajta. Najvia etiri bita predstavljaju
podeavanje preskalera, a niih dvanaest koliko jedinica od 50ms prescaler treba da
protekne da bi se generisao zahtev za upis podataka u memorijsku karticu.
Komanda write -source slui za ukljuenje/iskljuenje analognig ulaza. Ovaj
broj je veliine jedan bajt i najstariji bit odreuje stanje AN8 analognog ulaza, a
najnii bit stanje AN0 analognog ulaza. Vrednost 1 odreuje analogni ulaz kao
ukljuen, a vrednost 0 kao iskljuen.
Komanda write -ds1820 ukljuuje/iskljuuje DS1820 temperaturni sensor.
Vrednost 0xFF odreuje temperaturni senzor kao ukljuen, a vrednost 0x00 kao
iskljuen.

3.5 ITANJE REZULTATA A/D KONVERZIJE


Neposredno pred upis podataka u memorijsku karticu potrebno je oitati rezultat
A/D konverzije. Sama A/D konverzija se pokree u modulu za start A/D konverzije i
bie posebno objanjena u poglavlju Start A/D konverzije. Prilikom itanja rezultata
vri se korekcija na osnovu kalibracione konstante. Vrednost A/D konverzije je broj
izmeu 0 i 1023 pa je ta vrednost pomnoena sa 4 da bi se dobila vrednost od 0 do
4092. Prilikom ispisa ove vrednosti na displej neophodno je jo prikazati znak
decimale nakon prve cifre.
Da bi se smanjio um prilikom merenja uvodi se integracija rezultata
(smoothing) koja se svodi na to da je nova vrednost konverzije jednaka srednjoj
vrednosti prethodne i trenutne vrednosti konverzije:

VCH =

V pret + Vtren

3.6 ITANJE TEMPERATURE


DS1820 temperaturni senzor meri temperature od -55C do +125C. U opsegu
od -10C do +85C ima tanost 0.5C. Rezolucija rezultata merenja temperature je 9
bitova. Najvii bit (bit 9) nosi znak temperature; 0 je pozitivna temperatura, a 1 je
negativna temperatura. Niih 8 bitova nose vrednost izmerene temperature to se
moe videti iz sledee tabele:

- 20 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

TEMPERATURE
+85.0C
+25.0C
+0.5C
0C
-0.5C
-25.0C
-55.0C

DIGITAL OUTPUT

DIGITAL OUTPUT

(Binary)

(Hex)

0000 0000 1010 1010


0000 0000 0011 0010
0000 0000 0000 0001
0000 0000 0000 0000
1111 1111 1111 1111
1111 1111 1100 1110
1111 1111 1001 0010

00AAh
0032h
0001h
0000h
FFFFh
FFCEh
FF92h

Tabela 2. Vrednosti rezultata merenja temprature

Rezultat temperature je zapisan tako da jedan podeok ima vrednost 0.5C. To


znai da je prilikom prikaza temperature na displeju neophodno pomnoiti ovaj broj
sa 0.5.

3.7 UPIS U MEMORIJSKU KARTICU


MMC/SD memorijske kartice su danas veoma popularne zbog svoje
kompaktnosti i velike koliine podataka koji se mogu sauvati na njima. Kapacitet
memorije ide od 32MB do 2GB. MMC/SD kartice su organizovane po sektorima koji
su obino veliine 512B ali mogu i odstupati od ove vrednosti. Na DataLogger
sistemu nalazi se interfejs (konektror) za memorijsku karticu.
Ovaj deo programa organizovan je tako da se prilikom ubacivanja kartice u slot
vri verifikacija kartice. Naime, u EEPROM-u se uva podatak o poslednjoj korienoj
kartici. Taj podatak je lini identifikator kartice koji se isitava iz CID (Card
IDentification) registra kartice. Ukoliko je ubaena nova kartica sistem e upisati njen
CID u EEPROM i poeti sa upisom vrednosti analognih napona i temperature u
memorijsku karticu poevi od sektora 1. Sektor 0 slui za uvanje podatka o prvom
slobodnom sektoru na memorijskoj kartici kao i o prvom slobodnom bajtu unutar
sektora. Ovo je znaajno u sluaju da je prilikom verifikacije kartice otkriveno da je
ubaena kartica takoe i poslednja kriena. Tada se itanjem podataka iz sektora 0
upis nastavlja od prvog slobodnog mesta na kartici to znai da nee doi do
prepisivnja ranije upisanih podataka.
Upis u memorijsku karticu se vri u blokovima od 512 bajtova tako da je
neophodno obezbediti bafer u koji e se upisivati podaci sve dok se bafer ne popuni.
Pored vrednosti analognog napona i temperature u memorijsku karticu se upisuje i
referentno vreme (vreme zapisa podatka) i broj izvora iju vrednost taj podatak
predstavlja. Zatim sledi upis bafera u memorijsku karticu i upis broja sektora u sektor
0. Ovakvom organizacijom programa dobija se mogunost da se nakon nestanka
napajanja uredjaja ili reseta nastavi sa upisom od prve slobodne lokacije na kartici.
Kominikacija izmedju MMC kartice i mikrokontrolera se obavlja SPI
komunikacijom iji je hardverski aspekt obraen u poglavlju Interfejs za memorijsku
karticu. Sam protokol se svodi na slanje komandi memorijskoj kartici i primanje
odgovora.

- 21 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

MMC/SD memorijske kartice imaju interne registre u kojima se uvaju kako


identifikacija same kartice tako i njene karakteristike. Dva najbitnija registra su
svakako CID (Card IDentification) i CSD (Card Specific Data). Oba registra su
veliine 16 bajta. Uloga CID registra je ve ranije pomenuta pa emo se zadrati na
CSD registru.
CSD registar je registar specifinih podataka kartice. U njemu se nalaze
najbitnije karakteristike memorijske kartice. Podaci koji su neophodni za
izraunavanje veliine memorijske kartice su READ_BL_LEN, C_SIZE_MUL i
C_SIZE.
READ_BL_LEN predstavlja veliinu jednog bloka (sektora) koji se moe
upisati/proitati iz memorijske kartice. Vrednost ovog podatka ide od 1B do 2KB i
tipino je 512B.
C_SIZE_MUL predstavlja konstantu kaja se koristi prilikom izraunavanja
veliine kartice. Vrednost ove konstante je od 4 do 512.
C_SIZE je jo jedan parametar bitan za odreivanje veliine kartice. Formula po
kojoj se rauna veliina je:

Capacity = (C _ SIZE + 1) 2 C _ SIZE _ MUL + 2 2 READ _ BL _ LEN

3.8 START A/D KONVERZIJE


A/D konverzija se vri u dva koraka. Prvo je neophodno izvriti akviziciju
vrednosti napona, a tek onda konverziju tog napona u digitalni oblik.
U ovom modulu startuje se A/D konverzija poevi od prvog ukljuenog kanala.
A/D konvertor mikrokontrolera je inicijalizovan tako da se generie interapt nakon
zavrene konverzije. Kada je konverzija jednog kanala zavrena u interapt rutini se
upisuje rezultat konverzije u sistemsku promenljivu, a zatim se pokree konverzija
sledeeg ukljuenog kanala.
U inicijalizaciji A/D konvertora neophodno je podesiti vreme akvizicije
analognog napona i brzinu A/D konverzije. Akvizicija analognog napona predstavlja
punjenje internog C HOLD kondenzatora nakon ega se analogni ulaz odvaja od
mikrokontrolera, a konverzija se vri na osnovu vrednosti napona u kondenzatoru.
to je vreme akvizicije due i brzina konverzije manja to je rezultat taniji. Ipak
podesena je optimalna vrednost koja e za to manje vreme dati prihvatljivu tanost
rezultata konverzije.
T AD predstavlja osnovni period A/D konverzije i odreuje se prema formuli:

TAD = 32 TOSC = 32

TCY
0.1356s
= 32
= 1.085s
4
4

T ACQ predstavlja vreme trajanja akvizicije i odreuje se prema formuli:

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:

T = T ACQ + 11 T AD = 6.51s + 11 1.085s = 18.445s

- 22 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

Vrednosti konstanti u formulama zavise od inicijalizacije A/D konvertora i vie


podataka o njima moe se nai u originalnoj Microchip dokumentaciji za PIC18F8722
mikrokontroler.

3.9 ITANJE PODATAKA IZ MEMORIJSKE KARTICE


itanje podataka iz memorijske kartice se obavlja brzom serijskom
komunikacijom koja se ipom FT232BM konvertuje u USB komunikaciju. Pored toga
slui i za proveru statusa i brisanje memorijske kartice, ispis CSD i CID registara.
Brzina prenosa je 921600bit/s i da ne bi dolo do gubitka podataka prilikom prenosa
koristi se hardverski handshaking.
Na PC-u je neophodno instalirati drajver za FT232BM chip koji se moe skinuti
sa sajta proizvoaa FTDIchip. Posle toga USART modul 2 se na PC-u prepoznaje
kao standardni COM port. Nakon povezivanja PC-a i DataLogger-a na strani PC-a je
neophodno pokrenuti neki od terminala (preporuuje se HyperTerminal koji ima svaki
Windows operativni sistem) i podesiti brzinu i karakteristike prenosa podataka.
Ukoliko se otkuca komanda help (bez navodnika) i pritisne enter na ekranu
terminala dobie se spisak komandi:

***********************************************************
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

Viekanalni ureaj za akviziciju analognih signala

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

Tabela 3. Oznake izvora podataka

Sve vrednosti su predstavljene u heksadecimalnom brojnom sistemu.

- 24 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

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:

MMC/SD card usage: 3% of 122MB!

3.10 GRAFIKI DISPLEJ


Ispis na grafikom displeju daje konani izgled i funkcionalnost sistemu. Slui
za direktnu interakciju sa korisnikom i veoma je bitno da prikaz na displeju bude lepo
dizajniran. DataLogger sistem ima dva naina prikaza informacija; grafiki i
tekstualni. Prvi (aktivan pri podizanju sistema) je grafiki reim rada u kome su
analogni naponi sa ulaza i temperatura prikazani u obliku dijagrama. Ovaj reim se
moe izabrati pritiskom na taster #1, a izbor jednog od etiri razliita prikaza
dijagrama vri se pritiskom na taster (levo) ili na taster (desno). Na sledeoj
slici se moe videti jedan on naina grafikog prikaza:

Slika 22. Izgled displeja u grafikom reimu rada

Pritiskom na taster #2 ulazi se u tekstualni nain prikaza. Ovaj nain prikaza je


podeljen na tri segmenta koji se menjaju pritiskom na taster (levo) ili na taster
(desno). Prvo se prikazuju izmerene vrednosti analognih napona oznaenih sa

- 25 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

SENSOR0-SENSOR7. Drugi segment je prikaz temperature u stepenima


Celzijusovih. Trei segment prikazuje trenutno stanje sitema vezano za memorijsku
karticu.
Ukoliko je memorijska kartica ubaena u slot na displeju e biti prikazane
vrednosti READ_BL_LEN, C_SIZE_MUL i C_SIZE parametara iz CSD registra,
ukupan broj sektora i veliina memorijske kartice. Takoe u ovom segmentu se
prikazuju informacije o prenosu podataka sa sistema na PC i podatak da je
memorijska kartica puna.

- 26 -

Mihajlovi Duan

Viekanalni ureaj za akviziciju analognih signala

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

Viekanalni ureaj za akviziciju analognih signala

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

Viekanalni ureaj za akviziciju analognih signala

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

Viekanalni ureaj za akviziciju analognih signala

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;
}

1/5 mikroPascal compiler for dsPIC by mikroElektronika

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:

2/5 mikroPascal compiler for dsPIC by mikroElektronika

DataLogger.c

113:

9/19/2006

if((buttons_new ^ buttons_old) & buttons_old)

//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

3/5 mikroPascal compiler for dsPIC by mikroElektronika

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

/* PORTF - Analogue inputs:


RF7
RF6
RF5
RF4
NC
NC
NC
NC
*/
PORTF = 0x00;
//00000000
TRISF = 0x0F;
//00001111

RF3
AN8

RF2
AN7

RF1
AN6

RF0
AN5

RG3
CTS2

RG2
Rx2

RG1
Tx2

RG0
NC

/* PORTG - RS232-2 (FTDI):


RG4
RTS2
*/
PORTG = 0x38;
TRISG = 0x2C;

//00111000
//00101100

//PORTH - Digital I/O:


//PORTH = 0x00;
//TRISH = 0x00;
//PORTJ - Digital I/O:
//PORTJ = 0x00;
//TRISJ = 0x00;
//GLCD initialization:
Glcd_Init(&PORTE,2,3,4,5,7,6,&PORTD);
Glcd_Set_Font(FontSystem5x8,5,8,32);
//RS232-1 initialization - 115200:
Usart_InitHS1();
//Microcontroller is ready for comm. on RS232-1:
RTS1 = 0;
//RS232-2 initialization (FTDI) - 921600:
Usart_InitHS2();
//Microcontroller is ready for comm. on RS232-2:
RTS2 = 0;
Eeprom_startup();

//reads parameters from EEPROM into system

//turn on analog inputs AN0-AN8, VREF+ as reference:


ADCON1 = 0x16; //00010110
// ADC result - right justified;
// ACQ = 6*Tad = 6*1.085us = 6.51us
// ACS = 32*Tosc = 1.085us = Tad
// Total = 6.51us + 11*1.085us = 18.445us
ADCON2 = 0x9A; //10011010
//Set up interrupt for ADC:
PIR1.ADIF = 0;
PIE1.ADIE = 1;
ADCON0 = 0x01; //AN0, IDLE, ON
//Set up Timer0 for interrupt (MMC write):
INTCON.TMR0IF = 0;
TMR0H = 0x70;
//0x7000 = 28672 (start value)

4/5 mikroPascal compiler for dsPIC by mikroElektronika

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:

//Set up Timer1 for interrupt (buttons):


PIR1.TMR1IF = 0;
TMR1H = 0x70;
//0x7000 = 28672 (start value)
TMR1L = 0x00;
//65536-28672=36864*Tcy => 5ms
//Enable Timer0, Timer1 and ADC:
INTCON.TMR0IE = 1; //Enable Timer0 interrupt
PIE1.TMR1IE = 1;
//Enable Timer1 interrupt
T0CON.TMR0ON = 0;
//Timer0 OFF (will be switched on when mmc verified)
T1CON.TMR1ON = 1;
//Timer1 ON
//Global interrupt enable:
INTCON.PEIE = 1;
INTCON.GIE = 1;
Glcd_Image(datalogger_bmp);
Delay_1sec();
Delay_1sec();
while(1)
//endless loop
{
//Console for EEPROM parameters setup:
Usart_console1();
//Read ADC result and do calibration:
Read_ADC();
//Read ds1820 temperature:
Read_ds1820();
//Writes ADC and DS1820 result into MMC when write_mmc flag is set
//and if mmc is not full:
MMC_write();
//Start A/D conversion:
Start_ADC();
//Console for MMC read and erase:
Usart_console2();
//Manage display modes depending on button presses
GLCD_main();
}

5/5 mikroPascal compiler for dsPIC by mikroElektronika

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

//vref_cal address in EEPROM (2-bytes)


//mmc_cycle address in EEPROM (2-bytes)
//adc_source address in EEPROM (1-byte)
//ds1820 address in EEPROM (1-byte)
//CID address in EEPROM (16-bytes)

#define DIRECT_MAX
#define CYCLE_MAX
writes (in 50ms)

16 //Max number of chars in console directives


200 //Max time that can elapse between two mmc

#define
#define
#define
#define

PORTC.F1
PORTC.F0
PORTG.F4
PORTG.F3

//RTS
//CTS
//RTS
//CTS

80

//ADC scaler value (scaling for

13
6

//glcd graph bar width


//glcd graph bar offset

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

1/1 mikroPascal compiler for dsPIC by mikroElektronika

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";

1/2 mikroPascal compiler for dsPIC by mikroElektronika

Constants.h

9/19/2006

58: const char *empty = "MMC/SD card is empty!\r\n";


59: const char *usage[3] = {"MMC/SD card usage: ","% of ","MB!\r\n"};
60:
61: extern const unsigned short datalogger_bmp[1024];
//picture: DataLogger
startUp
62:
63: #endif
64:

2/2 mikroPascal compiler for dsPIC by mikroElektronika

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;

//calibration value for 4.096V reference


//timebase for MMC write cycle

/* ADC sources (1 - Enabled, 0 - Disabled):


AN8, AN7, AN6, AN5, AN4, AN2, AN1, AN0
*/
unsigned short adc_source;
unsigned short ds1820;
int ds1820_result = 0;

//DS1820 On/Off (1 - Enabled, 0 - Disabled)


//ds1820 temp. sensor result

char directive1[DIRECT_MAX+1];
NULL

//Directive from Usart_console1 - 16 chars +

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

1/2 mikroPascal compiler for dsPIC by mikroElektronika

Variables.h

9/19/2006

51: unsigned long sector = 0, max_sector = 0;


//last accessed sector, maximal
sector address
52: unsigned short card_verified = 0;
//card ID verified flag
53:
54: unsigned short adc_started = 0; //adc started flag
55: unsigned short ch_num = 0;
//channel number
56: unsigned adc_result[8] = {0,0,0,0,0,0,0,0};
//adc result buffer
57: unsigned adc_result_cal[8] = {0,0,0,0,0,0,0,0};
//adc result buffer
(calibrated)
58:
59: unsigned short read_bl_len = 0;
//CSD register (4-bit)
60: unsigned short c_size_mult = 0;
//CSD register (3-bit)
61: unsigned c_size = 0;
//CSD register (12-bit)
62: unsigned card_size = 0;
//card size in MB
63:
64: unsigned short count2 = 0;
//count of chars in the string (console 2)
65: char directive2[DIRECT_MAX+1];
//Directive from Usart_console2 - 16 chars
+ NULL
66: unsigned short erase = 0;
//erase flag
67: unsigned short terminal_err = 0;
//terminal error flag
68:
69: unsigned short glcd_refresh = 1;
//refresh glcd flag
70: unsigned short mmc_refresh = 1;
//refresh glcd screen on mmc event
71: unsigned short adc_refresh = 1;
//refresh glcd screen when entering
text mode
72:
73: unsigned graph_new[9] = {0,0,0,0,0,0,0,0,0};
//new results for GLCD (0-7
- ADC channels, 8 - ds1820)
74: unsigned graph_old[9] = {0,0,0,0,0,0,0,0,0};
//old results for GLCD (0-7
- ADC channels, 8 - ds1820)
75: //flag for determening graph couloring
76: //(0: white-black, 1: black-white, 2: white, 3: black):
77: unsigned short couloring = 0;
78:
79: char *sometext, text[16], text_sec[16];
80: unsigned short left = 0, right = 0, graph_mode = 1, text_mode = 0, position = 0;
81:
82: #endif
83:

2/2 mikroPascal compiler for dsPIC by mikroElektronika

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();

//Read parameters from EEPROM


//Initialize Usart1 to 115200 bps
//Initialize Usart2 to 921600 bps
//Console for EEPROM parameters setup
//Console for MMC read and erase

unsigned short atobHEX(char *s);


to byte
unsigned atowHEX(char *s);
to word
void ByteToStrHEX(unsigned short number, char *output);
string (HEX)
void WordToStrHEX(unsigned number, char *output);
string (HEX)
void LongToStrHEX(unsigned long number, char *output);
string (HEX)

//converts string (HEX)


//converts string (HEX)
//converts byte to
//converts word to
//converts long to

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

1/2 mikroPascal compiler for dsPIC by mikroElektronika

Declarations.h

9/19/2006

47: void GLCD_text();


//writes data on glcd depending on analogue input and
temperature
48: void Refresh(unsigned short source);
//refresh glcd graph
49:
50: void RemoveSpace(char *input, char *output);
//remove space at begining of
string
51:
52: #endif
53:

2/2 mikroPascal compiler for dsPIC by mikroElektronika

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"

extern unsigned vref_cal;


//calibration value for 4.096V reference
extern unsigned mmc_cycle;
//timebase for MMC write cycle
extern unsigned short adc_source;
//ADC sources On/Off
extern unsigned short ds1820;
//DS1820 On/Off (1 - Enabled, 0 - Disabled)
extern unsigned short CID_old[16]; //buffer for last CID
extern unsigned long partial_time; //mmc_cycle in 50ms (with prescaler
included)
22: extern unsigned data_counter;
//counts how many bytes are writen into
buffer
23: extern unsigned short mmc_backup;
//mmc_backup flag
24:
25: void Eeprom_startup()
//Read parameters from EEPROM
26: {
27:
unsigned short i;
28:
//Reads 4.096V reference calibration value (2-bytes):
29:
Lo(vref_cal) = Eeprom_Read(VREF_CAL_ADDR);
30:
Hi(vref_cal) = Eeprom_Read(VREF_CAL_ADDR+1);
31:
32:
//Reads timebase for MMC write cycle (2-bytes) and calculate mmc_cycle in
50ms:
33:
Lo(mmc_cycle) = Eeprom_Read(MMC_CYCLE_ADDR);
34:
Hi(mmc_cycle) = Eeprom_Read(MMC_CYCLE_ADDR+1);
35:
36:
if(T0CON.F3 == 1)
//if Prescaler is not assigned mmc write period equals
mmc_cycle (bits 0 - 11)
37:
{
38:
partial_time = (unsigned long)(mmc_cycle & 0x0FFF);
39:
}
40:
else
//if Prescaler is assigned mmc write period equals
mmc_cycle*prescaler_value
41:
{
42:
switch(T0CON & 0x07)
43:
{
44:
case 0b00000111: partial_time = (unsigned long)(mmc_cycle & 0x0FFF) <<
8; break;
45:
case 0b00000110: partial_time = (unsigned long)(mmc_cycle & 0x0FFF) <<
7; break;
46:
case 0b00000101: partial_time = (unsigned long)(mmc_cycle & 0x0FFF) <<
6; break;
47:
case 0b00000100: partial_time = (unsigned long)(mmc_cycle & 0x0FFF) <<
5; break;
48:
case 0b00000011: partial_time = (unsigned long)(mmc_cycle & 0x0FFF) <<
4; break;

1/6 mikroPascal compiler for dsPIC by mikroElektronika

EEPROM.c

49:
50:
51:

9/19/2006

case 0b00000010: partial_time = (unsigned long)(mmc_cycle & 0x0FFF) <<


3; break;
case 0b00000001: partial_time = (unsigned long)(mmc_cycle & 0x0FFF) <<
2; break;
case 0b00000000: partial_time = (unsigned long)(mmc_cycle & 0x0FFF) <<
1; break;
}
}

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)

2/6 mikroPascal compiler for dsPIC by mikroElektronika

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;

3/6 mikroPascal compiler for dsPIC by mikroElektronika

EEPROM.c

142:

9/19/2006

case 0b00000000: partial_time = (unsigned long)(mmc_cycle &


0x0FFF) << 1; break;

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)
{

4/6 mikroPascal compiler for dsPIC by mikroElektronika

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:

//displays byte value on the terminal (in

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:

//displays byte value on the terminal (in

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;

5/6 mikroPascal compiler for dsPIC by mikroElektronika

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:

6/6 mikroPascal compiler for dsPIC by mikroElektronika

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;

1/3 mikroPascal compiler for dsPIC by mikroElektronika

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

//adc_result_cal[3] = (unsigned)((adc_result[3] << 2)*cal_value);


graph_new[3] = adc_result_cal[3]/ADC_SCALER;
}
else graph_new[3] = 0xFF;
if(adc_source.F4)
{
adc_result_cal[4] = (adc_result_cal[4] + (unsigned)((adc_result[4]
2)*cal_value)) >> 1;
//adc_result_cal[4] = (unsigned)((adc_result[4] << 2)*cal_value);
graph_new[4] = adc_result_cal[4]/ADC_SCALER;
}
else graph_new[4] = 0xFF;
if(adc_source.F5)
{
adc_result_cal[5] = (adc_result_cal[5] + (unsigned)((adc_result[5]
2)*cal_value)) >> 1;
//adc_result_cal[5] = (unsigned)((adc_result[5] << 2)*cal_value);
graph_new[5] = adc_result_cal[5]/ADC_SCALER;
}
else graph_new[5] = 0xFF;
if(adc_source.F6)
{
adc_result_cal[6] = (adc_result_cal[6] + (unsigned)((adc_result[6]
2)*cal_value)) >> 1;
//adc_result_cal[6] = (unsigned)((adc_result[6] << 2)*cal_value);
graph_new[6] = adc_result_cal[6]/ADC_SCALER;
}
else graph_new[6] = 0xFF;
if(adc_source.F7)
{
adc_result_cal[7] = (adc_result_cal[7] + (unsigned)((adc_result[7]
2)*cal_value)) >> 1;
//adc_result_cal[7] = (unsigned)((adc_result[7] << 2)*cal_value);
graph_new[7] = adc_result_cal[7]/ADC_SCALER;
}
else graph_new[7] = 0xFF;
PIE1.ADIE = 1; //enable A/D conversion interrupt
}

<<

<<

<<

<<

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

2/3 mikroPascal compiler for dsPIC by mikroElektronika

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
}
}

3/3 mikroPascal compiler for dsPIC by mikroElektronika

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)

//refresh glcd screen on mmc event


//old results for GLCD (0-7 - ADC

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

1/12 mikroPascal compiler for dsPIC by mikroElektronika

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

extern unsigned short CID_old[16];


extern unsigned adc_result_cal[8];
extern unsigned short card_verified;
extern unsigned short read_bl_len;
extern unsigned short c_size_mult;
extern unsigned c_size;
unsigned short temp = 0;
unsigned short CSD_rev[16];

//buffer for old CID


//adc result (calibrated)
//card ID verified flag
//CSD register (4-bit)
//CSD register (3-bit)
//CSD register (12-bit)
//temp variable
//reversed buffer for CSD

if(Mmc_Init(&PORTC,2)) //if MMC is detected and initialized


{
if(!card_verified) //if card is not verified
{
if(Mmc_Read_Csd_Cust(CSD)) //Reads CSD register
{
mmc_err = 4;
//error No. 4: READ_CSD
return;
}
for(j=0; j<16; j++) //reverse order in CSD register (place MSB in
15-th byte)
{
CSD_rev[j] = CSD[15-j];
}
for(j=0; j<3; j++) //decode c_size_mult
{
if(GetBit(CSD_rev,47+j)) c_size_mult |= 0b00000001 << j;
}
for(j=0; j<4; j++) //decode read_bl_len
{
if(GetBit(CSD_rev,80+j)) read_bl_len |= 0b00000001 << j;
}
for(j=0; j<12; j++) //decode c_size
{
if(GetBit(CSD_rev,62+j)) c_size |= 0x0001 << j;
}
//calculate number of sectors (1 sector = 512 bytes):
max_sector = (unsigned long)(c_size+1) <<
(c_size_mult+2+read_bl_len-9);
card_size = max_sector >> 11;
//card_size = max_sector/2048
if(Mmc_Read_Cid(CID_new))
//Reads CID register
{
mmc_err = 3;
//error No. 3: READ_CID
return;
}
for(i=0; i<16; i++) //compare inserted card with last one used
{
if(CID_new[i] != CID_old[i])
//if CID_new is different than
CID_old

95:
96:

{
for(j=0; j<16; j++)

//write CID_new to CID_old and

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)

2/12 mikroPascal compiler for dsPIC by mikroElektronika

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
{

3/12 mikroPascal compiler for dsPIC by mikroElektronika

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

mmc_err = 1; //error No. 1: READ_SECTOR


return;
}
}
mmc_refresh = 1;
T0CON.TMR0ON = 1;

//if card was not verified set mmc_refresh flag


//Timer0 ON

}
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
{

4/12 mikroPascal compiler for dsPIC by mikroElektronika

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;

//set mmc_full flag


//clear card_verified flag

}
}
}
}
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

5/12 mikroPascal compiler for dsPIC by mikroElektronika

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;

//without changing sector value


//error No. 2: WRITE_SECTOR

}
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: {

6/12 mikroPascal compiler for dsPIC by mikroElektronika

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

char ch, temp[8];


//received
character and temporary string
unsigned short string_done = 0;
//flag for string
completion
unsigned i;
//counters
unsigned long j;
//...
unsigned k;
//...
unsigned timeout = 0;
//terminal timeout
extern unsigned short count2;
//count of chars in
the string
extern const char *help2, *read2[2], *abort, *yes_no, *erase_ok, *no_card;
//help2, read2, abort, yes_no, erase_ok, no_card strings
extern const char *err_write, *err_read, *full, *empty, *usage[3];
//err_write, err_read, full, empty, usage strings
extern char directive2[DIRECT_MAX+1];
//buffer for
received string
extern unsigned short terminal_err;
//terminal error
flag
extern unsigned short erase;
if(Usart_Data_Ready2())
{
ch = Usart_Read2();
//If there is no more space in string and last recaived char is not
//CR do nothing - return
if(count2 == DIRECT_MAX && ch != 13) return;
Usart_Write2(ch);
//writes back received char so we
can see what we type
directive2[count2++] = tolower(ch);
if(ch == 13)
{
directive2[count2-1] = 0;
count2 = 0;
string_done = 1;
//string completion flag
Usart_Write2(13);
//CR
Usart_Write2(10);
//LF
}
if(string_done)
{
terminal_err = 0;
//clear terminal_err flag
if(erase == 1) //if erase flag is set
{
if(0 == strcmp_cust(directive2,"yes"))
{
if(Mmc_Init(&PORTC,2)) //if mmc card is detected
{
//writes total_time (init value 0) into boot sector
(sector 0)
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)
data_sec[4] = 0;
data_sec[5] = 0;
//write address of first free sector (sector 1) into
boot sector (sector 0)

7/12 mikroPascal compiler for dsPIC by mikroElektronika

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"))

//displays "help" on the

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;
}

8/12 mikroPascal compiler for dsPIC by mikroElektronika

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;

//if there is terminal timeout


//set terminal_err flag

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
{

9/12 mikroPascal compiler for dsPIC by mikroElektronika

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:
{

10/12mikroPascal compiler for dsPIC by mikroElektronika

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;
}
}
}

11/12mikroPascal compiler for dsPIC by mikroElektronika

MMC.c

9/19/2006

580: }
581:

12/12mikroPascal compiler for dsPIC by mikroElektronika

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!!!

//flag for determening graph couloring


//(0: white-black, 1: black-white, 2: white, 3: black):
extern unsigned short couloring;
extern unsigned short buttons;

extern unsigned short card_verified;


//card ID verified flag
extern unsigned short read_bl_len;
//CSD register (4-bit)
extern unsigned short c_size_mult;
//CSD register (3-bit)
extern unsigned c_size;
//CSD register (12-bit)
extern unsigned card_size;
//card size in MB
extern unsigned long max_sector;
//last accessed sector, maximal
sector address
36: extern unsigned short mmc_full;
//mmc card full
37:
38: extern unsigned adc_result_cal[8];
//adc result buffer (calibrated)
39:
40: /* ADC sources (1 - Enabled, 0 - Disabled):
41:
AN8, AN7, AN6, AN5, AN4, AN2, AN1, AN0
42: */
43: extern unsigned short adc_source;
44:
45: extern unsigned short ds1820;
//DS1820 On/Off (1 - Enabled, 0
- Disabled)
46: extern int ds1820_result;
//ds1820 temp. sensor result
47:
48: extern char *sometext, text[16], text_sec[16];
49: extern unsigned short left, right, graph_mode, text_mode, position;
50:
51: void GLCD_main()
//manage display modes depending on button presses

1/8 mikroPascal compiler for dsPIC by mikroElektronika

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;

2/8 mikroPascal compiler for dsPIC by mikroElektronika

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);

3/8 mikroPascal compiler for dsPIC by mikroElektronika

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 channel (ds1820) is ON

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);

4/8 mikroPascal compiler for dsPIC by mikroElektronika

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:

5/8 mikroPascal compiler for dsPIC by mikroElektronika

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

";

6/8 mikroPascal compiler for dsPIC by mikroElektronika

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);

7/8 mikroPascal compiler for dsPIC by mikroElektronika

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);
}

8/8 mikroPascal compiler for dsPIC by mikroElektronika

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;
}

//Initialize Usart1 to 115200 bps

void Usart_InitHS2()
{
TXSTA2.TXEN = 1;
RCSTA2.CREN = 1;
TXSTA2.BRGH = 1;
BAUDCON2.BRG16 = 1;
SPBRGH2 = 0x00;
SPBRG2 = 0x07;
RCSTA2.SPEN = 1;
}

//Initialize Usart2 to 921600 bps

//calculated from formula: ((Fosc/BAUD)/4)-1


//((29491200/115200)/4)-1 = 63 = 0x3F

//calculated from formula: ((Fosc/BAUD)/4)-1


//((29491200/921600)/4)-1 = 7

unsigned short atobHEX(char *s)


//converts string (HEX) to byte
{
unsigned short i;
unsigned short result = 0;
for(i = 0; i<2; i++)
{
if(isdigit(s[i])) result += s[i] - '0';
else
{
if(islower(s[i])) result += 10 + s[i] - 'a';
else result += 10 + s[i] - 'A';
}
if(i == 0) result <<= 4;
}
return result;
}
unsigned atowHEX(char *s)
{
unsigned short i;
unsigned result = 0;
for(i = 0; i<4; i++)
{

//converts string (HEX) to word

1/6 mikroPascal compiler for dsPIC by mikroElektronika

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: }

2/6 mikroPascal compiler for dsPIC by mikroElektronika

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;

3/6 mikroPascal compiler for dsPIC by mikroElektronika

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)

4/6 mikroPascal compiler for dsPIC by mikroElektronika

Subroutines.c

225:
226:
227:
228:
229:
230:
231:

9/19/2006

{
unsigned short byte = bit/8;
return (array[byte] >> bit%8) & 0x01;
}

//Send command to MMC:


unsigned short Mmc_Send_Command_Cust(unsigned short partial_cmm, unsigned long
address, unsigned short crc)
232: {
233:
unsigned short res;
234:
unsigned int timeout;
235:
236:
Mmc_Spi(0xFF);
237:
238:
Mmc_Spi(partial_cmm + 0x40);
239:
Mmc_Spi(Highest(address));
240:
Mmc_Spi(Higher(address));
241:
Mmc_Spi(Hi(address));
242:
Mmc_Spi(Lo(address));
243:
Mmc_Spi(crc);
244:
245:
res = Mmc_Spi(0xFF);
246:
timeout = 0;
247:
while(res != 0 && res != 1 && timeout++ < 20000)
248:
{
249:
res = Mmc_Spi(0xFF);
250:
}
251:
return res;
252: }
253:
254: //Read CSD Register:
255: unsigned short Mmc_Read_Csd_Cust(unsigned short * data_for_registers)
256: {
257:
unsigned short i;
258:
259:
//Send read_CSD command:
260:
if (Mmc_Send_Command_Cust(0x09, 0, 0xFF))
261:
{
262:
return 1;
//error
263:
}
264:
265:
//Wait for card response:
266:
while(Mmc_Spi(0xFF) == 0xFF);
267:
268:
//Receive CSD register (MSB first):
269:
for(i=0; i<16; i++)
270:
{
271:
data_for_registers[i] = Mmc_Spi(0xFF);
272:
273:
}
274:
return 0; //success
275: }
276:
277: unsigned short strcmp_cust(char *str1, char *str2) //compares two strings
278: {
279:
unsigned short result;
280:
281:
while(!(result = *str1++ - *str2++) && (*str1 || *str2));

5/6 mikroPascal compiler for dsPIC by mikroElektronika

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

//remove space at begining of

6/6 mikroPascal compiler for dsPIC by mikroElektronika

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.
*******************************************************************************/
//
//
//
//

-----------------------------------------------------GLCD Picture name: graph.bmp


GLCD Model: KS0108 128x64
------------------------------------------------------

const unsigned short graph_bmp[1024] = {


0, 0, 0, 0, 0, 0, 0, 0, 18, 21,
0, 0, 0, 0, 0, 18, 21, 21, 9, 0,
0, 0, 18, 21, 21, 9, 0, 29, 21, 23,
21, 21, 9, 0, 17, 21, 31, 0, 0, 0,
0, 15, 8, 30, 0, 0, 0, 0, 0, 18,
29, 0, 0, 0, 0, 0, 18, 21, 21, 9,
0, 0, 0, 18, 21, 21, 9, 0, 1, 25,
1, 31, 1, 29, 4, 28, 4, 28, 0,124,
64, 79, 72, 94, 64, 7, 8, 7, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 23, 21, 29, 0, 31, 17,
32, 32, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 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, 8, 8, 8, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
130,130,128,128,128, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0,

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,

31, 17, 31,


0, 0, 0,
0, 0, 18,
21, 21, 9,
0, 23, 21,
29, 0, 0,
0, 0, 1,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
73, 73, 64,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 8, 8,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
1, 33, 33,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 0,
4,132,132,
0, 0, 0,

1/8 mikroPascal compiler for dsPIC by mikroElektronika

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

};
//
//
//
//

-----------------------------------------------------GLCD Picture name: datalogger.bmp


GLCD Model: KS0108 128x64
------------------------------------------------------

const unsigned short datalogger_bmp[1024] = {


255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,127,127,127,127,127,127,127,127,127,
127,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,127,127,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,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,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,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,252,252,252,252,252,252,252,
248, 0, 1, 7,255,255,227, 99, 35, 35, 35, 35, 35, 35, 7, 15,
255,255,255,227,227, 0, 0,227,227,227,255,227, 99, 35, 35, 35,

2/8 mikroPascal compiler for dsPIC by mikroElektronika

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

35, 35, 35, 7, 15,255,255,255,255, 0, 0,255,255,255,255,255,


255,255,255, 31, 7,199,227,227,227,227,199, 7, 31,255,255, 31,
7,199,227,227,227,227,227, 3, 3,255,255, 31, 7,199,227,227,
227,227,227, 3, 3,255,255,255, 31, 7, 35, 35, 35, 35, 35, 35,
255,255,255, 3, 3,243,243,131,135,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,224,224,227,227,227,227,227,227,227,
225,240,248,254,255,255,240,224,226,226,226,226,226,226,224,224,
255,255,255,255,255,240,224,227,227,227,255,240,224,226,226,226,
226,226,226,224,224,255,255,255,255,252,240,225,227,227,227,227,
227,227,255,252,240,241,227,227,227,227,241,240,252,255,255,252,
48, 49, 35, 35, 35, 35, 35, 0,128,255,255,252, 48, 49, 35, 35,
35, 35, 35, 0,128,255,255,255,252,240,226,226,226,226,226,226,
255,255,255,224,224,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
254,254,254,254,254,254,254,255,255,255,255,255,254,254,254,254,
254,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
};
//
//
//
//

-----------------------------------------------------GLCD Picture name: downloading_data.bmp


GLCD Model: KS0108 128x64
------------------------------------------------------

unsigned char const downloading_data_bmp[1024] = {


255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,127,127,127,127,127,127,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,255,255,255,255,255,255,255,255,127,127,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,

3/8 mikroPascal compiler for dsPIC by mikroElektronika

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
};
//
//
//
//

-----------------------------------------------------GLCD Picture name: terminal_error.bmp


GLCD Model: KS0108 128x64
------------------------------------------------------

4/8 mikroPascal compiler for dsPIC by mikroElektronika

Pictures.c

9/19/2006

233: const unsigned short terminal_error_bmp[1024] = {


234: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
235: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
236: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
237: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
238: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
239: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
240: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
241: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
242: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
243: 255,255,255,255,255,255,255,255,255,255,127,127,127,127,127,127,
244: 127,127,127,127,127,255,255,255,255,255,255,255,255,255,255,255,
245: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
246: 255,255,255,255,255,255,255,255,127,127,255,255,255,255,255,255,
247: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
248: 255,255,255,127,127,255,255,255,255,255,255,255,255,255,255,255,
249: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
250: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
251: 255,255,255,255,255,255,255,255,255,255,254,254,254,254,254, 0,
252:
0,254,254,254,254,255, 15, 7, 35, 51, 51, 51, 51, 51,255, 3,
253:
3,243,243,195,199,255,255, 3, 3,243,243,243,243, 3, 3,243,
254: 243,243,243, 3, 7,255,255,255, 2, 2,255,255, 3, 3,243,243,
255: 243,243,243, 7, 7,255,255,115, 51, 51, 51, 51, 51, 51, 3, 15,
256: 255,255,255, 0, 0,255,255,255,255,255,255,255,255,255,255,255,
257: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
258: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
259: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,240,
260: 240,255,255,255,255,255,252,248,243,243,243,243,243,243,255,240,
261: 240,255,255,255,255,255,255,240,240,255,255,255,255,240,240,255,
262: 255,255,255,240,240,255,255,255,240,240,255,255,240,240,255,255,
263: 255,255,255,240,240,255,255,248,240,243,243,243,243,243,240,240,
264: 255,255,255,240,240,255,255,255,255,255,255,255,255,255,255,255,
265: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
266: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
267: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
268: 255,255,255,255,255,255,255,127, 63, 31,143,207,207,207,207,207,
269: 207,255,255,127,127,127,127,127,255,255,255,127,127,127,127,127,
270: 255,255,255,255,255,127,127,127,127,127,255,255,255,255,127,127,
271: 127,127,127,255,255,255,255, 15, 15,255,255,255,255,255,255,255,
272: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
273: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
274: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
275: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
276: 255,255,255,255,255,255,255,192, 0, 0, 57,121,121,121,121,121,
277: 121,255,255, 0, 0,254,254,248,248,255,255, 0, 0,254,254,248,
278: 248,255,255,195, 0, 60,126,126,126, 60, 0,195,255,255, 0, 0,
279: 254,254,248,248,255,255,255, 64, 64,255,255,255,255,255,255,255,
280: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
281: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
282: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
283: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
284: 255,255,255,255,255,255,255,255,255,255,254,254,254,254,254,254,
285: 254,255,255,254,254,255,255,255,255,255,255,254,254,255,255,255,
286: 255,255,255,255,255,254,254,254,254,254,255,255,255,255,254,254,
287: 255,255,255,255,255,255,255,254,254,255,255,255,255,255,255,255,
288: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
289: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
290: 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,

5/8 mikroPascal compiler for dsPIC by mikroElektronika

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
};
//
//
//
//

-----------------------------------------------------GLCD Picture name: NoMMC.bmp


GLCD Model: KS0108 128x64
------------------------------------------------------

const unsigned short noMMC_bmp[1024] = {


255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,127,127,127,127,255,255,
255,255,255,255,255,127,127,127,127,255,255,127,127,127,127,255,
255,255,255,255,255,255,127,127,127,127,255,255,255,255,127,127,
127,127,127,127,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,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,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, 0,224,128, 7,
63,255, 63, 7, 0,224, 0, 0, 0,255,255, 0, 0, 0,224,128,
7, 63,255, 63, 7, 0,224, 0, 0, 0,255, 7, 1, 0,248,254,
254,254,254,254,254,254,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,240,240,240,255,255,252,
240,241,240,248,255,255,240,240,240,255,255,240,240,240,255,255,
252,240,241,240,248,255,255,240,240,240,255,254,248,248,241,243,
243,243,243,243,243,243,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,127,127,127,127,127,127,127,255,
255,255,255,255,255,127,127,127,127,127,255,255,255,127,127, 15,
15,127,127,127,255,255,255,255,255,255, 15, 15,207,207,207,207,
207,143, 31, 31,127,255,255,255,255,127,127,127,127,127,127,127,
127, 15, 15,127,127,127,255,255,255,127,127,127,127,127,127,255,
255,255,127,127,127,127,127,127,127,127, 15, 15,127,127,127,255,
255,255,127,127,127,127,127,127,255,255,255,127,127,127,127,127,
15, 15,255,255,255, 15, 15,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255, 0, 0,254,254,254,254,254, 0,
0,255,255,195, 0, 60,126,126,126, 60, 0,195,255,254,254, 0,
0,126,126,126,255,255,255,255,255,255, 0, 0,127,127,127,127,

6/8 mikroPascal compiler for dsPIC by mikroElektronika

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

127, 63, 0, 0,192,255,255,129, 0,100,102,102,102,102,102,254,


254, 0, 0,126,126,126,255,129, 0,100,102,102,102,102,102,255,
193, 0, 60,126,126,126,126,126,254,254, 0, 0,126,126,126,255,
129, 0,100,102,102,102,102,102,255,129, 0, 60,126,126,126,126,
0, 0,255,255,255, 64, 64,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,254,254,255,255,255,255,255,254,
254,255,255,255,255,254,254,254,254,254,255,255,255,255,255,255,
254,254,254,254,255,255,255,255,255,255,254,254,254,254,254,254,
254,254,255,255,255,255,255,255,255,254,254,254,254,254,254,255,
255,255,254,254,254,254,255,255,255,254,254,254,254,254,254,255,
255,255,254,254,254,254,254,254,255,255,255,254,254,254,254,255,
255,255,254,254,254,254,254,254,255,255,255,254,254,254,254,254,
254,254,255,255,255,254,254,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
};
//
//
//
//

-----------------------------------------------------GLCD Picture name: mmc_full.bmp


GLCD Model: KS0108 128x64
------------------------------------------------------

const unsigned short mmc_full_bmp[1024] = {


255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,127,127,127,127,255,255,
255,255,255,255,255,127,127,127,127,255,255,127,127,127,127,255,
255,255,255,255,255,255,127,127,127,127,255,255,255,255,127,127,
127,127,127,127,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,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,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, 0,224,128, 7,
63,255, 63, 7, 0,224, 0, 0, 0,255,255, 0, 0, 0,224,128,
7, 63,255, 63, 7, 0,224, 0, 0, 0,255, 7, 1, 0,248,254,
254,254,254,254,254,254,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,240,240,240,255,255,252,
240,241,240,248,255,255,240,240,240,255,255,240,240,240,255,255,
252,240,241,240,248,255,255,240,240,240,255,254,248,248,241,243,

7/8 mikroPascal compiler for dsPIC by mikroElektronika

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:

8/8 mikroPascal compiler for dsPIC by mikroElektronika

You might also like