Sunteți pe pagina 1din 9

Masurare 4 temperaturi diferite folosind AT

Mega 16
Cerinta

Sa se proiecteze un aparat care sa masoare 4 temperaturi diferite si sa le afiseze pe un afisaj cu leduri de 3 digiti.
Se va afisa o singura temperatura la un moment dat ; alegerea temperaturii se va face folosind un buton fara retinere,
existand un afisaj suplimentar de un digit care va afisa numarul temperaturii afisate. De asemenea se va putea selecta
afisarea diferentei mexime intre cele 4 tempereturi.
Se vor folosi :
afisaje cu leduri cu anod sau catod comun.
microcontroler AT Mega 16
traductori de temperatura LM335
Temperaturile se vor afisa in grade C.
Programul pentru microcontroler va fi scris in asamblare.

I. Conditii impuse
1.
2.
3.
4.
5.

Termometru digital cu 3 digiti care masoara 4 temperaturi


Gama de masura: -40 C100C
Eroarea de masura: 0.5C ( dictata de traductorul de temperature )
Traductor de temperatura: LM335
Microcontroller:ATMega16

II. Schema Bloc

1.

Traductor de temperatura LM335


2. Amplificator de semnal
3. Convertor analog digital
4. Microcontroller ATMega16
5. Buton de incrementare canal
6. Bloc de afijare numerica (4 digiti)

III. Senzorul de temperatura

Este folosit LM335 care este un sensor de temperatura ce poate fi calibrat cu usurinta.
Acest senzor functioneaza intre temperaturile -40C si 100C pastrandu-si liniaritatea si impedanta scazuta. Functionand
ca o dioda Zener cu doua terminale avand tensiunea de strapungere direct proportionala cu temperatura absoluta, panta
fiind de 10mV/K. Impedana sczut i caracteristica de ieire liniar fac interconectarea cu circuitele de control foarte
usor de realizat. Instrumentul este disponibil ncapsulat ermetic in tranzistorul TO-46. Circuitul are o impedanta dinamica
mai mica de 1 si functioneaza intre 0.45mA si 5mA fara degradari ale perfomantelor. Calibrat la 25C LM335 are o
eroare mai mica de 1C la o variatie a temperaturii de 100C (tipic 0.5C). Spre deosebire de alti senzori de temperature
LM335 are o iesire liniara in tensiune care variaza in functie de tempeatura cu 10mV/K.
Rezistenta R7 este folosita pentru calibrarea la 25C trebuind sa asigure la iesiere tensiunea de 2.982V pentru
aceasta temperatura.
Tensiune de iesire la +100C: 3.732V
Tensiune de iesire la -40C: 2.332V

IV. Adaptorul de semnal

Amplificatorul LT1013 este primul AO dual de precizie cu 8 pini, mbuntind performanele unor dispozitive mai vechi.
Poate fi alimentat de la o singur surs de 5V. Gama intrrii de mod comun poate include si masa. Ieirea poate oscila in
limita a civa mV de la masa. Distorsiunea de crossover, foarte evident la alte amplificatoare, este eliminat.
Deoarece traductorul de temperatura LM335 are o panta de 10mV/K rezulta ca, la capetele de scala ale termometrului (
-40C si 100C ) tensiunile de iesire vor avea valorile +2.332V (pt -40C) si 3.732V (pt100C) => excursia de tensiune va
fi de 1.400V.
Acest adaptor are rolul de a mari excursia tensiunii de la iesire de la 1.4V la 5V deoarece intrarea analogica a
convertorului este cuprinsa intre valorile 0...5V.
Amplificarea acestui adaptor trebuie sa fie A=Uf/Ui=5/1.4=3.5714 pe fiecare grad celsius.
Amplificarea este: A=(R3+Rv2)/R2
R6R3+Rv2. Pentru R2=10k avem:
R3+Rv2=35.714k rezulta ca R3=33K, iar Rv2=5K
Se alege R6=36k.

V. Convertorul analog digital


Se foloseste convertorul analog digital oferit de microcontroller-ul ATMEGA16.
Acest ADC prezinta urmatoarele caracteristici:
-eroare totala de 2 LSB,

-rezolutia este de 10biti,


