PCF8574

Başlatan eeburakdemir, 07 Mart 2016, 12:28:20

eeburakdemir

Arkadaşlar merhaba. Pic16f877 ' e aynı sda ve scl hattına 2 tane pcf8574 bağladım. Kodu paylasıyorum arkadaşlar. Sorunum okuma yaptığım birinci pcf ' den interrupt alıyorum ve bunu görebiliyorum. Fakat ikinci pcf'ye yazdıramıyorum. Sizce sorun ne olabilir. Datasheet de ne istiyorsa aynısını yaptım. Açıklama satırlarına takılmayın , okadar çok denedim ki , insanların yazdıklarını dahi mix yaptım yine de bana mısın demiyor 
Saygılar.


#include <16F877.h>  

#FUSES NOWDT, XT, NOPUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG  

#use delay(clock=20000000)

#use i2c(master,sda=pin_C4,scl=pin_C3,slow=100000)  



#define PCF8574_WRITE_ADDRESS 0x40 
#define PCF8574_READ_ADDRESS 0x4F 

#define TEST_LED PIN_A0 

int8 data;                 // Byte received from PCF8574 
int1 PCF8574_int_flag = 0; 

#INT_EXT 
void ext_int_isr(void) 
{ 
   PCF8574_int_flag = 1; 
   clear_interrupt(INT_EXT);
} 

void main(void) 
{ 

   set_tris_a(0b00000000);
   output_a(0); 

   ext_int_edge(H_TO_L); 
   clear_interrupt(INT_EXT);      // Added. Clear flag. 
   enable_interrupts(INT_EXT); 
   enable_interrupts(GLOBAL); 
    
   // Configure PCF8574 pins as inputs. Defaults to inputs on power-up, 
   // but do anyway. 
    
   
    
   // Get and display current switch state 
   // The read also resets the interrupt logic of the PCF8574 
    
   i2c_start(); 
   i2c_write(PCF8574_READ_ADDRESS); 
   data = i2c_read(0);  // First byte is also last so NACK 
   i2c_stop(); 
    
   // Display state of switch on PCF8574 pin P0 
    
   if(bit_test(data,0)) 
      output_bit(TEST_LED,1); 
      
   else output_bit(TEST_LED,0); 
    
    
   while(1) 
   { 
      // If switch state has changed read PCF8574 port 
      
      if (PCF8574_int_flag) 
      { 
         PCF8574_int_flag = 0;   // Clear for next time 
          
         i2c_start(); 
         i2c_write(PCF8574_READ_ADDRESS); 
         data = i2c_read(0);     // First byte is also last so NACK 
         i2c_stop(); 
          
         // Display state of switch on PCF8574 pin P0 
          
         if(bit_test(data,0)) 
            output_bit(TEST_LED,1); 
            
         else output_bit(TEST_LED,0); 
         
         
         i2c_start(); 
         i2c_write(PCF8574_WRITE_ADDRESS); 
         i2c_write(0x00);     // Set all pins as inputs 
         i2c_stop();
         
         
      } 
   } 
}
Asla pes etme...

DaRt

Okunan pcf8574 ün a0, a1 ve a2 pinleri vcc ye bağlanmalı, okunduğuna göre bunu yapmışsınız. Yazılan pcf8574 ün ise a0, a1 ve a2 bacakları gnd ye bağlanmalı. Bunu yaptıysanız yazdığınız değeri 0dan farklı bir değer verip deneyin. Bir de pcf8574a adresi farklı. Belki elinizdeki çipler birbirinden farklıdır.

dursuncemal

#2
daha once hic kulamadimn ama anladigim kadari ile  ao ile a2  pinleri ciplerin adres pinleri dolayisi ile cikis yapacagin cipin adresi ile giris yapacagin cipin adresinin bu pinlrerden ayarlaman  ayarlaman gerekiyor.  buraya bir bak kesin cozersin zor bir kompenant diil

http://garagelab.com/profiles/blogs/tutorial-arduino-i-o-port-expander-with-pcf8574

mesaj birleştirme:: 07 Mart 2016, 18:35:09

#define PORT_BASE_ADDRESS 0x40 


unsigned char read_from_port(); 
void write_to_port(unsigned char data_byte); 


unsigned char read_from_port() 
{ 
    unsigned char port_byte=0; 
    i2c_start();                              
    i2c_write((PORT_BASE_ADDRESS + 1));        
    port_byte=i2c_read(0);              
    i2c_stop(); 
    return port_byte; 
} 
                                                

void write_to_port(unsigned char data_byte) 
{ 
    i2c_start(); 
    i2c_write(PORT_BASE_ADDRESS); 
    i2c_write(data_byte); 
    i2c_stop(); 
}
:=

