24C128 EPROM YAZMA SORUNU

Başlatan picagor, 03 Nisan 2011, 00:52:36

picagor

24C128 Harici EEPROM un ilk 19 adresine "9" sayısını yazmak istiyorum. Her seferinde ilk 19 hücreden rastgele yerlere "9" verisini yazıyor. Adres atlaması yapıyor. Başka bir veri yazmak istediğimde eskiden yazdığım "9" ların bazılarını silip yerine yeni verileri yazıyor. Fakat önceden yazdırdığım "9" ların bazıları yerlerinde kalıyor. Okuma kısmında sorun yok. ETE hocanın 9. dersindeki I2C bölümününden harici EEPROM  yazma işini deneme yanılma ile öğrenmek istiyorum. Kodlamada acemiyim.. Saygılar..

'****************************************************************
'*  Name     : I2C-Eeprom.BAS                                      	*
'*  Author   : [E.T.E]                                           	*
'*  Notice    : Copyright (c) 2005 Ete]                           	*
'*            : All Rights Reserved                               	*
'*  Date      : 30.06.2005                                        	*
'*  Version : 1.0                                               	*
'*  Notes    :                                                   	*
'*                :                                                 *
'****************************************************************
DEFINE OSC 10

PORTA=0
PORTB=0
TRISB=%00000000   'PortB.0 giriş diğerleri çıkış yapıldı.
TRISA=%00010000   'A portu tamamı çıkış yapıldı.
'-----------------------------------------------------------------
@ DEVICE pic16F628a                      'işlemci 16F628                                
@ DEVICE pic16F628a, WDT_on              'Watch Dog timer açık
@ DEVICE pic16F628a, PWRT_ON             'Power on timer açık
@ DEVICE pic16F628a, PROTECT_OFF         'Kod Protek kapalı
@ DEVICE pic16F628a, MCLR_OFF             'MCLR pini kullanılıyor.
@ DEVICE pic16F628a, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak 
'---------------------------------------------------------------------
SYMBOL CPIN=PortA.0       ' Clock pini
SYMBOL DPIN=PortA.1       ' Data pini     
X VAR BYTE                'portb için geçici değişken
DTA   VAR  BYTE           'EPROMA yazılacak DATA
ADRS  VAR  WORD            'EPROM ADRESİ
KONT	Con	%10100000		' EPROM KONTROL KODU
DTA=9  'DATA
ADRS=0  
'-------------------------------------------------------EPROMA YAZ 
E_YAZ:  

       I2CWRITE DPIN,CPIN,KONT,ADRS,[DTA]
       ADRS=ADRS+1
       Pause 1
       IF ADRS<20 THEN 
       GOTO E_YAZ
       ENDIF                		  
HIGH PORTA.2    'YAZILDI LEDİNİ YAK
PAUSE 1000
LOW PORTA.2
PAUSE 1000
'------------------------------------------------------- EPROMU OKU
E_OKU: 	
   ADRS=0
   FOR ADRS=0 TO 19  '$19 E KADAR TÜM ADRESLERİ OKU
       I2CREAD DPIN, CPIN, KONT, ADRS, [X]    'EPROMDAKİ VERİYİ OKU X e KAYDET
       PORTB=X       'PORTB DE X i GÖSTER
       PAUSE 250      '250 ms bekle 
       NEXT ADRS      'SONRAKİ ADRESİ OKU
       
HIGH PORTA.3    'OKUNDU LEDİNİ YAK
PAUSE 1000
LOW PORTA.3
PAUSE 1000
'----------------------------------------------------------

END



ete

2 önemli kusurun var. Birincisi 16F628 de default olan komparatörleri iptal etmemişsin. Dolayısıyla A portu analog çalışıyor.
Bunu yapmak için CMCON=7 komutunu kullanıp A portunu digital giriş çıkış olarak kullanman gerekir.

İkincisi epromlarda yazma süresi 10ms dir ve iki yazma komutu arasında bu sürenin mutlaka verilmesi gerekirdi.
Sen bunu  "Pause 1"  şeklinde  1ms olarak vermişsin. Dolayısıyla bu süre 10 ms olarak verilmelidir.
Bu iki noktayı düzelt program düzgün çalışacaktır.

