Belli pinlere belli bitler atama

Başlatan Faruk53, 31 Ocak 2017, 15:22:03

Faruk53

Arkadaşlar kolay gelsin. Bir konuda yardımınıza ihtiyacım var. 7 seg. Display kontrol etmek için bir lookup tablosu oluşturulduğunu düşünün.
örneğin;
unsigned char const segment[10]={0x64,0x121,0x36,0x48,0x25,0x18,0x02,0x120,0x00,0x16};
benim bu oluşturduğum tablonun her bitini bir pine atamam gerekiyor. işin içinden bir türlü çıkamadım. yani yapmak istediğim;
PORTDbits.RD0 = segment.bit0

şeklinde 8 biti de ayrı ayrı pinlere atayıp taramayı o şekilde yapmam gerekiyor. yardımlarınızı bekliyorum iyi çalışmalar.

Cemre.

Display'in tüm segmentleri bir porta (misal D portu) bağlı ise portd = segment[  x  ] şeklinde bir atama yapabilirsiniz.

(Doğru yazımı hakkında fikrim yok, xc8 kullanmıyorum.)

Faruk53

Cevap için teşekkür ederim. Malesef hocam sorunum orda zaten. Bu şekildeki kullanımına hakimim ama bu biraz kafamı karıştırdı. displayin segmentleri karmaşık şekilde bağlı.  "struct" yapısına takılmış durumdayım şuanda. segmenti bit bit burada ayırıp pinlere aktarabilir miyim onunla uğraşıyorum.

Cemre.

#3
Şöyle bir çözüm önereyim o zaman anladığım kadarıyla.

Sanırım segment(x).bit0 gibi bir kullanım arıyorsunuz. Bunun yerine segment(x)'in misal 5. bitini kullanmak istediğinizi varsayalım.

segment(x) = 0b10x0 1010 olsun.

5'inci biti almak için, önce 0b0010 0000 ile AND işlemine tabi tutulur. Sonra 5 kez sağa kaydırılır. Misal;

segment(x).bit5 = ((segment(x) & 0b00100000) >> 5);

0b10x0 1010 & 0b0010 0000 işleminin sonucu, 0b00x0 0000'dır. Bu sonucu 5 kez sağa kaydırarak 0b0000 000x sonucuna ulaşırız. X burada 1 veya 0 olabilir.

Bu şekilde tüm bitleri kontrol edebilirsiniz.
Daha hızlı bir yol varsa bilen arkadaşlardan duymak isteriz.

Faruk53

#4
Hocam tam olarak açıklamak gerekirse tanımladığımız lookup tablosundaki her bir biti  işlemcinin bir pinine atamam lazım. Yani normalde tarama yapılırken displayin bütün segmentleri bir porta bağlı olduğunda sizinde dediğiniz gibi  PORTD= segmenteler [ x ] şeklinde atayabiliyoruz.
Fakat problem şurdaki displayimin segmentleri farklı portun pinlerinde. Yani a segmenti RD3, b segmenti RC4, c segmenti RD0, d segmenti RC2 gibi gidiyor. Benim bu segmentleri tek tek pinlere tanıtıp daha sonrasında lookupdaki veriyi tek seferde çıkışa basmam gerekiyor. Tam tamam hallettim diyorum yok yine bi sorun :) mantığını bi türlü oturtamadım hocam.

Cemre.

#5
Yazdığım mantığı anlayabildiniz mi? Bu soruna çözüm olmaması için hiç bir neden yok çünkü.

Tamam basit bir kod parçası yazayım, siz kendinize göre uyarlarsınız.

portd0'ın A segmenti olduğunu varsayıyorum. A segmentini de segment(x)'in 0'ıncı biti ile ifade ettiğinizi varsayıyorum. Bu durumda;

for(int i = 0; i < 9; i++){
PORTDbits.RD0 = ((segment[i] & 0b00000001));   // 0ıncı bit, A segmentine bağlı olan pine yazıldı.
PORTXbits.RXY = ((segment[i] & 0b00000010) >> 1);  //1inci bit, B seg. bağlı olan pine yazıldı.
PORTXbits.RXY = ((segment[i] & 0b00000100) >> 2);  //2.............................................
....
...
...
..
delayms(xxx); // bir süre gecikme
}


Yukarıdaki kod parçası sırayla xxx gecikme ile segment[] dizisindeki değerleri gerekli pinlere yansıtır.

kimlenbu

