Pic ile LM35 Kalibrasyonu

Başlatan b_sansal, 19 Aralık 2006, 09:41:09

b_sansal

Projemde LM35 ten aldığım bilgiyi Lcd ekranda göstermek istiyordum.Fakat nette bunun pic basic pro da yapılmış işe yarar
bir algoritmasını bulamadım.Ben de kendim bir kod yazdım ve istediğim formata çevirdim.Doğru olduğunu düşünüyorum.Kodla ilgili görüşlerinizi bekliyorum.
TRISA=%00000001
TRISB=0

DEFINE LCD_DREG PORTB        'LCD data bacakları PortB ye bağlı
DEFINE LCD_DBIT 4            'LCD data bacakları 4. bit den başlıyor
DEFINE LCD_RSREG PORTB       'LCD RS Bacağı PortB ye bağlı 
DEFINE LCD_RSBIT 1           'LCD RS bacağı 1. Bite bağlı 
DEFINE LCD_EREG PORTB        'LCD Enable Bacağı PortB ye bağlı
DEFINE LCD_EBIT 3            'LCD Enable Bacağı 3. bite bağlı 
DEFINE LCD_RWREG PORTB       'LCD RW Bacağı PortB ye bağlı
DEFINE LCD_RWBIT 2            'LCD RW Bacağı 2. bite bağlı
DEFINE LCD_BITS 4            'LCD 4 bit olarak bağlı
DEFINE LCD_LINES 2           'LCD 2 sıra yazabiliyor
DEFINE ADC_BITS 10           'A/D çevirim sonucu kaç bit olacak
DEFINE ADC_CLOCK 3           'Clock kaynağı (3=rc)
DEFINE ADC_SAMPLEUS 50       'Şarj  zamanı mikro saniye cinsinden.
'-------------------------------------------------------------------------------
ADCON1=%10001110 '7. bit 1 yapıldı 10 bit sonuç almak için.
'-------------------------------------------------------------------------------
ISI   VAR word
HAM   VAR WORD
ONDA  VAR BYTE
dummy var word
I var byte
Toplam var word
RW_BIT var portb.2 

'LCD Paneli Hazırla ------------------------------------------------------------
Low RW_BIT              ' LCD R/W line Low (W), direkt GND ye de bağlanabilir.
LCDOut $FE,1            ' LCD de CLS yapar
pause 200               ' LCD nin açılması için gerekli süredir.

'Ana Döngü --------------------------------------------------------------------- 
BASLA:

'Isı değerini hassas şekilde ölç -----------------------------------------------                 
adcin 0,HAM            
BAK:   
IF ADCON0.2=1 THEN BAK 
dummy=(HAM*5000)
ISI=div32 1024     
ONDA=ISI//10
ISI=ISI/10

'Hava sıcaklığını göster -------------------------------------------------------
lcdout $fe,1                         
LCDOUT "SICAKLIK : "
LCDOUT $FE,$C0,#ISI,",",DEC1 ONDA," 'C"
pause 500
goto BASLA

arslan74

ADC değerini normal Voltaja cevirmek için aşağıdaki formülü kullan daha net sonuc cıkar.

Alıntı Yap// U[mV] = 5*adc - 5*adc/64 - 5*adc/128


Bir değeri 64 bölmek 6 defa sağ ötelemektir, 128'e bölmek ise 7 defa sağ ötelemektir. Normal bölme ilemine göre daha az işlem maliyeti ve hız getirir.


Örnek C kodu:
unsigned int 
convert2mV(unsigned int adc){
	
	unsigned int val,temp;

// U[mV] = 5*adc - 5*adc/64 - 5*adc/128
	
	val  = (5*adc);
	temp = val;
	val -= temp >> 6;
	val -= temp >> 7;
		
	return	val;
}

bkrtncr

Zamaninda asagidaki gibi bir kod yazmistim..
Burada 10 tane okunan deger toplaniyor, 125 ile carpiliyor ve daha sonra 8 birim shift edilerek (yani 256'ya bolerek) gercek deger bulunuyor..
Cok sade ve hizli calisan bir kod...
125 ile carpilmasinin sebebine gelince...
Bilindigi gibi LM35 0-100mV arasinda cikis verir.. eger biz adc channell'i 10bit olarak alirsak 1024 bizim max voltajimiz yani (5V olacaktir..)
buna gore 5000mV 1024'de denk geldigine gore 1mV 4,88281'e denk gelir ki buda 1 Celciusdur.. bende boyle bir float degerle ugrasmamak icin bu degeri 256 ile carptim ve sonuc 1250 cikti...
neden 125 ile carptim cunku 10 tane degerin ortalamasini aldigimdan... :D

void read_temp (void)         //Bekir
{
   set_adc_channel(channel.InputChannel);
   delay_us(10);
   wValue = read_adc();
   channel.Sum += wValue;

   if (--cPass == 0)
   {
      channel.Sum = (channel.Sum*125) >> 8;         // average channel value
      iAverage = channel.Sum;
      cPass = 10;
   }
}
Bildigini paylaşan, ALİM'dir...