I2C sistem 400Khzlik bir hızla çalışır. Bu nedenle genelde 8Mhz aşan OSC frekanslarında I2C işleme hızını yavaşlatmak gerekebilir. Bunun için programın başına;
DEFINE I2C_SLOW 1
komutunuda ilave etmende yarar vardır. Zira OSC frekansın 10Mhz olarak seçilmiş.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

picagor

Ete hocam dediklerini yapınca simulasyonda istediğim gibi çalıştı fakat breadboarda sonradan kurduğum devre çalışmadı.. Kolay bir devre ama bağlantıları defalarca kontrol ettim.. Acaba donanımsal bişeyler daha mı eklemek gerekiyor? 

ete

Mümkünse 4 Mhzde bir dene yada yavaşlatma komutunu ilave edip deneyiver.
Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

picagor

#4
Breadboard kalitesizliği + Pic besleme hassasiyeti yüzünden çalışmamış. Hallettim sayın ETE. Bu arada 150 display kullanarak bilgi panosu yapmak istiyordum hatırlarsanız(elektrotekno). Doğru yoldamı ilerliyorum sizce? Eproma bu şekilde 150 byte yükleyip daha sonra bu bilgileri EPROMdan okutturup displaylerde göstermeyi düşünüyorum.

ete

Bütün 74595 leri bir zincir şeklinde seri olarak bir birine bağlayabilirsin. Ancak 150 adet display için 150 adet byte yollaman gerekecek.
Bence çok akıllıca değil. Bunu kademelere yada guruplara ayırsan hiçde fena olmaz. Zaten sana başından beri bunu anlatmaya çalışıyorum.
Guruplama yaparsan bir seferde yollayacağın byte sayısı azalacaktır.
Teorik olarak çalışmaz demiyorum ama çalışmada zaman sorunları yaşarsın gibime geliyor. Denenmemiş veya sonuçların ne olacağı görülmemiş bir şey üzerine konuşmak yanlış olur. En iyisi yapıp sorunları görüp ona göre düzeltme yapmak bence. Arge böyle oluyor işte.

Hserout bu iş için kullanılmaz. Shiftout dta,clk,1,[veri_0,...,veri_n] komutunu kullanman gerekiyor.
Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

picagor

EEprom olayını sayenizde çözdüm fakat bilgi eksikliğinden kaynaklanan sorunlardan dolayı günlerdir bu işle uğraşmama rağmen halen seri porttan 1 byte lık herhangi bir karakteri bilgisayardan gönderip 16F877 nin portd sinde gösteremedim.

Virtual Serial Port Driver programını kurup ISIS Commpim ayarını COM3 yaptım, Visual Basic programı ile yazdığım yazılımı ise COM2 den gönderiyorum. VB TextBox tan bir kaç karakterlik veri gönderdiğimde ISIS simulasyonunda COMMpimm in üstteki ışıkları yanıp sönüyor. Hatta virtual serial Port programınıda aynı anda açıyorum COM2-COM3 arasında veri alışverişi olduğunu gösteriyor. Fakat bir türlü 877 yi USART kesmesine sokamıyorum. Kesme alt programında PC den herhangi bir veri gelirse PORT D portundaki ledleri yak diye komut verdim..  Başaramadım.. Bu forumdan araştırdığım kadarıyla şöyle bir program yazdım..

'****************************************************************
'*  Name    : picagors7-segment_board.BAS                       *
'*  Author  : picagor                                           *
'*  Notice  : Copyright (c) 2011                                *
'*          : All Rights Reserved                               *
'*  Date    : 06.04.2011                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************

'==============================TANIMLAMALAR
Include "MODEDEFS.BAS" 'Seri İletişim İçin Gerekli
Define OSC 20
DEFINE I2C_SLOW 1
ADCON1 = 7
CMCON=7
TrisA=0:TrisB=0:TrisC=0:TrisC.7=1:TrisC.6=0:TrisD=0:TrisE=0
PortA=0:PortB=%00000000:PortC=0:PortD=0:PortE=0:
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 24h     'BU SAYI 20 Mİ 24 MÜ OLACAK? 
DEFINE HSER_BAUD 2400  'BÖYLE BİR KOMUT VARMI BAUD HIZINI 2400 YAPARMI?
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
'DEFINE HSER_SPBRG 25  ' 9600 Baud @ 0,16%