@Cemre. nin çözümü elindeki en mantıklı çözümlerden.

Benzer bir şey yapmak isteyen birisininin konusu :

http://www.microchip.com/forums/m559135.aspx

Bu da çözümü :

http://www.xargs.com/pic/c-faq.html#pinremap

pic kullanmayalı 10 seneden fazla olduğu için port ve pin syntax'ına hakim değilim.

F493

Selam,


unsigned char const segment[10]={0x64,0x121,0x36,0x48,0x25,0x18,0x02,0x120,0x00,0x16};

union _PortDataSegmentBit
{
	unsigned char segmentByte[1];

	struct {
		unsigned char DataBit_0 : 1;
		unsigned char DataBit_1 : 1;
		unsigned char DataBit_2 : 1;
		unsigned char DataBit_3 : 1;
		unsigned char DataBit_4 : 1;
		unsigned char DataBit_5 : 1;
		unsigned char DataBit_6 : 1;
		unsigned char DataBit_7 : 1;
	};
};

union _PortDataSegmentBit  PortDataSegmentBit;

//Kullanmak istedigimiz segment byte'ını bizim struct'a atıyoruz.

PortDataSegmentBit.segmentByte[0] = segment[0]
//PortDataSegmentBit.segmentByte[0] = segment[1]
//PortDataSegmentBit.segmentByte[0] = segment[2]
//PortDataSegmentBit.segmentByte[0] = segment[3]


PORTDbits.RD0 = PortDataSegmentBit.DataBit_0;
PORTDbits.RD1 = PortDataSegmentBit.DataBit_1;
PORTDbits.RD2 = PortDataSegmentBit.DataBit_2;
PORTDbits.RD3 = PortDataSegmentBit.DataBit_3;
PORTDbits.RD4 = PortDataSegmentBit.DataBit_4;
PORTDbits.RD5 = PortDataSegmentBit.DataBit_5;
PORTDbits.RD6 = PortDataSegmentBit.DataBit_6;
PORTDbits.RD7 = PortDataSegmentBit.DataBit_7;


Esen kalın.

Faruk53

Hocam değerli bilgilerinizi paylaştığınız için çok ama çok teşekkür ederim. Toparladığım an sizlerle paylaşacağım.

Faruk53

@Cemre. hocam sizinle konuştuğumuz gibi ilerledim programda ve sonuca ulaştım teşekkür ederim. Kod aşağıdaki gibi.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "config.h"


                                // 0    1   2    3    4    5    6    7    8    9     A    b    C   d    E    F    G    H    -    ı    j     k   l    N     n    o    p    r   s    t    u    U
unsigned char const segment[32]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,0xBC,0x6E,0x02,0x20,0x78,0x1E,0x1C,0xEC,0x2A,0x3A,0xCE,0x0A,0xB6,0x8C,0x38,0x7C};

unsigned char orta_data[4];
unsigned long orjinal_sayac=1234; //gerçek sayı
int a_orta,b_orta,c_orta,d_orta; // 65532 dönüşümü yapmak için kullanılan değişkenler. orta ekrana basılmak için yazılanlar.

//****************************İŞLEMCİYİ HAZIRLA*******************************//
void mcu_init()
{
    ANSELC = 0x00;
    ANSELD = 0x00;
    ANSELB = 0x00;
    ANSELA = 0x00;         // A portundaki bütün adcler iptal edildi.
    ANSELE = 0x00;

    OSCCONbits.IRCF = 0b110; // OSSCON registerının IRCF bayrağı kullanılarak 16Mhz RC osilatör seçildi.
   // OSCTUNEbits.PLLEN = 0b1; //OSCTUNE registerının PLLEN bayrağı kullanılarak 4XLL aktif edildi.

    //while(!OSCCON2bits.PLLRDY); //PLL sağlanana kadar bekle
    while(!OSCCONbits.HFIOFS); //Frekans kararlı olana kadar bekle
  
    TRISAbits.TRISA0 = 1; // A portunun 0. pini giriş olarak belirlendi.
    TRISAbits.TRISA1 = 1; // A portunun 1. pini giriş olarak belirlendi.
    TRISAbits.TRISA2 = 1; // A portunun 2. pini giriş olarak belirlendi.
    TRISAbits.TRISA3 = 1; // A portunun 3. pini giriş olarak belirlendi.
    TRISAbits.TRISA4 = 0; // A portunun 4. pini çıkış olarak belirlendi.
    TRISAbits.TRISA5 = 0; // A portunun 5. pini çıkış olarak belirlendi.
    TRISAbits.TRISA6 = 0; // A portunun 6. pini çıkış olarak belirlendi.
    TRISAbits.TRISA7 = 0; // A portunun 7. pini çıkış olarak belirlendi.
    
    TRISBbits.TRISB0 = 1; // B portunun 0.pini giriş olarak ayarlandı.
    TRISBbits.TRISB5 = 1; // B portunun 5.pini giriş olarak ayarlandı.
    TRISBbits.TRISB1 = 0; // B portunun 1.pini çıkış olarak ayarlandı.
    TRISBbits.TRISB2 = 0; // B portunun 2.pini çıkış olarak ayarlandı.
    TRISBbits.TRISB3 = 0; // B portunun 3.pini çıkış olarak ayarlandı.
    TRISBbits.TRISB4 = 0; // B portunun 4.pini çıkış olarak ayarlandı.
   
    TRISC=0x00;
    TRISD=0x00;
   
    PORTA=0x00;
    PORTB=0x00;
    PORTC=0x00;
    PORTD=0x00; 
 
}
//****************************************************************************//

