Stránka 1 z 2
mam gulas v bitovych operatoroch ...pls HELP
Napsal: 25 čer 2010, 15:04
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

Napsal: 25 čer 2010, 15:47
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.
Napsal: 25 čer 2010, 16:04
od Atlan
a hlavne je to neprehladne pre zaciatoxnika

Napsal: 25 čer 2010, 16:07
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

dakujem velmi pekne
Napsal: 25 čer 2010, 17:00
od ZdenekHQ
Atlan píše:a hlavne je to neprehladne pre zaciatoxnika

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..

Napsal: 25 čer 2010, 17:51
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
Napsal: 26 čer 2010, 07:53
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.
Napsal: 26 čer 2010, 08:42
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
Napsal: 26 čer 2010, 10:50
od procesor
...ja sa iba ucim .
To sme tu takmer všetci až do smrti, iba poniektorí učia

Napsal: 26 čer 2010, 21:10
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
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[i]);
}
}
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 ?

Napsal: 26 čer 2010, 21:26
od Andrea
Zkus tam dát místo apostrofů uvozovky "MISKO".
Napsal: 26 čer 2010, 21:37
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 ?

Napsal: 26 čer 2010, 21:47
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?

Napsal: 26 čer 2010, 21:54
od arbet
nie nie nemam ...setko studujem z internetu ..ucim sa na zdrojakoch ..atd ... ale ak mas niaku fakt dobru knihu ..v pdf ..uvitam

Napsal: 26 čer 2010, 21:56
od Andrea
V PDF ne, na papíře. Pavel Herout, Učebnice jazyka C.