mam gulas v bitovych operatoroch ...pls HELP

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
arbet
Příspěvky: 61
Registrován: 23 říj 2007, 02:00

mam gulas v bitovych operatoroch ...pls HELP

#1 Příspěvek od arbet »

mozem sa spytat ako to funguje s jednotlivymi bitovymi operatormi ..akosi tomu nechapem..ale chcem pochopit

takze viem ze & je logicky sucin ..aj viem co robi logicky sucin..len akosi neviem porozumiet preco sa znak nasobi prave tym osembitovym cislom (dost viem o tom viem ze aj preto lebo je to 4bitova komunikacia tak je to tam dva krat ...len stale mi ta podstata unika ze preco..neviem si predstavit prakticky priklad)

<< toto viem ze je bitovy posun vlavo a bitovy sucet je | ..ibaze akosi si to vobec neviem predstavit ...a kombinaciu oboch ako je to napr LCD|=1<<LCD_RS; us vobec nechapem

alebo LCD&=~(1<<LCD_E); viem ze to je sucin a negacia ..ale absolutne si neviem predstavit co to v konecnom dosledku sposobi ...asi je to sposobene tym ze ked vymyslali jazyk c ..boli strasne lenivy ..a namiesto a+a dali rovno a+ ...ci ako to je ..viete ako to myslim ..viete mi to niekto kusok podrobnejsie vysvetlit ? ja to us potom budem chapat ...dakujem



void PosliZnakLCD(uint8_t cmd)
{
LCD=(cmd&0b11110000);
LCD|=1<<LCD_RS;
LCD|=1<<LCD_E;
_delay_ms(1);
LCD&=~(1<<LCD_E);
LCD&=~(1<<LCD_RS);
_delay_ms(1);
LCD=((cmd&0b00001111)<<4);
LCD|=1<<LCD_RS;
LCD|=1<<LCD_E;
_delay_ms(1);
LCD&=~(1<<LCD_E);
LCD&=~(1<<LCD_RS);
_delay_ms(1);

}

dakujem dopredu za vysvetlenie ..pripadne za poskytnutie webovych stranok kde je tato tema rozoberana podrobne na pochopenie ..fakt som len uplny zaciatocnik ..a setko sa skusam ucit iba metodou pokus-omyl :)

Uživatelský avatar
piitr
Příspěvky: 1003
Registrován: 19 říj 2007, 02:00
Kontaktovat uživatele:

#2 Příspěvek od piitr »

Bajt má osm bitů. Operace & provede operaci AND pro každý bit. Dělá to tedy jakoby osmkrát. Vezme nejnižší bit levého bajtu a nejnižší bit pravého bajtu, udělá s nimi AND a výsledek bude nejnižší bit výsledku. S ostatními bity udělá totéž.

Pak je dobré si uvědomit, že pro každý bit platí x&0=0 a x&1=x. Tedy anduju-li jedničkou, nic se neděje. Anduju-li něco nulou, smažu to. Takže AND použiju, když chci nějaké bity vynulovat. Takže v tom příkladu cmd&0b11110000 vrátí hodnotu cmd, ale se smazanou spodní půlkou bajtu. Přenese tedy jen tu horní půlku. Tu spodní schválně mažeme, abychom pak ORem mohli přidat jedničku, kam chceme.

S ORem je to podobné. Platí pro každý bit: x|0=x a x|1=1. Tedy OR jedničkou nastaví daný bit a OR nulou neudělá nic. OR použiju, chci-li některé bity nastavit na jedna. 1<<LCD_RS je bajt, kde jsou všechny bity nulové, jen LCD_RS-tý bit je jedničkový. Když tím něco vyoruješ, tak se v tom ten LCD_RS-tý bit nastaví na jedničku.

Takže:
x |= 1 << n; // nastaví n-tý bit
x &= ~(1 << n); // smaže n-tý bit

A tak podobně. Dá se s tím dost kouzlit.

Uživatelský avatar
Atlan
Příspěvky: 4499
Registrován: 10 kvě 2004, 02:00
Bydliště: Košice

#3 Příspěvek od Atlan »

a hlavne je to neprehladne pre zaciatoxnika :D

Uživatelský avatar
arbet
Příspěvky: 61
Registrován: 23 říj 2007, 02:00