-timpul de conversie este de 13-260s.
ADC-ul este conectat la un multiplexor analog pe 8 canale, intrarile analogice fiind conectate pe portul A al controllerului.ADC-ul contine un circuit Sample and Hold care asiura ca tensiunea de la intrare este mentinuta la un nivel constant
pe durata conversiei.
Acesta primeste pe intrarile CH1(ADC0)...CH4(ADC3) o tensiune Vin(0..5V) si este alimentat la Vref=5V .
Cod la 0V: 0000 0000 (00H)
Cod la 5V: 1111 1111 (FFH)
Am folosit portul A al microcontrollerului, configurand pinii 0-3 (ADC0-ADC3) ca intrari in registrul de stare al ADC-ului
ADMUX. Rezultatul oferrit de ADC este pe 10 biti si se gaseste in registrii ADCH si ADCL. Dar, cum precizia dorita este cea
pe 8 biti, vom citi doar ADCL, lucru care va fi precizat in registrul de stare.
ADC-ul are o intrerupere proprie care eset chemata atunci cand se termina o conversie. Acest moment este anuntat si
prin starea bitilor ADIF=1 si ADSC=0 (ADSC=1 atunci cand porneste o conversie).
Ca alimentare se poate alege intre AVCC, AREF si o valoare interna (2.56V).
Am folosit 8 biti ceea ce inseamna 256 de valori reprezentabile. Noi avem 140 de valori adica rezolutia acestui convertor
este de aproximativ 0.54C/bit:
Rezolutia=(1/256)*Ui=(1/256)/5V=0.01953V19.53V/bit
Rezolutia=(1/256)*T =(1/256)/140C0.54C/bit

VI. Microcontrollerul
Microcontrollerul utilizat este ATMega16, care este fabricat de ATMEL, iar a carui AVR core combina un set bogat de
instructiuni cu scopul general de a lucra cu registrii. Toti cei 32 de registri sunt direct conectati la Unitatea AritmeticoLogica, permitand ca o singura instructiune executata intr-un tact, sa acceseze 2 registri independenti.
ATmega16 are urmatoarele caracteristici:
-16K bytes of In-System Programmable Flash Program memory with Read-While-Write capabilities,
- 512 bytes EEPROM,
- 1K byte SRAM
- 32 general purpose I/O lines
- 32 general purpose working registers,
- On-chip Debugging support and programming,
- Three flexible Timer/Counters with compare modes,
- Internal and External Interrupts,
- a serial programmable USART,
- a byte oriented Two-wire Serial Interface,
- 10-bit ADC with optional differential input stage
- a programmable Watchdog Timer with Internal Oscillator,
- an SPI serial port,
Astfel Atmel ATmega16 e un microcontroller puternic care ofera o flexibilitate marita.
ATmega16 AVR e compatibil cu gama larga de medii de programare, dintre care: compilator C compilers, macro
assembler si programe de debugging si simulare

La pini corespunzatori XTAL1 si XTAL2, din portul D, care sunt pini de intrare respectiv iesire este legat oscilatorul.
Oscilatorul este prezentat in figura urmatoare

Alegerea condensatoarelor si a quartului se face conform tabelului, in functie de modul de functionare ales

Configuratia pinilor porturilor este urmatoarea:


Portul A- pinii 0-3 setati ca intrari (de la senzori)
pinul 4 intrare Start/Stop
pinul 5 intrarea Incrementare canal
Portul B neutilizat
Portul C pinii 0-7 iesiri catre blocul de fisare(prin care se trimite cifra de afisat)
Portul D pinii 0-4 iesiri catre blocul de afisare (prin care se selecteaza digitul de afisat)

VII.Afisajul
Pentru acest proiect am folosit un afisaj cu leduri de tip BCD (4 digiti- unul pentru canal si 3 pentru afisarea temperaturii).
Numarul canalului este afisat atunci cand este apasat butonul de incrementare,iar microcontroller-ul citeste din registru si
trimite cifra pe portul C, selectia facandu-se prind intermediul portului D, pinul 4.
Display-ul folosit este de tip BCD anod comun cu multiplexare. Temperatura se afiseaza cu 3 cifre si cu semn. Afisajul se
face cu leduri, ledurile functionand conform tabelului urmator:
A

Nr

Unde A, B, C, D este numarul pe 4 biti stocat in eprom de microcontroller iar a...g sunt segmentele ledurilor conform
figurii urmatoare:

