8255 Sorunu

Başlatan NaMcHo, 05 Ağustos 2010, 14:13:37

NaMcHo

8255'in A portuna bagladıgım 8 ledi yakmak istedim,fakat once hızlıca tum ledler yanıp sonuyor sadece 7.pindeki led yanık kalıyor.
Isis dosyası :http://hotfile.com/dl/59959435/301663a/8255deneme.rar.html
#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NODEBUG,NOLVP,NOCPD,NOPUT,NOWRT
#use delay(clock=4MHz)
#use fast_io(b)
#use fast_io(a)

int1 x=1;
void main(void)
{
   setup_psp(psp_disabled);
   setup_timer_1(t1_disabled);
   setup_timer_2(t2_disabled,0,1);
   setup_adc_ports(no_analogs);
   setup_adc(adc_off);
   setup_ccp1(ccp_off);
   setup_ccp2(ccp_off);
   
   set_tris_b(0);    
   set_tris_a(0);   
   
               
   output_a(0b00001101);    //PortD ye yazma secildi.
   delay_ms(50);
   output_b(0b10000000);   //8255 de tüm pinler çıkış
   delay_ms(50);
   output_a(0b00000001);   //A portuna yazma secildi.
   delay_ms(50);
   while(1)
   {  
      if(x==1){   
      output_b(0);                //8255 A portu 1 defalığına sıfırlanıyor.
      x=0;}
      output_b(0b11111111); //8255 deki A portundaki 8 ledin yanması gerekiyor.
   }
  
}


Birde CCS C İLE PİC PROGRAMLA kitabındada bununla ilgili bir ornek duzgun calısmıyor onuda yolluyayım.
http://hotfile.com/dl/59959673/f879c81/8255_le_Port_Kontrol_Uygulamas.rar.html

Sorun kodlardanmı,devre kurumundanmı yoksa isi de 8255 düzgün calısmıyormu?

JKramer

#1
Okuma-yazma kısmı karışmış. Kataloğa bakarsanız (Intel, üçüncü sayfa) a,b ve c olmak üzere üç adet port var. D ile kastedilen data bus portu. İlgili portun veri yoluna bilgi yollamak için RD biti 0, WR biti 1 olmalı. Daha sonra ilgili portun veri yolunda bulunan bilgiyi porta göndermek istiyorsak önce RD bitini 1, WR bitini 0 yapmalıyız. Bu tip işlemlerde karışıklığı önlemek için #define direktifiyle ilgili bitleri tanımlamak faydalıdır. Bunun dışında size şöyle bir kod yazdım:
#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NODEBUG,NOLVP,NOCPD,NOPUT,NOWRT
#use delay(clock=4MHz)
#use fast_io(b)
#use fast_io(a)

#define RD PIN_A0
#define WR PIN_A1
#define A0 PIN_A2
#define A1 PIN_A3


enum {READ,WRITE}x8255_action;
enum {XPORT_A,XPORT_B,XPORT_C}x8255_port;

void x8255(x8255_action,x8255_port)
{
   if(x8255_action==READ)
   {
      output_low(RD);
      output_high(WR);
   }
   else //WRITE
   {
      output_high(RD);
      output_low(WR);
   }
   switch(x8255_port)
   {
      case XPORT_A:
         output_low(A0);
         output_low(A1);
         break;
      case XPORT_B:
         output_high(A0);
         output_low(A1);
         break;
      case XPORT_C:
         output_low(A0);
         output_high(A1);
         break;
   }
}

void main(void)
{
   setup_psp(psp_disabled);
   setup_timer_1(t1_disabled);
   setup_timer_2(t2_disabled,0,1);
   setup_adc_ports(no_analogs);
   setup_adc(adc_off);
   setup_ccp1(ccp_off);
   setup_ccp2(ccp_off);
   
   set_tris_b(0);
   set_tris_a(0);
   output_b(0b00000100);
   x8255(WRITE,XPORT_A);
   
   for(;;)
   {  

   }
}

NaMcHo

#2
Alıntı yapılan: JKramer - 05 Ağustos 2010, 14:54:41
Okuma-yazma kısmı karışmış. Kataloğa bakarsanız (Intel, üçüncü sayfa) a,b ve c olmak üzere üç adet port var. D ile kastedilen data bus portu. İlgili portun veri yoluna bilgi yollamak için RD biti 0, WR biti 1 olmalı. Daha sonra ilgili portun veri yolunda bulunan bilgiyi porta göndermek istiyorsak önce RD bitini 1, WR bitini 0 yapmalıyız. Bu tip işlemlerde karışıklığı önlemek için #define direktifiyle ilgili bitleri tanımlamak faydalıdır. Bunun dışında size şöyle bir kod yazdım:
#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NODEBUG,NOLVP,NOCPD,NOPUT,NOWRT
#use delay(clock=4MHz)
#use fast_io(b)
#use fast_io(a)

