XC de değişken ve bit yönetimi ile ilgili sorularım

Başlatan elektroacemi, 28 Şubat 2022, 18:48:33

elektroacemi

Merhaba arkadaşlar.

Proton Basic kullandım uzun süre şimdi XC ile C ye geçtim. Proton  basitçe yapılan bazı şeyleri C de çok uzun yapıyorum. Bunları sizler nasıl yapıyorsunuz.

1)Data yollarken ve alırken bir değişkenini birinci bitini almak Proton da çok kolaydı
SDA_OUT = YOLLANAN_VERI.1 
ALINAN_VERI.5 = SDA_IN     demek yeterliydi.

2)Word tanımladığımız değişkenini iki byte şeklinde ulaşmak için
YOLLANAN7 = DEGER_A.Byte0
YOLLANAN8 = DEGER_A.Byte1   demek yeterliydi.

Yazılımsal seri iletişim yapmak istiyorum da. (DHT11 ve MCP4921 için)

Teşekkür ederim


Tagli

C'de rahat etmek için bit işlemlerine alışmak gerekiyor.

Bir değişkenin (adı foo olsun) n. bitine (0'dan başlamak üzere) erişmek için:
((foo >> n) & 1)

uint16_t türünden bir değişkenin 0. ve 1. byte'larına erişmek için:
(uint8_t)foo // Küçük (0.) byte
(uint8_t)(foo >> 8) // Büyük (1.) byte

Ancak C'de işaretli sayılar üzerinde kaydırma yapmak beklenmedik ve hatalı sonuçlara sebep olabiliyor. Bu sebeple dikkatli olmak ve mümkün olduğunca bundan kaçınmak lazım. Kuralları ile ilgili ayrıntılar tam olarak aklımda değil. Ek olarak, C'de interger promotion kuralları da bazen beklenmedik sorunlara sebep olabiliyor. Bunları iyi öğrenip sürekli olarak tetikte olmak gerekiyor.
Gökçe Tağlıoğlu

mehmet

Basit makrolar var.
#define _BV(bit)        (1 << (bit))
#define sbi(port, bit)  (port) |= _BV(bit) 
#define cbi(port, bit)  (port) &= ~_BV(bit)

//#define sbi(b,n) ((b) |=  (1<<(n)))        /* Set bit number n in byte b  */
//#define cbi(b,n) ((b) &= (~(1<<(n))))      /* Clear bit number n in byte b */
#define rbi(b,n) ((b) &    (1<<(n)))        /* Read bit number n in byte b  */
#define fbi(b,n) ((b) ^=  (1<<(n)))        /* Flip bit number n in byte b  */

#define bit_is_set(b,n)  (b & (1<<n))      /* Test if bit number n in byte b is set  */
#define bit_is_clear(b,n) (!(b & (1<<n)))  /* Test if bit number n in byte b is clear */ 

#define pinToggle(PORT, n)  (PORT ^= 1 << n)
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

ahuramazda

#3
Alıntı yapılan: elektroacemi - 28 Şubat 2022, 18:48:332)Word tanımladığımız değişkenini iki byte şeklinde ulaşmak için
YOLLANAN7 = DEGER_A.Byte0
YOLLANAN8 = DEGER_A.Byte1  demek yeterliydi.

union MY_DATAU16{
    uint16_t Dummy;
    uint8_t Bytes[2];
};

union MY_DATAU16 DegerA;

DegerA.Bytes[0] = YOLLANAN7;
DegerA.Bytes[1] = YOLLANAN6;

YOLLANAN7 = DegerA.Bytes[0];
YOLLANAN6 = DegerA.Bytes[1];

elektroacemi

Merhabalar.

((foo >> n) & 1)

bunu denedim oldu. Epey de kullandım teşekkür ederim.

uint16_t  OLCUM;
uint8_t OLCUM0;
uint8_t OLCUM1;

(uint8_t)OLCUM = OLCUM0;
(uint8_t)(OLCUM >> 8) = OLCUM1;
Bunda hata aldım. Bunun için kütüphane eklemek gerekiyor mu ?


Alıntı yapılan: ahuramazda - 01 Mart 2022, 10:19:56
union MY_DATAU16{
    uint16_t Dummy;
    uint8_t Bytes[2];
};