'=============================== EEPROM TANIMLARI
I2C_SDA var PortC.4         'EPROM DATA
I2C_SCL var PortC.3         'EPROM CLOCK
sayac var byte
'============================== USART KESME TANIMLARI
INTCON.7=1
INTCON.6=1
PIE1.5=1 		
PIR1.5=1


ON INTERRUPT GoTo COMPORTOKU 			
'===============================ANA PROGRAM BAŞLANGICI
anaprogrambasla:

PORTB=$FF
PAUSE 100
PORTB=$00
PAUSE 100

goto anaprogrambasla
Disable 

'=================================USART KESMESİ    
    
COMPORTOKU:   

If PIR1.5 = 1 Then 

for sayac=1 to 10
PORTD=$FF 
pause 200 
PORTD=00
pause 100 
next sayac
EndIf 

portd=$ff
pause 1000

INTCON = %11000000			
PIE1.5 = 1

Resume 
Return 

'END NEREYE KONACAK?   





ete

#7
PC ile Pic leri seri yoldan haberleştirmenin bazı kuralları var . Bu kurallara uyarsanız sorunsuz haberleşebilirsiniz.
Nedir  kurallar derseniz;
1. Pic le PC de aynı haberleşme hızı ve sistemi seçili olması gerekir.  Kablolu haberleşeceksiniz ve Pic kristal hızı 4Mhz in üzerind eise 9600 Baud 8N1 formatını seçebilirsiniz.  Bu format her iki tarafta aynı olmalı hızda iki tarfta eşit olmalıdır.

2. Pic TTL çıkışlıdır. Yani HIGH denildimi +5V anlaşılır. LOW ise GND dir (0V).  PC de RS232 portunda High denildimi -10V anlaşılır. Low denildimi +10V anlaşılır. BU voltajlar bazı lapoplarda 7-8V seviyelerine kadar düşebilir. Gördüğün gibi birinin high diye yolladığı sinyal diğerinde farklı seviyeye tekabül etmekte ve bu nedenle direk bağlantı yapılırsa iki cihaz bir birini kesinlikle görememektedir. Bunu önlemek ve iki cihaz arasında hem alınan hem yollananın sinyal seviyelerinin cihaza göre düzeltilmesi amacı ile seviye düzletici entegreler üretilmiştir. MAx232 veya aynı amaçlı benzerleri bu iş için kullanılırlar. Entegreler 5V ile çalışmalarına rağmen içlerinde yer alan voltaj pompaları sayesinde hem -10V hemde +10 gibi voltajları üretir ve gerekli sinyal çevirimlerini yaparlar. Bu açıklamalrdan Pic ile PC arasında RS232 çeviricisinin kullanılmasıgerektiğini anlamışsındır.

3. Genelde yollanacak veri bir paket halinde yollanır. Önce başına bir uyandırma sinyali eklenir. Ardından bir işaretçi koyulur ve peşine asıl veri eklenerek paket yollanır. Alıcı uyandırma sinyali ile portunu uyandırır. Ardından programın emrettiği şekilde işaretçiyi bekler ve onu bulduktan sonra gerisinden gelen asıl veriyi alır. Bunu bir örnekle açıklarsak;
- Uyandırma bilgisi 5 byte $AA , 5 byte $00 ve 5 byte $FF
- İşaretçi  "E","T","E" gibi 3 veya 4 karekterden oluşan bir bilgi dizisi.
- Veri   ise  SAYI, SAYAC  gibi bir veya birkaç byte değişkeni  şeklinde olabilir.

Alıcı kısmında önce gelen veride "ETE" bilgisi varmı ona bakılır. [Wait ("ETE") ] . Yoksa daha sonra gelen veriye bakmak üzere başka işlere bakılır. Ardından SAYI,SAYAC şeklinde değişkenler yazılarak gelen bilginin bu değişkenlere aktarılması sağlanır.

Bu kuralları yerine getirirseniz haberleşme yapmanız mümkün olacaktır.
Bu arada hemen belireyim. Pic alıcı olarak çalışacak ise USART kesmesini açmanız gerekiyor.
Bunun için;
INTCON=%11000000  'ile genel kesmeleri açıyorsunuz
ON INTERRUPT GOTO KESME '   ile kesmeoluştuğunda programı KESME isimli etikete yönlendiriyorsunuz
PIE1.5=1      'yaparak  USART receive kesmesini açıyorsunuz