eeburakdemir

#3
@DaRt hocam , peki zorunlu mu okuduğumuz entegrenin a0 - a1 - a2 bacakları vdd ye bağlanmaya ? çünkü datasheet de baktığımızda olabilcek durumlara göre adres değerleri yazıyor. Ayrıca ben okudum diyorum ama , entegrenin datasheetinde int verdikten sonra int tekrar eski haline gelmesi gerekiyor ama benimki gelmedi. İnt pull-up yaptım çunku datasheetinde typicial app kısmında nasıl yaptıysa oyle kurdum devreyı. Hatta sda ve int bacaklarına 15pf bile koydum , ama int geliyor ve kalıyor. Taki girişi yenileyinceye kadar. Diğer sorum da şu. Bu entegrede giriş geldiğinde girişler yenilenmez ise int kendini yenilemiyor mu. Ayrıca değer okduğumu da int içinde led e blink yaptırarak gördüm. Yarın okuduğum değeri direk portlara vereceğim. Hocam siz bu entegreyi kullandınız mı daha önce ? 

mesaj birleştirme:: 07 Mart 2016, 21:01:48

@dursuncemal hocam valla sabahtan beri uğraştım ama göründüğü  gibi değil. Çiplerimiiz pcf8574p yani a seriside değil. onların farklı olduğuunu biliyorum ama , sizlere de danışmak istedim.
Asla pes etme...

Murat Mert

elinizde hazırda yoksa mcp23017 veya 23s17 kullansanız.
mert07

DaRt

i2ecprom kullanmak gibi. Aynı i2c hattında 8 adet pc8574 kullanabilmeniz hatta, 8 tanesi pc8574 8 tanesi pc8574a olmak üzere 16 tane kullanmanız için adres bacaklarını bağlamalısınız. Bu bacaklar 3 bit toplam 8 değer alır. Sizin programınızda aynı hatta 2 adet kullanılmış. Yazdığınız verilerin hangisine gittiğini bilmesi için gerekli bu bacaklar. Yoksa yazdığınız veri ikisine de gitmez. Şimdi Programınızda

#define PCF8574_WRITE_ADDRESS 0x40
#define PCF8574_READ_ADDRESS 0x4F

satırları okunacak ve yazılacak entegreyi belirler. adresin ilk 4 biti 0b0100 hattaki pc8574lere veri gönderir. Ancak birden fazla varsa hangisine gönderdiğimiz henüz belli değildir. Ardından yazdığımız 3 bit (sizin programınızda okunacak 0b111, yazılalak 0b000) hangi entegre ile iletişim kuracağınızı belirler. Yazdığınız değer tüm entegrelere gider, gelen adres verisinin 3 biti ile, entegrenin bacaklarının 3 biti aynı ise verinin kendine geldiğini anlayıp ack üretir. İletişim başlar. Siz hiçbir bacağı bağlamazsanız entegreler gelen i2c adres verisi ile bacaklara bağlı veriyi karşılaştıramaz ve verinin kendine geldiğini anlayamaz. Aynı hatta bağlı i2c eprom gibi. Entegreyi daha önce kullanmadım, interrupt nasıl oluşur, nasıl silinir bilmiyorum. temel mantığı anlatıyorum. Ayrıca programınızda ledin yanması sorunsuz olarak i2c verisi aldığınız anlamına gelmez. Devrenin fotoğrafını eklerseniz sorunu daha kolay çözeriz.

eeburakdemir

#6
@Murat Mert hocam aldık onuda yarın deneyceğiz. İnşallah sıkıntısı olmaz

mesaj birleştirme:: 07 Mart 2016, 23:29:42

@DaRt hocam devre kurmadık deneme aşamasındayız da , 20metreden haberleşme yapacağız. RS485 kullanalım dedik olmadı can bus. Girşlerimizi okumak için kullanacağım bu entegreyi.
Asla pes etme...

dursuncemal

Alıntı yapılan: eeburakdemir - 07 Mart 2016, 21:00:21
@DaRt hocam , peki zorunlu mu okuduğumuz entegrenin a0 - a1 - a2 bacakları vdd ye bağlanmaya ? çünkü datasheet de baktığımızda olabilcek durumlara göre adres değerleri yazıyor. Ayrıca ben okudum diyorum ama , entegrenin datasheetinde int verdikten sonra int tekrar eski haline gelmesi gerekiyor ama benimki gelmedi. İnt pull-up yaptım çunku datasheetinde typicial app kısmında nasıl yaptıysa oyle kurdum devreyı. Hatta sda ve int bacaklarına 15pf bile koydum , ama int geliyor ve kalıyor. Taki girişi yenileyinceye kadar. Diğer sorum da şu. Bu entegrede giriş geldiğinde girişler yenilenmez ise int kendini yenilemiyor mu. Ayrıca değer okduğumu da int içinde led e blink yaptırarak gördüm. Yarın okuduğum değeri direk portlara vereceğim. Hocam siz bu entegreyi kullandınız mı daha önce ? 

