casomira pomoci atmega8 a dvou IR zavor v jazyce C

Zdravim,
me zadani prace je takove:
Mam udelat casomiru s obvodem atmega8, pouzit externich preruseni (vystupy IR zavor), projeti jednou zavorou - start, projeti druhou zavorou - cil. Vystup na 7 segmentovku a PC (zatim 7seg.)

Chtel jsem se zkusenych poptat na programove reseni.
Projel jsem datasheet, ruzne navody a podobne, mam postavene opticke zavory, nakreslene schema k atmega8 ale ten program mi zatim moc nerika.

Ovladani 7 segmentovky by nemel byt proglem. Pouziji multiplex. ovladani. Problem mi spis dela casovani a vnejsi preruseni jak vyresit.
Byl bych rad za jakoukoliv radu ci klidne odkaz na nejake reseni casovani a preruseni, rad si to projdu. Ale potreboval bych to v jazyce C.

Dekuji za rady, s pozdravem Vasek

no ja bych zacal vystupem do PC misto na displej, myslim ze se to lip ladi

Tak já to nahodím jen tak teoreticky. Dělal jsem totiž zkusmo něco podobného. Místo optozávor jsem měl na bastldesce pouze DIP spínač, hodnoty jsem vypisoval na LCD 2 x 16 znaků, ale chodilo to.

Nastavil jsem čítač a počítal pulsy hodin (Atmega 16 s 16MHz krystalem). Po dosažení určité hodnoty čítače (teď z hlavy nevím kolik) jsem vygeneroval přerušení a zvýšil hodnotu času.

Čas jsem počítal tak, že jsem měl proměnné jednotky_s, desítky_s, jednotky_m, desítky_m, jednotky_h a v přerušení od čítače jsem tyto proměnné navyšoval.

Procesor pak celou dobu mimo přerušení nedělal nic jiného, než že stále dokola zobrazoval hodnoty na LCD a kontroloval vstupy.

Můžu se zeptat jaký používáš překladač? Jestli si udělám odpoledne chvíli čas tak ti sem hodím nějaký kód.

Ahoj, pouzivam AVR studio (neni problem nainstalovat neco jineho). Kdyby sis udelal cas, byl bych ti moc vdecny, at na to mrknu .) (ani komentarema nepohrdnu).
Jinak, sedmisegmentovku v multiplex. rezimu mi neprijde tezke ovladat, proto bych s ni chtel zacit, ale i na PC jiste dojde.
Jde mi spis hlavne o ty citace a externi preruseni.
Dekuji Vasek

tak tady je slíbený kod. Pokud budou nejake dotazy tak napiš. Od statnich si vyslechnu kritiku a popř. zlepšení kodu, jsem pogramator hadra.

Jinak je to delane v CodeVision, s trochou námahy neni problem predelat pro AVR studio.



//ATmega8 - 8,000000 MHz

#include <mega8.h>

unsigned char a[8];
unsigned char sekunda = 0, minuta = 0, hodina = 0;
unsigned int tisicina = 0;
float pom = 0;

// externí přerušení INT0, nastává při průchodu startem, začátek časomíry
interrupt [EXT_INT0] void ext_int0_isr(void)
{
#asm("cli")  //zákaz přerušení

//nulování času - průchod startem 
tisicina = 0;
sekunda = 0;
minuta = 0;
hodina = 0;

TCNT1 = 0;          //nulování čítače/časovače 1
TCCR1B=0x05;         //spouštění čítače/časovače 1, nastavení na 7 813 Hz,

#asm("clv")  //vynulování příznaku přetečení
#asm("sei")  //povolení přerušení
}

// externí přerušení INT1, konec časomíry
interrupt [EXT_INT1] void ext_int1_isr(void)
{
#asm("cli")  //zákaz přerušení

TCCR1B=0x00; //zastavení čítače/časovače 1 = zastavení času     
        
#asm("clv")  //vynulování příznaku přetečení
#asm("sei")  //povolení přerušení
}


// přerušení čítače/časovače 1 při načtení 7 813 pulzů do TCNT1
// přerušení nastáva při shodě TCNT1 s OCR1A
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
#asm("cli")  //zákaz přerušení 

sekunda++;   
TCNT1 = 0; 

#asm("clv")  //vynulování příznaku přetečení
#asm("sei")  //povolení přerušení
}

// Declare your global variables here