Programın KESME ismili etiketini de aşağıdaki şekilde düzenliyorsunuz.


DISABLE
INT:
   
    HSERIN 5,ATLA, [WAIT("ETE"),SAYI,SAYAC]  'varsa başka değişkenleri ekleyebilirsiniz. 
Atla:
    TEMP=RCREG   'bu komut kesme bayrağının sıfırlanmasını sağlamaktadır.
    Resume
    enable

Komut satırında yer alan 5 sayısı Hserin komutunun 5 ms gelecek bilgiyi bekleyeceğini ve gelmez ise ATLA isimli satıra gideceğini belirliyor.

END komutu programın istisnasız en sonuna eklenir.

Bu arada haberleşme ile ilgili define komutlarında sorun yaşadığınızı anlıyorum.
Internetten   "picmulticalc.exe" isimli bir program araştırıp bulun. Onu çalıştırınca bir çok konuda size yardımcı olacak seçenekleri olduğunu göreceksiniz.
Seçeneklerden biriside USART dır. oraya girin ve OSC hızınızı ve haberleşme hızınızı  verin karşılığında Define ayarlarını direk PBP komutları olarak  alabilirsiniz. Böylece onları direk programa yapıştırabilirsiniz.
Ben sizin için aldım ;
4 Mhz ve 9600 baud için;
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

4 Mhz ve 2400 Baud için ;
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 25  ' 2400 Baud @ 4MHz, 0,17%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

Kolay gelsin
Ete

Var ise
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

picagor

Üstadım verdiğiniz bilgiler için çok teşekkür ederim. Umarım bu projeyi sonlandırmayı başarırım. 1 hafta önce PIC konusunda sadece led yakıp söndürecek kadar şey bilirken şimdi USART kesmesi , RS232, harici EEPROM yazma okuma gibi işler yapabiliyorum.  Halen sürekli aksilikler çıksada umarım bilgi panosu işini tamamlayabilirim. Bu arada yeni konu açmadan sonraki paylaşımlarımı burdan devam ettireceğim..       Saygılar...

picagor

#9
Ana programda devam eden işler ne olursa olsun portta küçük bir uyarılmada USART kesme alt yordamına gider yazmıştınız. (tabi kod doğruysa)

Hazırladığım kodda VB den seri porta gönderilen karakterin BCD karşılığını 4 bit halinde epromun ilk 20 adresine PBP altprogramda yazıyorum. PBP Ana program ise epromun ilk 20 adresini okuyup verileri PORTD de gösteriyor.  Sorunum şu an için porttan gönderdiğim 4 bitlik veriyi devrenin her zaman yakalamaması. Bazen veriyi porttan alıp eproma yazıyor, istediğim gibi devam ediyor. Fakat arasıra kesmeye girmediği durumlar oluyor. Veriyi 10 kere üstüste gönderince sorun düzeliyor. Buda amacıma aykırı bir durum. Yada sleep süresiyle oynama yaptığımda düzeliyor.. gönder butonuna bastığım anda kesmeye bazen geçiyor bazen geçmiyor.. 

150 display için EPROMUN 150 adresine farklı textlerdeki verileri yazdırma olayıda ayrı bir sorun..

VB ile PBP arasındaki senkronizasyonu nasıl sağlamalıyım?
Video yükledim örnekte VB den önce 9 gönderdim BCD karşılık olan 1001 yazdı, 6 gönderdim 0110 yazıyor. Ama dediğim gibi her zaman kesmeye girmiyor..

Video: http://www.youtube.com/watch?v=9Kd8UcFrglg

Visual Basic kodu:

Dim giden As Integer

Private Sub Command1_Click()
   On Error GoTo Hata:
    MSComm1.CommPort = Combo1.ListIndex + 1 'COM PORTU COMBOBOXTAN SEÇ
    MSComm1.Settings = "2400,N,8,1"         'COM İLETİŞİM HIZI
    MSComm1.PortOpen = True                 'PORTU AÇ
    giden = Val(Text1.Text)                'TEXTTEKİ VERİNİN SAYI DEĞERİNİ giden değişkenine yaz
    
    'For i = 0 To 10
    MSComm1.Output = "HAKAN" & giden
    Sleep (1)
    'Next
    
    MSComm1.PortOpen = False
    MsgBox "Yükleme Tamamlandı", 64, "Bilgiler Cihaza gönderildi"
    Exit Sub
    