#4 Příspěvek od arbet »

piitr píše:Bajt má osm bitů. Operace & provede operaci AND pro každý bit. Dělá to tedy jakoby osmkrát. Vezme nejnižší bit levého bajtu a nejnižší bit pravého bajtu, udělá s nimi AND a výsledek bude nejnižší bit výsledku. S ostatními bity udělá totéž.

Pak je dobré si uvědomit, že pro každý bit platí x&0=0 a x&1=x. Tedy anduju-li jedničkou, nic se neděje. Anduju-li něco nulou, smažu to. Takže AND použiju, když chci nějaké bity vynulovat. Takže v tom příkladu cmd&0b11110000 vrátí hodnotu cmd, ale se smazanou spodní půlkou bajtu. Přenese tedy jen tu horní půlku. Tu spodní schválně mažeme, abychom pak ORem mohli přidat jedničku, kam chceme.

S ORem je to podobné. Platí pro každý bit: x|0=x a x|1=1. Tedy OR jedničkou nastaví daný bit a OR nulou neudělá nic. OR použiju, chci-li některé bity nastavit na jedna. 1<<LCD_RS je bajt, kde jsou všechny bity nulové, jen LCD_RS-tý bit je jedničkový. Když tím něco vyoruješ, tak se v tom ten LCD_RS-tý bit nastaví na jedničku.

Takže:
x |= 1 << n; // nastaví n-tý bit
x &= ~(1 << n); // smaže n-tý bit

A tak podobně. Dá se s tím dost kouzlit.

tak toto nema chybu ...uplne si mi v tom spravil jasno ..us tomu chapem ..idem sa pokusit nieco naprogramovat :P dakujem velmi pekne

Uživatelský avatar
ZdenekHQ
Administrátor
Administrátor
Příspěvky: 25593
Registrován: 21 črc 2006, 02:00
Bydliště: skoro Brno
Kontaktovat uživatele:

#5 Příspěvek od ZdenekHQ »

Atlan píše:a hlavne je to neprehladne pre zaciatoxnika :D
Je to příšerný. Když podobný programátor potom doma stejnou logikou požádá manželku o večeři, tak jeho pes odejde zasadit kropící konev na Saharu.. :D
Pro moje oslovení klidně použijte jméno Zdeněk
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?
]

Uživatelský avatar
arbet
Příspěvky: 61
Registrován: 23 říj 2007, 02:00

#6 Příspěvek od arbet »

podla mna je to praveze pekne a prehladne ...co sa kde nastavuje je to aspon vidiet ... no ale teraz o niecom inom ..viacej krat som to rozoberal tun..ale este raz ..nech mam v tom jasno ... mam displej PC106 2x16 riadkov zapojeny podla tejto schemy na obrazku (akurat namiesto atmega 8 je 32) ...no a takisto vam prikladam zdrojak ... malo by mi to pekne vypisat AHOJ ...ale ono nevypise nic ..iba svietia dva rady stvorcekov ...mohli by ste mi povedat v com je problem ?

dakujem za odpovede


#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 8000000UL



#define LCD_E 5
#define LCD_RS 4
#define LCD_D7 3 // bit, na ktory je dany signal na porte pripojeny
#define LCD_D6 2
#define LCD_D5 1
#define LCD_D4 0
#define LCD PORTC // definovany port kde je LCD pripojeny
#define LCDR DDRC // definovany smerovy register pre LCD




void PosliPrikazLCD(uint8_t cmd) //v proměnné cmd máme poslaný typ příkazu

{

LCD=((cmd&0b11110000))>>4; // pro nastaveni pouzijeme jen 4-bity

LCD|=1<<LCD_E; // cvaknem E signalem

_delay_ms(1);

LCD&=~(1<<LCD_E);

_delay_ms(1); // pokazde pockame, displej ma pomaly procesor

LCD=(cmd&0b00001111); // nastavime zbyle 4-bity

LCD|=1<<LCD_E;

_delay_ms(1);

LCD&=~(1<<LCD_E);

_delay_ms(1); // a zase jsme zacvakali E signalem

}




void PosliZnakLCD(uint8_t cmd) //v proměnné cmd máme poslany znak na LCD