//**********************************Gerçek sayı için çevirme******************//
void int_to_seg_orta(unsigned long sayi,int DP)//Dot Point.
{
 a_orta=sayi%10; orta_data[3]=segment[a_orta]+DP;
 sayi/=10;
 b_orta=sayi%10; orta_data[2]=segment[b_orta];
 sayi/=10;
 c_orta=sayi%10; orta_data[1]=segment[c_orta];
 d_orta=sayi/=10; orta_data[0]=segment[d_orta]; 
}
//****************************************************************************//

//******************orta ekran taraması için yazılan algoritma****************//
void orta_ekran_tarama()
{
    i=d_orta;  // yukarıda port_tanımla_yaz dizisi i değişkeni ile çalışıyor. i dizisini sürekli olarak o anki yazmak istediğimiz basamağa eşitliyoruz.
    int_to_seg_orta(orjinal_sayac,0); // daha sonra çevirme işlemi yapılıyor.
    port_tanimla_yaz(); // yazılıyor.
    ortahane1=1;      // ilgili pin açılıyor.
    __delay_ms(4); // 150us bekleniyor.
    ortahane1=0; //ilgili pin kapatılıyor.
        
    i=c_orta;
    int_to_seg_orta(orjinal_sayac,0);
    port_tanimla_yaz();         
    ortahane2=1;  
    __delay_ms(4);      
    ortahane2=0;
        
    i=b_orta;
    int_to_seg_orta(orjinal_sayac,0);
    port_tanimla_yaz();   
    ortahane3=1;         
    __delay_ms(4);
    ortahane3=0;
        
    i=a_orta;
    port_tanimla_yaz();
    int_to_seg_orta(orjinal_sayac,0);
    ortahane4=1;                
    __delay_ms(4);
    ortahane4=0;
}
//****************************************************************************//

//***************************Displaye Veri Bas********************************//
//yapıln işlem segmentin o anki durumunu 7 bit bulunmak isteniyorsa 7.biti 1 olan 8 bitlik bir değişkenle ve(&) işlemine 
//tabi tutularak yine işlem sonucunu 7 bit sağa öteleyerek elde edilir.
void port_tanimla_yaz()
{  
//i değişkenime göre sayı değeri değişiyor.
//for( i = -1; i < 10; i++)
LATDbits.LATD3 = ((segment[i] & 0b10000000) >> 7);   //7ıncı bit, A segmentine bağlı olan pine yazıldı.
LATCbits.LATC4 = ((segment[i] & 0b01000000) >> 6);  //6inci bit, B seg. bağlı olan pine yazıldı.
LATDbits.LATD0 = ((segment[i] & 0b00100000) >> 5);  //5.............................................
LATCbits.LATC2 = ((segment[i] & 0b00010000) >> 4);
LATCbits.LATC1 = ((segment[i] & 0b00001000) >> 3);
LATDbits.LATD2 = ((segment[i] & 0b00000100) >> 2);
LATDbits.LATD1 = ((segment[i] & 0b00000010) >> 1);
LATCbits.LATC3 = ((segment[i] & 0b00000001));

}
//****************************************************************************//

void main()
{
    mcu_init();
    
    while (1)
    {       
        orta_ekran_tarama();       
           
    }
}