#define RD PIN_A0
#define WR PIN_A1
#define A0 PIN_A2
#define A1 PIN_A3


enum {READ,WRITE}x8255_action;
enum {XPORT_A,XPORT_B,XPORT_C}x8255_port;

void x8255(x8255_action,x8255_port)
{
   if(x8255_action==WRITE)
   {
      output_low(RD);
      output_high(WR);
   }
   else //READ
   {
      output_high(RD);
      output_low(WR);
   }
   switch(x8255_port)
   {
      case XPORT_A:
         output_low(A0);
         output_low(A1);
         break;
      case XPORT_B:
         output_high(A0);
         output_low(A1);
         break;
      case XPORT_C:
         output_low(A0);
         output_high(A1);
         break;
   }
}

void main(void)
{
   setup_psp(psp_disabled);
   setup_timer_1(t1_disabled);
   setup_timer_2(t2_disabled,0,1);
   setup_adc_ports(no_analogs);
   setup_adc(adc_off);
   setup_ccp1(ccp_off);
   setup_ccp2(ccp_off);
   
   set_tris_b(0);    
   set_tris_a(0);
   x8255(WRITE,XPORT_A);
   output_b(0b00001110);
   x8255(READ,XPORT_A);
   /*x8255(WRITE,XPORT_B);
   output_b(0b00000001);
   x8255(READ,XPORT_B);
   x8255(WRITE,XPORT_C);
   output_b(0b10000000);
   x8255(READ,XPORT_C);*/
   for(;;)
   {  

   }
}


Bir kaç sorum olucak:
   x8255(WRITE,XPORT_A);             
                                           Şunu yazdıkdan sonra   

   if(x8255_action==WRITE)
   {
      output_low(RD);
      output_high(WR);
   }                                            Burdaki if aktif oluyor ve yazma modu seçilmiş oluyor. Daha sonra    XPORT_A  verisi ilede 8255 in A portu seciliyor. (case XPORT_A:output_low(A0);output_low(A1); ) sonra output_b(0b00001110); komutu  ile ise 16f877 nin  B portundan Data bus'a(8255 in D PORTUNA) bu bilgi gonderiliyor buda 8255 in A portuna gidicek veri oluyor.

x8255(READ,XPORT_A);  aynı şekilde okuma iş, içinde else kısmı işlem görüp daha sonra y=input_b(); fonksiyonu ile A portundan okunan değer ise y değişkenine alınabiliyor. Doğrumu anlaşım yazdığınız kodu?

Birde benim indirdiğim 8255 Datasheetinde şöyle yazıyordu :
-READ: Read is an active low input control signal used by the CPU to read status
information or data via the data bus.
-WRITE: Write is an active low input control signal used by the CPU to load control
words and data into the 82C55A.


Yani eger ben yazma seciceksen yazmanın low read seciceksem read in low olması gerektiği yazıyor burdada.
Sizdeki kaynak dosyayı buraya ekleyebilirmisiniz.Sanırım benim indirdiğimde hata var.
Bendeki Datasheet: http://hotfile.com/dl/59980531/f75bbce/8255_DS.rar.html

JKramer

#3
Aynen dediğiniz gibi, ben ters yazmışım. WRITE yerine READ yazarak düzeltebilirsiniz:
if(x8255_action==READ)
{
   output_low(RD);
   output_high(WR);
}       


Gönderdiğiniz katalog bendekiyle uyuşuyor.

Ekleme:

Şimdi simulasyonda denedim, aceleyle bir hata daha yapmışım, önce pic_portb'ye yazıp daha sonra 8255 yazma komutunu vermek gerekiyormuş. İlk mesajı düzenliyorum.

NaMcHo

#4
Denedim en son anladığım şekilde ve RD WR terslemesinden sonra ama
x8255(WRITE,XPORT_A);    Bunu yazıkdan sonra
   output_b(0b00001101);   Data bus a ne gönderirsem gönderiyim herzaman ilk 3 led ve sondaki led yanıyor.

output_b(0b11111111);  de yazsam ilk 3 ve sonuncu led yanıyor.

Son Düzeltme ile Isis dosyası,Cof,ve C dosyaları : http://hotfile.com/dl/59985827/e3e7ab5/8255denemeyeni.rar.html

Not : Tersleme yapmadan öncede ilk 3 ve sonuncu led yandı ilgiç bi şekilde Read modunun aktif olmasına rağmen.normalde hic bir ledin yanmaması gerekmezmiydi?

#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NODEBUG,NOLVP,NOCPD,NOPUT,NOWRT
#use delay(clock=4MHz)
#use fast_io(b)
#use fast_io(a)

