Max7219 ve pic16f877A ile yaptığım çalışmamı bitirdim

Başlatan tekniker_murat, 09 Kasım 2019, 23:39:14

tekniker_murat

Herkese selamun aleyküm değerli ustalarım.

Bayağı uzun bir süredir işim gerekçesiyle elektronik ve yazılımlardan uzakta kalmıştım ama aklım hep buradaydı... Fırsat buldukça bir çalışma yapmak istedim ve 7 segment displayler ile bir çalışma yapıp pratik yapmak istedim bir çok yerde araştırma yapmama rağmen anlayabileceğim ve açık bir döküman bulamadım bu sebepten dolayı da çalışmam bittiği zaman paylaşmak istedim. Umarım ilgilenen arkadaşlara faydası dokunur.

Öncelikle belirtmek istediğim noktalardan işe koyulayım.

Bu çalışmayı her hangi bir siteden temin edebileceğiniz hazır yapılmış bir devre üzerinde yaptım aşağıda fotoğraflarını paylaşıyorum Fiyatı 10 liraya aldım :). Ama tabii ki burada küçücük bir 7 segment display ile yapılmış basit bir proje olarak olayı kafamızda kısıtlamamamız gerekir çünkü burada önemli olan max7219 ile haberleşmek ve istediğimiz haneye istediğimiz veriyi yazabileceğimiz bir yazılım geliştirmektir.

Sonra ihtiyaç duyulması halinde max7219 kullanılarak daha büyük 7 segmentler tasarlanarak daha büyük projeler yapılabilir dediğim gibi önemli olan max7219 ile haberleşmek....

resimler :

[IMG]https://resmim.net/f/mEE6pG.jpg[/img]

[IMG]https://resmim.net/f/zUivLO.jpg[/img]

Şimdi biraz da max7219 un datasheet kısmını inceleyelim...

Datasheet :

https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf

Datasheet incelendiği zaman max7219 un bir mikro denetleyici ile spi üzerinden haberleşme yaptığını görüyoruz ve bunun haricinde mikro denetleyiciden max7219 a bazı komutlar yollanması gerektiği karşımıza çıkıyor...

Peki bu komutlar neler :

1 : Display tarama hızını belirten bir komut yollamamız gerekiyor bu da max7219 un 0x0A adresi oluyor datasheet de açıklandığı sayfa : 9 da ve ben buraya 0xff değerini yolladım yani 31/32 ye denk geliyor...

2: Display aktif etme değeri yani max7219 a 8 adet 7 segment display bağlanabiliyor ama biz burda kaç tanesini aktif etmek istiyoruz örneğin ben 8 tanesini de kullandım ama istenirse sadece tek hanesi istenirse 4 hane 3  hane gibi 1-8 arası bir hane seçilebilir...

Burası da max7219 un 0x0B adresi oluyor bu adrese 0x07 yollarsak şayet 8 dijitin 8 tanesini de aktif etmiş oluruz... yine datasheetin 9. sayfasında Table 8. Scan-Limit Register Format (Address (Hex) = 0xXB) olarak anlatılıyor...

3: Display e veri yollamayı açma yada kapama komutunun gönderildiği adres. Shutdown Register Format (Address (Hex) = 0xXC) olarak sayfa 7 de anlatılıyor...

Eğer biz bu adrese yani 0x0c adresine 0x00 yollarsak display kapalı konuma alınmış oluyor ve ekranda bir şey göremiyoruz. aynı adrese 0x01  yollarsak bu defa displayleri normal operasyon moduna almış oluyoruz.

4: Display test modu : 0x0F adresi eğer biz buraya test modu kodu olan 0x01 yollarsak bütün displaylerin bütün dijitlerini yakıyor yani displayı test etmiş oluyor... Ama normal kullanım için buraya 0x00 yollamamız gerekiyor tabi test yaptırmak istiyorsak 0x01 yolladıktan sonra tekrar 0x00 yollar tekrar kullanıma açabiliriz...

5: Display kod çözme modu 0x09 adresi burasını ben de çok anlayamadım ama max7219 un binary kod çözmesi ile alakalı olarak seçim yapma imkanı sağladığı gibi bir şeyler yazıyor... sayfa 7 de  ve ben bu adrese 0xFF yolladığım zaman dijitlerde gönderdiğim rakamların çıktığını görebiliyorum...

Datasheet biraz daha incelenecek olursa displaylerin max7219 a nasıl bağlandığı ve hangi displayda hangi değeri görmek istediğimiz gibi bir çok konuyu bulabiliyoruz.

Şimdi kısaca biraz da programdan bahsetmeye çalışalım. Ben mikroC programlama dili kullandım bir çok spi versiyonunu denedim soft spi normal spi ve advanced spi ama çalıştırdığım komut ise advanced spi oldu...

