PİC16f628a serial haberlesme sorunu

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

ete

Serial komutları gönderilen karekterlerde modifier denilen ve sayının sayımı veya ASCII mi olduğunu gösteren parametreler kullanabilir.

MicroCode STudio da program yazarken Seri komutu (HESERIN,HSEROUT , SERIN vs) üzerine kursorü getirip F1 tuşuna basarsanız komutun açıklaması ekrana gelir. Orada da göreceğiniz gibi ,
Modifier......Operation
 
BIN{1..16} ..Receive binary digits
 
DEC{1..5}....Receive decimal digits
 
HEX{1..4}.... Receive hexadecimal digits
 
şeklinde açıklamaları görebilirsiniz.
Başına bir şey koymaz iseniz bilgi ASCII olarak yollanır. Yada alınır.
Bunları HSERIN açıklamasından aldım.
SERIN ile ilgili açıklamada şunları yazıyor;
"Once the qualifiers are satisfied, SERIN begins storing data in the variables associated with each Item. If the variable name is used alone, the value of the received ASCII character is stored in the variable. If variable is preceded by a pound sign ( # ), SERIN converts a decimal value in ASCII and stores the result in that variable"
Değişken adınınbaşında bir şey olmaz ise o bilgi ASCII karekter olarak depolanır ama başına # işaretini koyarsanız gelen karekter bir ASCII ile ilişkili bir sayıya dönüştürülüp depolanır.

Bu açıklamaya uygun olarak kodları değiştirirseniz sorununuz düzelecektir.

Ete

redmen

Teşekkür ederim ete hocam,uyarılarınızı dikkate alıp,değişikleri yapıp deneyeceğim inşallah.

redmen

Merhaba ete hocam dediğiniz gibi verdiğiniz komut bilgisi ile data yı alıyorum, güzel istediğim gibi oluyor lakin
durum şu, misal HSERIN 100,INT,[WAIT("VER9"), HEX VERI14[0],VERI14[1]] komutu girdiğim de gelen veri CA ise  epromun sadece 8 bitlik bölümüne CA verisini yazıyor,aslında olmasını istediğimiz şey ise 0C-0A olması yani 16 bitlik verinin ikişer 8 bitlik bölümü,misal hex komutunu girmeden ise gelen veri 8 bitlik ayrı ayrı CA için 43-41 sorun nerde anlamadım hocam.

ete

Redmen,

Çok garip ve önceden görmediğim bir veri aktarma sistemin mevcut.
CA bilgisi yollanıyor ise bunu 0C-0A olarak alamazsın. Bu işi ancak o veriyi aldıktan sonra yapabilirsin. Ama dikkat et gelen bütün veriler bu şekilde geliyor ise bir genelleme yapabilirsin.
Bundan eminmisin? EMin isen

Gelen veriyi $CA olarak al sonra,
TEMP=$CA
DUSUK=TEMP DIG 0 Bu komut sayının yalnızca $A kısmını ayırır. Bu aslında DUSUK=$0A şeklindedir.
YUKSEK=TEMP DIG 1 bu komut da sayının $C kısmını alır YUSEK=$0C olur.
SOnra bunları nasıl istersen kullanırsın.

Ete


redmen

Hocam inşallah pazartesi günü önerinizi dikkate alarak değişiklik yapacağım,lakin çok garip şeyler ortaya çıkıyor,sayeniz de bir çok şey öğrendim Allah razı olsun hayırlı geceler.

ete

Aslında bir deneme yapayım dedim ve baktım ki DIG komutları Decimal çalışıyormuş.
Bu nedenle taktik değiştirmek gerekecek.
Gelen veriyi $CA olarak al sonra,
TEMP=$CA
DUSUK=TEMP/16  Bu komut sayının yalnızca $A kısmını ayırır. Bunu 2 hane yazdırırsan yada yollarsan (Hex2 DUSUK) aslında DUSUK=$0A şeklindedir.

YUKSEK=TEMP-(DUSUK*16) bu komut da sayının $C kısmını alır YUSEK=$0C olur.
SOnra bunları nasıl istersen kullanırsın.

Bu şekilde garanti olacaktır.

Ete

redmen

