PIC le servo yönlendirme

Başlatan hakıkat, 04 Eylül 2012, 21:57:12

hakıkat

Merhabalar,
16f873 le uzktan bir servoyu   1k pot la yönlendirmek istiyorum .Sadece servoyu
yönlendirmek istedigimde devre çalışıyor ama ek olarak iki button kullanarak iki ayrı led yakmak istediğimde ise
devre çalışmamaktadır.konunun daha iyi anlaşılması için programı gönderiyorum
verici kısmı

.
@ DEVICE pic16F873A 'islemci 16F873A
@ DEVICE pic16F873A, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F873A, PWRT_ON 'Power on timer acik
@ DEVICE pic16F873A, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F873A, XT_OSC 'Dahili osilator kullanilmayacak
@ DEVICE pic16F873A, LVP_OFF
@ DEVICE pic16F873A, BOD_OFF


DEFINE OSC 4

DEFINE ADC_BITS 8    ' ADCIN resolution  (Bits)
DEFINE ADC_CLOCK 1    ' ADC clock source  (Fosc/8)
DEFINE ADC_SAMPLEUS 3 ' ADC sampling time (uSec)

PORTA=0:TRISA=%00000011
PORTB=0:TRISB=%00000000
PORTC=0:TRISC=%00001000

ADCON1 = %00001110
OPTION_REG.7=1

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 25  ' 2400 Baud @ 4MHz, 0,17%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically


RAWA    VAR WORD 56
VALA    VAR BYTE 64
SURE    VAR WORD
VER    VAR BYTE

SYMBOL SERVO= PORTC.3
SYMBOL TUS1=PORTA.0
SYMBOL TUS2=PORTA.1
CLEAR

PORTA=0
PORTB=0
PORTC=0
PAUSE 300

BASLA: SERVO=0
IF TUS1=1 THEN
VER=12
GOSUB GONDER
ENDIF
IF TUS2=1 THEN
VER=24
GOSUB GONDER
ENDIF
       ADCIN 0,RAWA
       IF RAWA>126 AND RAWA<134 THEN
       VER=45
       GOSUB GONDER
       SERVO=1
       ADCIN 0,RAWA:VALA=((1+RAWA)*/150)+50
       ENDIF
       GONDER:
       hserout [REP$AA\5,REP$00\5,REP$FF\5]
       hserout ["A","R","A",VER]
       PAUSE 10
       GOTO BASLA
       END

alıcı kısmı
@ DEVICE pic16F873A 'islemci 16F628A
@ DEVICE pic16F873A, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F873A, PWRT_ON 'Power on timer acik
@ DEVICE pic16F873A, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F873A, XT_OSC 'Dahili osilator kullanilmayacak
@ DEVICE pic16F873A, LVP_OFF
@ DEVICE pic16F873A, BOD_OFF

Define OSC 4

PORTA=0:TRISA=%00000001
PORTB=0:TRISB=%00000000
PORTC=0:TRISC=%10000000

ADCON1 = %00001110

Define ADC_BITS 8
Define ADC_CLOCK 3
Define ADC_SAMPLEUS 50

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 25  ' 2400 Baud @ 4MHz, 0,17%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

DEGER  VAR BYTE 56
AL    VAR BYTE
TEMP  var BYTE 60
I     VAR word
SAYAC VAR BYTE
SART  VAR BYTE
SYMBOL GIE  =INTCON.7   'genel interruptlar? aç?yor
SYMBOL PEIE =INTCON.6   'peripheral interruptlar? aç?yor
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART Receive interrupt flag bit           
PORTA=0
PORTB=0
SYMBOL SERVO = PORTC.4
SYMBOL LED1=PORTC.3
SYMBOL LED2=PORTC.2
ON INTERRUPT GOTO KESME
CLEAR
PAUSE 200

RCIE=1
PEIE=1
GIE=1

BASLA:
IF AL=12 THEN
SART=1
LED1=1:PAUSE 200:LED1=0
ENDIF
IF SART=1 AND AL=24 THEN
LED1=1:LED2=1:PAUSE 1000:LED1=0:LED2=0
ENDIF
IF SART=1 AND AL=45 THEN
      pulsout SERVO, DEGER   
      SERVO=0
      FOR I=0 TO 255
        PAUSEUS 5
      NEXT
       SAYAC=SAYAC+1
       IF SAYAC=3 THEN DEGER=150
       ENDIF
     GOTO BASLA
'_________________________________________________________
DISABLE
KESME:
    GIE=0
    hSerIn 1,ATLA,[WAIT("ARA"),DEGER,AL]
ATLA:
    TEMP=RCREG
    GIE=1:SAYAC=0
    Resume
    enable   
    end
 

ete