mesaj birleştirme:: 08 Mart 2016, 11:01:48

@dursuncemal hocam valla sabahtan beri uğraştım ama göründüğü  gibi değil. Çiplerimiiz pcf8574p yani a seriside değil. onların farklı olduğuunu biliyorum ama , sizlere de danışmak istedim.

burda giris yenilenene kadar int degismiyor demissiniz.olmasi gereken de bu zaten yani giris degisince yeni bir int gelmeli.yanlis anlamadi isem.
:=

Murat Mert

Sn. eeburakdemir 20 mt den I2C mi haberleşeceksin yoksa canbus mu ?
mert07

Murat Mert

Değişiklik yaparak bir deneme yaptım isiste  çalışıyor.

bu arada code butonu çalışmadı.

#include <18F45K22.h>
#device ADC=10
#use delay(internal=32000000)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)

#define YAZMA_KOMUTU 0b01000000
#define OKUMA_KOMUTU 0b01000001

unsigned char port_oku();
void port_yaz(unsigned char data,int adres);
int say=0;

unsigned char port_oku(int adres)
{
     unsigned char data_oku=0;
     i2c_start();                             
     i2c_write(OKUMA_KOMUTU|adres<<1);       
     data_oku=i2c_read(0);             
     i2c_stop();
     return data_oku;
}
                                                 
void port_yaz(unsigned char data,int adres)
{
     i2c_start();
     i2c_write(YAZMA_KOMUTU|adres<<1);
     i2c_write(data);
     i2c_stop();
}

void pcf_init()
{
   port_yaz(0,4);//çıkış olacak olan IC
   delay_ms(2);
   port_yaz(0,7);//çıkış olacak olan IC
}

void main()
{
   pcf_init();
   while(TRUE)
   {
   say=port_oku(0);
   delay_ms(2);
   port_yaz(say,7);
   delay_ms(2);
   port_yaz(say,4);
   delay_ms(2);
   }

}
mert07

eeburakdemir

#10
@Murat Mert hocam rs485 kullancağız. Ama bugun mcp23017 ile bu okuma işini halllettik. anca cevap yazabildim kusura bakmayın. ayrıca ilgilenmeniz içinde çok teşşekkür ederim.

mesaj birleştirme:: 09 Mart 2016, 09:30:20

@dursuncemal hocam anca yazabildim. ilginize teşekkür ettim, bahsettiğim gibi hallettik sorunu ama bu entegreyi çözmek ve haberleşmek farz oldu.
Asla pes etme...

Murat Mert

S.A.
mcp23017 serisini okumak ve yazmak kolay ve pcf den ucuza geliyor tek adreste16 pin io ve girişi high yada low giriş olarak ayarlayabiiyorsun vs.. vs..
canbus bilgim yok ama denemelerim oldu çok hoşuma gitti. 485 gibi data kontrolü, doğruluk kontrolü vb.. şeylerle uğraşmıyorsun al gülüm ver gülüm. IO kontrolü için ideal gibi.
mert07

eeburakdemir

anladım hocam , peki 40 metreden haberlşemede özellikle motorların olduğu yerlerden geçecek gibi duruyor ama tam olarak nerden geçireceğiz kesin değil. Benim korkum gürültü ve parazit olması.
Asla pes etme...

Murat Mert

S.A.
Antalya da bir tekstil firmasına dikiş makinalarının bulunduğu masalara üretim sayısının kontrolü için otomasyon yapmıştık. Haberleşme kabloları tavanda atölyeyi besleyen ana besleme ve diğer motorları kontrol eden kabloların arasından gidiyordu. kablo ekranlı kablo yada zırhlı kablo olarak isimlendirilen 2x1,5 lıycy kablo ile çekmiştim.
mert07

dursuncemal

Alıntı yapılan: eeburakdemir - 08 Mart 2016, 19:29:27
@Murat Mert hocam rs485 kullancağız. Ama bugun mcp23017 ile bu okuma işini halllettik. anca cevap yazabildim kusura bakmayın. ayrıca ilgilenmeniz içinde çok teşşekkür ederim.

mesaj birleştirme:: 09 Mart 2016, 09:30:20

@dursuncemal hocam anca yazabildim. ilginize teşekkür ettim, bahsettiğim gibi hallettik sorunu ama bu entegreyi çözmek ve haberleşmek farz oldu.
su birkac gun yogunlugum var piyasadan bulabilinen bir sey ise alip dener yazarim buraya
:=