2 Satır LCD'de DC voltmetre+bar vumetre

Başlatan solidus, 01 Nisan 2009, 14:28:17

solidus

2 Satır LCD'de DC voltmetre+vumetre yapmaya çalışıyorum. Kodlarda bir yerde hata var. Bi türlü bulamadım.
@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, XT_OSC
'-------------------------------------------------------------------------------
DEFINE LCD_DREG PORTC 'LCD data bacakları hangi Porta bağlı?
DEFINE LCD_DBIT 4 'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG PORTC 'LCD Enable Bacağı Hangi Porta 
DEFINE LCD_EBIT 3 'LCD Enable Bacağı Hangi bite bağlı ?
'define LCD RWREG  PORTC  'LCD R/W Bacağı Hangi Porta bağlı?
'define LCD_RWBIT 2 'LCD R/W Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG PORTC 'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT 2 'LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_BITS 4 'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES 2 'LCD Kaç 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 'Örnekleme zamanı mikro saniye 
'-------------------------------------------------------------------------------
TRISA=%00001011
TRISB=0
TRISC=0
TRISD=0
'-------------------------------------------------------------------------------
ADCON1=%10001100 '7. bit 1 yapıldı 10 bit sonuç almak için.7. bit 0 olursa 8 bit
'-------------------------------------------------------------------------------
HAMDC    var word   'ADC den okunan ham Digital değer.                                                                        
VOLTDC   var word   '16 bit değişken tipi seçtik kullanacağımız değer 10 bit olacak.
MVOLTDC  var word
TOPLAM   var word
VDC      VAR WORD
VUU      var byte
TOTAL    var word
OKU      VAR WORD
barval   VAR Byte
bar1     VAR Byte
bar2     VAR Byte
bar3     VAR Byte
bar4     VAR Byte
bar5     VAR Byte
pad      VAR Byte
kalan    VAR Byte 
pause 200              
'------------------------------------------------------------------------------- 
GREET:
LCDOut $FE,1
LCDOUT $FE,$C0,"By Maestr0"
pause 1000
LCDOut $FE,1
pause 20
LCDOUT $FE,$40,$1F,$1F,$1F,$1F,$1F,$1F,$1F,$1F
LCDOUT $FE,$48,$1E,$1E,$1E,$1E,$1E,$1E,$1E,$1E
LCDOUT $FE,$50,$1C,$1C,$1C,$1C,$1C,$1C,$1C,$1C
LCDOUT $FE,$58,$18,$18,$18,$18,$18,$18,$18,$18
LCDOUT $FE,$60,$10,$10,$10,$10,$10,$10,$10,$10

BASLA:
If barval>80 Then barval=80
If barval=240 Then barval=0
PAUSE 200