Gelen veriler ascıı kodunda geliyor 41_42_43 şeklinde veriyi direkt olarak eproma kayıt ediyoruz,kullanabiliyoruz misal kullandığım modül asc kodlarını diret alıyor ve haberleşiyor,ancak iş dtmf kod çözücüye geldiğinde ascıı kodundan $30 sayısını çıkarıp 1_9 arası sorunsuz çalışıyor,ancak 9 dan sonra A_F arası 10_15 arası karekter istiyor sayıyı kabul etmiyor,karşılaştırma yaparak 10 ise A gibi mesala aşıyorum,ama şifre bölümü 7 ve kendi içinde 3 karekter olunca yazdığım satır sayısı çok artıyor ve picin komut satır limitini aşıyor.c#üzerinden  karekter olarak göndersek bu sorunu acaba aşabilirmiyiz diye düşünüyorum hocam.

ete

Hiç bir yerde gelen giden verielre bu kadar müdahale edildiğini görmemiştim.
Bilmediğim bir şeyler var ama ne olduğunu da kestiremedim.
Bu sorunu hacımsal boyu olarak kafama yerleştiremediğim için ancak yüzeysel düşünebiliyorum.

Şimdi yeniden düşünelim. Gelen veriler ACSII kodu olarak geliyor. Sıfır rakamı 48 olarak sırası ile 1=49 , 2=50 şeklinde gidiyor. 9 dan sonra gelen sayılar mutlaka 65-66-67-68-69-70 şekline dönüyor olması gerekir.
O halde gelen verilerin alındığı yere ;
IF GELEN>54 and GELEN<71 then VERI=GELEN-55
komutu otomatikman gelen verileri 64 den büyük ise 10-11-12-13-14-15 rakamlarına çevirecektir.
Ancak böyle olur sanırım.

Ete

redmen

Hocam inanın söylediğiniz gibi gelmiyor gelen verileri pickit 3 üzerinden okuduğum da hex bölümünde  sayılar 30_39 arası A_F arası harfler için ise 41_45arası veriler okuyorum,ASCİİ konumunda ise bildiğimiz üzere 1_9 arası A_F verileri görünüyorC# üzerinde bu verileri string olarak tanımladım hiç bir şekilde convert yapmadım.Ama baya ilginç şeyler görüyorum.aslında verinin alımında ve gönderilmesinde hiç sıkıntı yaşamayorum,A-F arası veri kullanmadığım sürece dtmf epromdan arayüzden aldığım veriler ile açma kapama yapıyor.

redmen

#39
Kapsamlı bir çalışma olduğu için,bir çok işi bir ara da yapmak zorunda kalıyorum elimde AT komutu ile çalışan kendi içinde yazılımı olan bir modül var,bu modül aslında bir kere programlayınca artık o frekans ve ayar da çalışabiliyor,lakin modülün bir sorunu var bazen elektriksel yada başka nedenden dolayı kendi işlemcisine yüklü verileri silebiliyor,o yüzden bu işi ancak bu pic üzerinden arayüzle bir kere programlayabiliyor ve pic sıfırdan her başladığında modüle hatırlatma verisi gönderiyor,daha sonra epromdaki şifre bilgilerini dtmf bölümüne yükliyerek artık sürekli sadece o bölümde çalışıyor.sistem üzerinden sinyal geldiği zaman şifrelere göre açma yada kapama yapıyor.

redmen

#40
@ 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
              
