PİC16f628a serial haberlesme sorunu

Başlatan redmen, 01 Kasım 2023, 09:40:20

ete

Programdaki bazı noktalara dikkat çekmek isterim.
HSERIN 100,NERE,[WAIT("VER1"),VERI[0],VERI[1],VERI[2],VERI[3],VERI[4],VERI[5],VERI[6],VERI[7]]
satırları
HSERIN 100,NERE,[WAIT("VER1"),STR VERI\8]
şeklinde yazılabilir.

VER1=VERI  satırı dizi index parametresi vermezseniz anlamı şu şekildedir. VER1[0]=VERI[0]
burada bütün diziyi diğer değişkene aktarmak ise amacınız döngü kullanmanız gerekir.

Bu işi aşağıdaki döngüde iki işi birden yaptırabilirsiniz.
	  
FOR I=0 TO 7
WRITE I,VERI[I]
VER1[I]=VERI[I]
NEXT
böylece ;
	    WRITE 0,VERI[0],VERI[1]
	    WRITE 2,VERI[2],VERI[3]
	    WRITE 4,VERI[4],VERI[5]
	    WRITE 6,VERI[6],VERI[7]
satırlarıda kısaltılmış olur.
Benzer şekilde ;
HSEROUT [VERI[0],VERI[1],VERI[2],VERI[3],VERI[4],VERI[5],VERI[6],VERI[7]]
satırı,
hserout [STR VERI\8]
şeklinde yazılabilir.

Ete



enes

kesme rutınınde de bı hatalı durum sozkonusu. şoylekı:

DISABLE
INT:
    GIE=0
    HSERIN 100,NERE,[WAIT("VER1"),VERI[0],VERI[1],VERI[2],VERI[3],VERI[4],VERI[5],VERI[6],VERI[7]]
    VER1=VERI
    WRITE 0,VERI[0],VERI[1]
    WRITE 2,VERI[2],VERI[3]
    WRITE 4,VERI[4],VERI[5]
    WRITE 6,VERI[6],VERI[7]
    HSEROUT [VERI[0],VERI[1],VERI[2],VERI[3],VERI[4],VERI[5],VERI[6],VERI[7]]
    RCA=RCREG
    RCIF=0
    GIE=1
    Resume
    enable
    goto nere
    END

şoyle olmalı:


DISABLE
INT:
    GIE=0
    HSERIN 100,ATLA,[WAIT("VER1"),VERI[0],VERI[1],VERI[2],VERI[3],VERI[4],VERI[5],VERI[6],VERI[7]]
    VER1=VERI
    WRITE 0,VERI[0],VERI[1]
    WRITE 2,VERI[2],VERI[3]
    WRITE 4,VERI[4],VERI[5]
    WRITE 6,VERI[6],VERI[7]
    HSEROUT [VERI[0],VERI[1],VERI[2],VERI[3],VERI[4],VERI[5],VERI[6],VERI[7]]

ATLA:
    RCA=RCREG
    RCIF=0
    GIE=1
    Resume
    enable

    END


EN sonlardakı goto nere adlı satıra gerek yok..

ete

Enes'in tespiti doğru. Kesme içinden kasme dışı bir etikete Goto ile gidilmez gidilemez.
Gidilirse stack hatası ortaya çıkar.

Kesme işlemi otomatik adreslemeli çalışır. Programın herhangi bir anında kesme oluştuğu zaman ki işlemci bunu kesme bayraklarının set edilmesinden anlayabiliyor işlemci önce işlediği komutu bitirir.
Sonra bulunduğu adresi (programın ASM karşılığında) STACK içine yazar ve doğruca kesme etiketine gelir.
Oradaki işlemleri bitirdikten sonra RESUME (ENABLE) ile hemen STACK içinden yazılmış en son adresi alıp o adrese otomatik olarak döner. Bu nedenle kesme içinden GOTO ile başka bir yere giderseniz geliş adresi stack da kalır ve bir sonrakinde yeniden stack dan adres alınacağı için bir kaç işlem sonra stack dolar ve taşma oluşur. Program kontrolünü kaybeder. Bir noktada kilitlenir kalır.

Ete

redmen