void main(void)
{
//nastavení do OCR1A hodnotu 7 813
OCR1AH=0x1E;
OCR1AL=0x85;



//nastavení externího přerušení na nástupnou hranu
GICR|=0xC0;
MCUCR=0x0F;
MCUCSR=0x00;
GIFR=0xC0;

// povolení přerušení pro čítač/časovač1
TIMSK=0x10;

// analogový komparátor
ACSR=0x80;
SFIOR=0x00;


// globalni povolení přerušení
#asm("sei")

while (1)
      {
         
        //tato cast pocita tisiciny sekundy, ale nezaokrouhluje, pouze orezava na 3 desetinna mista
        //nechtelo se me psat se zaokrouhlovanim
        pom = TCNT1;
        pom  /= 7813;
        pom *=1000;
        tisicina = (int)(pom);
        
        
        //přičtení minuty, nulování sekundy
        if(sekunda > 59)                  
        {
                minuta++;
                sekunda = 0;
                
                
        }
        //přičtení hodiny, nulování minuty      
        if(minuta > 59)
        {
                hodina++;
                minuta = 0;
        }
       //nulování hodiny
        if(hodina > 23)
        {
                hodina = 0;
        }
      
      
    
      };
}

Jeste me tak napadlo, s tim internim oscilatorem to neni nijak extra presne, kdyby jsi chtel neco presnejsiho, poves si na timer2 hodinkovy krystal, pak si myslim ze ta presnost uz bude slusna. Ale zrejme to mas do skoly a pujde jen o princip.

Zdar,
globální zakazování přerušení na začátku a povolování na konci není třeba, avr to dělá automaticky. To “#asm(“clv”)” má nějaký zvláštní význam?
Globální proměnné, se kterými pracuješ v přerušení, by měly být deklarovány s klíčovým slovem “volatile”. Nevím jak CodeVision, ale ve winavr by bez toho optimalizace kód pravděpodobně znefunkčnily.

myslim ze nulovani toho priznaku #asm(“clv”) je tam zbytecne, stejne tak jsi psal to povolovani, funguje to i bez toho, ale ja to tam obcas davam, zacinal jsem na knize od vani a ten to tam daval vzdy, tak me to asi zustalo. S tim volatile si codevision poradi a kod funguje, ale dik za pripominku a pro jistotu to zacnu pouzivat. Rad se priucim, dik za pripominky.

Dekuji moc za ochotu, zitra to v klidu projedu a kdyztak se budu ptat :slight_smile: a to ze asi budu. Samozrejmne, s krystalem pocitam, je to do skoly, ale ma to byt i jako funkcni aplikace kterou bych pak chtel pouzit na zavodech (pokud se teda podari dat vse dohromady).
Jeste jednou dekuji, zitra si to prelozim a upravim do avr studia a kdyztak se poptam na pripadne nejasnosti…

Tak jsem to projel a par otazek, vim ze budou asi dost hloupe, ale zacinam, proto budu rad pokud poradite…

16b citac je pouzit proc…?? Kvuli tomu ze mam hod, min, sec a tisic…??
Kdybych mel na stopkach pouze min, sec a tisic, stacil by 8b citac…??
(nebo jsem pouziti citacu spatne pochopil?)

Komparator je pouzit proc…?? Kvuli porovnavani citanych pulsu…?? Aby nedoslo k preteceni…??

Jinak pouziju externi krystal o frekvenci 8MHz, chtel jsem se zeptat jak jsi zjistil hodnutu 7 813 pulzů (vrchol) - to je podle frekvence vnitrniho RC clanku…??

A snad posledni otazka, co jaky registr dela vim, ale jaky bity nastavit pro jakou cinnost moc netusim, mas na to nejaky prehled v cestine nebo pouzivas pouze datasheet…??

Dekuji moc za pomoc, to je zatim snad vse.
Vasek

Není to kvůli tomu co píšeš. 16bit. čítač jsem použil protože můžeš napočítat jednu sekundu aniž bys musel pak něco dopočítávat. (8-bit. by ti i při max. dělícím poměru přetekl cca 30x za sekundu, 16bit jen jednou( v tomto pripadě nepřetéká ale porovnáva). Je to to nejjednodušší řešení, ale jde použít i 8bit. Použitá komparace se mě zdá lepší řešení než použít přetečení. Rozdíl je pouze minimální.
př. při přetečení v obslužné rutine nastavis do TCNT1 57723 a jedeš dál
při komparaci v obslužné rutině TCNT1 pouze vynuluješ, hodnotu 7813 mam jiz nastavenou v OCR1A

  - žádný velký rozdíl 

Ještě poznámka, těch 7813Hz (8000000Hz / 1024 = 7812,5, 8000000Hz /256 = 31250Hz) bude nepřesnější než 31250Hz. Tímto jsem myslím odpověděl na tvou další otázku. Mega má dělení oscilátoru u timerů -1,8,64,256,1024 proto při max. dělícím poměru je to těch 7813Hz, to znamená načítaných pulsů za sekundu.

Samozřejmě nejlepší je použít datasheet. Já osobně používám codewizard v codevision, tam si to jenom naklikám a on mě pak automaticky vyplivne nastavení registrů. Tady na foru je sekce download, viděl jsem tam nějake knihy v češtine, ale jestli tam je nejaka s popisem registru tak to nevim, zkus se podivat.