#define RD PIN_A0
#define WR PIN_A1
#define A0 PIN_A2
#define A1 PIN_A3


enum {READ,WRITE}x8255_action;
enum {XPORT_A,XPORT_B,XPORT_C}x8255_port;

void x8255(x8255_action,x8255_port)
{
   if(x8255_action==WRITE)
   {
      output_low(WR);
      output_high(RD);
   }
   else //READ
   {
      output_high(WR);
      output_low(RD);
   }
   switch(x8255_port)
   {
      case XPORT_A:
         output_low(A0);
         output_low(A1);
         break;
      case XPORT_B:
         output_high(A0);
         output_low(A1);
         break;
      case XPORT_C:
         output_low(A0);
         output_high(A1);
         break;
   }
}

void main(void)
{
   setup_psp(psp_disabled);
   setup_timer_1(t1_disabled);
   setup_timer_2(t2_disabled,0,1);
   setup_adc_ports(no_analogs);
   setup_adc(adc_off);
   setup_ccp1(ccp_off);
   setup_ccp2(ccp_off);
   
   set_tris_b(0);   
   set_tris_a(0);
   x8255(WRITE,XPORT_A);
   output_b(0b11111111);

}
Kodun son hali.Gerci burda B ve C yi yazmama gerek yoktu ama dursunlar zararı yok :)

JKramer

x8255(WRITE,XPORT_A);
output_b(0b11111111);

Bu satırlar yer değiştirecek:
output_b(0b11111111);
x8255(WRITE,XPORT_A);


Daha önce hiç kullanmamıştım, kataloğun alt sayfalarına göz gezdirdim de bir sürü özelliği varmış :).

NaMcHo

#6
Teşekkürler tamamdır  ;)
Birde sormak isterim nasıl anladığınızı Gönderilcek verinin önce yazılması gerektiğini.:)
Mantıken önce yapcak oldugumuz işi belirtmemiz sonrada eğer veri yazıcaksak yazılacak veriyi göndermemizdir bence

Birde ben okumayla ilgilide bir deneme yapıyım sorun olursa aynı başlık altında belirteyim.

JKramer

#7
Simulasyonda pic portlarının 8255 portlarından farklı olduğunu görünce bir şeylerin ters olduğunu anladım :D. Aslında olay kataloğu doğru düzgün okumamamızdan kaynaklanıyor, arada bir buffer var.

Ekleme:
Okurken önce tris ayarlarıyla portu giriş yapmayı unutmayın. Sorun olursa yine dosyaları gönderirsiniz, bakarız.

Kolay gelsin.

NaMcHo

#8
                                                                  8255'den Okuma
tris ayarını yapın demişşiniz şöyle birsey yaptım (kodun diğer kısımları aynıdır.)
   set_tris_b(0);   
   set_tris_a(0);
   
   while(1)
   { 
          set_tris_b(0xff);
          x8255(READ,XPORT_B);
          y=input_b();
          
       if(y!=0)
       {
             set_tris_b(0);
             output_b(y);
             x8255(WRITE,XPORT_A);
             
       }
       else
       {    
            set_tris_b(0);
            output_b(0b11111111);
            x8255(WRITE,XPORT_A);   
       }
    }

Bundan sonuç alamadım,butona basıldıgında algılanmıyor.
Isis,Cof,C dosyaları : http://hotfile.com/dl/60002765/a3e9523/8255denemeokuma.rar.html

NaMcHo

#9
Hala yapamadım okuma işini.
#include <16f877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NODEBUG,NOLVP,NOCPD,NOPUT,NOWRT
#use delay(clock=4MHz)
#use fast_io(b)
#use fast_io(a)

#define RD PIN_A0
#define WR PIN_A1
#define A0 PIN_A2
#define A1 PIN_A3


enum {READ,WRITE}x8255_action;
enum {XPORT_A,XPORT_B,XPORT_C}x8255_port;
int y;

void x8255(x8255_action,x8255_port)
{
   if(x8255_action==WRITE)
   {
      output_low(WR);
      output_high(RD);
   }
   else //READ
   {
      output_high(WR);
      output_low(RD);
   }
   switch(x8255_port)
   {
      case XPORT_A:
         output_low(A0);
         output_low(A1);
         break;
      case XPORT_B:
         output_high(A0);
         output_low(A1);
         break;
      case XPORT_C:
         output_low(A0);
         output_high(A1);
         break;
   }
}

int x8255_okuma()
{

   x8255(READ,XPORT_B); 
   set_tris_b(0xFF);            // 16f877 B portu giris oluyor.
   y=input_b();                  //okunan değer alınıp Buffer da tutuluyor 
   delay_ms(50);
   set_tris_b(0);
   return y;
   
}