Öncelikle verdiğiniz altın değerinde ki bilgiler için teşekkür ederim kesme için de ki goto nere komutu sumilatör yaparken bir kaç değişikliği görebilmem içindi,çünkü yazılım içinde ki ufak değişikliğin simulatör de ki değişimini görmemi sağlıyordu,zira zaten programın bir bölümü bu çünkü program.ilk çalıştığında module iki tane komut gönderecek,sonra dtmf şifrelerini değişkenlere atayacak.sonra,sistem dtmf bölümünde kalacak.dtmf aktif olduğunda portun birinden sayacın çalışması için pulse alacak.bu arada bu kısaltmaları uygulayıp deneyeceğim ancak programın şu hali bile umut verici benim için.

redmen

#19
'****************************************************************
'*  Name    :                                   *
'*  Author  :                         *
'*  Notice  : *
'*          :                             *
'*  Date    :                                     *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
@ DEVICE pic16f628A                      'DENETLEYİCİ 16f628A                                
@ DEVICE pic16f628A, WDT_ON              'BEKÇİ KÖPEĞİ AÇIK
@ DEVICE pic16f628A, PWRT_ON             'GERİLİMDENGELENİNCE 1 KEZ RESET AT
@ DEVICE pic16f628A, PROTECT_OFF         'KOD KORUMA KAPALI
@ DEVICE pic16f628A, MCLR_OFF            'MCLR PİNİ KULLANILMAYACAK
@ DEVICE pic16f628A, INTRC_OSC_NOCLKOUT  'DAHİLİ OSİLATÖRÜ KULLAN
@ DEVICE Pic16f628A, BOD_OFF             'GERİLİM DALGALANMASI RESET KAPALI
INCLUDE "MODEDEFS.BAS"
'*****************************************************************
    DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
    DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
    DEFINE HSER_SPBRG 25  ' 9600 Baud @ 4MHz, 0,16%
    DEFINE HSER_CLROERR 1 ' Clear overflow automatically
    DEFINE HSER_BAUD 9600 ' BaudRate 9600
    DEFINE OSC 4 
'******************************************************************
TRISA=%00111100                             'A PORTU ÇIKIŞ
TRISB=%00000011                             'B PORTUNUN 2.BİTİ GİRİŞ
PORTB=0:PORTA=0                             'A VE B PORTLARI SIFIRLANDI
CMCON=7                                     'COMPARATÖR İPTAL
                  
VERI  VAR byte[7]
SIF1 VAR BYTE[3]
SIF2 VAR BYTE[3]
SIF3 VAR BYTE[3]
SIF4 VAR BYTE[3]
SIF5 VAR BYTE[3]
SIF6 VAR BYTE[3]
SIF7 VAR BYTE[2]
SES VAR BYTE   
RCA     VAR byte                           'RCA  ADINDA 8 BİTLİK DEĞİŞKEN TANIMLANDI
SYMBOL GIE  =INTCON.7                       'BUTÜN İNTERRUPTLAR AÇILDI
SYMBOL PEIE =INTCON.6                       'USARTR INTERRUPT AÇILDI
SYMBOL RCIE =PIE1.5                         'USART ALMA AÇILIYOR
SYMBOL RCIF =PIR1.5                         'USART INTERRUPT OLUŞTU BBAYRAĞI


NERE:
              
FREKANS1:
pause 2000
serout PORTA.1,T9600,["*"]
pause 2000
READ 0,VERI[0],VERI[1]
READ 2,VERI[2],VERI[3] 
READ 4,VERI[4],VERI[5]
READ 6,VERI[6],VERI[7]
serout PORTA.1,T9600,["AT+DMOSETGROUP=0,173.9750,",VERI[0],VERI[1],VERI[2],VERI[3],VERI[4],VERI[5],VERI[6],"0,0012,0,0013",13,10]
pause 2000
READ 8,VERI[8]
SEROUT PORTA.1,T9600,["AT+DMOSETVOLUME=",VERI[8],13,10] 
READ 10,SIF1[0],SIF1[1]
READ 12,SIF1[2],SIF2[0]
READ 14,SIF2[1],SIF2[2]
READ 16,SIF3[0],SIF3[1]
READ 18,SIF3[2],SIF4[0]
READ 20,SIF4[1],SIF4[2]
READ 22,SIF5[0],SIF5[1]
READ 24,SIF5[2],SIF6[0]
READ 26,SIF6[1],SIF6[2]
READ 28,SIF7[0],SIF7[1]


  
 DEVAM:
                       
  STD var  PORTA.2    '1 STD  8870
  E1  var  PORTB.0    'Q1 du 8870
  E2  var  PORTA.5    'Q2 du 8870
  E3  var  PORTA.4    'Q3 du 8870
  E4  var  PORTA.3   'Q4 du 8870
  SIFRE_1 var PORTB.5      ' 
  PORTA.0=1
  
  
  b1 VAR BYTE
  b2 VAR BYTE
  b3 VAR BYTE
  b1=0
  b2=0
  b3=0
      
  c1  var BYTE   '1° code DTMF
  c2  var BYTE   '2° code DTMF
  c3  var BYTE   '3° code DTMF
  c4  var BYTE   '4° code DTMF
  Q1  var BIT
  Q2  var BIT
  Q3  var BIT
  Q4  var BIT
 