VOLTAJ:
TOPLAM=0
FOR VDC = 1 TO 10
ADCIN 0,HAMDC '0 nolu kanaldan Analog değeri oku ve HAMDC değişkenine aktar.
TOPLAM = TOPLAM + HAMDC
NEXT VDC
HAMDC= TOPLAM/10
BAK:   
IF ADCON0.2=1 THEN BAK 'Çevirme işlemi tamamlanınca Adcon0.2=0 olacak.
IF HAMDC < 10 THEN
VOLTDC = 0
ELSE
VOLTDC = (hamDC-5)*20/100
ENDIF
MVOLTDC = (VOLTDC//10)  
voltDC = VOLTDC /10      
LCDOUT $FE,$80,"BATT: ",#VOLTDC,",",# MVOLTDC,"V "
PAUSE 250

lcd_bar:
TOTAL=0
for OKU =1 to 10
adcin 1,VUU'1 nolu kanaldan analog değeri oku ve VUU değişkenine aktar.
total=total+vuu
next OKU
vuu=total/3
bar1 = barval/5	
kalan = barval // 5	
If kalan=4 Then 
bar2=1
Else
bar2=0
EndIf
If kalan=3 Then
bar3=1
Else
bar3=0
EndIf
If kalan=2 Then 
bar4=1
Else
bar4=0
EndIf
If kalan=1 Then
bar5=1
Else
bar5=0
EndIf
pad=16-bar1 
LCDOUT $FE,$C0,"SIGN: ", Rep $00\bar1,Rep $01\bar2,Rep $02\bar3,Rep $03\bar4,Rep $04\bar5,Rep " "\pad

GOTO BASLA
end

Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

ferit06

Kodunuzun;
....
FOR VDC = 1 TO 10
ADCIN 0,HAMDC '0 nolu kanaldan Analog değeri oku ve HAMDC değişkenine aktar.
TOPLAM = TOPLAM + HAMDC
NEXT  (' VDC  buna gerek varmı?
HAMDC= TOPLAM/10
BAK:    
IF ADCON0.2=1 THEN BAK 'Çevirme işlemi tamamlanınca Adcon0.2=0 olacak.
....

bölümünün  hatalı olduğunu düşünüyorum.
...
FOR VDC = 1 TO 10
ADCIN 0,HAMDC '0 nolu kanaldan Analog değeri oku ve HAMDC değişkenine aktar.
BAK:    
IF ADCON0.2=1 THEN BAK 'Çevirme işlemi tamamlanınca Adcon0.2=0 olacak. ( Çevirme işleminin tamamlanması sorgulanıyor....)
TOPLAM = TOPLAM + HAMDC ' (Çevirme işleminden sonra toplama işlemine dahil edilmeli)
NEXT
HAMDC= TOPLAM/10
....

Ne gibi hata aldığınız belirmemişsiniz benim yorumum bu kadar..

wishbone

toplam registerini her örneklemeden sonra resetlemen gerekmiyormu....

solidus

Merhaba arkadaşlar voltmetre kısmı sorunsuz çalışıyor. Vumetre yapmak için kodlar eklenince oda çalışmaz oldu. Kodlar tamirci_erhan adlı bir arkadaştan alıntıdır. Isis uyarısı şöyle;
"Voltage references for ADC conversion yield a 0V range(V+ =0,V- =0)"
Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

ferit06

ADCON1=%10001100  olarak belirlemişsiniz.

AN3 pinine Vref+ bağlamanız gerekir.
Diğer taraftan Vu metre için hangi pinlerden ölçüm yapmayı planlıyorsunuz. yukarıdaki ADCON 1 registeri ile sadece 2 adet A/D girişiniz olabilir.

PCFG
<3:0>AN7 AN6 AN5 AN4 _ AN3_ AN2__AN1_ AN0_ VREF+ VREF- C/R
1100 _D__  D__D__ A__ VREF+ VREF-_ A___A__ AN3__ AN2___3/2

vermiş olduğunuz şemayı yeni gördüm.(şema çok küçük yüklenmiş hangi pinler kullanılıyor göremiyorum)
Tek kanal VU metre imiş.....

solidus

Evet tek kanal vu metre an0 dan voltaj an1 dende vu metre kullandım. an3 e vref + bağlamıştım. sanırım resimde görünmüyor yada ben yanlış resmi yükledim. Kodlar aşağıdaki şekilde simülasyonda çalışmaya başladı ama genede bi gariplik var gibi. ADCON1 registerinin bu haliyle vref+ pini kumanda etmiyor.inceleme fırsatınız olursa sevinirim.
@ DEVICE pic16F877
@ DEVICE pic16F877, WDT_on
@ DEVICE pic16F877, PWRT_ON
@ DEVICE pic16F877, PROTECT_OFF
@ DEVICE pic16F877, XT_OSC
'-------------------------------------------------------------------------------
DEFINE LCD_DREG PORTC 'LCD data bacakları hangi Porta bağlı?
DEFINE LCD_DBIT 4 'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG PORTC 'LCD Enable Bacağı Hangi Porta 
DEFINE LCD_EBIT 3 'LCD Enable Bacağı Hangi bite bağlı ?
'define LCD RWREG  PORTC  'LCD R/W Bacağı Hangi Porta bağlı?
'define LCD_RWBIT 2 'LCD R/W Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG PORTC 'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT 2 'LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_BITS 4 'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES 2 'LCD Kaç 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 100 'Örnekleme zamanı mikro saniye 
'----------------------------------------------------------
ADCON1=%10000100 '7. bit 1 yapıldı 10 bit sonuç almak için.
'----------------------------------------------------------
TRISA=%00000011
TRISB=0
TRISC=0
TRISD=0
'----------------------------------------------------------
HAMDCV      var word   'ADC den okunan ham Digital voltaj değeri.                                                                        
DCVOLT      var word   'Çevrim sonucunda ekrana yazılacak değer.
MVOLT       var word
TOPLAM      var word
DC          VAR WORD

SIGNAL_IN   VAR BYTE   'ADC den okunan ham Digital sinyal değeri.

FULLBARS VAR	Byte	
PARTBAR	VAR Byte
BARVAL VAR Byte
PAD VAR Byte
LCDOut $FE,1           ' LCD'yi temizle
pause 200              ' LCD nin açılması için gereken bekleme süresi.

BASLA:
If barval>80 Then barval=80
If barval=240 Then barval=0
GOSUB BARAYAR
gosub VOLTAJ
GOSUB SIGNALS
PAUSE 10
GoTo basla

VOLTAJ: 
TOPLAM=0     
FOR DC = 1 TO 10
ADCIN 0,HAMDCV '0 nolu kanaldan Analog değeri oku ve HAM değişkenine aktar. 
TOPLAM = TOPLAM + HAMDCV
NEXT DC
HAMDCV= TOPLAM/10
BAK:   IF ADCON0.2=1 THEN BAK 'Çevirme işlemi tamamlanınca Adcon0.2=0 olacak.
IF HAMDCV < 10 THEN
DCVOLT = 0 
ELSE
DCVOLT = (hamDCV-5)*20/100
ENDIF
MVOLT = (DCVOLT//10)  
DCvolt = DCVOLT /10
IF DCVOLT<=8 THEN
LCDOUT $FE,$80,"   BATTERY LOW   "
ELSE
LCDOUT $FE,$80,"BATT: ",#DCVOLT,",",dec MVOLT," VOLT"
PAUSE 250
ENDIF
return

SIGNALS:
ADCIN 1,SIGNAL_IN     
barval = ((SIGNAL_IN * 30) / 240)
fullbars = barval
partbar = barval // 2 
pad = fullbars
LCDOUT $FE,$C0,"SIGN:", Rep " "\16
LCDOUT $FE,$C5, Rep $0\fullbars, partbar, Rep " "\pad
PAUSE 250

RETURN
BARAYAR:
LCDOUT $FE,$40,$1F,$1F,$1F,$1F,$1F,$1F,$1F,$1F
LCDOUT $FE,$48,$1E,$1E,$1E,$1E,$1E,$1E,$1E,$1E
LCDOUT $FE,$50,$1C,$1C,$1C,$1C,$1C,$1C,$1C,$1C
LCDOUT $FE,$58,$18,$18,$18,$18,$18,$18,$18,$18
LCDOUT $FE,$60,$10,$10,$10,$10,$10,$10,$10,$10
RETURN
GOTO BASLA
END

Kimine göre kralım kimine göre yalanım… Herkes rahatına baksın, ben adamına göre adamım..

ferit06

Nasıl bir gariplik var?

Ayrıca 2 önceki mesajımda önermiş olduğum 10 defa ölçüm yapıp ortalama alma ile ilgili satırlar aynen duruyor. Bana göre burada ölçüm tamamlanmadan  siz sonuçların yer alacağı yazmacın değerini toplama dahil ediyorsunuz.

BAK: etiketli satır A/D dönüşümünün tamamlandığını test ediyor. Bu dönüşüm tamamlandıktan sonra sonucun yer aldığı ADRESH-ADRESL deki değeri toplama dahil etmelisiniz.
877 nin data sheetinde
FIGURE 11-3: A/D CONVERSION TAD CYCLES
burayı incelemenizi öneririm.
Çevrim sırası:
Set GO bit(ADCIN 0,HAMDCV  komutu ile başlıyor)
Holding capacitor is disconnected from analog input (typically 100 ns)
Conversion starts
...
ADRES is loaded
GO bit is cleared
ADIF bit is set (When ADON = 1:
1 = A/D conversion in progress (setting this bit starts the A/D conversion which is automatically
cleared by hardware when the A/D conversion is complete)
0 = A/D conversion not in progress) (siz bunu  if ADCON.2=0 then BAK komutu ile sorguluyorsunuz.)
Holding capacitor is connected to analog input
şeklinde

ayrıca ;
SIGNALS:
ADCIN 1,SIGNAL_IN      
>> BAK1: ADCON.2=0 then BAK1  bu satırı ilave etmelisiniz
barval = ((SIGNAL_IN * 30) / 240)
fullbars = barval
partbar = barval // 2
pad = fullbars
LCDOUT $FE,$C0,"SIGN:", Rep " "\16
LCDOUT $FE,$C5, Rep $0\fullbars, partbar, Rep " "\pad
PAUSE 250
bölümünde de A/D dönüşümün tamamlanıp tamamlanmadığı denetlenmiyor. burada da BAK etikettinin olduğu satırı BAK1 gibi yenilemeniz gerekir.

Ayrıca şemada verdiğiniz 88.8V değerler çok yüksek...