Hata:
    MsgBox "Yükleme Sırasında Bir Hata Oluştu", 64, "Yükleme Yapılamadı."
    Exit Sub
End Sub

Private Sub Command4_Click()

    On Error Resume Next
    MSComm1.PortOpen = False
    MSComm1.CommPort = Combo1.ListIndex + 1
    MSComm1.Settings = "2400,N,8,1"
    MSComm1.PortOpen = True
    If Err.Number = 8002 Then
        MsgBox "Geçersiz Port Numarası", 64, "Port Bulunamadı"
        Exit Sub
    End If
    
    MsgBox "Port Seçimi Başarı İle Yapıldı", 64, Combo1.Text & " Seçildi"
    MSComm1.PortOpen = False
    
    Open App.Path & "\Com.ini" For Output As #1
        Write #1, Combo1.ListIndex + 1
    Close #1
    
End Sub


Pic Basic Code:

'****************************************************************
'*  Name    : picagors7-segment_board.BAS                       *
'*  Author  : picagor                                           *
'*  Notice  : Copyright (c) 2011                                *
'*          : All Rights Reserved                               *
'*  Date    : 06.04.2011                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
'================================================= TANIMLAMALAR
@ DEVICE PIC16F877A                                                    
@ DEVICE PIC16F877A, WDT_OFF             
@ DEVICE PIC16F877A, PWRT_OFF            
@ DEVICE PIC16F877A, PROTECT_OFF        
@ DEVICE PIC16F877A, XT_OSC             

Include "MODEDEFS.BAS" 'Seri İletişim İçin Gerekli
Define OSC 4          
DEFINE I2C_SLOW 1

ADCON1 = 7
CMCON=7
TrisA=0:TrisB=0:TrisC=0:TrisC.7=1:TrisC.6=0:TrisD=0:TrisE=0
PortA=0:PortB=%00000000:PortC=0:PortD=0:PortE=0:

'====================================4 Mhz ve 2400 Baud için COM port ayarları  ;
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 25  ' 2400 Baud @ 4MHz, 0,17%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_BAUD 2400 



'=============================== EEPROM TANIMLARI
    DPIN var PortC.4            'EPROM DATA pini
    CPIN var PortC.3            'EPROM CLOCK pini
    X VAR BYTE                  'PORTD için geçici değişken
    DTA   VAR  BYTE             'EPROMA yazılacak DATA
    ADRS  VAR  WORD             'EPROM ADRESİ
    KONT	Con	%10100000	    'EPROM KONTROL KODU
	
'============================================================
    gelendata var byte
'============================== USART KESME TANIMLARI
    
'SYMBOL GIE  =INTCON.7   'genel interruptları açıyor     'sonradan ekledim
'SYMBOL PEIE =INTCON.6   'peripheralinterruptları açıyor                 'sonradan ekledim
'SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit  'sonradan ekledim
'SYMBOL RCIF =PIR1.5     'USART Receive interrupt flag bit 'sonradan ekledim
'RCIE=1  'sonradan ekledim
'PEIE=1  'sonradan ekledim
'GIE=1   'sonradan ekledim
 INTCON.7=1
 INTCON.6=1
 PIE1.5=1

ON INTERRUPT GoTo COMPORTOKU 			
'===============================ANA PROGRAM BAŞLANGICI
    anaprogrambasla:
    
        PIE1.5=1
        portb.2=1
        pause 250
        portb.2=0
        pause 250
'================================= EPROM OKU
ADRS=0 '2 alttaydı
E_OKU: 	
FOR ADRS=0 TO 19  '$19 E KADAR TÜM ADRESLERİ OKU
       
       I2CREAD DPIN, CPIN, KONT, ADRS, [X]'EPROMDAKİ VERİYİ OKU X e KAYDET
       PORTD=X                            'PORTB DE X i GÖSTER
       PAUSE 50
       PORTD=$00
       PAUSE 50
       NEXT ADRS      'SONRAKİ ADRESİ OKU