void main(void)
{
   setup_psp(psp_disabled);
   setup_timer_1(t1_disabled);
   setup_timer_2(t2_disabled,0,1);
   setup_adc_ports(no_analogs);
   setup_adc(adc_off);
   setup_ccp1(ccp_off);
   setup_ccp2(ccp_off);
   
   set_tris_b(0);   
   set_tris_a(0);
   
   output_a(0b00001101);           //8255 D portunda mod ayarı yapmak icin D yazma modunda
   output_b(0b10000010);          //A,C Cıkıs B giriş olarak ayarlanıyor 8255 de.
  
  while(1)
   {
      output_b(0b11111111);
      x8255(WRITE,XPORT_A);
      y=x8255_okuma();
      y=~y;                         //y tersleniyor amac hangi butona basılırsa o led sonucek 8255 in A portundakilerden.
      delay_ms(50);
      output_b(y);                 //veri buffer a gonderiliyor.
      x8255(WRITE,xPORT_A);       //A portuna yazma gerceklestiriliyor,ama olmuyor :(
           
      
   }
}

8255 in D portundanda ayar yaparak yapmaya calıstım ama gene olmadı datasheeti bi guzel anlayabilsem sorun cozulcekde yarımyamalak ingilizceyle olmuyor.

Isis,Cof,C : http://hotfile.com/dl/60233978/edcbc64/8255denemeokuma3.rar.html

acemi2010

Merhaba
Örnek 8255 uygulaması için kod ;

Alıntı http://www.t-robot.info/dokumanlar/yazilim/pic-c-ccs-uygulamalari.html
/******************************************************
 Uygulama Adı      : 8255 İle Port Kontrol Uygulaması
*******************************************************/
#include <16f877.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.

//***********Denetleyici konfigürasyon ayarları************
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD

#use delay(clock=4000000)   // Gecikme fonksiyonu için kullanılan osilatör frekansı belirtiliyor

#use standard_io (a) // A portu için giriş/çıkış yönlendirmesi yapılmasına gerek yok
#use standard_io (b) // B portu için giriş/çıkış yönlendirmesi yapılmasına gerek yok

int data; // Tamsayı tipinde değişken tanımlanıyor

//************** 8255 OKUMA FONKSİYONU ***************
void _8255_yazma (char x, char bilgi)
{
   switch (x)
   {
      case   'k':                   // Kaydediciye yazma seçilirse
             output_a(0b00001101);  // Kaydediciye yazma
             output_b(bilgi);       // Yazılacak bilgi gönderiliyor
             break;

      case   'a':                   // A portuna yazma seçilirse
             output_a(0b00000001);  // A portuna yazma
             output_b(bilgi);       // Yazılacak bilgi gönderiliyor
             break;

      case   'b':                   // B portuna yazma seçilirse
             output_a(0b00000101);  // B portuna yazma
             output_b(bilgi);       // Yazılacak bilgi gönderiliyor
             break;

      case   'c':                   // C portuna yazma seçilirse
             output_a(0b00001001);  // C portuna yazma
             output_b(bilgi);       // Yazılacak bilgi gönderiliyor
             break;

      default:
             break;
     }
}

//************** 8255 YAZMA FONKSİYONU ***************
int _8255_okuma (char x)
{
   switch (x)
   {
      case   'k':
             output_a(0b00001110); // Kaydediciden okuma
             return(input_b());    // Kaydedici değeri okunuyor
             break;
      case   'a':
             output_a(0b00000010); // A portundan okuma
             return(input_b());    // A portu değeri okunuyor ve fonksiyondan bu değerle çıkılıyor
             break;
      case   'b':
             output_a(0b00000110); // B portu okuma
             return(input_b());    // B portu değeri okunuyor ve fonksiyondan bu değerle çıkılıyor
             break;
      case   'c':
             output_a(0b00001010); // C portu okuma
             return(input_b());    // C portu değeri okunuyor ve fonksiyondan bu değerle çıkılıyor
             break;
      default:
             break;
   }
}
/********* ANA PROGRAM FONKSİYONU********/

void main ()
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_spi(SPI_SS_DISABLED);     // SPI birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı

   _8255_yazma('k',0b10001001); // A portu çıkış, C portu giriş, B portu çıkış yapılıyor

   while(1) // Sonsuz döngü
   {
      data=(_8255_okuma('c'));  // C portu okunuyor
      _8255_yazma('a',data);    // A portuna okunan C portu değeri yazılıyor
   }
}


http://www.turkpaylasim.com/board/8255-entegresi-ozellikleri-t25517.0.html

saygılarımla
Timuçin

NaMcHo

Merhaba Acemi2010 bunlara bakmıstım bunlar calısmıyor :) Okumada sorun var.