union MY_DATAU16 DegerA;

DegerA.Bytes[0] = YOLLANAN7;
DegerA.Bytes[1] = YOLLANAN6;

YOLLANAN7 = DegerA.Bytes[0];
YOLLANAN6 = DegerA.Bytes[1];


Bunları denedim hata verdi.

ahuramazda

Alıntı YapBunda hata aldım. Bunun için kütüphane eklemek gerekiyor mu ?

bir şey eklemenize gerek yok

power20

#6
(uint8_t)OLCUM = OLCUM0;
(uint8_t)(OLCUM >> 8) = OLCUM1;
yerine
OLCUM0 = (uint8_t)OLCUM ;
 OLCUM1 =(uint8_t)(OLCUM >> 8);
olursa hata çözülecek gibi

Alıntı Yaphata aldım.

elektroacemi

#7
Alıntı yapılan: ahuramazda - 03 Mart 2022, 14:11:57bir şey eklemenize gerek yok

Tekrar denedim oldu. Bir şeyi atlamışım galiba. Bu seferde oluşturduğum değeri yolladığım yer kabul etmiyor değişken tipinden dolayı.

"********Source/main.c:82:41: error: assigning to 'short' from incompatible type 'union MY_DATAU16'**********"



03 Mart 2022, 14:45:57
Alıntı yapılan: Kılıç - 03 Mart 2022, 14:39:30
(uint8_t)OLCUM = OLCUM0;
(uint8_t)(OLCUM >> 8) = OLCUM1;
yerine
OLCUM0 = (uint8_t)OLCUM ;
 OLCUM1 =(uint8_t)(OLCUM >> 8);
olursa hata çözülecek gibi


O şekilde 16 bitlik sayıyı 2 adet 8 bitlik sayıya çevirdik.

2 adet 8 bitlik sayıyı 16 ya nasıl çeviririz ?

power20

#8
  Sayi16bit = (uint16_t ) (Sayi8bitLeft<<8) |  Sayi8bitRight;
(aradaki "or" işareti oluyor. Klavyeden Alt+124 )

Tagli

uint8_t gibi değişken tipleri için stdint.h dosyasının include edilmesi gerekir. Sık kullanılan bir dosya olduğu için, başka bir .h dosyasının içinde zaten gelmiş de olabilir.
Gökçe Tağlıoğlu

hasankara

#10
typedef union
{
    unsigned long dword;
    struct
    {
        unsigned short word_0;
        unsigned short word_1;
    };
    struct
    {
        unsigned char byte_0;
        unsigned char byte_1;
        unsigned char byte_2;
        unsigned char byte_3;
    };
    struct
    {
        unsigned char b0 : 1;
        unsigned char b1 : 1;
        unsigned char b2 : 1;
        unsigned char b3 : 1;
        unsigned char b4 : 1;
        unsigned char b5 : 1;
        unsigned char b6 : 1;
        unsigned char b7 : 1;
        unsigned char b8 : 1;
        unsigned char b9 : 1;
        unsigned char b10 : 1;
        unsigned char b11 : 1;
        unsigned char b12 : 1;
        unsigned char b13 : 1;
        unsigned char b14 : 1;
        unsigned char b15 : 1;
        unsigned char b16 : 1;
        unsigned char b17 : 1;
        unsigned char b18 : 1;
        unsigned char b19 : 1;
        unsigned char b20 : 1;
        unsigned char b21 : 1;
        unsigned char b22 : 1;
        unsigned char b23 : 1;
        unsigned char b24 : 1;
        unsigned char b25 : 1;
        unsigned char b26 : 1;
        unsigned char b27 : 1;
        unsigned char b28 : 1;
        unsigned char b29 : 1;
        unsigned char b30 : 1;
        unsigned char b31 : 1;
    };

} dword_parse_ts;
void foo()
{
    dword_parse_ts data;
    data.dword = 0x5aa55aa5;
    if (!data.b1)
    {
        /*1 degil ise 1 yapar*/
        data.b1 = 1;
    }
    /* guncel deger  0x5aa55aa7 oldu*/
}
typedef struct ı bir kez tanımlamak yeterli olacak.

elektroacemi