goto anaprogrambasla
'=================================USART KESMESİ ALTPROGRAMDA EPROMA VERİ YAZILACAK
DISABLE

COMPORTOKU:
       
       
       
       
       HSERIN 300,ATLA,[WAIT ("HAKAN"),gelendata]
       'HSERIN [WAIT ("HAKAN"),gelendata]
   'porttan gelen seri bilgilerin içinde HAKAN stringinden sonra gelen 8 bitlik datayı
   'gelendata değişkenine ata
     
'========================================='EPROMU YAZ
       ADRS=0      
       E_YAZ:  
       DTA=gelendata
       I2CWRITE DPIN,CPIN,KONT,ADRS,[DTA] 'HER HÜCREYE AYNI DATAYI YAZ..
       ADRS=ADRS+1
       Pause 10
       IF ADRS<20 THEN                    '10. ADRESE KADAR aynı veriyi yaz.. 
       GOTO E_YAZ
       ENDIF 
'================================= YAZILDIĞINA DAİR LEDE FLASH YAPTIR           
       PORTB.1=1
       PAUSE 50
       PORTB.1=0
       PAUSE 50        
       PORTB.1=1
       PAUSE 50
       PORTB.1=0
       PAUSE 50  
       PORTB.1=1
       PAUSE 50
       PORTB.1=0
       PAUSE 50          '
                
                 
Atla:         '300ms içinde veri girişi olmazsa ana programa dön 
    'RCIF=0   'sonradan ekledim
    'GIE=1    'sonradan ekledim 
    PIE1.5=0   'bu komut kesme bayrağının sıfırlanmasını sağlamaktadır.
    Resume
    enable
END   



Ruzgarbey

anaprogramda   pause 250  komutu kullanmışsınız. PBP pause komutlarında genellikle Kesme işlemine giremiyor maalesef.
pause komutu yerine bir döngü kullanıp gecikme sağlamalısınız.
comoku kesmesinde eeprom yazma komutlarından sonra pause 10  komutu kullanmışsınız. kesme içerisinde pause komutu kullanılmaması tavsiye edilir. gecikme komutuna ihtiyacınız var ise bu ihtiyacınızı bir daha kesme gelme süresi kadar ayarlamalısınınz.

harici eeprom yazmalarında yazma işlemi epproma göre değişerek en az 5 ms sürmektedir. bu yazma süresini datasheete bakarak görebilirsiniz. tüm bunları dikkate aldığınızda yapılması gerekenler şöyledir.

1:)  anaprogramdaki pause 250 komutu yerine gecikme döngüsü kurmak
2:)  comoku kesme alt programındaki pause 10 komutunu kaldırmak.
3:) eeprom yazma zamanını 10ms olarak ele alarak  VB programınızda veri gönderme kısmında preamble verisi dışındaki verileri 11ms aralıklarla göndermek.

bütün bunları yaptıktan sonra sorununuz çözülecektir.saygılarımla.
Hayatta En Hakiki Mürşid İlimdir. M.K. ATATÜRK

ete

Rüzgarbey'in de açıkladığı gibi bütün pause komutlarını kaldırman gerekiyor. Gecikme gerekiyor ise;
For I=o to 255
   Pauseus 5
next
şeklinde veya daha büyük deöngüler kurarak alt program şeklinde gecikme sağlayabilirsin.
Bu işde temel mantık he rbir puse komutunun 1-5 us den fazla olmaması. Bu sana en fazla 5us lik bir gecikme ile kesme etiketine dallanmayı sağlar. Aksi halde direk pause kullanırsan verilen gecikme bitmeden kesmeye gidemezsin. Bu ise alıncak verinin kaçmasına sebep olur.

Kesme kısmındaki gecikmelerin zararı olmayacağını düşünüyorum. Çünki zaten kesme içindesin ve oradaki gecikmelerin veri almaya etkisi olmayacaktır. Ancak arka arkaya yollanan verilerde kaybın olabilir.

