Zdravím, řeším další otázku z programování : jak udělat hodiny(mozna spis stopky).
Potrerebuji stopovat čas od startu jedne udalosti po jeji konec (napr. Od pripojeni napeti na AD prevodnik po jeho odpojení)
jak byste takovou situaci resili....? Vyuzit casovace a jejich preruseni....? také potřebuji aby byl hodne přesný, jelikož se používá k výpočtu a vzikla by tak chyba.
Jako MCU pouzivam ATMEGA16, krystal 16Mhz
hodil by se nejaky priklad...
diky za odpovedi
Fórum › Mikrokontroléry
Jak udělat hodiny
jestli se jedna jenom o binar ( je napeti vs neni napeti) a ono napeti je 0 nebo 5 V, tak bych to soupnul na externi preruseni a nastavil jej na reakci na vzestupnou hranu
v obsluze bych potom spustil casovac nastaveny na generovani preruseni kazdych X s/ms/ns jak uznas za vhodne, a potom nastavil reakci na sestupnou hranu, kdy casovac vypnes
v obsluze preruseni casovace inkrementovat promennou
tedy neco v tomto duchu
long cas=0
bool konec=false;
bool pocitam=false;
nastav_timer_na_generovani_preruseni_ale_jeste_nespoustet = cs0,cs1,cs2 musi byt v 0
nastav_externi_preruseni_na_vzestupnou_hranu
sei();
while(1)
{
if(konec)
{
proved_vypocet;
cas=0;
konec=false;
}
}
obsluha_preruseni_casovace()
{
cas++;
}
obsluha_externiho_preruseni()
{
if(!pocitam)
{
zapni_citac;
pocitam=true;
nastav_na_sestupnou_hranu;
}
else
{
vypni_citac;
pocitam=false;
nastav_vzestupnou_hranu;
konec=true;
}
}
pokud bude napeti na vstupu nizsi nez rozhodovaci uroven nebo vyssi nez 5V lze pouzit komparator, tady zalezi na frekvenci zmen
Udelal sem tenhle program... pri preruseni by se mela promenna "sek" zvysit o 1, a zobrazit na displeji. Problem vsak je ze se na displeji poprve zobrazi hodnota 2...pak uz to jde poporade 3,4,5,... s intervalem 1s. Jak byste udelali aby se jako prvni hodnota na displeji zobrazila 0, pak 1,2,3,....
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include "lcd_lib.h"
volatile uint8_t sek =0;
char cas[2];
void timerInit( void);
///////////////////////////////////////////////////////////////////////////
int main(void)
{
LCDinit();//init LCD bit, dual line, cursor right
LCDclr();//clears LCD
timerInit();
while(1)//loop demos
{
itoa(sek ,cas,10);
LCDchar(cas);
}
}
void timerInit( void)
{
//Nastavení citace/casovace
TCCR1A=0x0B;
TCCR1B=0x14; // FCPU/256
TCNT1=0; // spodni hodnota casovace
OCR1AH=0x7A; // dvojice registru urcujici TOP casovace
OCR1AL=0x12;
TIMSK=0x04; // Timer(s)/Counter(s) Interrupt(s) initialization
sei();
}
ISR(TIMER1_OVF_vect)
{
sek++;
}
Tak nevím, tady chodí perfektně.
// Atmega8 8MHz
// Winavr 20100110
volatile uint8_t sek = 0;
volatile uint8_t flag;
char cas[6];
void timerInit( void);
///////////////////////////////////////////////////////////////////////////
int main(void)
{
uart_init();
timerInit();
uart_putc('0');
uart_n(); // new line
sei();
while(1)//loop demos
{
if(flag)
{
itoa(sek ,cas,10);
uart_puts(cas);
uart_n();
flag=0;
}
}
}
///////////////////////////////////////////////////////////////////////////
void timerInit( void)
{
//Nastavení citace/casovace mod 14
TCCR1A = (1<<WGM11);
TCCR1B = (1<<WGM12) | (1<<WGM13) | (1<<CS12); // FCPU/256
TIMSK=0x04; // Timer(s)/Counter(s) Interrupt(s) initialization
ICR1=31250;
}
//-------------------------------------------------------------------------
ISR(TIMER1_OVF_vect)
{
sek++;
flag=1;
}
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Jak to udělat — založil Dave
Otázka - Jak to udělat? — založil Q.
Jak udělat gradient? — založil ingiraxo
Jak to lze udělat — založil Radka
Jak udělat aplikaci? — založil Jakub
Moderátoři diskuze