#1
Programın verici kısmında sorun var.
Gosub komutu ile gidilen yerden mutlaka RETURN komutu ile dönülmelidir. Gosub ile gidip senin yaptığın gibi GOTO BASLA ile geri dönersen işlemcide STACK (Yığın) taşması meydana gelir. Sebebide şudur. İşlemci Gosub komutunu görünce bulunduğu adresi stack denilen serbest hafızaya atar. Bu stack ancak 6 adet adres alacak şekilde dizayn edilmiştir. İlk giren en son çıkar. Program RETURN komutunu görünce stack'e koyduğu adresi geri alır ve oraya döner. Bu sayede stack hafızası bir adet boşalmış olur.
Returun yerine goto görürse adres falan geri alamaz ve yeniden program akışında Gosub göreceği için yendien stack e adres bırakır. Böylece hiç geri almadan sürekli stack'e adres yazılması sonucu bir müddet sonra stack de yer kalmaz ve programda ne yapacağını şaşırıp kilitlenir.

Yapılması gereken, GONDER isimli etiketten bir öncesine Goto BASLA satırı ilave etmek ve GONDER etiketinin sonundaki GOTO BASLA satırını ise RETURN olarak değiştirmek gerekir.

İki defa ADC okuması yapmışsın ve iki okuma sonuçları ise farklı değerlendirilmiş. Bana kalırsa tek okuma yapıp
orada değerlendirme yapmak en doğrusu olurdu. Zira ilk okumayı yakalamak epeyce zor olabilir programda. Bir şekilde mantığını değiştirip tek okuma ile işini halletmen gerekiyor.

Ete

hakıkat

Belirtiğiniz noktaları düzelttim ama yinede herhangibir değişim olmadı. ISIS te bile ne servo kısmı çalışıyor nede
buttonlarla ilgili kısım çalışıyor.Acaba buna benzer örneği yanında olan var mı?

ete

#3
Elindeki bas ve isis dosyalarını bana mail ile yolla bakayım. Buraya koyma sitede yer problemimiz var.

Bu arada programlara henüz tam olarak bakmadım ama dikkatimi ilk çeken şey alıcı daki HESERIN komutunda yer alan timeout süresi 1 ms olarak verilmiş. Bu sürede hiç bir ver alınmaz. 5 ms den az değerlerle çalışması çok zor. İstersen 1 rakamını 5 yapıp yeniden bir dene.

Diğe bir konu da Kesme kullanılan programlarda pause komutundan kaçınılması gerekir. Zira pause komutu işlediği sürece kesme oluşması engellenir. Kısaca kesme oluşsa bile pause süresi bitmeden program kesme etiketine gidemez. Bu nedenle pause süreleri pauseus komutununa dönüştürülerek vede döngü kurularak en azından komut süresi kısaltılarak yeni kesme oluşması sağlanmalıdır.
Dahada açık anlatmak gerekirse programda yer alan pause 200 veya pause 1000 yerine,
For I=0 to 1000
  pauseus 5
next
şeklinde bir komut kullanmak ve döngü miktarını süreye göre artırmak gerekir. Unutmayın her komutun yarattığı bir gecikme vardır. Burada da pauseus 5 (5 us) yazmış olmanıza rğmen komutun oluşturulması için program en azından 100us den fazla süre harcar. Bunedenle süreleri deneme yanılma ile yada timer1 ile zaman ölçerek ayarlayabilirsiniz.

Ete

Edit: Programlarda çok fazla hata var. Belirgin olanları söyleyeyim.
Analog Kanal-0 dan okuma yapıyorsun ama aynı zamanda aynı pinde Tus1 bağlı gözüküyor. Hem tus hem analog okuma aynı pinden çalışmaz. Çalışırsada özel tedbir almak gerekir. Butonları POrtB ye geçirsen iyi olur.
Haberleşme define komutları hatalı.
Bir taraf tek veri yolluyor diğer taraf iki veri alıyor yada tersi galiba bir taraf tek veri yolluyor alıcı iki veri alıyor gibi bir durum var. Bunların düzeltilmesi gerekir. Düzelteyim dedim ama program mantığını kodlardan çıkartamadım.
Bana anlamsız gelen pek çok şart komutu bulunuyor. Bu sistemin ana amacınıda maddeler halinde yazarsan ancak yardımcı olabilirim.

Ete


hakıkat

Hocam belirttiğiniz noktaları sonradan fark ettim.Onları şimdi düzelterek ve birazda programı dahada toparlayıp
değiştirdim.Şimdilik hem pot ayarıyla hem servo çalışıyor gibi ve tuslarla bilgi gidiyor ama tus1 ac olarak kullandığım
programda basar basmaz sürekli yanıp sönmekte ve aynı zamanda tus2 yede bastığımda da led2 de sürekli yanıp sönmektedir acaba program servo pulslarından mı etkileniyor bu arada size mail olarak programı göndermek istedim ama adres bulamadım.
tesekurler.

hakıkat

Programın çalışma biçimi aslında bir buttonu aç olarak kullanarak hem servo pot unu hemde ikinci leddi açma  aşamasının başlangıcı olarak kullanmak.Sonra birinci bilgi geldikten sonra istediğim zaman ikinci ledi hemen yaka bilmek yada istediğim zaman servoyu çalıştıra bilmektir. Yani böyle bir program  bu programı bir oyuncak arabada kullanacamda.

Powered by EzPortal