VERI0  VAR byte[7]
VERI1 VAR BYTE[3]
VERI2 VAR BYTE[3]
VERI3 VAR BYTE[3]
VERI4 VAR BYTE[3]
VERI5 VAR BYTE[3]
VERI6 VAR BYTE[3]
VERI7 VAR BYTE[2]
VERI8 VAR BYTE[3]
VERI9 VAR BYTE[3]
VERI10 VAR BYTE[3]
VERI11 VAR BYTE[3]
VERI12 VAR BYTE[3]
VERI13 VAR BYTE[3]
VERI14 VAR BYTE[2]
A1  VAR BYTE[3]
A2  VAR BYTE[3]
A3  VAR BYTE[3]
A4  VAR BYTE[3]
A5  VAR BYTE[3]
A6  VAR BYTE[3]
A7  VAR BYTE[2]
A VAR BYTE
SES VAR BYTE
A=$30
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,VERI0[0],VERI0[1]
READ 2,VERI0[2],VERI0[3] 
READ 4,VERI0[4],VERI0[5]
READ 6,VERI0[6]
serout PORTA.1,T9600,["AT+DMOSETGROUP=0,173.9750,",VERI0[0],VERI0[1],VERI0[2],VERI0[3],VERI0[4],VERI0[5],VERI0[6],"0,0012,0,0013",13,10]
pause 2000
READ 8,SES
SEROUT PORTA.1,T9600,["AT+DMOSETVOLUME=",SES,13,10] 
READ 10,VERI1[0],VERI1[1]
READ 12,VERI1[2]
READ 14,VERI2[0],VERI2[1]
READ 16,VERI2[2]
READ 18,VERI3[0],VERI3[1]
READ 20,VERI3[2]
READ 22,VERI4[0],VERI4[1]
READ 24,VERI4[2]
READ 26,VERI5[0],VERI5[1]
READ 28,VERI5[2]
READ 30,VERI6[0],VERI6[1]
READ 32,VERI6[2]
READ 34,VERI7[0],VERI7[1]


                       
  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     
           
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     
        
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:     
          
           
           IF c1=VERI1[0] AND c2=VERI1[1] AND c3=VERI1[2] THEN 
           SIFRE_1=1
           PORTA.0=0
           ENDIF
           
SIFRE1:
           
           IF c1=VERI2[0] AND c2=VERI2[1] AND c3=VERI2[2] THEN 
           SIFRE_1=1
           PORTA.0=0
           ENDIF 
           
SIFRE2:
            
           
           IF c1=VERI3[0] AND c2=VERI3[1] AND c3=VERI3[2] THEN
           SIFRE_1=1
           PORTA.0=0
           ENDIF
          
SIFRE3:
          
           
           IF c1=VERI4[0] AND c2=VERI4[1] AND c3=VERI4[2] THEN 
           SIFRE_1=1
           PORTA.0=0
           ENDIF
          
SIFRE4:
          
       
           IF c1=VERI5[0] AND c2=VERI5[1] AND c3=VERI5[2] THEN
           SIFRE_1=1
           PORTA.0=0
           ENDIF
          
SIFRE5:
          
           IF c1=VERI6[0] AND c2=VERI6[1] AND c3=VERI6[2] THEN 
           SIFRE_1=1
           PORTA.0=0
           ENDIF
           