VII.Functionarea
Variatia de temperatura de la nivelul fiecarui canal este transformata in variatie de tensiune la iesirea traductorului cu o
rata de 10mV/C. In acest fel dat fiind faptul ca semnalul la iesirea traductorului este in format mV/K vom obtine o
variatie a tensiunii de iesire care variaza intr 2.332V la -40C si 3.732V la 100C ( variatia fiind de 1400mV). Cum ADC-ul
are scala maxima de conversie de la 0 la 5V pentru toate cuvintele binare oferite de numarul lui de biti (256 trepte de
esantionare a semanlului la intrare, fiind un convertor cu aproximatii successive) rezulta necesitatea scalarii semnalului
de la iesirea fiecarui canalin gama 0.000V la -40C pana la 5.000V la 100C. Adaptorul 2 din schema bloc va realize
acest lucru si cuprinde doua circuite de calibrare: unul de nul ( corespunzator la -40C ) si unul de capat de scare ( SPAN )
pentru 100C.
In schema practica, data fiind dificultatea calibrarii la -40C se poate utiliza si o calibrare de referinta la 25C, atunci cand
se face verificarea ansamblului traductor-adaptor in conditiile reale ( cu termometru martor ).
Amplificarea adaptorului de semnal este:
A=Uf/Ui=5/1.4=3.5714, unde Uf este tensiunea la intrarea convertorului analog digital iar Ui este tensiunea la iesirea

senzorului de temperatura. Valorile de intrare si iesire din adaptorul de semnal se gasesc in tabelul anexat la pagina 13.
Convertorul analog digital este cu aproximari succesive pe 8 biti care are 256 de trepte de esantionare obtinandu-se o
rezolutie a convertorului de 19.53mV/treapta respectiv de 0.54C/treapta.
In tabelul urmator sunt prezentate valorile tensiunilor de intrare si de iesire din adaptorul de semnal, precum si numarul
treptei de esantionare din ADC.
T(C)
Ui
Uf
Te
Nr Te
Nr binar
-40
2,332
0,0000
0,0000
0
0000 0000
-35
2,382
0,1786
9,1428
9
0000 1001
-30
2,432
0,3571
18,2856
18
0001 0010
-25
2,482
0,5357
27,4284
27
0001 1011
-20
2,532
0,7143
36,5711
37
0010 0101
-15
2,582
0,8929
45,7139
46
0010 1110
-10
2,632
1,0714
54,8567
55
0011 0111
-5
2,682
1,2500
63,9995
64
0100 0000
0
2,732
1,4286
73,1423
73
0100 1001
5
2,782
1,6071
82,2851
82
0101 0010
10
2,832
1,7857
91,4278
91
0101 1011
15
2,882
1,9643
100,5706
101
0110 0101
20
2,932
2,1428
109,7134
110
0110 1110
25
2,982
2,3214
118,8562
119
0111 0111
26
2,992
2,3571
120,6847
121
0111 1001
30
3,032
2,5000
127,9990
128
1000 0000
35
3,082
2,6786
137,1418
137
1000 1001
40
3,132
2,8571
146,2845
146
1001 0010
45
3,182
3,0357
155,4273
155
1001 1011
50
3,232
3,2143
164,5701
165
1010 0101
55
3,282
3,3928
173,7129
174
1010 1110
60
3,332
3,5714
182,8557
183
1011 0111
65
3,382
3,7500
191,9985
192
1100 0000
70
3,432
3,9285
201,1412
201
1100 1001
75
3,482
4,1071
210,2840
210
1101 0010
80
3,532
4,2857
219,4268
219
1101 1011
85
3,582
4,4643
228,5696
229
1110 0101
90
3,632
4,6428
237,7124
238
1110 1110
95
3,682
4,8214
246,8552
247
1111 0111
100
3,732
5,0000
255,9980
255
1111 1111
Semnificatia marimilor din tabel:
T (C)
temperatura masurata de LM335.
Ui(V) tensiunea la iesirea LM335.
Uf(V) tensiunea la intrare analogica a ADC0844.
Te
numarul treptei de esantionare din ADC0844.
Te(apr) numarul aproximat al treptei de esantionare din ADC0844.

Codul sursa pentru programarea microcontrollerului :


