Ahoj, potřeboval bych poradit jak by se dala naprogramovat co nejjednodušeji Minutka tj. takový program, který bude mít k dispozici 8LEDek pro zobrazení max. hodnoty 80s (1LED = 10s) a libovolný počet tlačítek na ovládání. Jedno tlačítko by sloužilo k samotnému startu minutky, další dvě tlačítka by sloužila k nastavování odčítaného času tj. tlačítko + na přidání 10s a tlačítko - na odčítání 10s. Poslední tlačítko by bylo na vyvolání přerušení, které by přecházelo právě z režimu běhu minutky na režim nastavování a opačně. Předem děkuji za jakékoliv rady.
administrator: přejmenováno z "Minutka pomocí ATmega32"
Otázka je co myslíš tím jak naprogramovat? Nejjednodušší to bude zřejmě v céčku. Podle toho, že na takovou věc budeš dávat ATmega32, tak předpokládám že je to školní projekt, a z otázky jak naprogramovat zase, že o tom asi moc vědět nebudeš. Zkus napsat jak zdatný v tom jsi a můžem to postupně nějak splácat.
Tak jsem něco ubastlil, ale stále nevim jak vyřešit samotný běh minutky, jakožto aby se po nastavení např. 4ledek=40s se zhasínaly postupně další ledky směrem dolů.
a=0; //nastavení proměnné
DDRA=255; //všechny LED na výstup
DDRB=0; //všechny tlačítka na vstup
GICR=(1<<INT2); //nastavení prerušení nastaví 1 na INT2
sei();
while(1)
{
if(a==0) //nastavení doby odčítání
{
if(PINB==254) //nastavení času +
{
LED++;
if(LED>8)LED=8;
}
else if(PINB==253) //nastavení času -
{
LED--;
if(LED<0)LED=0;
}
PORTA=255;
PORTA=PORTA<<LED;
_delay_ms(200);
}
else //běh minutky
{
if(LED>0) //1led=10s
{
//
//kód běhu
//
_delay_ms(5000); //zpoždění 10s
_delay_ms(5000);
}
else if(LED==0) //blikání diod na konci programu
{
while(1)
{
PORTA=0b01010101;
_delay_ms(500);
PORTA=0b10101010;
_delay_ms(500);
}
}
}
}
int main()
{
a=0; //nastavení proměnné
DDRA=255; //všechny LED na výstup
DDRB=0; //všechny tlačítka na vstup
GICR=(1<<INT2); //nastavení prerušení nastaví 1 na INT2
sei();
while(1)
{
if(a==0) //nastavení doby odčítání
{
if(PINB==254) //nastavení času +
{
LED++;
if(LED>8)LED=8;
}
else if(PINB==253) //nastavení času -
{
LED–;
if(LED<0) LED=0;
}
PORTA=255;
PORTA=PORTA<<LED;
_delay_ms(200);
}
else //běh minutky
{
if(LED>0) //1led=10s
{
//
//kód běhu
//
_delay_ms(5000); //zpoždění 10s
_delay_ms(5000);
}
else if(LED==0) //blikání diod na konci programu
{
while(1)
{
PORTA=0b01010101;
_delay_ms(500);
PORTA=0b10101010;
_delay_ms(500);
}
}
}
}
}[/code]
Pokud pouzijes v promenne a pouze 0 a 1 staci definovat jako volatile unsigned char
Preruseni INT2 netrva tak dlouho aby si ho musel zakazovat a mezi programatory zakazovat v preruseni preruseni neni koser
_delay_ms(5000) nebude fungovat, myslim ze nejvetsi doba je 1200 ms, ale mozna se mylim.
Kod behu minutky
Vzhledem jak mas ten program napsany, pouzil bych obycejny for cyklus, kde ve vnitrni smycce bude zpozdeni 1 sekunda a zaroven osetreni spravneho sviceni led, ve for cyklu bych pracoval s promennou LED, kterou bych vynasobil *10
S tim cyklem přes for souhlasim, ale stále mám problém vyřešit to správné svícení LED. A ktomu kódu určitě je 100% špatně, jelikož při každé dekrementaci LED-- všechny diody zhasnou (PORTA=255). Jako tip bych viděl, že by se to posunulo o LED (PORTA=PORTA<<LED;) jen při prvním průběhu cyklem a poté už po uplynutí dané doby posunulo jen o PORTA=PORTA<<1. A ještě jsem přesně nepochopil, jak by si tu proměnou LED násobil 10*, ale zřejmě si myslel, že bych nedělal zpoždění rovnou 10s ale jen 1s.
PORTA = (0xFF <<(8-LED)); //Nastavit počáteční stav
for (unsigned char a = 0; a < LED ; a++)
{
_delay_ms(5000) ;
_delay_ms(5000) ;
PORTA <<= 1; // a pak jen posouvat
}
Děkuji za radu. Mohu se jenom zeptat. V tom kódu kde vlastně nastavím PORTA = (0xFF) což je jasný, že si zhasnu všechny diody, ale jak je tam ten bitovej pusun(8-LED), tak to mi dá např. při zadání času 50s=5LED (8-5) což jestli se nemýlim jsou 3, takže se mi z pravé strany nasunou 3 nuly (svítí 3LEDky zprava). Ted k tomu co bych chtěl je, aby se nasunuly ne ty 3LEDky jak jsem popsal výše, ale aby se mi nasunulo 5 nul zprava, aby mi jich svítilo vlastně 5 zprava a postupně zhasínaly, což už udělá posun PORTA <<= 1;.
Napadlo mě jedině tohle, ale určitě se to dá řešit elegantněji. Vždycky po posunu, když se nasune na LEDku první zleva nula, tak tam hned hodit na to místo 1 (PORTA += 128; neboli 0b10000000;)
[code]
PORTA = (0xFF <<(LED)); //Nastavit počáteční stav
for (unsigned char a = 0; a < (LED-1) ; a++)
{
PORTA =PORTA >> 1 ; // a pak jen posouvat
PORTA += 128 ;
} [/code]
A nevznikne tam nějaká prodleva tím, že to vždy posune o jednu pozici doprava a než se tam vloží na to poslední místo ta 1 ?? Jde mi o to, aby nevniklo to, že ta poslední LEDka vždy na chviličku zhasne a zas se rozsvítí. Nemám u sebe kit s programátorem, takže to nemohu otestovat.