SIFRE6:
                       
           IF c1=VERI7[0] AND c2=VERI7[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 VERI0\7]
    HSERIN 100,INT,[WAIT("VER2"),SES[0]]
    HSERIN 100,INT,[WAIT("VER3"),STR VERI8\3]
    HSERIN 100,INT,[WAIT("VER4"),STR VERI9\3]
    HSERIN 100,INT,[WAIT("VER5"),STR VERI10\3]
    HSERIN 100,INT,[WAIT("VER6"),STR VERI11\3]
    HSERIN 100,INT,[WAIT("VER7"),STR VERI12\3]
    HSERIN 100,INT,[WAIT("VER8"),STR VERI13\3]
    HSERIN 100,INT,[WAIT("VER9"),STR VERI14\2]
   
    WRITE 0,VERI0[0],VERI0[1]
    WRITE 2,VERI0[2],VERI0[3]
    WRITE 4,VERI0[4],VERI0[5]
    WRITE 6,VERI0[6]
    WRITE 8,SES 
              
    A1[0] = VERI8[0]
    A1[1] = VERI8[1]
    A1[2] = VERI8[2]
    VERI1[0] = A1[0]-A
    VERI1[1] = A1[1]-A
    VERI1[2] = A1[2]-A
    WRITE 10,VERI1[0],VERI1[1]
    WRITE 12,VERI1[2]
    A2[0] = VERI9[0]
    A2[1] = VERI9[1]
    A2[2] = VERI9[2]
    VERI2[0] = A2[0]-A
    VERI2[1] = A2[1]-A
    VERI2[2] = A2[2]-A
    WRITE 14,VERI2[0],VERI2[1]
    WRITE 16,VERI2[2]
    A3[0] = VERI10[0]
    A3[1] = VERI10[1]
    A3[2] = VERI10[2]  
    VERI3[0] = A3[0]-A 
    VERI3[1] = A3[1]-A   
    VERI3[2] = A3[2]-A
    WRITE 18,VERI3[0],VERI3[1]
    WRITE 20,VERI3[2]
    A4[0] = VERI11[0]
    A4[1] = VERI11[1]
    A4[2] = VERI11[2]   
    VERI4[0] = A4[0]-A   
    VERI4[1] = A4[1]-A    
    VERI4[2] = A4[2]-A
    WRITE 22,VERI4[0],VERI4[1]
    WRITE 24,VERI4[2]
    A5[0] = VERI12[0]
    A5[1] = VERI12[1]
    A5[2] = VERI12[2]
    VERI5[0] = A5[0]-A
    VERI5[1] = A5[1]-A 
    VERI5[2] = A5[2]-A
    WRITE 26,VERI5[0],VERI5[1]
    WRITE 28,VERI5[2]
    A6[0] = VERI13[0]
    A6[1] = VERI13[1]
    A6[2] = VERI13[2]   
    VERI6[0] = A6[0]-A  
    VERI6[1] = A6[1]-A   
    VERI6[2] = A6[2]-A 
    WRITE 30,VERI6[0],VERI6[1]
    WRITE 32,VERI6[2]
    A7[0] = VERI14[0]
    A7[1] = VERI14[1]
    VERI7[0] = A7[0]-A   
    VERI7[1] = A7[1]-A
    WRITE 34,VERI7[0],VERI7[1]
    
    
            
    RCA=RCREG
    RCIF=0
    GIE=1
    Resume
    enable
    end
       Hocam öncelikle sizleri yorduğum için özür diler ilginiz için de ayrıyaca teşekkür ederim,yine serial iletişim kodlarınının yerine takılmayın,orası problem değil,yazdığım proğram ile geldiğim sonuç zaten bu şekilde.benim sorunum şu misal 10-11-12-13-14-15 sayılarının yerinde A-B-C-D-E-F görmem gerekiyor.onu da ilave yazdığım proğramla aşabiliyorum ama 7 şifre ve herbiri 3 kareterden oluşunca satır yoğunluğu oluyor ve epromun kapasitesi yetmiyor.


ete

Mikro işlemciler binary yani ikili sayı sistemi ile çalışır.
Basic gibi ara derleyicilerin bir çok komutu 10 tabanına göre yani desimal sayı sistemi üzerinden çalışır.
Ancak iş gösterime gelince başına koyduğunuz işaret yada paramtre diyelim sayesinde o sayıları ister binary ister desimal istersenizde hexadesimal sistemde görebilirsiniz. Yada sayıların kullanıldığı işlemlerin pek çoğunda da yine ön işaret kullanılarak o sayıyı ya binary ya desimal yada hexadesimal olarak kullanabiiyorsun.

Adım adım sorunları aştıkça başka sorunların ortaya çıkıyor. EN son sorunun yazdıklarına bakılırsa eprom hafıza yetersizliği gibi gözüküyor. Bunu aşmanın tek çaresi harici eprom kullanmaktır. Balkada çaren yok gibi.

Ete

redmen

Allah razı olsun hocam o kadar yol kat ettim artık bir çözüm bulacağım inşallah.ya c# üzerinde yada pic üzerinde.

DigMan

#43
Herkese merhaba. Konu usart olduğu için konu açmadan buraya yazayım dedim.

Aşağıda, Ete hocamın da ders notlarından örnek alıp sadeleştirdiğim bir yazılım var. Amacım, MODBUS protokolü ile PLC haberleşmesi yapmak. PLC den gönderdiğim veri ile, yapmış olduğum kartın PORTB çıkışlarını aktif/pasif etmek istiyorum.

Fakat ne yaptıysam bir türlü haberleştiremedim. Bu programda eksik, yanlış, unuttuğum bir şey var mı? Elimde PLC yok. Testi; Modbus Poll programı, USB to RS485 ve TTL to RS485 kartları ile yapıyorum. Aşağıda fotolarını da ekledim. Hocam, hata nerden kaynaklı bir türlü çözemiyorum. Aldığım hata kodları; Checksum Error veya insufficient bytes received.