//ICC-AVR application builder : 5/29/2005 7:34:50 PM
// Target : M16
// Crystal: 4.0000Mhz
#include <iom16v.h>
#include <macros.h>
#include <eeprom.h>
void port_init(void)
{
PORTA = 0x00;
DDRA = 0xC0; //configuratia porturilor ca intrari sau iesiri

PORTB
DDRB
PORTC
DDRC
PORTD
DDRD

=
=
=
=
=
=

0x00;
0x7F;
0x00;
0xFF;
0x00;
0x1F;

}
//ADC initialize
// Conversion time: 6uS
void adc_init(void)
{
ADCSR = 0x00;
ADMUX = 0x60; //select adc input 0
ACSR = 0x80;
ADCSR = 0xE9; //start ADC , set free run , set enable intrerupt, si
frecventa convertorului
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
adc_init();
MCUCR = 0x03; //seteaza intreruperea activa pe front crescator
GICR = 0x40;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void calcul_BCD( signed char tmp , unsigned int adr_base )
{
signed char tmpBCD;
unsigned char i=1;
if ( tmp < 0 )
EEPROM_WRITE( adr_base, i ); //scrie semn (daca e <0 scrie 1 altfel
0) la adresa adr_base
else EEPROM_WRITE( adr_base, i-1 );
do{
tmpBCD = tmp % 10;
EEPROM_WRITE(adr_base+i, tmpBCD ); //calculeaza cifrele si le scrie
in EEPROM la adrese consecutive
i++;
tmp /= 10;
}while( tmp != 0);
}
#pragma interrupt_handler adc_isr:15
void adc_isr(void) //intreruperea referitoare la terminarea conversiei
{
signed char tmp = ADCH; //folosind left adjustement
luam numai partea H din cei 10 biti
unsigned char canal =0 ;
canal |= ADMUX; // calculeza canalul de pe care a
facut conversia in
canal &= 0x0F; //funtie de valoarea ultimilor 4

biti din ADMUX


switch ( canal )
{
case 0 : calcul_BCD( tmp, 0 );break;
case 1 : calcul_BCD( tmp, 4 );break;
case 2 : calcul_BCD( tmp, 8 );break; //calculeaza
cifrele si le scrie la adrese predefinite
case 3 : calcul_BCD( tmp, 12 );break;
}
ADMUX++;
}
#pragma interrupt_handler button_pressed:2
void button_pressed() //intreruprerea coresp butonului de incrementare
canal
{
unsigned char dst;
EEPROM_READ( 0x0100 , dst ); //citesc valoarea canalului prezent
dst++; //trec la urmatoru canal
dst %= 4;
EEPROM_WRITE(0x0100, dst );
}
void afisare_cifra( unsigned char cifra )
{
switch (cifra) //afisare fiecare cifra pe un afisaj cu 7 segmente
aprinzand pt fiecare cifra segemntele respective
{
case 0 : PORTC = 0x7E;break;
case 1 : PORTC = 0x30;break;
case 2 : PORTC = 0x6D;break;
case 3 : PORTC = 0x79;break;
case 4 : PORTC = 0x33;break;
case 5 : PORTC = 0x5B;break;
case 6 : PORTC = 0x5F;break;
case 7 : PORTC = 0x70;break;
case 8 : PORTC = 0x7F;break;
case 9 : PORTC = 0x7B;break;
}
}
void delay() //delay de aprox 50 ms pt a afisa practic cifrele in
acelasi timp
{
int i;
for( i=0; i<65000 ; i++ ) ;
}
void afisare( int adr_base , unsigned char canal ) // afisez
temperatura , si canalul selectat
{
unsigned char dst,i;
EEPROM_READ( adr_base , dst );
if( dst == 1 )
PORTD |= 0x10; //afisam semnu , pind3 =1
i=0;
while( i<3 )
{
adr_base++;
EEPROM_READ( adr_base , dst ); //citesc prima cifra

switch ( i )
{
case 0 : PORTD
moment dat
case 1 : PORTD
case 2 : PORTD
}
afisare_cifra(
delay();
i++;
}

|= 0x01;break; // aleg care cifra trebuie afisata la un


|= 0x02;break;
|= 0x08;break;
dst ); // afisare cifra

afisare_cifra( canal ); //afisez canalul selectat


PORTD |= 0x20;
}
void main()
{
unsigned char tmp = 0x00;
unsigned char canal;
init_devices();
EEPROM_WRITE(0x0100, tmp);
ADMUX = 0x60;
while( PORTA & 0x10 )
{
SEI();
while( (ADMUX & 0x04) == 0 ) //convertesc pentru toate cele 4 canale
dar se afiseaza doar cifra selectata
{}
ADMUX = 0x60;
EEPROM_READ( 0x0100 , canal ); //citeste canalul din memorie
switch (canal)
{
case 0 : afisare( 0 , 0 ); break; //selecteaza
canalul si afiseaza valoarea temperaturii pentru canalul resp
case 1 : afisare( 4 , 1 ); break;
case 2 : afisare( 8 , 2 ); break;
case 3 : afisare( 12 , 3 ); break;
}
}
}

S-ar putea să vă placă și