mam gulas v bitovych operatoroch ...pls HELP
Moderátor: Moderátoři
mam gulas v bitovych operatoroch ...pls HELP
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
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
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.
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.
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
- ZdenekHQ
- Administrátor
- Příspěvky: 25593
- Registrován: 21 črc 2006, 02:00
- Bydliště: skoro Brno
- Kontaktovat uživatele:
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..Atlan píše:a hlavne je to neprehladne pre zaciatoxnika
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[?]
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[?]
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
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
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.
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 ...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.
AHOJ
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);
}
}
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 ?
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;
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 ?
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 ?
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 ?