Ete hocam bir de ders notunuzda, 2 adet hsrout komutu kullanmışsınız, bunun bir amacı var mı?
Bir başka sorum, RS485 gelen komut diziliminde, sırasıyla,
1. cihaz kodu - 8 bit
2. Komut kodu - 8 bit
3. adres(Reg) kodu - 2x 8 bit  (bu 40000 li kod nedir bir türlü anlamış değilim)
4. data kodu  - n x 8 bit
5. CRC kodu  - 2x 8 bit

şeklinde. Biz bu kodları alırken/yollarken Hserin veya Hserout komutları içinde kullandığımız byte tanımlı değişkenlere otomatik atamış mı oluyoruz? Yani bu 5 kod için, (data kodunu tek bir byte sayarsak) 7 adet byte tanımlı değişken yazmamız yeterli oluyor mu? Eğer data kodumuz birden fazla ise bu komut data mı CRC mi  olduğunu nasıl anlayacak anlayamadım.

Proton kullanan arkadaşlara da bir sorum olacak. Define ile declare aynı şeyler mi? Protonda define kullanılıyor mu?   

Yardımcı olabilirseniz sevinirim.


 



Device 18F2620
XTAL = 20
ALL_DIGITAL = On
Include "modedefs.bas"


'#DEFINE HSERIAL_CLROERR = 1
Declare HSERIAL_BAUD    = 9600    
Declare HSERIAL_RCSTA   = 90 '%10010000  '90
Declare HSERIAL_TXSTA   = 24 '%00100100  '24 
Declare HSERIAL_SPBRG   = 129    
Declare HSERIAL_CLEAR   = 1  
   
Symbol RedLed   = PORTA.0
Symbol GreenLed = PORTA.1

Symbol TxKesmE = PIE1.4
Symbol TxByraK = PIR1.4

Symbol RxKesmE = PIE1.5
Symbol RxByraK = PIR1.5

Symbol GenelKesme = INTCON.7  'GIE
Symbol CevreKesme = INTCON.6  'PEIE
Symbol CIKIS = PORTB
 

TRISA = 0
TRISB = 0
TRISC = 0
TRISC.7 = 1
Low PORTA
Low PORTB
Low PORTC
Input PORTC.7


Dim GelenID       As Byte
Dim GelenEmiR     As Byte
Dim GelenBoS      As Byte
Dim GelenFonks    As Byte
Dim GelenRegL     As Byte
Dim GelenRegH     As Byte
Dim GelenDataL    As Byte
Dim GelenDataH    As Byte
Dim GelenCrcL     As Byte
Dim GelenCrcH     As Byte
Dim TempCleaR     As Byte
Dim IDKayit       As Byte
Dim EmirKayit     As Byte
Dim BosKayit      As Byte
Dim FonkKayit     As Byte
Dim RegKayitL     As Byte
Dim RegKayitH     As Byte
Dim DataKayitL    As Byte
Dim DataKayitH    As Byte
Dim CRCKayitL     As Byte
Dim CRCKayitH     As Byte
Dim ALDI          As Byte
Dim SAYAC         As Word
Dim CihazKodu     As Byte
Dim A             As Byte

Clear
DelayMS 700

CihazKodu = %00000001  'Cihaz-1
DelayMS 250

'-------------------------------------------

TempCleaR = RCREG                
GenelKesme = 1
CevreKesme = 1
RxKesmE    = 1
On Interrupt GoTo KesmeRutiN ' hem SW hem de donanım kesmeyi denedim 


'-------------------------------------------

START:

   If IDKayit = CihazKodu And ALDI = 1 Then
      CIKIS = DataKayitL
      IDKayit   = GelenID
      FonkKayit = GelenFonks
      RegKayitH  = GelenRegH
      RegKayitL  = GelenRegL
      DataKayitH = GelenDataH
      DataKayitL = GelenDataL
      CRCKayitH  = GelenCrcH
      CRCKayitL  = GelenCrcL
      Toggle GreenLed
      GoSub DataYolla      
      ALDI = 0
   EndIf
      
   GoTo StarT


;------------------------ALT PROGRAMLAR------------------------------
''-------------------------------------------------------------------


