Převod čísla do 4 pinů

Odpovědět
Ludek
Příspěvky: 289
Registrován: 02 pro 2019, 08:14
Reputation: 0
Bydliště: České Budějovice

Převod čísla do 4 pinů

Příspěvek od Ludek » 23 zář 2022, 12:07

Zdravím, trápím se procedrkou pro převod čísla do 4 výstupů.
Potřebuji třeba rozsvítit 4 ledky binárně. To znamená číslo 0-15 tak aby svítily dle hex kodu.
0 - nesvítí žádná třeba 5- svítí 0101 a z čísla 15 svítí všechny. díky

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: Převod čísla do 4 pinů

Příspěvek od ondraN » 23 zář 2022, 12:41

V cyklu si postupně zamaskuj logickou operací AND jednotlivé bity. Máš třeba číslo X. když (X and 1) je nenulové rozsvítíš diodu na pozici 0. Dále anduješ s váhami binární soustavy, tj. 1,2,4,8,16,32,64,128..... a zjišťuješ nenulovost a rozsvěcíš nebo zhasínáš ledky, až ti to bude stačit. Taky si můžeš dát jedničku do pomocné proměnné a pak ji po každém kroku shiftnout doleva o jednu pozici, to ti udělá tu masku pro jednotlivé bity.
Nebo můřeš použít přímo bitové operace co to udělají za tebe, třeba bitRead()
https://www.arduino.cc/reference/en/lan ... s/bitread/

Ludek
Příspěvky: 289
Registrován: 02 pro 2019, 08:14
Reputation: 0
Bydliště: České Budějovice

Re: Převod čísla do 4 pinů

Příspěvek od Ludek » 23 zář 2022, 13:02

Ondro díky, jdu na to.

Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Převod čísla do 4 pinů

Příspěvek od kiRRow » 23 zář 2022, 15:04

Nebo jako výstup použít piny, které jsou všechny na jednom PORTu 0-3 a to číslo rovnou zapsat do patřičného registru.

Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Převod čísla do 4 pinů

Příspěvek od kiRRow » 23 zář 2022, 15:49

Příklad pro UNO ... zapojím ledky na pin 8,9,10,11

Kód: Vybrat vše

byte cislo = 15;
PORTB = PORTB | cislo;// je potřeba to zapsat pomocí operace OR, aby se nezměnil zbytek registru
jelikož se hrabe přímo do registru, doporučuji kontrolu jestli nezadal někdo číslo větší než 15 nebo menší než 0

Kód: Vybrat vše

byte cislo = 15;
cislo = cislo & 0x0F;// kontrola pomocí maskování operací AND
PORTB = PORTB | cislo;// je potřeba to zapsat pomocí operace OR, aby se nezměnil zbytek registru

peterple
Příspěvky: 156
Registrován: 22 zář 2021, 20:20
Reputation: 0

Re: Převod čísla do 4 pinů

Příspěvek od peterple » 23 zář 2022, 21:14

Tak pozor. C má dva operátory pre súčin a súčet. Jeden je logický a jeden je bitový.
V predošlom príspevku sú nesprávne použité logické, ktoré by viedli k nesprávnym výsledkom

Správne by to malo byť takto nejako:

Kód: Vybrat vše

byte cislo = 12;
cislo = cislo & 0x0F;// odreže horné 4 bity čísla pre istotu (vynuluje ich) pomocou bitoveho sucinu
PORTB = PORTB & 0xF0; //vynuluje dolne 4 bity portu B
PORTB = PORTB | cislo; //nastavi dolne 4 bity pomocou bitoveho suctu

// da sa aj kratsi zapis 
cislo &=  0x0F;// odreže horné 4 bity čísla pre istotu (vynuluje ich) pomocou bitoveho sucinu
PORTB &= 0xF0; //vynuluje dolne 4 bity portu B
PORTB |=  cislo; //nastavi dolne 4 bity pomocou bitoveho suctu

Ešte som tam pridal aj maskovanie dolných 4 bitov portu B lebo inak by to nefungovalo pre iné čísla ako 15 dobre.


Logický súčet a sučin funguje inak. pretože výsledkom sú fodnoty true a false. false zodpoveda 0 a true zodpovedá 1

Kód: Vybrat vše

byte cislo = 15;
cislo = cislo && 0x0F;  //v premennej cislo bude 1 a nie 15 