BASLA:

DTMF1:

          RCIE=1
          PEIE=1
          GIE=1
          RCIF=0
          INTCON=%11000000
         ON INTERRUPT GOTO INT
                             
            BUTTON STD,1,255,0,b1,1,DECODER1	
            PAUSE 20
    		BUTTON STD,0,255,0,b2,1,RAZ          
           	GOTO DTMF1
DECODER1:	
            Q1=E1		
    		Q2=E2
    		Q3=E3
    		Q4=E4
     		c1 =  Q1 + 2*Q2 + 4*Q3 +  8*Q4 	
            GOTO DTMF2
           
DTMF2: 	
            b3=0
            WHILE b3<75	
    		BUTTON STD,1,255,0,b1,1,DECODER2	
       	    PAUSE 20
        	b3=b3+1
            WEND
            GOTO DTMF1
DECODER2:	
            Q1=E1		
    		Q2=E2
    		Q3=E3
    		Q4=E4
     		c2 =  Q1 + 2*Q2 + 4*Q3 +  8*Q4 	
      	    GOTO DTMF3
        
DTMF3: 	
            b3=0
            WHILE b3<75	
    		BUTTON STD,1,255,0,b1,1,DECODER3	
         	PAUSE 20
	        b3=b3+1
            WEND
            GOTO DTMF1
DECODER3:	
            Q1=E1		
    		Q2=E2
    		Q3=E3
    		Q4=E4
     		c3 =  Q1 + 2*Q2 + 4*Q3 +  8*Q4 	
            GOTO SIFRE
              
RAZ:  
	  
        	Q1=0
        	Q2=0
	 	    Q3=0
            Q4=0
       	    GOTO DTMF1
            END
SIFRE:     
           PORTA.0=0
           PAUSE 10
           serout PORTA.1,T9600,[SIF1[0],SIF1[1],SIF1[2]]
           
           IF c1=4 AND c2=9 AND c3=3 THEN 
           SIFRE_1=1
           PORTA.0=1
           ENDIF
           IF c1=SIF2[0] AND c2=SIF2[1] AND c3=SIF2[2] THEN 
           SIFRE_1=1
           PORTA.0=1 
           ENDIF
           IF c1=SIF3[0] AND c2=SIF3[1] AND c3=SIF3[2] THEN
           SIFRE_1=1
           PORTA.0=1
           ENDIF
           IF c1=SIF4[0] AND c2=SIF4[1] AND c3=SIF4[2] THEN 
           SIFRE_1=1
           PORTA.0=0
           ENDIF	
           IF c1=SIF5[0] AND c2=SIF5[1] AND c3=SIF5[2] THEN
           SIFRE_1=1
           PORTA.0=0
           ENDIF
           IF c1=SIF6[0] AND c2=SIF6[1] AND c3=SIF6[2] THEN 
           SIFRE_1=1
           PORTA.0=0
           ENDIF
           IF c1=SIF7[0] AND c2=SIF7[1]  THEN 
           SIFRE_1=0
           PORTA.0=1 
           ENDIF
                     
          c1=0	
          c2=0
          c3=0
   	      c4=0
          GOTO DTMF1  
               