DataYolla:

   HSerOut[Rep $AA\5, Rep $00\5, Rep $FF\5]
   HSerOut["A","B","C", IDKayit, FonkKayit, RegKayitH, RegKayitL, DataKayitH, DataKayitL, CRCKayitH, CRCKayitL]
   'HSerOut["A","B","C", IDKayit, FonkKayit, RegKayitH, RegKayitL, DataKayitH, DataKayitL, CRCKayitH, CRCKayitL]
   Return          


;------------------------------KESME---------------------------------

Disable
KesmeRutiN:
   
   If RxByraK = 1 Then
      GenelKesme = 0
      Toggle RedLed
      HSerIn 100, TimeOut, [Wait("ABC"), GelenID, GelenFonks, GelenRegH, GelenRegL, GelenDataH, GelenDataL, GelenCrcH, GelenCrcH] 
      ALDI = 1
   EndIf     
   
TimeOut:
   TempCleaR = RCREG
   RxByraK = 0 
   GenelKesme = 1
   Resume
   Enable

''-------------------------------------------------------------------


ete

Programına baktım ve herhangi bir hata göremedim. Usulüne uygun yazılmış.
Fazlalık var hatta. Global kesmeler kesme içine girildiğinde otomatik olarak iptal edilir. Yeniden kesme içinde kesme oluşmasın diye. Sen bunu kendinde yapıyorsun. Hata değil ama gereksiz iş.

Bu sistemde bana kalırsa asıl sorun modbus5 protokolünü çok iyi bilmemen. Bu protokolü bende bilmiyorum araştırmadım. Bana kalırsa bunu araştır.
USART kullanılarak yaoılan karşılıklı alışverişte alınan ve verilen byte sayıları belirli olması gerekir. Hiç bir zaman bir taraf 5 byte yollar diğeri 6 byte bekler yada bir taraf 6 yollar diğeri 5byte alacak şekilde bir uyarlama olamaz. Alınan ve verilen byte sayıları her iki taraf için aynı olmalıdır. Senin sorunun burada. "Unsufficient byte received" demek beklenenden daha az byte alındı anlamına geliiyor ve zaten alınan az olduğu içinde checksum tutmuyor.
Bence protokolü araştır ve alınan verilen byte sayılarını eşitlemeye çalış. Checksum mutlaka alınan en son byte veya bytlar olmalıdır ve byte sayısına dahil edilmelidir.
Senin sisteminde kaç tane data byte'ı olduğu önemli bunu sen ihtiyacına göre belirleyeceksin sanırım. Bu durumda sen;
- Cihaz kodu için 1 Byte
- Komut kodu için 1 byte
- Adres Kodu için 2 byte
- Data kodu için 1 byte (1 byte olduğunu kabul ederek)
- CRC kodu için 2 byte
olmak üzere toplam 7 byte olacak şekilde heserim komutu içinde 7 ayrı değişken kullanmak zorundasın. Gelen bilgi alındığında yukarıdaki sıralamaya uygun olarak bilgiler bu byte lar içine otomatik yerleşmiş olacaktır.
Burada kritik konu CRC nin oluşturulmasıdır.Doğruluğunu kim değerlendiriyor onu pek anlamadım ama aldığın hataya bakılırsa kullandığın arayüz bunu değerlendiriyor. Dolayısıyla CRC nin nasıl oluşturulduğunada dikkat etmen gerekiyor.

USART gönderme komutlarını tek bir defa kullanmak daima yeterli oluyor. Ben 2 defa kullanmış isem o zamanlar emin olamadığımdandır. Ama aradan geçen zamanda gördümki tek komut daima yeterli oluyor. Yerine göre 2 defa yollamak sorun yaratmıyor ama senin sisteminde yaratabilir çünki byte sayısı önemli.

Define ve declare aynı şeyler. Bildiğim kadarı ile proton Declare kullanıyor PBP ise define kullanıyor ama Proton ikisinide kabul ediyor olabilir. Ancak eski Proton user manualine baktığımde direk Define komutu göremedim. Hep Declare kullanılmış. Positron isimli yeni Protonda durum nasıldır bilemiyorum. Bana kalırsa sen daima Declare kullan.


Ete

Powered by EzPortal