AstroMiK
Příspěvky: 592
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Převod čísla do 4 pinů

Příspěvek od AstroMiK » 24 zář 2022, 08:55

- Pro zjištění hodnoty zbývajících pinů (pokud jsou nastaveny jako vstupy) se musí použít registr PINB.

- Zápis do registru PORTB bych nechal až úplně nakonec a ty bitové operace bych prováděl na nějaké proměnné, protože tak jak je to zapsané by vždycky na chvíli ty spodní 4 bity ťukly do nuly.

Kód: Vybrat vše


byte cislo;
byte puvodni_stav;

void setup()
  {
    Serial.begin(9600);
    
    pinMode(8,OUTPUT);
    pinMode(9,OUTPUT);
    pinMode(10,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(12,INPUT_PULLUP);                     // defaultne v '1', do '0' se shodi pripojenim na GND
    pinMode(13,INPUT);                            // pozor na D13 - obsahuje LED proti GND, takze je PULL_DOWN. Do '1' se musi privest pripnutim na Vcc.
  }

void loop()
  {
    if (Serial.available())
      {
        cislo = Serial.parseInt();                // precist zadane cislo ze seriove linky
        cislo = cislo & 0x0F;                     // odrezat horni 4 bity (jen ochrana pred zadanim cisla vyssiho nez 15)

        puvodni_stav = PINB;                      // do promenne 'puvodni_stav' nacist aktualni stav celeho portu B
        puvodni_stav = puvodni_stav & 0xF0;       // spodni bity vynulovat, horni bity nechat beze zmeny   
        PORTB = puvodni_stav | cislo;             // k vynulovanym spodnim bitum pridat 'cislo' horni bity zustavaji beze zmeny v puvodnim stavu
      }

   Serial.print("PORTB = 0b");                    // jen zobrazeni obou registru v binarnim formatu
   Serial.print(PORTB,BIN);
   Serial.print("     PINB = 0b");
   Serial.println(PINB,BIN);
    
   delay(100);
  }


AstroMiK
Příspěvky: 592
Registrován: 08 pro 2017, 19:05
Reputation: 0

Re: Převod čísla do 4 pinů

Příspěvek od AstroMiK » 24 zář 2022, 09:45

... OMLUVA - chyba v mém předchozím příspěvku, která už se to nedá opravit.

Registr PINB se sice používá pro čtení pinu, ale v tomhle případě je to blbost.
PORTB nastavuje na vstupních pinech PULL-UPY, a to je to, co se musí zachovat.

Kód: Vybrat vše


byte cislo;
byte puvodni_stav;

void setup()
  {
    Serial.begin(9600);
    
    pinMode(8,OUTPUT);
    pinMode(9,OUTPUT);
    pinMode(10,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(12,INPUT_PULLUP);                     // defaultne v '1', do '0' se shodi pripojenim na GND
    pinMode(13,INPUT);                            // pozor na D13 - obsahuje LED proti GND, takze je PULL_DOWN. Do '1' se musi privest pripnutim na Vcc.
  }

void loop()
  {
    if (Serial.available())
      {
        cislo = Serial.parseInt();                // precist zadane cislo ze seriove linky
        cislo = cislo & 0x0F;                     // odrezat horni 4 bity (jen ochrana pred zadanim cisla vyssiho nez 15)

        puvodni_stav = PORTB;                      // do promenne 'puvodni_stav' nacist aktualni stav vystupu a nastavenych Pull-Upu celeho portu B
        puvodni_stav = puvodni_stav & 0xF0;       // spodni bity vynulovat, horni bity nechat beze zmeny   
        PORTB = puvodni_stav | cislo;             // k vynulovanym spodnim bitum pridat 'cislo' horni bity zustavaji beze zmeny v puvodnim stavu
      }

   Serial.print("PORTB = 0b");                    // jen zobrazeni obou registru v binarnim formatu
   Serial.print(PORTB,BIN);
   Serial.print("     PINB = 0b");
   Serial.println(PINB,BIN);
    
   delay(100);
  }

Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Převod čísla do 4 pinů

Příspěvek od kiRRow » 24 zář 2022, 09:51

peterple píše:
23 zář 2022, 21:14
Tak pozor....
Díky za upozornění, chybu jsem odstranil ... raději ať to nemate

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 17 hostů