DISABLE
INT:
    GIE=0
    HSERIN 100,INT,[WAIT("VER1"),STR VERI\7]
    HSERIN 100,INT,[WAIT("VER2"),SES[0]]
    HSERIN 100,INT,[WAIT("VER3"),STR SIF1\3]
    HSERIN 100,INT,[WAIT("VER4"),STR SIF2\3]
    HSERIN 100,INT,[WAIT("VER5"),STR SIF3\3]
    HSERIN 100,INT,[WAIT("VER6"),STR SIF4\3]
    HSERIN 100,INT,[WAIT("VER7"),STR SIF5\3]
    HSERIN 100,INT,[WAIT("VER8"),STR SIF6\3]
    HSERIN 100,INT,[WAIT("VER9"),STR SIF7\2]
   
    
    WRITE 0,VERI[0],VERI[1]
    WRITE 2,VERI[2],VERI[3]
    WRITE 4,VERI[4],VERI[5]
    WRITE 6,VERI[6],VERI[7]
    WRITE 8,SES
    WRITE 10,SIF1[0],SIF1[1]
    WRITE 12,SIF1[2],SIF2[0]
    WRITE 14,SIF2[1],SIF2[2]
    WRITE 16,SIF3[0],SIF3[1]
    WRITE 18,SIF3[2],SIF4[0]
    WRITE 20,SIF4[1],SIF4[2]
    WRITE 22,SIF5[0],SIF5[1]
    WRITE 24,SIF5[2],SIF6[0]
    WRITE 26,SIF6[1],SIF6[2]
    WRITE 28,SIF7[0],SIF7[1]
    
    RCA=RCREG
    RCIF=0
    GIE=1
    Resume
    enable
    goto NERE
Öncelikle kodun sondan bir önceki hali bu,şuan iletişim kurabiliyor değişkenleri değişterebiliyor serout komutunu kullanıp modulü istediğim gibi programlıyabiliyorum,şöyle bir sorun var,dtmf şifresini epromdan aldığım da dtmf açma yapmıyor,lakin epromdan çağırmadan rakamları direkt giresem sorunsuz açıyor,epromdan aldığım bilgiyi serout yaptığımda verinin girdiğim rakamsal ifade ile aynı olduğunu görüyorum.

ete

Programda görebildiğim tek kusur;
	 
	          RCIE=1
	          PEIE=1
	          GIE=1
	          RCIF=0
	          INTCON=%11000000
	         ON INTERRUPT GOTO INT
kod satırlarının program içine yerleştirilmesi nedeni ile sürekli olarak tekrarlanması.
Bu kodlar ilk açılışta yalnızca bir kereliğine çalışması gerekir. Bu nedenle bu satırların BASLA etiketinden önceki bölüme alınması gerekir.

Hala kesme son satırında GOTO NERE satırı yer alıyor bunuda kaldırsan iyi olacak.

Şifrenin epromdan okunması ile direk girilmesi arasında oluşabilecek tek fark tuş takımından girilen şifrenin rakamsal değerler taşıması diğerinde ise ASCII yani rakamların karekter karşılıklarının yer alması olabilir. Bunu bir şekilde test etmek gerekir.
İşlemciyi yerinden sökerek programlayıcıya takıp READ komutu ile içini okumak ve Eprom adreslerine bakarak şifre olarak hangi rakamlar kayıt edilmiş görmek gerekir.
Bilgi amaçlı şunları söyleyebilirim.
1 rakamını rakam olarak kayıt ederseniz epromda kayıtlı olan değer 1 dir. Aynı sayıyı karekter olarak kayıt ederseniz epromda 49 rakamını görürsünüz.

Ete

Ete

redmen

Hocam kesmye gidebilmek için proğramın başına koyunca program şifre bölümünde kalıyor bu aralıkta 16f628 içerisine herhangi bir veri yükliyemiyorum,ama programın içine yazarsam istediğim an veri atabiliyorum,goto nere zaten kalıcı değil orda end lieceğimi biliyorum lakin değişim yaptığımda simülatör de anlık değişimi görmemi sağlıyor,rakamsal ve karek meselesini iyice bir inceleyeceğim,şu an devreyi fiziksel olarak kurdum önerinizi uygulayacağım inşallah teşekkür ederim ilginiz için.

ete

Yazdığın program tamamen Basic kurallarına aykırı bölümler içeriyor ve bu şekilde sağlıklı çalışmasını beklemek bence hata olur.