Soft spi de iletişimin yükselen kenarda mı düşen kenarda mı vs başlayacağını anlatan bir komut sistemi bulamadım. ama advanced spi de bir abimin yardımı ile şu satırı buldum.

SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);

Normalde bu satırı şu şekilde görürsünüz SPI1_Init_Advanced() yani parantezin içi boştur ama yukarıdaki komutlar eklendiği zaman iletişim ayarlarını yapmış oluyorsunuz.

Şimdi ise biraz da hangi display e hangi veriyi nası yollarız kısmından bahsedelim.... Datasheet incelendiği zaman sayfa 7 de

[IMG]https://resmim.net/f/inus7I.jpg[/img]

resimde gördüğünüz gibi dijit0 yani en sağdaki 1'ler basamağının dijit adresi olarak 0x01 verilmiş ve sola doğru 0x02,0x03,0x04...0x08 e kadar gelmiş yani 10 milyonlar basamağı olan en sol taraftaki 7 segment displayın adresi 0x08 birler basamağı olan en sağdaki displayın adresi ise 0x01 olduğunu görüyoruz...

Biz buna göre örneğin 1984 sayısını display e yollamak istersek

0x01 e 4 0x02 ye 8 0x03 e 9 ve 0x04 e de 1 göndermemiz gerekiyor... Tabi bunun daha geliştirilmiş yöntemleri de elbette ki var ve bunları da paylaşacağım...

Lafı sözü fazla uzun uzun uzatmadan biraz da nokta işaretinden söz etmek istiyorum. Nokta işareti dp olarak geçiyor

Şimdi şöyle bir şey düşünelim birler basamağında 3. göstermek istiyorsak bunu nasıl göndermeliyiz ? işte bunun için max7219 un 0x01 adresine 0x83 yollamamız gerekiyor yani baştaki 8 dp yi aktif ediyor 3 de normal rakam olarak ekranda görünüyor.

Evet kısaca entegre hakkında bunları söyledikten sonra bir de yazılım paylaşalım olmuşken tam olsun :D

programa burada başlıyorum :

sbit Chip_Select at RC0_bit;
sbit Chip_Select_Direction at TRISC0_bit;

void main() {
adcon1=7;
trisd=0;
portd=0;

     Chip_Select = 1;                       // Deselect DAC
     Chip_Select_Direction = 0;             // Set CS# pin as Output
     SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
            Chip_Select = 1;                        // DAC seçimini kaldırın
            Chip_Select_Direction = 0;             // CS # pinini Output olarak ayarla

            Chip_select=0;
            spi1_write(0x0A);// DİSPLAY TARAMA HIZINI BELİRLEYEN ADRES ( OSİLATÖR BÖLME ORANI DATASHEET'E BAK )
            spi1_write(0xFF);// BÖLME ORANI 31/32
            Chip_select=1;

            Chip_select=0;
            spi1_write(0x0B);// DİSPLAY AKTİF ETME DEĞERİ YANİ 8 DİSPLAYDAN KAÇ TANE AKTİF EDİLMEK İSTENİYORSA BU ADRES BELİRLER
            spi1_write(0x07);// 0X00 DEĞERİ SADECE 1'LER BASAMAĞINDAKİ DİSPLAYI AKTİF EDER. 0X07 BÜTÜN BASAMAK DİSPLAYLERİ AKTİF EDER
            Chip_select=1;

            Chip_select=0;
            spi1_write(0x0C);//DSİPLAYLERE VERİ YOLLAMAYI AÇMA VE KAPAMA BİTİ
            spi1_write(0x01);//0X00 OLURSA DİSPLAYLER KAPALI 0X01 OLURSA DİSPLAYLER AÇIK MODDADIR.
            Chip_select=1;

            Chip_select=0;
            spi1_write(0x0F);//DİSPLAY TEST MODU REGİSTERİ
            spi1_write(0x00);//0X00 OLURSA TEST MODU KAPALI KONUMDA OLUR 0X01 OLURSA BÜTÜN DİPLYALARIN BÜTÜN DİJİTLERİNİ YAKAR
            Chip_select=1;

            Chip_select=0;
            spi1_write(0x09);//KOD ÇÖZME MODU KAYIT ÖRNEKLERİ REGİSTERİ
            spi1_write(0xFF);
            Chip_select=1; ///++++++++
            //////////////////////////////////////
            Chip_select=0;
            spi1_write(0x02);//KOD ÇÖZME MODU KAYIT ÖRNEKLERİ REGİSTERİ
            spi1_write(0x0);
            Chip_select=1; ///++++++++

            Chip_select=0;
            spi1_write(0x03);//KOD ÇÖZME MODU KAYIT ÖRNEKLERİ REGİSTERİ
            spi1_write(0x00);
            Chip_select=1; ///++++++++

            Chip_select=0;
            spi1_write(0x04);//KOD ÇÖZME MODU KAYIT ÖRNEKLERİ REGİSTERİ
            spi1_write(0x00);
            Chip_select=1; ///++++++++

            Chip_select=0;
            spi1_write(0x05);//KOD ÇÖZME MODU KAYIT ÖRNEKLERİ REGİSTERİ
            spi1_write(0x00);
            Chip_select=1; ///++++++++

            Chip_select=0;
            spi1_write(0x06);//KOD ÇÖZME MODU KAYIT ÖRNEKLERİ REGİSTERİ
            spi1_write(0x00);
            Chip_select=1; ///++++++++

            Chip_select=0;
            spi1_write(0x07);//KOD ÇÖZME MODU KAYIT ÖRNEKLERİ REGİSTERİ
            spi1_write(0x00);
            Chip_select=1; ///++++++++

            Chip_select=0;
            spi1_write(0x08);//KOD ÇÖZME MODU KAYIT ÖRNEKLERİ REGİSTERİ
            spi1_write(0x00);
            Chip_select=1; ///++++++
            ////////////////////////////////////////////////
            
            while          (1){
            Chip_select=0;
            spi1_write(0x01);//KOD ÇÖZME MODU KAYIT ÖRNEKLERİ REGİSTERİ
            spi1_write(0x08);
            Chip_select=1; ///++++++++
            
don:
goto        don;
            }
}

