současný běh dvou funkcí
Moderátor: Moderátoři
současný běh dvou funkcí
jsem začátečník,
chtěl bych udělat počítadlo pulzů (vstup + sedmisegmentovka)
Jen mi není jasný, jak se dělá to, že běží jedna fce + druhá k tomu
(Ideálně pořád svítí LEDka=zapnuto, počítají se pulzy, zobrazuje se číslo)
Pro zjednodušení program:
Jedna ledka pořád svítí + druhý dvě na jiným portu bliknou:
tohle logicky nemůže fungovat:
int main (void){
DDRB=0xff;
DDRC=0xff;
while(1)
{
PORTC=0b11111111;
}
for(char n=0;n<2;n++)
{
PORTB=0b00010000;
_delay_ms(400);
PORTB=0b00000000;
_delay_ms(400);
}}
Dalsie prerusenie bude dajme to mu od casovaca cca 25Hz(resp viac ak mas viac segmentov), v tomto preruseni budes multiplexovat displej. A ostatne mozes hodit do hlavnej slucky, alebo do dalsieho prerusenia a zbytok casu moze procesor byt v sleep
Kód: Vybrat vše
int main (void){
DDRB=0xff;
DDRC=0xff;
PORTC
while(1)
{
PORTC=0b11111111;
}
for(char n=0;n<2;n++)
{
PORTB=0b00010000;
_delay_ms(400);
PORTB=0b00000000;
_delay_ms(400);
}}Toto jistě fungovat nebude, protože program bude běžet v nekonečné smyčce while(1) a dál se nikdy nedostane.
(Pozn.: Pokud má ledka na PORTC stále svítit, tak stačí nastavit PORTC jednou, před vstupem do hlavní smyčky while(1). )
Trochu obměním kód.
Kód: Vybrat vše
while(1)
{
PORTC = ~PORTC; // invertuj všechny bity portu C.
for(char n=0;n<2;n++)
{
PORTB = 0b00010000;
_delay_ms(400);
PORTB = 0b00000000;
_delay_ms(400);
}
}Ale přitom nedělá "dvě funkce současně".
Napřed invertuje portC.
Pak dvakrát blikne ledkou na PORTB.4.
Pak opět invertuje portC.
Atd.
Jen mi není jasný, jak se dělá to, že běží jedna fce + druhá k tomu
(Ideálně pořád svítí LEDka=zapnuto, počítají se pulzy, zobrazuje se číslo)
Např. jednoduše takto:
Využiješ toho, že timery se dají přepnout do módu čítání impulsů.
V tomto módu timer počítá impulsy nezávisle na hlavním programu.
Kód: Vybrat vše
// atmega8
//-------------------------------------
int main(void)
{
uint16_t pocet_pulsu;
// nastav timer1 do režimu čítání impulsů na pinu T1
TCCR1B = 0b111;
// vynuluj timer1
TCNT1 = 0;
DDRC = 0xff;
PORTC = 0xff; // ledka na portC svítí
while(1)
{
pocet_pulsu = TCNT1;
zobraz hodnotu pocet_pulsu;
_delay_ms(200);
}
}Pokud použiješ sedmisegmentovky, tak ovšem musíš přidat přerušení pro multiplex, jak píše mikollar.
už se mi povedlo udělat program téměř podle mých představ
Když jsem řešil to přerušení, napadla mě takové (typicky české) řešení...potřeboval bych daleko větší čas přerušení (třeba 100ms), což s 4MHz krystalem neudělám...
...tak jsem zkoušel, co to udělá, když se do programu deklaruje 8MHz a krystal bude pořád stejnej...
Zvláštní je, že to funguje u fce _delay_ms(), ale u přerušení to zřejmě nefunguje
...tak jsem to přestal řešit a pustil se do PWM
Pro další nováčky: (počítání přetečení T1)
ISR (TIMER0_OVF_vect){
TCNT0 = 0; // nastavení počáteční hodnoty počítadla
if (T1==30) // kolikrat pretekl TIMER1
{
if (cislice==10) //pokud je cislo vetsi jak 9
{
cislice=0;
ukazC (cislice);
cislice++;
}
else
{
ukazC (cislice);
cislice++;
}
T1=0;
}
T1++;
}
A
Kód: Vybrat vše
ukazC (cislice);
cislice++;
by mohlo byt mimo ten if, ne?
Jirka
Už dlouho jsem se tomuto tématu věnoval, ale pořád jsem se nějak nemohl pustit do pořádnýho programování
Teď mám zdravotní volno a pustil jsem se do toho ve velkým!
Už mám naprogramovanou čtyřcifernou sedmisegmentovku, čítač (a odečítač
Teď bych ještě rád přepojil sedmisegmentovku na posuvnej registr a nastudoval PWM a nějaký typy úspornejch režimů včetně nějakýho podtaktování na snížení spotřeby. Potom jdu na LCD
Je až neuvěřitelný, jak rychle se na to všechno dá přijít když se do toho člověk fakt vrhne
Kód: Vybrat vše
... místo ...
PORTB=0b00010000;
_delay_ms(400);
PORTB=0b00000000;
... můžeš napsat ...
PORTB ^=0b00010000;
_delay_ms(400);
... a bude to mít stejný efekt :-)
pirat077 píše:Díky za odpovědi,
Když jsem řešil to přerušení, napadla mě takové (typicky české) řešení...potřeboval bych daleko větší čas přerušení (třeba 100ms), což s 4MHz krystalem neudělám...
Toto je trik ktorým oblbneš simulátor ale nie mikrokontrolér, ten bude mať
takt podľa pripojeného kryštálu.Nechápem ako súvisí frekvencia kryštálu
s prerušením.Pokiaľ chceš vytvoriť časovú základňu pomocou časovača pre dlhšie časy,stačí v prerušení od pretečenia časovača dekrementovať ďalšie počítadlo.Keď bude počítadlo na nule, čas vypršal.