Programın SIFRE bölümünde takılmasınada bir anlam veremiyorum. Takılma yalnızca stack taşması olursa olabilecek bir durum. Ama senin programında her hangi bir GOSUB komutu bile yok.
Pause lerin büyük sorun olduğunu daha öncede belirtmiştim. Bir şekilde onlardan kurtulman gerekiyor.
Ayrıca STD pinini kontrol etmek için Buton komutu kullanmanda gerekmiyor. Biliyorsun bu pin "1" olduğunda ilgili bit çıkışlarında bilgi hazır demektir ve o bilgiyi bir defada okuyup sonrasında STD pinin tekrar LOW olmasını bekleyip arada başka iş yapmaman gerekir. Sen ise bu işi genelede while wend döngüsü içinde yapmaya çalışıyorsun.
Bana kalırsa STD 1 oluncaya kadar bekle ve olduğu zamanda Q1-Q2-Q3-Q4 bitlerini okuyup sayıyı al ama bir kerede al ve ardından STD pinin LOW olmasını bekle sonra ne yapacaksan yap.

Basic satır takip eden bir programlama dilidir. Aksine bir komut olmadıkça bir satırdaki komut işlemi bittikten sonra Basic bir sonraki satıra otomatik geçer.
Bir satırda GOTO DTMF3 var ise ve ondan sonraki satırda ise DTMF3 etiketi yer alıyor ise oradaki GOTO DTMF3 komutu lüzumsuz ve gereksiz bir komut olur. Onu koymasan da program zaten DTMF3 etiketine geçecektir.
Bu gibi olumsuz şeyleri gördükçe ikaz ediyorum. Değerlendirmen programın için hayırı olacaktır.

Dediğim satırların kesinlikle BASLA satırından öncesine alınması gerekir. Bu sorun oluşturyor ise yada oluşmuş soruna çözüm oluyor ise o soruna odaklanıp onu düzeltecek başka şeyler bulmalısın. Bu şekilde olmaz.

Ete

redmen

Hocam teşekkür ederim,kurallar açık,tabiki uymak gerek,ancak ben değişiklikler yapıp simülatör de ve fiziksel devre de sonuçları gözlemleyip yapacaklarımı planlıyorum,onlar şimdilik pek sorun çıkarmıyor,onları pek dert etmiyorum,asıl sorunu çözdükten sonra onları da hallederiz insallah,şifre kodları ASCII şeklinde eproma kaydetmiş görünüyor,bu gün sayıları eproma direkt klavyeden girip kaydedip deneyeceğim çıkan sonuca bakacağım inşallah.

ete

Sayılar ASCII olarak kayıt ediliyor ise kayıt ederken başlarına DEC ifadesini eklersen rakam olarak kayıt edilirler.

Ete

redmen

Teşekkür ederim hocam, telsizim şarj olunca sistem üzerinden deneyeceğim inşallah.

redmen

#26



Hocam durumu şöyle anlatayım, pic programı içerisine eprom adreslerinin 3 ne kendim klavyeden diret sayı atadım,sistem çalıştı,epromu tekrar söküp pic programer de okuduğum da gördüm ki,atadığım sayılar ascıı kodunda nokta olarak gösterirken,serial port üzerinden gönderdiğim veriler ise değer şeklinde gözüküyor,ve sorun yine devam ediyor.pic programerden aldığım resimde ki 3 nokta normal de benim eproma vermiş olduğum diret değerler.




Sanırım serial port üzerinden gelenler ascı kodları,klavyeden girlen değerler rakamsal değerler birisinde 08-09 şeklinde diğerinde ise 38-39.

istinaf duvarı

Serial haberleşmede ASCII kodları kullanılır. Mesela 1 verisini iletmek istiyorsan porttan 0x01 değil, bunun ASCII karşılığı olan 0x31'i iletmen gerekir. Buraya dikkat edin.

redmen

Teşekkür ederim kardeşim,eproma kayıt hex olarak yapılıyor,ancak dtmf şifresi çağrıldığın da bu geri mesala sayı 2 ise epromda kayıtlı olan hex sayısı 32 olduğu için sistem anlaşamıyor,bende eproma kayıt esnasın da gelen veriden  hex 30 sayısını çıkardım,böylelikle bu sorunu aştım,ancak bu kez de A,B,C,D,F lerde sorun yaşıyorum, doğru sayısal olarak eşitleniyorlar lakin bu kez de sistem  A isterken epromdan gelen bilgi 10 yine anlaşamıyorlar,bana pic içerisinde 16 lık sayı sistemine çeviren bir pic kodu lazım mesala 32-02,10-A şeklinde çevrim yapabilecek.

Pepe


Powered by EzPortal