Yukarıdaki programı yazdıp derleyip pic e yüklediğimiz zaman spi1 komutunun mikroc programındaki help kısmına bakınca aşağıdaki şemayı görüyoruz. Bu şemadaki mcp entegresini sizin max7219 olarak görürseniz 16F877A entegresinde hangi uçları pic de hangi ayaklara bağlayacağınız açıkça gösterilmiş olacaktır.

[IMG]https://resmim.net/f/f4ymjh.jpg[/img]

Buna göre :

SDI = Portc.5
CLK = Portc.3
CS = Portc.0

şimdi yukarıdaki programı derleyip pic e yükleyip gerekli bağlantıları da yaptıktan sonra bizim display göstergemizde birler basamağını 8 ve diğer basamakları 0 olarak görmekteyiz.

[IMG]https://resmim.net/f/020Pe2.jpg[/img]

Şimdi yukarıdaki yazılımı biraz değiştirelim ve ekranda 19. göreceğimiz şekilde yazalım bunun için

            while          (1){
            Chip_select=0;
            spi1_write(0x01);//KOD ÇÖZME MODU KAYIT ÖRNEKLERİ REGİSTERİ
            spi1_write(0x08);
            Chip_select=1; ///++++++++
            
don:
goto        don;
            }
bu kısımda biraz değişiklik yapacağız bu kısımı şu şekilde değiştirdiğimizi farz edelim ve tekrar bir resim paylaşayım....

            while          (1){
            Chip_select=0;
            spi1_write(0x01);//KOD ÇÖZME MODU KAYIT ÖRNEKLERİ REGİSTERİ
            spi1_write(0x89);
            Chip_select=1; ///++++++++


            Chip_select=0;
            spi1_write(0x02);//KOD ÇÖZME MODU KAYIT ÖRNEKLERİ REGİSTERİ
            spi1_write(0x01);
            Chip_select=1; ///++++++++
            
don:
goto        don;
            }
[IMG]https://resmim.net/f/F6vkxN.jpg[/img]

Değerli arkadaşlar ve değerli ustalarım umarım faydalı olmuş olur...

Aslında bir daha ki programda daha ileri versiyonu olan 10 milyonlu sayılar ile çalışmasını da anlatmak istiyorum biraz ama artık o da ya kısmet :)

Eğer fırsat bulursam onu da yazdım bitirdim ama proje olarak hazırlamadım burada paylaşılacak duruma geldiği zaman paylaşmak istiyorum...
[email]murat.yagci.1984@gmail.com[/email]

tekosis

Elbet birilerinin ihtiyacını görür. Elinize sağlık.
İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.

ÜC

#2
$09 adresine $FF değeri verdiğinizde 0-9 arası desimal sayıları ve H,E,L,P harflerini yazar.

$09 adresine $00 değeri verdiğinizde  çipe bağımlı kalmadan istediğimiz karakterleri oluşturabiliriz.Örn eksi karakteri için 7.segment değerini 1 yapmamız yeterli (%01000000) veya derece işareti için (%01100011).
  Tasarım esnasında çipin segment pinlerini displayin ilgili pinine birleştirmek yerine karışık birleştirmek istersek desimal karakterleri kendimizin oluşturması gerekir, $00 değeri vererek bu atamaları yapabiliriz.

$01 değeri yalnızca 1.dijite desimal yazma yapar
$0F değeri ilk 4 dijite desimal yazma yapar

tekniker_murat

@Ümit COŞKUN teşekkür ederim abi işte bize böyle bilgili insanların açıklamaları lazım ki rampaları düz yapabilelim tekrar teşekkür ederim.
[email]murat.yagci.1984@gmail.com[/email]