{

LCD=((cmd&0b11110000)>>4); // pro nastaveni pouzijeme jen 4-bity

LCD|=1<<LCD_RS;

LCD|=1<<LCD_E; // cvaknem E signalem

_delay_ms(1);

LCD&=~(1<<LCD_E);

LCD&=~(1<<LCD_RS);

_delay_ms(1); // pokazde pockame, displej ma pomaly procesor

LCD=(cmd&0b00001111); // nastavime zbyle 4-bity

LCD|=1<<LCD_RS;

LCD|=1<<LCD_E;

_delay_ms(1);

LCD&=~(1<<LCD_E);

LCD&=~(1<<LCD_RS);

_delay_ms(1); // a zase jsme zacvakali E signalem

}




void InicializujLCD(void) // teto procedure nic neposilame, proto je tam (void)

{

_delay_ms(15); // po zapnuti napajeni se displej sam nastavuje a to mu trva dost dlouho, dame mu cas!

LCD=0x00; // vsude bude L! Pak nastavime datove a ridici vodice

// nastavime 8-bitovy komunikacni mod !! (protoze nevime zda uz displej byl prepnut nebo ne)



LCDR|=1<<LCD_D7|1<<LCD_D6|1<<LCD_D5|1<<LCD_D4;

LCDR|=1<<LCD_E|1<<LCD_RS; // vsechny smery jsou VEN!

LCD=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4; // ted posleme specialni prikaz pro LCD

LCD|=1<<LCD_E|0<<LCD_RS; // pro zvedavce je to Function Set prikaz

_delay_ms(1);

LCD&=~(1<<LCD_E); // pockame a cvakneme E signalem, to uz zname z posilani prikazu a znaku

_delay_ms(1);

LCD=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4; //kvuli 4 bitove komunikaci musime poslat i dalsi 4 bity

LCD|=1<<LCD_E|0<<LCD_RS;

_delay_ms(1);

LCD&=~(1<<LCD_E);

_delay_ms(1);

// ted by mel byt display v 8-bitovem modu a definitivne ho prepneme do 4-bitoveho modu!

LCD=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|0<<LCD_D4;

LCD|=1<<LCD_E|0<<LCD_RS;

_delay_ms(1);

LCD&=~(1<<LCD_E);

_delay_ms(1);

// 2 radkovy displej

PosliPrikazLCD(0b00101000);

// zvedej sam adresu, posunuj kurzor

PosliPrikazLCD(0b00001110);

}




void VymazLCD(void) //nic se neposila

{

PosliPrikazLCD(0b00000001);

}



void KurzorPocatek(void) //nic se neposila

{

PosliPrikazLCD(0b00000010);

}




void main()

{

// nastavíme LCD

InicializujLCD();

VymazLCD();

PosliZnakLCD('A');

PosliZnakLCD('h');

PosliZnakLCD('o');

PosliZnakLCD('j');

while(1)

{

// nekonecna smycka

}

}

//konec programu
Přílohy
LCDLayout-full.gif
(23.09 KiB) Staženo 71 x

Uživatelský avatar
Standa33
Příspěvky: 283
Registrován: 07 lis 2009, 01:00

#7 Příspěvek od Standa33 »

Chyba bude v inicializaci LCD, máš dobře nastaveno po zapnutí napájení delay 15ms, ale po odeslání prvního příkazu (D7..D4 - 0011;8bitová komunikace) by mělo následovat delay 4,1ms. Pro další příkazy již stačí cca 40us. Jen pro příkaz Vymaž displej a Návrat na začátek by mělo být delay 1,64ms.

Takže pro příkazu VymazLCD by měl být delay 1,64ms. Pročti si datasheet pro ten LCD displej, najdeš tam jaké česování je nutné pro jednotlivé příkazy.

Uživatelský avatar
arbet
Příspěvky: 61
Registrován: 23 říj 2007, 02:00

#8 Příspěvek od arbet »

Standa33 píše:Chyba bude v inicializaci LCD, máš dobře nastaveno po zapnutí napájení delay 15ms, ale po odeslání prvního příkazu (D7..D4 - 0011;8bitová komunikace) by mělo následovat delay 4,1ms. Pro další příkazy již stačí cca 40us. Jen pro příkaz Vymaž displej a Návrat na začátek by mělo být delay 1,64ms.