Diğer bir kusur da kesme etiketi içinde kesme bayrağının sıfırlanması olayı eksik kalmış. USART kesme bayrağı RCIF yazılabilir bir register değildir. Ancak RCREG registerinin bir değişkene aktarılması ile bayrak sıfırlanır.  Bu nedenle Hserin ile okuma yapıldıktan sonra
TEMP=RCREG şeklinde bir satırı heserinden sonra programa ilave etmen uygun olacaktır.
Eproma yazma işlemini ana program döngüsü içinde de yapabilirsin. Bence en kısa sürede kesme kısmından çıkman yeni gelecek verilerin sağlıklı alınabilmesi için en doğrusudur.  Bu nedenle kesme kısmını aşağıdaki gibi yapsan iyi olur.

DISABLE
INT:
    GIE=0
    hSerIn 5,atla , [WAIT("HAKAN"),gelen] 
     Alındı=1
ATLA:
    TEMP=RCREG
    GIE=1
    Resume
    enable
Geçerli bir veri gelmiş ise ALINDI=1 şeklinde bir bit değişkenini set et ve ana program kısmında;
IF ALINDI=1 then
    eproma yaz
   flash yaptır
   ALINDI=0
endif
şeklinde bir kod ile istediklerini yapabilirsin. Böylece hem kesme kısmını meşgul etmemiş olursun hemde boş zaman değerlendirmesi yapmış olursun.

Diğer bir konuda Timeout süresini 300 ms girmişsinki bana çok fazla geldi . Ben genelde 5 ms kullanırım. Heleki tek verilik bir alımda 3 ms bile kullanabilirsin. Bu süreyide kısaltmanda yarar vardır. Yukardaki örnekte 5 ms olarak yazdım.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

Ruzgarbey

Merhaba ETE hocam. arkadaşın yazdıklarından anladığım kadarı ile seri porttan 20 bytelik veri alıp bunu eeproma yazıyor. ve ana program içinde eeprom okuyup ona göre işlem yapıyor.
Kesme içinde pause kullanma dememim sebebi şudur. arkadaşımız kesme alt programında 10 ms lik bir pause kullanmış. yazmış olduğu VB programda ise bu gecikmeleri hesaplayıp bekleme yapan bir kod maalesef yok.dolayısı ile dataları yakalamasına imkan yok.
Her seferinde Preamble kodu göndermenize gerek yok.
if kontrol=1 then
hserin[veri]
eeprom yaz
....
....
....
....
if veri=253 then Kontrol=0  'gönderilecek veri bitti. değişkenleri sıfırlayıp yeni kesme gelmesine hazırlan.
else
HSERIN 5,ATLA, [wait ("HAKAN"),veri]
if veri=254 then Kontrol=1
end if

dediğim gibi VB programınızda Eeprom yazma gecikmesini hesaplayıp iki veri arasında bekleme yapın. saygılarımla..
Hayatta En Hakiki Mürşid İlimdir. M.K. ATATÜRK

picagor

#13
Her iki arkadaşımında açıklamaları için çok teşekkürler.. Çok fazla hesap kitap yapmadan şu anda EEPROMA yazma zamanını optimum süreye almayı başardım. Visual basic tarafındaki
MSComm1.Output = "HAKAN" & giden     
           Sleep (1)

kodunda şöyle bir değişiklik yaptım. Sleep fonksiyonunu kullanmadım. Seri portu uyandırma ya da Start bitimidir artık tam bilmiyorum ilK gönderilen string bilgisini her iki yazılımda da  "A" yaptım. Düzeldi. Şimdi anaprogramda pause kullansam dahi kesmeye giriyor.

MSComm1.Output = "A" & giden     
           


Sayın Erol Tahir hocaya amacımdan bahsetmiştim Rüzgarbey arkadaşım. Amacım 150 displaylik (7-seg com katot) RS232 Kontrollü Fiyat panosu yapmak. Tarama kullanmadan 74595 leri seri yapıp tümünü sürmek istiyorum. Verilerin EPROMDA Kalmasını amaçlıyorum.

Adım adım gidiyorum ve yine kafanızı ağrıtacak sorularım var.. :