Takže pro příkazu VymazLCD by měl být delay 1,64ms. Pročti si datasheet pro ten LCD displej, najdeš tam jaké česování je nutné pro jednotlivé příkazy.
Dakujem velmi pekne...us mi to funguje na ten delay 4,1 sekundy som zabudol ...ja sa iba ucim ..toto su prve pokusy ...som velmi stastny ze sa mi to tam konecne rozsvietilo ...

AHOJ

Uživatelský avatar
procesor
Příspěvky: 5284
Registrován: 02 říj 2009, 02:00
Bydliště: PO

#9 Příspěvek od procesor »

...ja sa iba ucim .
To sme tu takmer všetci až do smrti, iba poniektorí učia :wink:

Uživatelský avatar
arbet
Příspěvky: 61
Registrován: 23 říj 2007, 02:00

#10 Příspěvek od arbet »

ahoj, takze displej mi uz ide davno ..setkemu chapem ..vypisovat viem znaky v pohode ..ale trapim sa s pochopenim funkcie na vypisanie rovno textu (string) a nielen vypisovanie po pismenku ... zevraj to ma fungovat takto :P

void VytiskniLCD(uint8_t* retezec, uint8_t nZnaku) //posílá se odkaz na řetězec a počet znaků

{

register uint8_t i;

// pro sichr si zkontrolujeme pointer

if (!retezec) return;



// print

for(i=0; i<nZnaku; i++)

{

PosliZnakLCD(retezec);

}

}




void PosliZnakLCD(uint8_t cmd) //v proměnné cmd máme poslany znak na LCD

{

LCD=((cmd&0b11110000)>>4); // pro nastaveni pouzijeme jen 4-bity

LCD|=1<<LCD_RS;

LCD|=1<<LCD_E; // cvaknem E signalem

_delay_ms(1);

LCD&=~(1<<LCD_E);

LCD&=~(1<<LCD_RS);

_delay_ms(1); // pokazde pockame, displej ma pomaly procesor

LCD=(cmd&0b00001111); // nastavime zbyle 4-bity

LCD|=1<<LCD_RS;

LCD|=1<<LCD_E;

_delay_ms(1);

LCD&=~(1<<LCD_E);

LCD&=~(1<<LCD_RS);

_delay_ms(1); // a zase jsme zacvakali E signalem






funkciu som zavolal takymto sposobom

VytiskniLCD('MISKO',6);


Kompilator mi nevypisal ani jednu chybu .. ibaze na displeji nieje MISKO ..ale 4 cierne stvorceky ..preco ? :(

Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#11 Příspěvek od Andrea »

Zkus tam dát místo apostrofů uvozovky "MISKO".

Uživatelský avatar
arbet
Příspěvky: 61
Registrován: 23 říj 2007, 02:00

#12 Příspěvek od arbet »

jj ide ...dakujeeeem ...a aky je v tom rozdiel ? medzi uvodzovkami a apostrofom ? + ak mozes ...

void VytiskniLCD(uint8_t* retezec, uint8_t nZnaku) preco je tam * ?
register uint8_t i; co to robi ?
if (!retezec) return; ...to je akoze negacia ci co ?

cyklu chapem ...

a nevies ako previest cislo (uint8_t) na string ?... potrebujem proste premennu vypisovat na displej a je to (integer) ..najlepsie podla mna previest na string do dakej premenej a tu rovno vypisat..lenze nevies teda ako ? :P

Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#13 Příspěvek od Andrea »

'X' je znaková konstanta, velikost je int
"XYZ" je řetězec
* značí pointer
register říká překladači, aby tu proměnnou umístil pokud možno do registru
! je negace
Na převod do stringu je funkce sprintf()

To nemáš nějakou učebnici C? :roll:

Uživatelský avatar
arbet
Příspěvky: 61
Registrován: 23 říj 2007, 02:00

#14 Příspěvek od arbet »

nie nie nemam ...setko studujem z internetu ..ucim sa na zdrojakoch ..atd ... ale ak mas niaku fakt dobru knihu ..v pdf ..uvitam :P

Andrea
Příspěvky: 9340
Registrován: 07 zář 2007, 02:00

#15 Příspěvek od Andrea »

V PDF ne, na papíře. Pavel Herout, Učebnice jazyka C.

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“