1) Visual basic tarafındaki forma her bir rakam için 150 adet textbox yerleştirdim diyelimki. Bu textboxların içindeki tüm sayıları 8 er bitlik halde tek çevrimde Devreme gönderirsem sorun çıkarmı? Ya da nasıl göndermeliyim?
Şöyle bi VB kodu yazdım dün:
Private Sub Command1_Click()
   On Error GoTo Hata:
    MSComm1.CommPort = Combo1.ListIndex + 1 'COM PORTU COMBOBOXTAN SEÇ
    MSComm1.Settings = "2400,N,8,1"         'COM İLETİŞİM HIZI
    MSComm1.PortOpen = True                 'PORTU AÇ
    giden1 = Val(Text1.Text)
    giden2 = Val(Text2.Text)
    giden3 = Val(Text3.Text)
    giden4 = Val(Text4.Text)
    giden5 = Val(Text5.Text)
    MSComm1.Output = "A1" & giden1 & "A2" & giden2 & "A3" & giden3 & "A4" & giden4 & "A5" & giden5
    MSComm1.PortOpen = False
    MsgBox "Yükleme Tamamlandı", 64, "Bilgiler Cihaza gönderildi"
    Exit Sub


Pic basic tarafında ise kesme alt programı için:

COMPORTOKU:
      HSERIN 300,ATLA,[WAIT ("A1"),gelendata1, WAIT ("A2"),gelendata2,WAIT("A3"),gelendata3,WAIT("A4"),gelendata4,WAIT("A5"),gelendata5]
       
   'porttan gelen seri bilgilerin içinde "A" stringinden sonra gelen 8 bitlik datayı
   'gelendata değişkenine ata
     
'========================================='EPROMU YAZ
       E_YAZ: 
       ADRS=1      
       DTA=gelendata1
       I2CWRITE DPIN,CPIN,KONT,ADRS,[DTA]
       Pause 10
       ADRS=2      
       DTA=gelendata2
       I2CWRITE DPIN,CPIN,KONT,ADRS,[DTA]
       Pause 10
       ADRS=3      
       DTA=gelendata3
       I2CWRITE DPIN,CPIN,KONT,ADRS,[DTA]
       Pause 10
       ADRS=4      
       DTA=gelendata4
       I2CWRITE DPIN,CPIN,KONT,ADRS,[DTA]
       Pause 10
       ADRS=5      
       DTA=gelendata5
       I2CWRITE DPIN,CPIN,KONT,ADRS,[DTA] 
       Pause 10


kodlarını çalıştırdım. Bir fiyat panosu yılda en fazla 1-2 kez programlanacağı için kesmeye girme süresi aslında çokta mühim değil.

EDİT: Mikrosaniye cinsinden 3 kere Döngü kurdum bunuda başka bir döngü ile 30 kez tekrarlattım kesmeye girişte hiçbir problem kalmadı . Teşekkürler ETE & Rüzgarbey

Fakat şimdiki sorunum

Text1.Text deki bilgiyi EPROMUN --->1. adresine
Text2.Text deki bilgiyi EPROMUN --->2. adresine
Text3.Text deki bilgiyi EPROMUN --->3. adresine
.......
Text150.Text deki bilgiyi EPROMUN --->150. adresine yazmak.

En son hazırladığım kodlar ile bu iş ya olmaz , ya da program hafızası bu işe yetmez sanırım. PBP tarafında porttan gelen 150 byteı  bir kerede alıp her byteı ayrı ayrı adreslere yazacak bir döngü yapısı kurmam lazım.  Bu konuyu nasıl halledebilirim?

2) Kullandığım işlemci 16F877A 04-I/P   
Pic Programlayıcım Microchip marka USB, üzerinde 40 Pin Zif soketi ve ayrıca 5 pin çıkışı var. Pin isimleri Vpp, GND, Vdd, Data ve Clock .
Bu işlemciyi in system programming modunda nasıl kullanabilirim? Defalarca yerine takıp çıkarmaktan bozulacak..



picagor

ETE Hocam önceki mesajdaki 1. sorunu gidermek üzereyim sanırım ama şurada takılı kaldım:

       E_YAZ: 
         for ADRS=1 TO 15
                DTA=gelendata(ADRS)           ' bu satırda takılı kaldım
                I2CWRITE DPIN,CPIN,KONT,ADRS,[DTA]
               Pause 5       
         NEXT ADRS 


gelendata1, gelendata2,.... gelendata15 e kadar byte tipinde değişkenim mevcut

3. satırdaki doğru yazım formatı nasıldır? 

DTA=gelendata[ADRS]            ?

DTA=gelendata&"ADRS"         ?

DTA="gelendata";(ADRS)       ?